def polar(row: Any) -> pandas.Series: v3d = Vector3d(row.x, row.y, row.z) sp = SpherePoint(v3d) return pandas.Series( [sp.getRa().asDegrees(), sp.getDec().asDegrees()], index=["ra", "decl"])
def register(self, name, registry): """Add SkyMap, Tract, and Patch Dimension entries to the given Gen3 Butler Registry. Parameters ---------- name : `str` The name of the skymap. registry : `lsst.daf.butler.Registry` The registry to add to. """ nxMax = 0 nyMax = 0 records = { "skymap": [], "tract": [], "patch": [], } for tractInfo in self: nx, ny = tractInfo.getNumPatches() nxMax = max(nxMax, nx) nyMax = max(nyMax, ny) region = tractInfo.getOuterSkyPolygon() centroid = SpherePoint(region.getCentroid()) records["tract"].append({ "skymap": name, "tract": tractInfo.getId(), "region": region, "ra": centroid.getRa().asDegrees(), "dec": centroid.getDec().asDegrees(), }) for patchInfo in tractInfo: cellX, cellY = patchInfo.getIndex() records["patch"].append({ "skymap": name, "tract": tractInfo.getId(), "patch": tractInfo.getSequentialPatchIndex(patchInfo), "cell_x": cellX, "cell_y": cellY, "region": patchInfo.getOuterSkyPolygon(tractInfo.getWcs()), }) records["skymap"].append({ "skymap": name, "hash": self.getSha1(), "tract_max": len(self), "patch_nx_max": nxMax, "patch_ny_max": nyMax, }) with registry.transaction(): for dimension, recordsForDimension in records.items(): registry.insertDimensionData(dimension, *recordsForDimension)
def register(self, name, registry): """Add SkyMap, Tract, and Patch Dimension entries to the given Gen3 Butler Registry. Parameters ---------- name : `str` The name of the skymap. registry : `lsst.daf.butler.Registry` The registry to add to. """ nxMax = 0 nyMax = 0 for tractInfo in self: nx, ny = tractInfo.getNumPatches() nxMax = max(nxMax, nx) nyMax = max(nyMax, ny) with registry.transaction(): registry.addDimensionEntry( "skymap", { "skymap": name, "hash": self.getSha1(), "tract_max": len(self), "patch_nx_max": nxMax, "patch_ny_max": nyMax }) for tractInfo in self: region = tractInfo.getOuterSkyPolygon() centroid = SpherePoint(region.getCentroid()) entry = ({ "skymap": name, "tract": tractInfo.getId(), "region": region, "ra": centroid.getRa().asDegrees(), "dec": centroid.getDec().asDegrees() }) registry.addDimensionEntry("tract", entry) patchDataIdList = [] for patchInfo in tractInfo: cellX, cellY = patchInfo.getIndex() patchDataIdList.append({ "skymap": name, "tract": tractInfo.getId(), "patch": tractInfo.getSequentialPatchIndex(patchInfo), "cell_x": cellX, "cell_y": cellY, "region": patchInfo.getOuterSkyPolygon(tractInfo.getWcs()) }) registry.addDimensionEntryList("patch", patchDataIdList)
def _makeDiaObjects(self, sources, indices, dt): """Over-simplified implementation of source-to-object matching and new DiaObject generation. Currently matching is based on info passed along by source generator and does not even use DiaObjects from database. Parameters ---------- sources : `numpy.array` (x, y, z) coordinates of sources, array dimension is (N, 3) indices : `numpy.array` array of indices of sources, 1-dim ndarray, transient sources have negative indices dt : `datetime.datetime` Visit time. Returns ------- `afw.table.BaseCatalog` """ schema = self._makeDiaObjectSchema() catalog = afwTable.SourceCatalog(schema) n_trans = 0 for i in range(len(sources)): var_idx = int(indices[i]) if var_idx == _OUTSIDER: continue xyz = sources[i] if var_idx >= _TRANSIENT_START_ID: n_trans += 1 v3d = Vector3d(xyz[0], xyz[1], xyz[2]) sp = SpherePoint(v3d) dir_v = UnitVector3d(v3d) pixelator = HtmPixelization(self.config.htm_level) index = pixelator.index(dir_v) record = catalog.addNew() record.set("id", var_idx) # record.set("validityStart", _utc_seconds(dt)) # record.set("validityEnd", 0) # record.set("lastNonForcedSource", _utc_seconds(dt)) record.set("coord_ra", sp.getRa()) record.set("coord_dec", sp.getDec()) record.set("pixelId", index) _LOG.info('found %s matching objects and %s transients/noise', len(catalog) - n_trans, n_trans) return catalog
def _makeDiaSources(self, sources, indices, visit_id): """Generate catalog of DiaSources to store in a database Parameters ---------- sources : `numpy.ndarray` (x, y, z) coordinates of sources, array dimension is (N, 3) indices : `numpy.array` array of indices of sources, 1-dim ndarray, transient sources have negative indices visit_id : `int` ID of the visit Returns ------- `afw.table.BaseCatalog` """ schema = self._makeDiaSourceSchema() catalog = afwTable.BaseCatalog(schema) for i in range(len(sources)): var_idx = int(indices[i]) if var_idx == _OUTSIDER: continue xyz = sources[i] v3d = Vector3d(xyz[0], xyz[1], xyz[2]) sp = SpherePoint(v3d) dir_v = UnitVector3d(v3d) pixelator = HtmPixelization(self.config.htm_level) index = pixelator.index(dir_v) self.lastSourceId += 1 record = catalog.addNew() record.set("id", self.lastSourceId) record.set("ccdVisitId", visit_id) record.set("diaObjectId", var_idx) record.set("parent", 0) record.set("coord_ra", sp.getRa()) record.set("coord_dec", sp.getDec()) record.set("flags", 0) record.set("pixelId", index) return catalog
def register(self, name, registry): """Add SkyMap, Tract, and Patch Dimension entries to the given Gen3 Butler Registry. Parameters ---------- name : `str` The name of the skymap. registry : `lsst.daf.butler.Registry` The registry to add to. """ nxMax = 0 nyMax = 0 for tractInfo in self: nx, ny = tractInfo.getNumPatches() nxMax = max(nxMax, nx) nyMax = max(nyMax, ny) with registry.transaction(): registry.addDimensionEntry( "skymap", {"skymap": name, "hash": self.getSha1(), "tract_max": len(self), "patch_nx_max": nxMax, "patch_ny_max": nyMax} ) for tractInfo in self: region = tractInfo.getOuterSkyPolygon() centroid = SpherePoint(region.getCentroid()) entry = ( {"skymap": name, "tract": tractInfo.getId(), "region": region, "ra": centroid.getRa().asDegrees(), "dec": centroid.getDec().asDegrees()} ) registry.addDimensionEntry("tract", entry) patchDataIdList = [] for patchInfo in tractInfo: cellX, cellY = patchInfo.getIndex() patchDataIdList.append( {"skymap": name, "tract": tractInfo.getId(), "patch": tractInfo.getSequentialPatchIndex(patchInfo), "cell_x": cellX, "cell_y": cellY, "region": patchInfo.getOuterSkyPolygon(tractInfo.getWcs())} ) registry.addDimensionEntryList("patch", patchDataIdList)
def _makeObjectCatalogPandas(pixel_ranges): """Make a catalog containing a bunch of DiaObjects inside pixel envelope. The number of created records will be equal to the number of ranges (one object per pixel range). Coordinates of the created objects are not usable. """ v3d = Vector3d(1., 1., -1.) sp = SpherePoint(v3d) data_list = [] for oid, (start, end) in enumerate(pixel_ranges): tmp_dict = {"diaObjectId": oid, "pixelId": start, "ra": sp.getRa().asDegrees(), "decl": sp.getDec().asDegrees()} data_list.append(tmp_dict) df = pandas.DataFrame(data=data_list) return df
def _makeObjectCatalog(pixel_ranges): """Make a catalog containing a bunch of DiaObjects inside pixel envelope. The number of created records will be equal number of ranges (one object per pixel range). Coordinates of the created objects are not usable. """ # make afw catalog schema = make_minimal_dia_object_schema() catalog = afwTable.SourceCatalog(schema) # make small bunch of records, one entry per one pixel range, # we do not care about coordinates here, in current implementation # they are not used in any query v3d = Vector3d(1., 1., -1.) sp = SpherePoint(v3d) for oid, (start, end) in enumerate(pixel_ranges): record = catalog.addNew() record.set("id", oid) record.set("pixelId", start) record.set("coord_ra", sp.getRa()) record.set("coord_dec", sp.getDec()) return catalog
def register(self, name, registry): """Add SkyMap, Tract, and Patch DataUnits to the given Gen3 Butler Registry. """ registry.addDataUnitEntry("SkyMap", {"skymap": name, "hash": self.getSha1()}) for tractInfo in self: region = tractInfo.getOuterSkyPolygon() centroid = SpherePoint(region.getCentroid()) registry.addDataUnitEntry( "Tract", {"skymap": name, "tract": tractInfo.getId(), "region": region, "ra": centroid.getRa().asDegrees(), "dec": centroid.getDec().asDegrees()} ) for patchInfo in tractInfo: cellX, cellY = patchInfo.getIndex() registry.addDataUnitEntry( "Patch", {"skymap": name, "tract": tractInfo.getId(), "patch": tractInfo.getSequentialPatchIndex(patchInfo), "cell_x": cellX, "cell_y": cellY, "region": patchInfo.getOuterSkyPolygon(tractInfo.getWcs())} )
def register(self, name, butler): """Add skymap, tract, and patch Dimension entries to the given Gen3 Butler. Parameters ---------- name : `str` The name of the skymap. butler : `lsst.daf.butler.Butler` The butler to add to. Raises ------ lsst.daf.butler.registry.ConflictingDefinitionError Raised if a different skymap exists with the same name. Notes ----- Registering the same skymap multiple times (with the exact same definition) is safe, but inefficient; most of the work of computing the rows to be inserted must be done first in order to check for consistency between the new skymap and any existing one. Re-registering a skymap with different tract and/or patch definitions but the same summary information may not be detected as a conflict but will never result in updating the skymap; there is intentionally no way to modify a registered skymap (aside from manual administrative operations on the database), as it is hard to guarantee that this can be done without affecting reproducibility. """ numPatches = [tractInfo.getNumPatches() for tractInfo in self] nxMax = max(nn[0] for nn in numPatches) nyMax = max(nn[1] for nn in numPatches) skyMapRecord = { "skymap": name, "hash": self.getSha1(), "tract_max": len(self), "patch_nx_max": nxMax, "patch_ny_max": nyMax, } butler.registry.registerRun(self.SKYMAP_RUN_COLLECTION_NAME) # Kind of crazy that we've got three different capitalizations of # "skymap" here, but that's what the various conventions (or at least # precedents) dictate. from lsst.daf.butler import DatasetType from lsst.daf.butler.registry import ConflictingDefinitionError datasetType = DatasetType(name=self.SKYMAP_DATASET_TYPE_NAME, dimensions=["skymap"], storageClass="SkyMap", universe=butler.registry.dimensions) butler.registry.registerDatasetType(datasetType) with butler.transaction(): try: inserted = butler.registry.syncDimensionData( "skymap", skyMapRecord) except ConflictingDefinitionError as err: raise ConflictingDefinitionError( f"SkyMap with hash {self.getSha1().hex()} is already registered with a different name." ) from err if inserted: for tractInfo in self: tractId = tractInfo.getId() tractRegion = tractInfo.getOuterSkyPolygon() centroid = SpherePoint(tractRegion.getCentroid()) tractWcs = tractInfo.getWcs() tractRecord = dict( skymap=name, tract=tractId, region=tractRegion, ra=centroid.getRa().asDegrees(), dec=centroid.getDec().asDegrees(), ) butler.registry.insertDimensionData("tract", tractRecord) patchRecords = [] for patchInfo in tractInfo: xx, yy = patchInfo.getIndex() patchRecords.append( dict( skymap=name, tract=tractId, patch=tractInfo.getSequentialPatchIndex( patchInfo), cell_x=xx, cell_y=yy, region=patchInfo.getOuterSkyPolygon(tractWcs), )) butler.registry.insertDimensionData("patch", *patchRecords) butler.put(self, datasetType, {"skymap": name}, run=self.SKYMAP_RUN_COLLECTION_NAME)