def test_slit_projection_on_detector(): step = assign_wcs_step.AssignWcsStep() hdul = create_nirspec_fs_file(grating="G395M", filter="OPAQUE", lamp="ARGON") hdul[0].header['DETECTOR'] = 'NRS2' im = datamodels.ImageModel(hdul) refs = {} for reftype in step.reference_file_types: refs[reftype] = step.get_reference_file(im, reftype) open_slits = nirspec.get_open_slits(im, refs) assert len(open_slits) == 1 assert open_slits[0].name == "S200B1" hdul[0].header['DETECTOR'] = 'NRS1' im = datamodels.ImageModel(hdul) open_slits = nirspec.get_open_slits(im, refs) assert len(open_slits) == 4 names = [s.name for s in open_slits] assert "S200A1" in names assert "S200A2" in names assert "S400A1" in names assert "S1600A1" in names
def test_split_container(tmp_path): path1 = tmp_path / "foo.fits" path2 = tmp_path / "bar.fits" im1 = datamodels.ImageModel() im1.save(path1) im2 = datamodels.ImageModel() im2.save(path2) container = datamodels.ModelContainer([im1, im2]) container.meta.asn_table = { "products": [{ "members": [ { "expname": f"{path1}", "exptype": "science" }, { "expname": f"{path2}", "exptype": "background" }, ] }] } sci, bkg = split_container(container) assert sci[0].meta.filename == "foo.fits" assert bkg[0].meta.filename == "bar.fits" assert len(sci) == 1 assert len(bkg) == 1
def test_is_irs2_2(): """Test is_irs2 using a jwst data model""" x = np.ones((2048, 2), dtype=np.float32) model = datamodels.ImageModel(data=x) assert not pipe_utils.is_irs2(model) x = np.ones((3200, 2), dtype=np.float32) model = datamodels.ImageModel(data=x) assert pipe_utils.is_irs2(model)
def test_bounding_box_from_subarray(): im = datamodels.ImageModel() im.meta.subarray.xstart = 4 im.meta.subarray.ystart = 6 im.meta.subarray.xsize = 400 im.meta.subarray.ysize = 600 assert bounding_box_from_subarray(im) == ((-.5, 599.5), (-.5, 399.5))
def test_nirspec_ifu_against_esa(): """ Test Nirspec IFU mode using CV3 reference files. """ ref = fits.open(get_file_path('Trace_IFU_Slice_00_SMOS-MOD-G1M-17-5344175105_30192_JLAB88.fits')) # Test NRS1 pyw = astwcs.WCS(ref['SLITY1'].header) hdul = create_nirspec_ifu_file("OPAQUE", "G140M") im = datamodels.ImageModel(hdul) im.meta.filename = "test_ifu.fits" refs = create_reference_files(im) pipe = nirspec.create_pipeline(im, refs, slit_y_range=[-.5, .5]) w = wcs.WCS(pipe) im.meta.wcs = w # Test evaluating the WCS (slice 0) w0 = nirspec.nrs_wcs_set_input(im, 0) # get positions within the slit and the coresponding lambda slit1 = ref['SLITY1'].data # y offset on the slit lam = ref['LAMBDA1'].data # filter out locations outside the slit cond = np.logical_and(slit1 < .5, slit1 > -.5) y, x = cond.nonzero() # 0-based x, y = pyw.wcs_pix2world(x, y, 0) # The pipeline accepts 0-based cooridnates x -= 1 y -= 1 sca2world = w0.get_transform('sca', 'msa_frame') _, slit_y, lp = sca2world(x, y) lp *= 10**-6 assert_allclose(lp, lam[cond], atol=1e-13)
def populate_datamodel(self, array): """Place the image and accopanying WCS information in an ImageModel instance. This makes passing the information to the blotting function easier. Parameters ---------- array : numpy.ndarray 2D array containing the cropped image """ # now we need to update the WCS of the mosaic piece cropped = datamodels.ImageModel() cropped.meta.wcsinfo.cdelt1 = self.mosaic_scale_x / 3600. cropped.meta.wcsinfo.cdelt2 = self.mosaic_scale_y / 3600. cropped.meta.wcsinfo.crpix1 = self.crpix1 cropped.meta.wcsinfo.crpix2 = self.crpix2 cropped.meta.wcsinfo.crval1 = self.center_ra cropped.meta.wcsinfo.crval2 = self.center_dec cropped.meta.wcsinfo.ctype1 = self.mosaic_x_type cropped.meta.wcsinfo.ctype2 = self.mosaic_y_type cropped.meta.wcsinfo.cunit1 = 'deg' cropped.meta.wcsinfo.cunit2 = 'deg' cropped.meta.wcsinfo.ra_ref = self.center_ra cropped.meta.wcsinfo.dec_ref = self.center_dec cropped.meta.wcsinfo.roll_ref = self.mosaic_roll * 180. / np.pi cropped.meta.wcsinfo.wcsaxes = 2 cropped.meta.wcsinfo.pc1_1 = self.cd11 / (self.mosaic_scale_x / 3600.) cropped.meta.wcsinfo.pc1_2 = self.cd12 / (self.mosaic_scale_x / 3600.) cropped.meta.wcsinfo.pc2_1 = self.cd21 / (self.mosaic_scale_y / 3600.) cropped.meta.wcsinfo.pc2_2 = self.cd22 / (self.mosaic_scale_y / 3600.) cropped.data = array return cropped
def test_exptype_is_none(): """ Test for when exposure type is None. """ with pytest.raises(RuntimeError): input = datamodels.ImageModel((10,10)) input.meta.exposure.type = None srctype.set_source_type(input)
def abtov2v3model(channel,**kwargs): # Construct the reference data model in general JWST imager type input_model = datamodels.ImageModel() # Convert input of type '1A' into the band and channel that pipeline needs theband,thechan=bandchan(channel) # Set the filter in the data model meta header input_model.meta.instrument.band = theband input_model.meta.instrument.channel = thechan # If passed input refs keyword, unpack and use it if ('refs' in kwargs): therefs=kwargs['refs'] # Otherwise use default reference files else: therefs=get_fitsreffile(channel) # The pipeline transform actually uses the triple # (alpha,beta,lambda) -> (v2,v3,lambda) basedistortion = miri.abl_to_v2v3l(input_model, therefs) distortion = basedistortion # Therefore we need to hack a reasonable wavelength onto our input, run transform, # then hack it back off again thewave=midwave(channel) # Duplicate the beta value at first, then replace with wavelength value map=models.Mapping((0,1,1)) | models.Identity(1) & models.Identity(1) & models.Const1D(thewave) map.inverse=models.Mapping((0,1),n_inputs=3) allmap= map | distortion | map.inverse allmap.inverse= map | distortion.inverse | map.inverse # Return the distortion object that can then be queried return allmap
def _run_flat_fetch_on_dataset(dataset_path): from jwst import datamodels step = CrdsStep() with datamodels.ImageModel(join(dirname(__file__), dataset_path)) as input_file: step.run(input_file) assert basename(step.ref_filename) == "jwst_nircam_flat_0296.fits"
def make_model(self, detname, raval, decval, v2, v3, v3angle, vpar, rollval, filt, pup): #define the WCS of the blotted output blot_to = datamodels.ImageModel((2048, 2048)) blot_to.meta.wcsinfo.cdelt1 = self.nrc_scale[detname][0] / 3600. blot_to.meta.wcsinfo.cdelt2 = self.nrc_scale[detname][1] / 3600. blot_to.meta.wcsinfo.crpix1 = 1024.5 blot_to.meta.wcsinfo.crpix2 = 1024.5 blot_to.meta.wcsinfo.crval1 = raval blot_to.meta.wcsinfo.crval2 = decval blot_to.meta.wcsinfo.ctype1 = 'RA---TAN' blot_to.meta.wcsinfo.ctype2 = 'DEC--TAN' blot_to.meta.wcsinfo.cunit1 = 'deg' blot_to.meta.wcsinfo.cunit2 = 'deg' blot_to.meta.wcsinfo.ra_ref = raval blot_to.meta.wcsinfo.dec_ref = decval blot_to.meta.wcsinfo.roll_ref = rollval blot_to.meta.wcsinfo.wcsaxes = 2 blot_to.meta.wcsinfo.v2_ref = v2 blot_to.meta.wcsinfo.v3_ref = v3 blot_to.meta.wcsinfo.v3yangle = v3angle blot_to.meta.wcsinfo.vparity = vpar blot_to.meta.instrument.channel = 'SHORT' blot_to.meta.instrument.detector = 'NRC' + detname blot_to.meta.instrument.filter = filt blot_to.meta.instrument.module = detname[0] blot_to.meta.instrument.name = 'NIRCAM' blot_to.meta.instrument.pupil = pup blot_to.meta.telescope = 'JWST' blot_to.meta.exposure.start_time = 57410.24546415885 blot_to.meta.exposure.end_time = 57410.2477009838 blot_to.meta.exposure.type = 'NRC_IMAGE' blot_to.meta.target.ra = raval blot_to.meta.target.dec = decval return blot_to
def xytov2v3lam_model(stype, **kwargs): # Construct the reference data model in general JWST imager type input_model = datamodels.ImageModel() # Set the subarray info in the data model meta header if (stype.lower() == 'slit'): input_model.meta.subarray.name = 'FULL' input_model.meta.subarray.xstart = 1 input_model.meta.subarray.ystart = 1 input_model.meta.subarray.xsize = 1032 input_model.meta.subarray.ysize = 1024 input_model.data = np.zeros((1024, 1032)) input_model.meta.exposure.type = 'MIR_LRS-FIXEDSLIT' elif (stype.lower() == 'slitless'): input_model.meta.subarray.name = 'SUBPRISM' input_model.meta.subarray.xstart = 1 input_model.meta.subarray.ystart = 529 input_model.meta.subarray.xsize = 72 input_model.meta.subarray.ysize = 416 input_model.data = np.zeros((416, 72)) input_model.meta.exposure.type = 'MIR_LRS-SLITLESS' else: print('Invalid operation type: specify either slit or slitless') # If passed input refs keyword, unpack and use these reference files if ('refs' in kwargs): therefs = kwargs['refs'] # Otherwise use default reference files else: therefs = get_fitsreffile() # Call the pipeline code to make a distortion object given these inputs distortion = miri.lrs_distortion(input_model, therefs) # Return the distortion object that can then be queried return distortion
def sci_blot_image_pair(): """Provide a science and blotted ImageModel pair.""" shape = (20, 20) sigma = 0.02 background = 3 sci = datamodels.ImageModel(shape) # Populate keywords sci.meta.exposure.exposure_time = 1 sci.meta.background.subtracted = False sci.meta.background.level = background sci.data = np.random.normal(loc=background, size=shape, scale=sigma) sci.err = np.zeros(shape) + sigma sci.var_rnoise += 0 # Add a source in the center signal = 20 * sigma sci.data[10, 10] += signal # update the noise for this source to include the photon/measurement noise sci.err[10, 10] = np.sqrt(sigma**2 + signal) # The blot image is just a smoothed version of the science image that has # its background subtracted blot = sci.copy() blot.data = gaussian_filter(blot.data, sigma=3) blot.data -= background return sci, blot
def test_shutter_size_on_sky(): """ Test the size of a MOS shutter on sky is ~ .2 x .4 arcsec. """ image = create_nirspec_mos_file() model = datamodels.ImageModel(image) msaconfl = get_file_path('msa_configuration.fits') model.meta.instrument.msa_metadata_file = msaconfl model.meta.instrument.msa_metadata_id = 12 refs = create_reference_files(model) pipe = nirspec.create_pipeline(model, refs, slit_y_range=(-.5, .5)) w = wcs.WCS(pipe) model.meta.wcs = w slit = w.get_transform('slit_frame', 'msa_frame').slits[0] wslit = nirspec.nrs_wcs_set_input(model, slit.name) virtual_corners_x = [-.5, -.5, .5, .5, -.5] virtual_corners_y = [-.5, .5, .5, -.5, -.5] input_lam = [2e-6] * 5 slit2world = wslit.get_transform('slit_frame', 'world') ra, dec, lam = slit2world(virtual_corners_x, virtual_corners_y, input_lam) sky = coords.SkyCoord(ra * u.deg, dec * u.deg) sep_x = sky[0].separation(sky[3]).to(u.arcsec) sep_y = sky[0].separation(sky[1]).to(u.arcsec) assert sep_x.value > 0.193 assert sep_x.value < 0.194 assert sep_y.value > 0.45 assert sep_y.value < 0.46
def test_master_background_userbg(_jail, user_background): """Verify data can run through the step with a user-supplied background""" image = datamodels.ImageModel((10, 10)) image.meta.instrument.name = 'MIRI' image.meta.instrument.detector = 'MIRIMAGE' image.meta.exposure.type = 'MIR_LRS-FIXEDSLIT' image.meta.observation.date = '2018-01-01' image.meta.observation.time = '00:00:00' image.meta.subarray.xstart = 1 image.meta.subarray.ystart = 1 image.meta.wcsinfo.v2_ref = 0 image.meta.wcsinfo.v3_ref = 0 image.meta.wcsinfo.roll_ref = 0 image.meta.wcsinfo.ra_ref = 0 image.meta.wcsinfo.dec_ref = 0 image = AssignWcsStep.call(image) # Run with a user-supplied background and verify this is recorded in header result = MasterBackgroundStep.call(image, user_background=user_background) collect_pipeline_cfgs('./config') result = MasterBackgroundStep.call( image, config_file='config/master_background.cfg', user_background=user_background, ) # For inputs that are not files, the following should be true assert type(image) is type(result) assert result is not image assert result.meta.cal_step.master_background == 'COMPLETE' assert result.meta.background.master_background_file == 'user_background.fits'
def test_flatfield_step_interface(instrument, exptype): """Test that the basic inferface works for data requiring a FLAT reffile""" shape = (20, 20) data = datamodels.ImageModel(shape) data.meta.instrument.name = instrument data.meta.exposure.type = exptype data.meta.subarray.xstart = 1 data.meta.subarray.ystart = 1 data.meta.subarray.xsize = shape[1] data.meta.subarray.ysize = shape[0] flat = datamodels.FlatModel(shape) flat.meta.instrument.name = instrument flat.meta.subarray.xstart = 1 flat.meta.subarray.ystart = 1 flat.meta.subarray.xsize = shape[1] flat.meta.subarray.ysize = shape[0] flat.data += 1 flat.data[0, 0] = np.nan flat.err = np.random.random(shape) * 0.05 # override class attribute so only the `flat` type needs to be overriden # in the step call. Otherwise CRDS calls will be made for the other 3 # types of flat reference file not used in this test. FlatFieldStep.reference_file_types = ["flat"] result = FlatFieldStep.call(data, override_flat=flat) assert (result.data == data.data).all() assert result.var_flat.shape == shape assert result.meta.cal_step.flat_field == 'COMPLETE'
def test_tso_types(): # Exposure without the SRCTYPE keyword present at all, # but it's a TSO mode input = datamodels.ImageModel((10, 10)) input.meta.observation.bkgdtarg = False input.meta.dither.primary_type = 'NONE' # All results should be POINT input.meta.exposure.type = 'NRS_BRIGHTOBJ' output = srctype.set_source_type(input) assert output.meta.target.source_type == 'POINT' del input.meta.target.source_type input.meta.exposure.type = 'NRC_TSGRISM' output = srctype.set_source_type(input) assert output.meta.target.source_type == 'POINT' del input.meta.target.source_type input.meta.exposure.type = 'NIS_SOSS' input.meta.visit.tsovisit = True output = srctype.set_source_type(input) assert output.meta.target.source_type == 'POINT' del input.meta.target.source_type input.meta.exposure.type = 'MIR_LRS-SLITLESS' input.meta.visit.tsovisit = True output = srctype.set_source_type(input) assert output.meta.target.source_type == 'POINT'
def create_image_model(input_model, image_info): """Creates an ImageModel from the computed arrays from ramp_fit. Parameters ---------- input_model: RampModel Input RampModel for which the output ImageModel is created. image_info: tuple The ramp fitting arrays needed for the ImageModel. Returns ------- out_model: jwst.datamodels.ImageModel The output ImageModel to be returned from the ramp fit step. """ data, dq, var_poisson, var_rnoise, err = image_info # Create output datamodel out_model = datamodels.ImageModel(data.shape) # ... and add all keys from input out_model.update(input_model) # Populate with output arrays out_model.data = data out_model.dq = dq out_model.var_poisson = var_poisson out_model.var_rnoise = var_rnoise out_model.err = err return out_model
def process(self, science, flat): self.log.info("Removing flat field") self.log.info("Threshold: {0}".format(self.threshold)) library_function() output = datamodels.ImageModel(data=science.data - flat.data) return output
def _convert_inputs(self): """Convert input into datamodel required for processing. This method converts `self.inputs` into a version of `self.input_models` suitable for processing by the class. This base class works on imaging data, and relies on use of the ModelContainer class as the format needed for processing. However, the input may not always be a ModelContainer object, so this method will convert the input to a ModelContainer object for processing. Additionally, sub-classes may redefine this to set up the input as whatever format the sub-class needs for processing. """ bits = self.outlierpars['good_bits'] if isinstance(self.inputs, datamodels.ModelContainer): self.input_models = self.inputs self.converted = False else: self.input_models = datamodels.ModelContainer() num_inputs = self.inputs.data.shape[0] log.debug("Converting CubeModel to ModelContainer with {} images". format(num_inputs)) for i in range(self.inputs.data.shape[0]): image = datamodels.ImageModel(data=self.inputs.data[i], err=self.inputs.err[i], dq=self.inputs.dq[i]) image.meta = self.inputs.meta image.wht = build_driz_weight(image, weight_type='ivm', good_bits=bits) self.input_models.append(image) self.converted = True
def xytov2v3l(x, y, file): im = datamodels.ImageModel(file) nslice = 30 # Big structure to save all the returned values v2all = np.zeros([len(x), nslice]) v3all = np.zeros([len(x), nslice]) lamall = np.zeros([len(x), nslice]) slall = np.zeros([len(x), nslice]) for ii in range(0, nslice): xform = (nirspec.nrs_wcs_set_input(im, ii)).get_transform( 'detector', 'v2v3') v2all[:, ii], v3all[:, ii], lamall[:, ii] = xform(x, y) slall[:, ii] = ii # slice all is nan where v2all is nan v2_1d = v2all.reshape(-1) sl_1d = slall.reshape(-1) finite = (np.isfinite(v2_1d)) indx = (np.where(finite == False))[0] if (len(indx) > 0): sl_1d[indx] = np.nan # Element 1330000 should be x=848,y=649, in slice 6 (0-ind) v2 = np.nanmedian(v2all, axis=1) v3 = np.nanmedian(v3all, axis=1) lam = np.nanmedian(lamall, axis=1) sl = np.nanmedian(slall, axis=1) return v2, v3, lam, sl
def test_calc_deltas(engdb, data_path): """Test `calc_deltas` basic running""" model = dm.ImageModel(data_path) deltas = ps.calc_deltas([model]) truth = Table.read(DATA_PATH / 'calc_deltas_truth.ecsv') assert report_diff_values(truth, deltas, fileobj=sys.stderr)
def imaging_coords(fname, output=None): """ Computes wavelengths, and space coordinates of a NIRSPEC imaging exposure after running assign_wcs. Parameters ---------- fname : str The name of a file after assign_wcs was run. output : str The name of the output file. If None the root of the input file is used with an extension world_coordinates. Examples -------- >>> compute_world_coordinates('nrs1_fixed_assign_wcs_extract_2d.fits') """ model = datamodels.ImageModel(fname) if model.meta.exposure.type.lower() not in imaging_modes: raise ValueError("Observation mode {0} is not supported.".format(model.meta.exposure.type)) hdulist = fits.HDUList() phdu = fits.PrimaryHDU() phdu.header['filename'] = model.meta.filename phdu.header['data'] = 'world coordinates' hdulist.append(phdu) output_frame = model.available_frames[-1] bb = model.meta.wcs.bounding_box x, y = wcstools.grid_from_bounding_box(bb, step=(1, 1), center=True) ra, dec, lam = slit(x + 1, y + 1) world_coordinates = np.array([lam, ra, dec]) imhdu = fits.ImageHDU(data=world_coordinates) imhdu.header['PLANE1'] = 'lambda, microns' imhdu.header['PLANE2'] = '{0}_x, deg'.format(output_frame) imhdu.header['PLANE3'] = '{0}_y, deg'.format(output_frame) imhdu.header['SLIT'] = "SLIT_{0}".format(i) # add the overall subarray offset imhdu.header['CRVAL1'] = model.meta.subarray.xstart - 1 + int(_toindex(bb[0][0])) imhdu.header['CRVAL2'] = model.meta.subarray.ystart - 1 + int(_toindex(bb[1][0])) # Input coordinates will be 1-based. imhdu.header['CRPIX1'] = 1 imhdu.header['CRPIX2'] = 1 imhdu.header['CTYPE1'] = 'pixel' imhdu.header['CTYPE2'] = 'pixel' hdulist.append(imhdu) if output is not None: base, ext = os.path.splitext(output) if ext != "fits": ext = "fits" if not base.endswith('world_coordinates'): "".join([base, '_world_coordinates']) "".join([base, ext]) else: root = model.meta.filename.split('_') output = "".join([root[0], '_world_coordinates', '.fits']) hdulist.writeto(output, overwrite=True) del hdulist model.close()
def test_ami_analyze_cube_fail(): """Make sure ami_analyze fails if input is CubeModel (_calints)""" model = datamodels.ImageModel((25, 19, 19)) model.meta.instrument.name = "NIRISS" model.meta.instrument.filter = "F277W" model.meta.observation.date = "2019-01-01" model.meta.observation.time = "00:00:00" with pytest.raises(RuntimeError): AmiAnalyzeStep.call(model)
def test_init_from_pathlib(tmp_path): """Test initializing model from a Path object""" path = tmp_path / "pathlib.fits" model1 = datamodels.ImageModel((50, 50)) model1.save(path) model = datamodels.open(path) # Test is basically, did we open the model? assert isinstance(model, ImageModel)
def test_subarray_transform(): im = datamodels.ImageModel() assert subarray_transform(im) is None im.meta.subarray.xstart = 3 transform = subarray_transform(im) assert isinstance(transform[0], Shift) and transform[0].offset == 2 assert isinstance(transform[1], Identity) im.meta.subarray.ystart = 5 transform = subarray_transform(im) assert isinstance(transform[0], Shift) and transform[0].offset == 2 assert isinstance(transform[1], Shift) and transform[1].offset == 4 im = datamodels.ImageModel() im.meta.subarray.ystart = 5 transform = subarray_transform(im) assert isinstance(transform[0], Identity) assert isinstance(transform[1], Shift) and transform[1].offset == 4
def xytoab_cdp5test(refs): # Construct the reference data model in general JWST imager type input_model = datamodels.ImageModel() # Set the filter in the data model meta header input_model.meta.instrument.band = 'SHORT' input_model.meta.instrument.channel = '12' distortion = miri.detector_to_alpha_beta(input_model, refs) # Return the distortion object that can then be queried return distortion
def _create_image_model(grating='G395H', filter='F290LP', **kwargs): hdul = create_nirspec_ifu_file(grating=grating, filter=filter, **kwargs) im = datamodels.ImageModel(hdul) refs = create_reference_files(im) pipeline = nirspec.create_pipeline(im, refs, slit_y_range=[-0.5, 0.5]) w = wcs.WCS(pipeline) im.meta.wcs = w return im, refs
def test_skipped(): """ Test all conditions that lead to skipping wavecorr.""" hdul = create_nirspec_fs_file(grating="G140H", filter="F100LP") im = datamodels.ImageModel(hdul) # test a non-valid exp_type2transform im.meta.exposure.type = 'NRS_IMAGE' out = WavecorrStep.call(im) assert out.meta.cal_step.wavecorr == "SKIPPED" # Test an error is raised if assign_wcs or extract_2d were not run. im.meta.exposure.type = 'NRS_FIXEDSLIT' with pytest.raises(AttributeError): WavecorrStep.call(im) outa = AssignWcsStep.call(im) oute = Extract2dStep.call(outa) outs = SourceTypeStep.call(oute) # Test step is skipped if no coverage in CRDS outs.slits[0].meta.observation.date = '2001-08-03' outw = WavecorrStep.call(outs) assert out.meta.cal_step.wavecorr == "SKIPPED" outs.meta.observation.date = '2017-08-03' outw = WavecorrStep.call(outs) # Primary name not set assert out.meta.cal_step.wavecorr == "SKIPPED" outs.meta.instrument.fixed_slit = "S400A1" # Test step is skipped if meta.dither is not populated outw = WavecorrStep.call(outs) assert out.meta.cal_step.wavecorr == "SKIPPED" dither = {'x_offset': 0.0, 'y_offset': 0.0} ind = np.nonzero([s.name == 'S400A1' for s in outs.slits])[0].item() outs.slits[ind].meta.dither = dither outs.slits[ind].meta.wcsinfo.v3yangle = 138.78 outs.slits[ind].meta.wcsinfo.vparity = -1 outs.slits[ind].meta.wcsinfo.v2_ref = 321.87 outs.slits[ind].meta.wcsinfo.v3_ref = -477.94 outs.slits[ind].meta.wcsinfo.roll_ref = 15.1234 # Test step is skipped if source is "EXTENDED" outw = WavecorrStep.call(outs) assert out.meta.cal_step.wavecorr == "SKIPPED" outs.slits[ind].source_type = 'POINT' outw = WavecorrStep.call(outs) source_pos = (0.004938526981283373, -0.02795306204991911) assert_allclose((outw.slits[ind].source_xpos, outw.slits[ind].source_ypos), source_pos)
def wfs_association(tmp_path_factory): imsize = 10 tmp_path = tmp_path_factory.mktemp("wfs") im1 = datamodels.ImageModel((imsize, imsize)) im1.meta.wcsinfo = { 'dec_ref': 11.99875540218638, 'ra_ref': 22.02351763251896, 'roll_ref': 0.005076934167039675, 'v2_ref': 86.039011, 'v3_ref': -493.385704, 'v3yangle': -0.07385127, 'vparity': -1, 'wcsaxes': 2 } im1.meta.instrument = { 'channel': 'SHORT', 'detector': 'NRCA4', 'filter': 'F212N', 'module': 'A', 'name': 'NIRCAM', 'pupil': 'CLEAR' } im1.meta.observation = { 'exposure_number': '1', 'date': '2021-10-25', 'time': '16:58:27.258' } im1.meta.exposure = {'type': 'NRC_IMAGE'} im1 = AssignWcsStep.call(im1, sip_approx=False) im2 = im1.copy() im2.meta.observation = { 'exposure_number': '2', 'date': '2021-10-25', 'time': '17:58:27.258' } path1 = str(tmp_path / "image1_cal.fits") path2 = str(tmp_path / "image2_cal.fits") im1.save(path1) im2.save(path2) asn = asn_from_list( [path1, path2], product_name='jw00024-a3001_t001_nircam_nrca4_{suffix}') asn.data["program"] = "00024" asn.data["asn_type"] = "wfs-image2" asn.sequence = 1 asn_name, serialized = asn.dump(format="json") path_asn = tmp_path / asn_name with open(path_asn, "w") as f: f.write(serialized) return path_asn, path1, path2
def test_missing_msa_file(): image = create_nirspec_mos_file() model = datamodels.ImageModel(image) model.meta.instrument.msa_metadata_file = "" with pytest.raises(MSAFileError): assign_wcs_step.AssignWcsStep.call(model) model.meta.instrument.msa_metadata_file = "missing.fits" with pytest.raises(MSAFileError): assign_wcs_step.AssignWcsStep.call(model)