33 import lsst.pex.config 
as pexConfig
 
   35 from .crosstalk 
import X_FLIP, Y_FLIP
 
   37 __all__ = [
"IsrMockConfig", 
"IsrMock", 
"RawMock", 
"TrimmedRawMock", 
"RawDictMock",
 
   38            "CalibratedRawMock", 
"MasterMock",
 
   39            "BiasMock", 
"DarkMock", 
"FlatMock", 
"FringeMock", 
"UntrimmedFringeMock",
 
   40            "BfKernelMock", 
"DefectMock", 
"CrosstalkCoeffMock", 
"TransmissionMock",
 
   45     """Configuration parameters for isrMock. 
   47     These parameters produce generic fixed position signals from 
   48     various sources, and combine them in a way that matches how those 
   49     signals are combined to create real data. The camera used is the 
   50     test camera defined by the afwUtils code. 
   53     isLsstLike = pexConfig.Field(
 
   56         doc=
"If True, products have one raw image per amplifier, otherwise, one raw image per detector.",
 
   58     plateScale = pexConfig.Field(
 
   61         doc=
"Plate scale used in constructing mock camera.",
 
   63     radialDistortion = pexConfig.Field(
 
   66         doc=
"Radial distortion term used in constructing mock camera.",
 
   68     isTrimmed = pexConfig.Field(
 
   71         doc=
"If True, amplifiers have been trimmed and mosaicked to remove regions outside the data BBox.",
 
   73     detectorIndex = pexConfig.Field(
 
   76         doc=
"Index for the detector to use. The default value uses a standard 2x4 array of amps.",
 
   78     rngSeed = pexConfig.Field(
 
   81         doc=
"Seed for random number generator used to add noise.",
 
   84     gain = pexConfig.Field(
 
   87         doc=
"Gain for simulated data in e^-/DN.",
 
   89     readNoise = pexConfig.Field(
 
   92         doc=
"Read noise of the detector in e-.",
 
   94     expTime = pexConfig.Field(
 
   97         doc=
"Exposure time for simulated data.",
 
  101     skyLevel = pexConfig.Field(
 
  104         doc=
"Background contribution to be generated from 'the sky' in DN.",
 
  106     sourceFlux = pexConfig.ListField(
 
  109         doc=
"Peak flux level (in DN) of simulated 'astronomical sources'.",
 
  111     sourceAmp = pexConfig.ListField(
 
  114         doc=
"Amplifier to place simulated 'astronomical sources'.",
 
  116     sourceX = pexConfig.ListField(
 
  119         doc=
"Peak position (in amplifier coordinates) of simulated 'astronomical sources'.",
 
  121     sourceY = pexConfig.ListField(
 
  124         doc=
"Peak position (in amplifier coordinates) of simulated 'astronomical sources'.",
 
  126     overscanScale = pexConfig.Field(
 
  129         doc=
"Amplitude (in DN) of the ramp function to add to overscan data.",
 
  131     biasLevel = pexConfig.Field(
 
  134         doc=
"Background contribution to be generated from the bias offset in DN.",
 
  136     darkRate = pexConfig.Field(
 
  139         doc=
"Background level contribution (in e-/s) to be generated from dark current.",
 
  141     darkTime = pexConfig.Field(
 
  144         doc=
"Exposure time for the dark current contribution.",
 
  146     flatDrop = pexConfig.Field(
 
  149         doc=
"Fractional flux drop due to flat from center to edge of detector along x-axis.",
 
  151     fringeScale = pexConfig.ListField(
 
  154         doc=
"Peak fluxes for the components of the fringe ripple in DN.",
 
  156     fringeX0 = pexConfig.ListField(
 
  159         doc=
"Center position for the fringe ripples.",
 
  161     fringeY0 = pexConfig.ListField(
 
  164         doc=
"Center position for the fringe ripples.",
 
  168     doAddSky = pexConfig.Field(
 
  171         doc=
"Apply 'sky' signal to output image.",
 
  173     doAddSource = pexConfig.Field(
 
  176         doc=
"Add simulated source to output image.",
 
  178     doAddCrosstalk = pexConfig.Field(
 
  181         doc=
"Apply simulated crosstalk to output image. This cannot be corrected by ISR, " 
  182         "as detector.hasCrosstalk()==False.",
 
  184     doAddOverscan = pexConfig.Field(
 
  187         doc=
"If untrimmed, add overscan ramp to overscan and data regions.",
 
  189     doAddBias = pexConfig.Field(
 
  192         doc=
"Add bias signal to data.",
 
  194     doAddDark = pexConfig.Field(
 
  197         doc=
"Add dark signal to data.",
 
  199     doAddFlat = pexConfig.Field(
 
  202         doc=
"Add flat signal to data.",
 
  204     doAddFringe = pexConfig.Field(
 
  207         doc=
"Add fringe signal to data.",
 
  211     doTransmissionCurve = pexConfig.Field(
 
  214         doc=
"Return a simulated transmission curve.",
 
  216     doDefects = pexConfig.Field(
 
  219         doc=
"Return a simulated defect list.",
 
  221     doBrighterFatter = pexConfig.Field(
 
  224         doc=
"Return a simulated brighter-fatter kernel.",
 
  226     doCrosstalkCoeffs = pexConfig.Field(
 
  229         doc=
"Return the matrix of crosstalk coefficients.",
 
  231     doDataRef = pexConfig.Field(
 
  234         doc=
"Return a simulated gen2 butler dataRef.",
 
  236     doGenerateImage = pexConfig.Field(
 
  239         doc=
"Return the generated output image if True.",
 
  241     doGenerateData = pexConfig.Field(
 
  244         doc=
"Return a non-image data structure if True.",
 
  246     doGenerateAmpDict = pexConfig.Field(
 
  249         doc=
"Return a dict of exposure amplifiers instead of an afwImage.Exposure.",
 
  254     """Class to generate consistent mock images for ISR testing. 
  256     ISR testing currently relies on one-off fake images that do not 
  257     accurately mimic the full set of detector effects. This class 
  258     uses the test camera/detector/amplifier structure defined in 
  259     `lsst.afw.cameraGeom.testUtils` to avoid making the test data 
  260     dependent on any of the actual obs package formats. 
  262     ConfigClass = IsrMockConfig
 
  263     _DefaultName = 
"isrMock" 
  267         self.
rng = np.random.RandomState(self.config.rngSeed)
 
  269                                          [1e-2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
 
  270                                          [1e-2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
 
  271                                          [1e-2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
 
  272                                          [1e-2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
 
  273                                          [1e-2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
 
  274                                          [1e-2, 0.0, 0.0, 2.2e-2, 0.0, 0.0, 0.0, 0.0],
 
  275                                          [1e-2, 5e-3, 5e-4, 3e-3, 4e-2, 5e-3, 5e-3, 0.0]])
 
  278                                   [4., 16., 26., 16., 4.],
 
  279                                   [7., 26., 41., 26., 7.],
 
  280                                   [4., 16., 26., 16., 4.],
 
  281                                   [1., 4., 7., 4., 1.]]) / 273.0
 
  284         """Generate a mock ISR product, and return it. 
  288         image : `lsst.afw.image.Exposure` 
  289             Simulated ISR image with signals added. 
  291             Simulated ISR data products. 
  293             Returned if no valid configuration was found. 
  298             Raised if both doGenerateImage and doGenerateData are specified. 
  300         if self.config.doGenerateImage 
and self.config.doGenerateData:
 
  301             raise RuntimeError(
"Only one of doGenerateImage and doGenerateData may be specified.")
 
  302         elif self.config.doGenerateImage:
 
  304         elif self.config.doGenerateData:
 
  310         """Generate simulated ISR data. 
  312         Currently, only the class defined crosstalk coefficient 
  313         matrix, brighter-fatter kernel, a constant unity transmission 
  314         curve, or a simple single-entry defect list can be generated. 
  319             Simulated ISR data product. 
  321         if sum(map(bool, [self.config.doBrighterFatter,
 
  322                           self.config.doDefects,
 
  323                           self.config.doTransmissionCurve,
 
  324                           self.config.doCrosstalkCoeffs])) != 1:
 
  325             raise RuntimeError(
"Only one data product can be generated at a time.")
 
  326         elif self.config.doBrighterFatter 
is True:
 
  328         elif self.config.doDefects 
is True:
 
  330         elif self.config.doTransmissionCurve 
is True:
 
  332         elif self.config.doCrosstalkCoeffs 
is True:
 
  338         """Generate a simple Gaussian brighter-fatter kernel. 
  342         kernel : `numpy.ndarray` 
  343             Simulated brighter-fatter kernel. 
  348         """Generate a simple single-entry defect list. 
  352         defectList : `lsst.meas.algorithms.Defects` 
  353             Simulated defect list 
  359         """Generate the simulated crosstalk coefficients. 
  363         coeffs : `numpy.ndarray` 
  364             Simulated crosstalk coefficients. 
  370         """Generate a simulated flat transmission curve. 
  374         transmission : `lsst.afw.image.TransmissionCurve` 
  375             Simulated transmission curve. 
  378         return afwImage.TransmissionCurve.makeIdentity()
 
  381         """Generate a simulated ISR image. 
  385         exposure : `lsst.afw.image.Exposure` or `dict` 
  386             Simulated ISR image data. 
  390         This method currently constructs a "raw" data image by: 
  391             * Generating a simulated sky with noise 
  392             * Adding a single Gaussian "star" 
  393             * Adding the fringe signal 
  394             * Multiplying the frame by the simulated flat 
  395             * Adding dark current (and noise) 
  396             * Adding a bias offset (and noise) 
  397             * Adding an overscan gradient parallel to the pixel y-axis 
  398             * Simulating crosstalk by adding a scaled version of each 
  399               amplifier to each other amplifier. 
  401         The exposure with image data constructed this way is in one of 
  403             * A single image, with overscan and prescan regions retained 
  404             * A single image, with overscan and prescan regions trimmed 
  405             * A `dict`, containing the amplifer data indexed by the 
  408         The nonlinearity, CTE, and brighter fatter are currently not 
  411         Note that this method generates an image in the reverse 
  412         direction as the ISR processing, as the output image here has 
  413         had a series of instrument effects added to an idealized 
  418         for idx, amp 
in enumerate(exposure.getDetector()):
 
  420             if self.config.isTrimmed 
is True:
 
  423                 bbox = amp.getRawDataBBox()
 
  425             ampData = exposure.image[bbox]
 
  427             if self.config.doAddSky 
is True:
 
  428                 self.
amplifierAddNoise(ampData, self.config.skyLevel, np.sqrt(self.config.skyLevel))
 
  430             if self.config.doAddSource 
is True:
 
  431                 for sourceAmp, sourceFlux, sourceX, sourceY 
in zip(self.config.sourceAmp,
 
  432                                                                    self.config.sourceFlux,
 
  434                                                                    self.config.sourceY):
 
  438             if self.config.doAddFringe 
is True:
 
  440                                         x0=np.array(self.config.fringeX0),
 
  441                                         y0=np.array(self.config.fringeY0))
 
  443             if self.config.doAddFlat 
is True:
 
  444                 if ampData.getArray().sum() == 0.0:
 
  446                 u0 = exposure.getDimensions().getX()
 
  447                 v0 = exposure.getDimensions().getY()
 
  450             if self.config.doAddDark 
is True:
 
  452                                        self.config.darkRate * self.config.darkTime / self.config.gain,
 
  453                                        np.sqrt(self.config.darkRate *
 
  454                                                self.config.darkTime / self.config.gain))
 
  456         if self.config.doAddCrosstalk 
is True:
 
  458             for idxS, ampS 
in enumerate(exposure.getDetector()):
 
  459                 for idxT, ampT 
in enumerate(exposure.getDetector()):
 
  460                     ampDataS = exposure.image[ampS.getBBox() 
if self.config.isTrimmed
 
  461                                               else ampS.getRawDataBBox()]
 
  462                     ampDataT = exposure.image[ampT.getBBox() 
if self.config.isTrimmed
 
  463                                               else ampT.getRawDataBBox()]
 
  465                                                  (X_FLIP[ampS.getReadoutCorner()] ^
 
  466                                                   X_FLIP[ampT.getReadoutCorner()]),
 
  467                                                  (Y_FLIP[ampS.getReadoutCorner()] ^
 
  468                                                   Y_FLIP[ampT.getReadoutCorner()]))
 
  471         for amp 
in exposure.getDetector():
 
  473             if self.config.isTrimmed 
is True:
 
  476                 bbox = amp.getRawDataBBox()
 
  478             ampData = exposure.image[bbox]
 
  480             if self.config.doAddBias 
is True:
 
  482                                        self.config.readNoise / self.config.gain)
 
  484             if self.config.doAddOverscan 
is True:
 
  485                 oscanBBox = amp.getRawHorizontalOverscanBBox()
 
  486                 oscanData = exposure.image[oscanBBox]
 
  488                                        self.config.readNoise / self.config.gain)
 
  491                                            1.0 * self.config.overscanScale)
 
  493                                            1.0 * self.config.overscanScale)
 
  495         if self.config.doGenerateAmpDict 
is True:
 
  497             for amp 
in exposure.getDetector():
 
  498                 expDict[amp.getName()] = exposure
 
  505         """Construct a test camera object. 
  509         camera : `lsst.afw.cameraGeom.camera` 
  512         cameraWrapper = afwTestUtils.CameraWrapper(
 
  513             plateScale=self.config.plateScale,
 
  514             radialDistortion=self.config.radialDistortion,
 
  515             isLsstLike=self.config.isLsstLike,
 
  517         camera = cameraWrapper.camera
 
  521         """Construct a test exposure. 
  523         The test exposure has a simple WCS set, as well as a list of 
  524         unlikely header keywords that can be removed during ISR 
  525         processing to exercise that code. 
  529         exposure : `lsst.afw.exposure.Exposure` 
  530             Construct exposure containing masked image of the 
  534         detector = camera[self.config.detectorIndex]
 
  535         image = afwUtils.makeImageFromCcd(detector,
 
  536                                           isTrimmed=self.config.isTrimmed,
 
  540                                           imageFactory=afwImage.ImageF)
 
  542         var = afwImage.ImageF(image.getDimensions())
 
  548         exposure.setDetector(detector)
 
  549         exposure.setWcs(self.
getWcs())
 
  551         visitInfo = 
afwImage.VisitInfo(exposureTime=self.config.expTime, darkTime=self.config.darkTime)
 
  552         exposure.getInfo().setVisitInfo(visitInfo)
 
  554         metadata = exposure.getMetadata()
 
  555         metadata.add(
"SHEEP", 7.3, 
"number of sheep on farm")
 
  556         metadata.add(
"MONKEYS", 155, 
"monkeys per tree")
 
  557         metadata.add(
"VAMPIRES", 4, 
"How scary are vampires.")
 
  559         ccd = exposure.getDetector()
 
  560         newCcd = ccd.rebuild()
 
  563             newAmp = amp.rebuild()
 
  564             newAmp.setLinearityCoeffs((0., 1., 0., 0.))
 
  565             newAmp.setLinearityType(
"Polynomial")
 
  566             newAmp.setGain(self.config.gain)
 
  567             newAmp.setSuspectLevel(25000.0)
 
  568             newAmp.setSaturation(32000.0)
 
  569             newCcd.append(newAmp)
 
  570         exposure.setDetector(newCcd.finish())
 
  572         exposure.image.array[:] = np.zeros(exposure.getImage().getDimensions()).transpose()
 
  573         exposure.mask.array[:] = np.zeros(exposure.getMask().getDimensions()).transpose()
 
  574         exposure.variance.array[:] = np.zeros(exposure.getVariance().getDimensions()).transpose()
 
  579         """Construct a dummy WCS object. 
  581         Taken from the deprecated ip_isr/examples/exampleUtils.py. 
  583         This is not guaranteed, given the distortion and pixel scale 
  584         listed in the afwTestUtils camera definition. 
  588         wcs : `lsst.afw.geom.SkyWcs` 
  596         """Convert between a local amplifier coordinate and the full 
  601         ampData : `lsst.afw.image.ImageF` 
  602             Amplifier image to use for conversions. 
  604             X-coordinate of the point to transform. 
  606             Y-coordinate of the point to transform. 
  611             Transformed x-coordinate. 
  613             Transformed y-coordinate. 
  617         The output is transposed intentionally here, to match the 
  618         internal transpose between numpy and afw.image coordinates. 
  620         u = x + ampData.getBBox().getBeginX()
 
  621         v = y + ampData.getBBox().getBeginY()
 
  627         """Add Gaussian noise to an amplifier's image data. 
  629          This method operates in the amplifier coordinate frame. 
  633         ampData : `lsst.afw.image.ImageF` 
  634             Amplifier image to operate on. 
  636             Mean value of the Gaussian noise. 
  638             Sigma of the Gaussian noise. 
  640         ampArr = ampData.array
 
  641         ampArr[:] = ampArr[:] + self.
rng.normal(mean, sigma,
 
  642                                                 size=ampData.getDimensions()).transpose()
 
  645         """Add a y-axis linear gradient to an amplifier's image data. 
  647          This method operates in the amplifier coordinate frame. 
  651         ampData : `lsst.afw.image.ImageF` 
  652             Amplifier image to operate on. 
  654             Start value of the gradient (at y=0). 
  656             End value of the gradient (at y=ymax). 
  658         nPixY = ampData.getDimensions().getY()
 
  659         ampArr = ampData.array
 
  660         ampArr[:] = ampArr[:] + (np.interp(range(nPixY), (0, nPixY - 1), (start, end)).reshape(nPixY, 1) +
 
  661                                  np.zeros(ampData.getDimensions()).transpose())
 
  664         """Add a single Gaussian source to an amplifier. 
  666          This method operates in the amplifier coordinate frame. 
  670         ampData : `lsst.afw.image.ImageF` 
  671             Amplifier image to operate on. 
  673             Peak flux of the source to add. 
  675             X-coordinate of the source peak. 
  677             Y-coordinate of the source peak. 
  679         for x 
in range(0, ampData.getDimensions().getX()):
 
  680             for y 
in range(0, ampData.getDimensions().getY()):
 
  681                 ampData.array[y][x] = (ampData.array[y][x] +
 
  682                                        scale * np.exp(-0.5 * ((x - x0)**2 + (y - y0)**2) / 3.0**2))
 
  685         """Add a scaled copy of an amplifier to another, simulating crosstalk. 
  687          This method operates in the amplifier coordinate frame. 
  691         ampDataSource : `lsst.afw.image.ImageF` 
  692             Amplifier image to add scaled copy from. 
  693         ampDataTarget : `lsst.afw.image.ImageF` 
  694             Amplifier image to add scaled copy to. 
  696             Flux scale of the copy to add to the target. 
  700         This simulates simple crosstalk between amplifiers. 
  702         ampDataTarget.array[:] = (ampDataTarget.array[:] +
 
  703                                   scale * ampDataSource.array[:])
 
  707         """Add a fringe-like ripple pattern to an amplifier's image data. 
  711         amp : `~lsst.afw.ampInfo.AmpInfoRecord` 
  712             Amplifier to operate on. Needed for amp<->exp coordinate transforms. 
  713         ampData : `lsst.afw.image.ImageF` 
  714             Amplifier image to operate on. 
  715         scale : `numpy.array` or `float` 
  716             Peak intensity scaling for the ripple. 
  717         x0 : `numpy.array` or `float`, optional 
  719         y0 : `numpy.array` or `float`, optional 
  724         This uses an offset sinc function to generate a ripple 
  725         pattern. True fringes have much finer structure, but this 
  726         pattern should be visually identifiable. The (x, y) 
  727         coordinates are in the frame of the amplifier, and (u, v) in 
  728         the frame of the full trimmed image. 
  730         for x 
in range(0, ampData.getDimensions().getX()):
 
  731             for y 
in range(0, ampData.getDimensions().getY()):
 
  733                 ampData.getArray()[y][x] = np.sum((ampData.getArray()[y][x] +
 
  735                                                    np.sinc(((u - x0) / 50)**2 +
 
  736                                                            ((v - y0) / 50)**2)))
 
  739         """Multiply an amplifier's image data by a flat-like pattern. 
  743         amp : `lsst.afw.ampInfo.AmpInfoRecord` 
  744             Amplifier to operate on. Needed for amp<->exp coordinate transforms. 
  745         ampData : `lsst.afw.image.ImageF` 
  746             Amplifier image to operate on. 
  748             Fractional drop from center to edge of detector along x-axis. 
  750             Peak location in detector coordinates. 
  752             Peak location in detector coordinates. 
  756         This uses a 2-d Gaussian to simulate an illumination pattern 
  757         that falls off towards the edge of the detector. The (x, y) 
  758         coordinates are in the frame of the amplifier, and (u, v) in 
  759         the frame of the full trimmed image. 
  762             raise RuntimeError(
"Flat fractional drop cannot be greater than 1.0")
 
  764         sigma = u0 / np.sqrt(-2.0 * np.log(fracDrop))
 
  766         for x 
in range(0, ampData.getDimensions().getX()):
 
  767             for y 
in range(0, ampData.getDimensions().getY()):
 
  769                 f = np.exp(-0.5 * ((u - u0)**2 + (v - v0)**2) / sigma**2)
 
  770                 ampData.array[y][x] = (ampData.array[y][x] * f)
 
  774     """Generate a raw exposure suitable for ISR. 
  778         self.config.isTrimmed = 
False 
  779         self.config.doGenerateImage = 
True 
  780         self.config.doGenerateAmpDict = 
False 
  781         self.config.doAddOverscan = 
True 
  782         self.config.doAddSky = 
True 
  783         self.config.doAddSource = 
True 
  784         self.config.doAddCrosstalk = 
False 
  785         self.config.doAddBias = 
True 
  786         self.config.doAddDark = 
True 
  790     """Generate a trimmed raw exposure. 
  794         self.config.isTrimmed = 
True 
  795         self.config.doAddOverscan = 
False 
  799     """Generate a trimmed raw exposure. 
  803         self.config.isTrimmed = 
True 
  804         self.config.doGenerateImage = 
True 
  805         self.config.doAddOverscan = 
False 
  806         self.config.doAddSky = 
True 
  807         self.config.doAddSource = 
True 
  808         self.config.doAddCrosstalk = 
False 
  810         self.config.doAddBias = 
False 
  811         self.config.doAddDark = 
False 
  812         self.config.doAddFlat = 
False 
  813         self.config.doAddFringe = 
True 
  815         self.config.biasLevel = 0.0
 
  816         self.config.readNoise = 10.0
 
  820     """Generate a raw exposure dict suitable for ISR. 
  824         self.config.doGenerateAmpDict = 
True 
  828     """Parent class for those that make master calibrations. 
  832         self.config.isTrimmed = 
True 
  833         self.config.doGenerateImage = 
True 
  834         self.config.doAddOverscan = 
False 
  835         self.config.doAddSky = 
False 
  836         self.config.doAddSource = 
False 
  837         self.config.doAddCrosstalk = 
False 
  839         self.config.doAddBias = 
False 
  840         self.config.doAddDark = 
False 
  841         self.config.doAddFlat = 
False 
  842         self.config.doAddFringe = 
False 
  846     """Simulated master bias calibration. 
  850         self.config.doAddBias = 
True 
  851         self.config.readNoise = 10.0
 
  855     """Simulated master dark calibration. 
  859         self.config.doAddDark = 
True 
  860         self.config.darkTime = 1.0
 
  864     """Simulated master flat calibration. 
  868         self.config.doAddFlat = 
True 
  872     """Simulated master fringe calibration. 
  876         self.config.doAddFringe = 
True 
  880     """Simulated untrimmed master fringe calibration. 
  884         self.config.isTrimmed = 
False 
  888     """Simulated brighter-fatter kernel. 
  892         self.config.doGenerateImage = 
False 
  893         self.config.doGenerateData = 
True 
  894         self.config.doBrighterFatter = 
True 
  895         self.config.doDefects = 
False 
  896         self.config.doCrosstalkCoeffs = 
False 
  897         self.config.doTransmissionCurve = 
False 
  901     """Simulated defect list. 
  905         self.config.doGenerateImage = 
False 
  906         self.config.doGenerateData = 
True 
  907         self.config.doBrighterFatter = 
False 
  908         self.config.doDefects = 
True 
  909         self.config.doCrosstalkCoeffs = 
False 
  910         self.config.doTransmissionCurve = 
False 
  914     """Simulated crosstalk coefficient matrix. 
  918         self.config.doGenerateImage = 
False 
  919         self.config.doGenerateData = 
True 
  920         self.config.doBrighterFatter = 
False 
  921         self.config.doDefects = 
False 
  922         self.config.doCrosstalkCoeffs = 
True 
  923         self.config.doTransmissionCurve = 
False 
  927     """Simulated transmission curve. 
  931         self.config.doGenerateImage = 
False 
  932         self.config.doGenerateData = 
True 
  933         self.config.doBrighterFatter = 
False 
  934         self.config.doDefects = 
False 
  935         self.config.doCrosstalkCoeffs = 
False 
  936         self.config.doTransmissionCurve = 
True 
  940     """Simulated gen2 butler data ref. 
  942     Currently only supports get and put operations, which are most 
  943     likely to be called for data in ISR processing. 
  946     dataId = 
"isrMock Fake Data" 
  954         if 'config' in kwargs.keys():
 
  962         self.
config.doGenerateImage = 
True 
  963         self.
config.doGenerateData = 
False 
  968         self.
config.doGenerateImage = 
False 
  969         self.
config.doGenerateData = 
True 
  971     def get(self, dataType, **kwargs):
 
  972         """Return an appropriate data product. 
  977             Type of data product to return. 
  981         mock : IsrMock.run() result 
  984         if "_filename" in dataType:
 
  986             return tempfile.mktemp(), 
"mock" 
  987         elif 'transmission_' in dataType:
 
  990         elif dataType == 
'ccdExposureId':
 
  993         elif dataType == 
'camera':
 
  996         elif dataType == 
'raw':
 
  999         elif dataType == 
'bias':
 
 1002         elif dataType == 
'dark':
 
 1005         elif dataType == 
'flat':
 
 1008         elif dataType == 
'fringe':
 
 1011         elif dataType == 
'defects':
 
 1014         elif dataType == 
'bfKernel':
 
 1017         elif dataType == 
'linearizer':
 
 1019         elif dataType == 
'crosstalkSources':
 
 1022             raise RuntimeError(
"ISR DataRefMock cannot return %s.", dataType)
 
 1024     def put(self, exposure, filename):
 
 1025         """Write an exposure to a FITS file. 
 1029         exposure : `lsst.afw.image.Exposure` 
 1030             Image data to write out. 
 1032             Base name of the output file. 
 1034         exposure.writeFits(filename+
".fits")
 
 1038     """Simulated gen2 butler data ref. 
 1040     Currently only supports get and put operations, which are most 
 1041     likely to be called for data in ISR processing. 
 1044     dataId = 
"isrMock Fake Data" 
 1052         if 'config' in kwargs.keys():
 
 1056             self.
config.isTrimmed = 
True 
 1057             self.
config.doAddFringe = 
True 
 1058             self.
config.readNoise = 10.0
 
 1060     def get(self, dataType, **kwargs):
 
 1061         """Return an appropriate data product. 
 1066             Type of data product to return. 
 1070         mock : IsrMock.run() result 
 1073         if "_filename" in dataType:
 
 1074             return tempfile.mktemp(), 
"mock" 
 1075         elif 'transmission_' in dataType:
 
 1077         elif dataType == 
'ccdExposureId':
 
 1079         elif dataType == 
'camera':
 
 1081         elif dataType == 
'raw':
 
 1083         elif dataType == 
'bias':
 
 1085         elif dataType == 
'dark':
 
 1087         elif dataType == 
'flat':
 
 1089         elif dataType == 
'fringe':
 
 1091             configCopy = copy.deepcopy(self.
config)
 
 1092             for scale, x, y 
in zip(self.
config.fringeScale, self.
config.fringeX0, self.
config.fringeY0):
 
 1093                 configCopy.fringeScale = [1.0]
 
 1094                 configCopy.fringeX0 = [x]
 
 1095                 configCopy.fringeY0 = [y]
 
 1098         elif dataType == 
'defects':
 
 1100         elif dataType == 
'bfKernel':
 
 1102         elif dataType == 
'linearizer':
 
 1104         elif dataType == 
'crosstalkSources':
 
 1109     def put(self, exposure, filename):
 
 1110         """Write an exposure to a FITS file. 
 1114         exposure : `lsst.afw.image.Exposure` 
 1115             Image data to write out. 
 1117             Base name of the output file. 
 1119         exposure.writeFits(filename+
".fits")