LSSTApplications  19.0.0-10-g920eed2,19.0.0-11-g48a0200+2,19.0.0-18-gfc4e62b+13,19.0.0-2-g3b2f90d+2,19.0.0-2-gd671419+5,19.0.0-20-g5a5a17ab+11,19.0.0-21-g2644856+13,19.0.0-23-g84eeccb+1,19.0.0-24-g878c510+1,19.0.0-25-g6c8df7140,19.0.0-25-gb330496+1,19.0.0-3-g2b32d65+5,19.0.0-3-g8227491+12,19.0.0-3-g9c54d0d+12,19.0.0-3-gca68e65+8,19.0.0-3-gcfc5f51+5,19.0.0-3-ge110943+11,19.0.0-3-ge74d124,19.0.0-3-gfe04aa6+13,19.0.0-30-g9c3fd16+1,19.0.0-4-g06f5963+5,19.0.0-4-g3d16501+13,19.0.0-4-g4a9c019+5,19.0.0-4-g5a8b323,19.0.0-4-g66397f0+1,19.0.0-4-g8278b9b+1,19.0.0-4-g8557e14,19.0.0-4-g8964aba+13,19.0.0-4-ge404a01+12,19.0.0-5-g40f3a5a,19.0.0-5-g4db63b3,19.0.0-5-gfb03ce7+13,19.0.0-6-gbaebbfb+12,19.0.0-61-gec4c6e08+1,19.0.0-7-g039c0b5+11,19.0.0-7-gbea9075+4,19.0.0-7-gc567de5+13,19.0.0-71-g41c0270,19.0.0-9-g2f02add+1,19.0.0-9-g463f923+12,w.2020.22
LSSTDataManagementBasePackage
utils.py
Go to the documentation of this file.
1 # This file is part of obs_base.
2 #
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (https://www.lsst.org).
6 # See the COPYRIGHT file at the top-level directory of this distribution
7 # for details of code ownership.
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 
22 __all__ = ('InitialSkyWcsError', 'createInitialSkyWcs', 'bboxFromIraf')
23 
24 import re
25 import lsst.geom as geom
26 
27 from . import Instrument
28 from lsst.afw.cameraGeom import PIXELS, FIELD_ANGLE
29 from lsst.afw.image import RotType
30 from lsst.afw.geom.skyWcs import makeSkyWcs
32 from lsst.utils import doImport
33 
34 
35 class InitialSkyWcsError(Exception):
36  """For handling failures when creating a SkyWcs from a camera geometry and
37  boresight.
38 
39  Typically used as a chained exception from a lower level exception.
40  """
41  pass
42 
43 
44 def createInitialSkyWcs(visitInfo, detector, flipX=False):
45  """Create a SkyWcs from the telescope boresight and detector geometry.
46 
47  A typical usecase for this is to create the initial WCS for a newly-read
48  raw exposure.
49 
50 
51  Parameters
52  ----------
53  visitInfo : `lsst.afw.image.VisitInfo`
54  Where to get the telescope boresight and rotator angle from.
55  detector : `lsst.afw.cameraGeom.Detector`
56  Where to get the camera geomtry from.
57  flipX : `bool`, optional
58  If False, +X is along W, if True +X is along E.
59 
60  Returns
61  -------
62  skyWcs : `lsst.afw.geom.SkyWcs`
63  The new composed WCS.
64 
65  Raises
66  ------
67  InitialSkyWcsError
68  Raised if there is an error generating the SkyWcs, chained from the
69  lower-level exception if available.
70  """
71  if visitInfo.getRotType() != RotType.SKY:
72  msg = (f"Cannot create SkyWcs from camera geometry: rotator angle defined using "
73  f"RotType={visitInfo.getRotType()} instead of SKY.")
74  raise InitialSkyWcsError(msg)
75  orientation = visitInfo.getBoresightRotAngle()
76  boresight = visitInfo.getBoresightRaDec()
77  try:
78  pixelsToFieldAngle = detector.getTransform(detector.makeCameraSys(PIXELS),
79  detector.makeCameraSys(FIELD_ANGLE))
81  raise InitialSkyWcsError("Cannot compute PIXELS to FIELD_ANGLE Transform.") from e
82  return makeSkyWcs(pixelsToFieldAngle, orientation, flipX, boresight)
83 
84 
85 def bboxFromIraf(irafBBoxStr):
86  """Return a Box2I corresponding to an IRAF-style BBOX
87 
88  [x0:x1,y0:y1] where x0 and x1 are the one-indexed start and end columns, and correspondingly
89  y0 and y1 are the start and end rows.
90  """
91 
92  mat = re.search(r"^\[([-\d]+):([-\d]+),([-\d]+):([-\d]+)\]$", irafBBoxStr)
93  if not mat:
94  raise RuntimeError("Unable to parse IRAF-style bbox \"%s\"" % irafBBoxStr)
95  x0, x1, y0, y1 = [int(_) for _ in mat.groups()]
96 
97  return geom.BoxI(geom.PointI(x0 - 1, y0 - 1), geom.PointI(x1 - 1, y1 - 1))
98 
99 
100 def getInstrument(instrumentName, registry=None):
101  """Return an instance of a named instrument.
102 
103  If the instrument name not is qualified (does not contain a '.') and a
104  butler registry is provided, this will attempt to load the instrument using
105  Instrument.fromName. Otherwise the instrument will be imported and
106  instantiated.
107 
108  Parameters
109  ----------
110  instrumentName : string
111  The name or fully-qualified class name of an instrument.
112  registry : `lsst.daf.butler.Registry`, optional
113  Butler registry to query to find information about the instrument, by
114  default None
115 
116  Returns
117  -------
118  Instrument subclass instance
119  The instantiated instrument.
120 
121  Raises
122  ------
123  RuntimeError
124  If the instrument can not be imported, instantiated, or obtained from
125  the registry.
126  TypeError
127  If the instrument is not a subclass of lsst.obs.base.Instrument.
128  """
129  if "." not in instrumentName and registry is not None:
130  try:
131  instr = Instrument.fromName(instrumentName, registry)
132  except Exception as err:
133  raise RuntimeError(
134  f"Could not get instrument from name: {instrumentName}. Failed with exception: {err}")
135  else:
136  try:
137  instr = doImport(instrumentName)
138  except Exception as err:
139  raise RuntimeError(f"Could not import instrument: {instrumentName}. Failed with exception: {err}")
140  instr = instr()
141  if not isinstance(instr, Instrument):
142  raise TypeError(f"{instrumentName} is not an Instrument subclass.")
143  return instr
144 
145 
146 # TODO remove the impl in pipe_base? (NB this combines setDottedAtr AND the
147 # handling in ConfigValueAction.__call__)
148 def setDottedAttr(item, name, value):
149  """Set an instance attribute (like `setattr` but accepting hierarchical
150  names such as ``foo.bar.baz``) If the attribute can not be set as a string,
151  will attempt to set the attribute with the result of eval'ing the value.
152 
153  Parameters
154  ----------
155  item : obj
156  Object whose attribute is to be set.
157  name : `str`
158  Name of attribute to set.
159  value : obj
160  New value for the attribute.
161 
162  Notes
163  -----
164  For example if name is ``foo.bar.baz`` then ``item.foo.bar.baz``
165  is set to the specified value.
166 
167  Raises
168  ------
169  AttributeError
170  If the item does not have a field specified by name that can be set.
171  RuntimeError
172  If the value can not be set as a string or rendered by eval, or if
173  there is an error setting the attribute with the rendered value.
174  """
175  subitem = item
176  subnameList = name.split(".")
177  for subname in subnameList[:-1]:
178  subitem = getattr(subitem, subname)
179  try:
180  setattr(subitem, subnameList[-1], value)
181  except AttributeError:
182  raise AttributeError(f"No field: {name!r}")
183  except Exception:
184  try:
185  v = eval(value, {})
186  except Exception:
187  raise RuntimeError(f"Cannot render {value!r} as a value for {name!r}")
188  try:
189  setattr(subitem, subnameList[-1], v)
190  except Exception as e:
191  raise RuntimeError(f"Cannot set config. {name}={value!r}: {e}")
192 
193 
194 def setDottedAttrs(item, attrs):
195  for name, value in attrs:
196  setDottedAttr(item, name, value)
lsst::afw::image
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Definition: imageAlgorithm.dox:1
lsst.obs.base.utils.getInstrument
def getInstrument(instrumentName, registry=None)
Definition: utils.py:100
lsst.obs.base.utils.setDottedAttrs
def setDottedAttrs(item, attrs)
Definition: utils.py:194
lsst::daf::persistence.utils.doImport
def doImport(pythonType)
Definition: utils.py:104
lsst.obs.base.utils.bboxFromIraf
def bboxFromIraf(irafBBoxStr)
Definition: utils.py:85
lsst::utils
Definition: Backtrace.h:29
lsst::geom
Definition: geomOperators.dox:4
lsst::afw::cameraGeom
Definition: Amplifier.h:33
lsst::pex::exceptions::InvalidParameterError
Reports invalid arguments.
Definition: Runtime.h:66
lsst.obs.base.utils.InitialSkyWcsError
Definition: utils.py:35
lsst::geom::Point< int, 2 >
lsst::afw::geom.skyWcs
Definition: __init__.py:1
lsst::geom::Box2I
An integer coordinate rectangle.
Definition: Box.h:55
lsst::afw::geom::makeSkyWcs
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.
Definition: SkyWcs.cc:526
lsst.obs.base.utils.createInitialSkyWcs
def createInitialSkyWcs(visitInfo, detector, flipX=False)
Definition: utils.py:44
lsst::pex::exceptions
Definition: Exception.h:37
lsst.obs.base.utils.setDottedAttr
def setDottedAttr(item, name, value)
Definition: utils.py:148