def testFactories(self): """This method tests the getters as well as the factories, since their behaviors are linked. """ self._checkFactory(FilterLabel.fromBandPhysical(self.band, self.physicalName), self.band, self.physicalName) self._checkFactory(FilterLabel.fromBand(self.band), self.band, None) self._checkFactory(FilterLabel.fromPhysical(self.physicalName), None, self.physicalName)
def _labelVariants(self): # Contains some redundant entries to check that equality behaves # consistently across both construction methods. return iter({FilterLabel(physical=self.physicalName, band=self.band), FilterLabel.fromBand(self.band), FilterLabel(band=self.band), FilterLabel(physical=self.physicalName), })
def testMultiPlaneFitsReaders(self): """Run tests for MaskedImageFitsReader and ExposureFitsReader. """ metadata = PropertyList() metadata.add("FIVE", 5) metadata.add("SIX", 6.0) wcs = makeSkyWcs(Point2D(2.5, 3.75), SpherePoint(40.0 * degrees, 50.0 * degrees), np.array([[1E-5, 0.0], [0.0, -1E-5]])) defineFilter("test_readers_filter", lambdaEff=470.0) calib = PhotoCalib(2.5E4) psf = GaussianPsf(21, 21, 8.0) polygon = Polygon(Box2D(self.bbox)) apCorrMap = ApCorrMap() visitInfo = VisitInfo(exposureTime=5.0) transmissionCurve = TransmissionCurve.makeIdentity() coaddInputs = CoaddInputs(ExposureTable.makeMinimalSchema(), ExposureTable.makeMinimalSchema()) detector = DetectorWrapper().detector record = coaddInputs.ccds.addNew() record.setWcs(wcs) record.setPhotoCalib(calib) record.setPsf(psf) record.setValidPolygon(polygon) record.setApCorrMap(apCorrMap) record.setVisitInfo(visitInfo) record.setTransmissionCurve(transmissionCurve) record.setDetector(detector) for n, dtypeIn in enumerate(self.dtypes): with self.subTest(dtypeIn=dtypeIn): exposureIn = Exposure(self.bbox, dtype=dtypeIn) shape = exposureIn.image.array.shape exposureIn.image.array[:, :] = np.random.randint(low=1, high=5, size=shape) exposureIn.mask.array[:, :] = np.random.randint(low=1, high=5, size=shape) exposureIn.variance.array[:, :] = np.random.randint(low=1, high=5, size=shape) exposureIn.setMetadata(metadata) exposureIn.setWcs(wcs) exposureIn.setFilter(Filter("test_readers_filter")) exposureIn.setFilterLabel( FilterLabel(physical="test_readers_filter")) exposureIn.setPhotoCalib(calib) exposureIn.setPsf(psf) exposureIn.getInfo().setValidPolygon(polygon) exposureIn.getInfo().setApCorrMap(apCorrMap) exposureIn.getInfo().setVisitInfo(visitInfo) exposureIn.getInfo().setTransmissionCurve(transmissionCurve) exposureIn.getInfo().setCoaddInputs(coaddInputs) exposureIn.setDetector(detector) with lsst.utils.tests.getTempFilePath(".fits") as fileName: exposureIn.writeFits(fileName) self.checkMaskedImageFitsReader(exposureIn, fileName, self.dtypes[n:]) self.checkExposureFitsReader(exposureIn, fileName, self.dtypes[n:])
def testPersistence(self): """Check persistence of a FilterLabel. """ for label in self._labelVariants(): with lsst.utils.tests.getTempFilePath(".fits") as outFile: label.writeFits(outFile) roundTrip = FilterLabel.readFits(outFile) self.assertEqual(roundTrip, label)
def testInit(self): with self.assertRaises(ValueError): FilterLabel() self.assertEqual(FilterLabel(physical=self.physicalName), FilterLabel.fromPhysical(self.physicalName)) self.assertEqual(FilterLabel(band=self.band), FilterLabel.fromBand(self.band)) self.assertEqual(FilterLabel(physical=self.physicalName, band=self.band), FilterLabel.fromBandPhysical(self.band, self.physicalName)) with self.assertRaises(TypeError): FilterLabel(physical=42) with self.assertRaises(TypeError): FilterLabel(band=("g", "r"))
def getComponent(self, label, derivedName): """Derive a Filter from a FilterLabel. Parameters ---------- label : `~lsst.afw.image.FilterLabel` The object to convert. derivedName : `str` Name of type to convert to. Only "filter" is supported. Returns ------- derived : `object` The converted type. Can be `None`. Raises ------ AttributeError An unknown component was requested. """ if derivedName == "filter": # Port of backwards-compatibility code in afw; don't want to # expose it as API. # Filters still have standard aliases, so can use almost any name # to define them. Prefer afw_name or band because that's what most # code assumes is Filter.getName(). if label == FilterLabel(band="r", physical="HSC-R2"): return Filter("r2", force=True) elif label == FilterLabel(band="i", physical="HSC-I2"): return Filter("i2", force=True) elif label == FilterLabel(physical="solid plate 0.0 0.0"): return Filter("SOLID", force=True) elif label.hasBandLabel(): return Filter(label.bandLabel, force=True) else: # FilterLabel guarantees at least one of band or physical # is defined. return Filter(label.physicalLabel, force=True) else: raise AttributeError( f"Do not know how to convert {type(label)} to {derivedName}")
def _fixFilterLabels(self, file_filter_label, should_be_standardized=None): """Compare the filter label read from the file with the one in the data ID. Parameters ---------- file_filter_label : `lsst.afw.image.FilterLabel` or `None` Filter label read from the file, if there was one. should_be_standardized : `bool`, optional If `True`, expect ``file_filter_label`` to be consistent with the data ID and warn only if it is not. If `False`, expect it to be inconsistent and warn only if the data ID is incomplete and hence the `FilterLabel` cannot be fixed. If `None` (default) guess whether the file should be standardized by looking at the serialization version number in file, which requires this method to have been run after `readFull` or `readComponent`. Returns ------- filter_label : `lsst.afw.image.FilterLabel` or `None` The preferred filter label; may be the given one or one built from the data ID. `None` is returned if there should never be any filters associated with this dataset type. Notes ----- Most test coverage for this method is in ci_hsc_gen3, where we have much easier access to test data that exhibits the problems it attempts to solve. """ # Remember filter data ID keys that weren't in this particular data ID, # so we can warn about them later. missing = [] band = None physical_filter = None if "band" in self.dataId.graph.dimensions.names: band = self.dataId.get("band") # band isn't in the data ID; is that just because this data ID # hasn't been filled in with everything the Registry knows, or # because this dataset is never associated with a band? if band is None and not self.dataId.hasFull() and "band" in self.dataId.graph.implied.names: missing.append("band") if "physical_filter" in self.dataId.graph.dimensions.names: physical_filter = self.dataId.get("physical_filter") # Same check as above for band, but for physical_filter. if (physical_filter is None and not self.dataId.hasFull() and "physical_filter" in self.dataId.graph.implied.names): missing.append("physical_filter") if should_be_standardized is None: version = self._reader.readSerializationVersion() should_be_standardized = (version >= 2) if missing: # Data ID identifies a filter but the actual filter label values # haven't been fetched from the database; we have no choice but # to use the one in the file. # Warn if that's more likely than not to be bad, because the file # predates filter standardization. if not should_be_standardized: warnings.warn(f"Data ID {self.dataId} is missing (implied) value(s) for {missing}; " "the correctness of this Exposure's FilterLabel cannot be guaranteed. " "Call Registry.expandDataId before Butler.get to avoid this.") return file_filter_label if band is None and physical_filter is None: data_id_filter_label = None else: data_id_filter_label = FilterLabel(band=band, physical=physical_filter) if data_id_filter_label != file_filter_label and should_be_standardized: # File was written after FilterLabel and standardization, but its # FilterLabel doesn't agree with the data ID: this indicates a bug # in whatever code produced the Exposure (though it may be one that # has been fixed since the file was written). warnings.warn(f"Reading {self.fileDescriptor.location} with data ID {self.dataId}: " f"filter label mismatch (file is {file_filter_label}, data ID is " f"{data_id_filter_label}). This is probably a bug in the code that produced it.") return data_id_filter_label
def testEqualsHash(self): self.assertEqual(hash(FilterLabel(band=self.band)), hash(FilterLabel(band=self.band))) self.assertEqual(hash(FilterLabel(physical=self.physicalName)), hash(FilterLabel(physical=self.physicalName)))
def testEqualsMissingField(self): self.assertNotEqual(FilterLabel(band=self.band), FilterLabel(band=self.band, physical=self.physicalName))
def testEqualsSameText(self): # Ensure different kinds of labels are distinguishable, even if they have the same string self.assertNotEqual(FilterLabel(band=self.band), FilterLabel(physical=self.band))
def testEqualsIdentical(self): self.assertEqual(FilterLabel(physical=self.physicalName), FilterLabel(physical=self.physicalName))