def ifupost2asdf(ifupost_files, outname): """ Create a reference file of type ``ifupost`` . Combines all IDT ``IFU-POST`` reference files in one ASDF file. forward direction : MSA to Collimator backward_direction: Collimator to MSA Parameters ---------- ifupost_files : list Names of all ``IFU-POST`` IDT reference files outname : str Name of output ``ASDF`` file """ ref_kw = common_reference_file_keywords("IFUPOST", "NIRSPEC IFU-POST transforms - CDP4") fa = AsdfFile() fa.tree = ref_kw for fifu in ifupost_files: n = int((fifu.split('IFU-POST_')[1]).split('.pcf')[0]) fa.tree[n] = {} with open(fifu) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2') + 1].split() rotation_angle = float(lines[lines.index('*Rotation') + 1]) input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split() output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split() linear_sky2det = homothetic_sky2det(input_rot_center, rotation_angle, factors, output_rot_center) degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1: xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22]) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_backward) output2poly_mapping = Identity(2, name='output_mapping') output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping') input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = linear_sky2det | model_poly fa.tree[n]['model'] = model asdffile = fa.write_to(outname) return asdffile
def oteip_to_v23(reference_files): """ Transform from the OTEIP frame to the V2V3 frame. Parameters ---------- reference_files: dict Dictionary with reference files returned by CRDS. Returns ------- model : `~astropy.modeling.core.Model` model. Transform from OTEIP to V2V3. """ with AsdfFile.open(reference_files['ote']) as f: ote = f.tree['model'].copy() fore2ote_mapping = Identity(3, name='fore2ote_mapping') fore2ote_mapping.inverse = Mapping((0, 1, 2, 2)) # Create the transform to v2/v3/lambda. The wavelength units up to this point are # meters as required by the pipeline but the desired output wavelength units is microns. # So we are going to Scale the spectral units by 1e6 (meters -> microns) # The spatial units are currently in deg. Convertin to arcsec. oteip_to_xyan = fore2ote_mapping | (ote & Scale(1e6)) # Add a shift for the aperture. oteip2v23 = oteip_to_xyan | Identity(1) & (Shift(468 / 3600) | Scale(-1)) & Identity(1) return oteip2v23
def pcf_forward(pcffile, outname): """ Create the **IDT** forward transform from collimator to gwa. """ with open(pcffile) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2') + 1].split() # factor==1/factor in backward msa2ote direction and factor==factor in sky2detector direction scale = models.Scale(float(factors[0]), name="x_scale") & \ models.Scale(float(factors[1]), name="y_scale") rotation_angle = lines[lines.index('*Rotation') + 1] # The minius sign here is because astropy.modeling has the opposite direction of rotation than the idl implementation rotation = models.Rotation2D(-float(rotation_angle), name='rotation') # Here the model is called "output_shift" but in the team version it is the "input_shift". input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split() input_rot_shift = models.Shift(-float(input_rot_center[0]), name='input_x_shift') & \ models.Shift(-float(input_rot_center[1]), name='input_y_shift') # Here the model is called "input_shift" but in the team version it is the "output_shift". output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split() output_rot_shift = models.Shift(float(output_rot_center[0]), name='output_x_shift') & \ models.Shift(float(output_rot_center[1]), name='output_y_shift') degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1: xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22]) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward poly_mapping1 = Mapping((0, 1, 0, 1)) poly_mapping1.inverse = Identity(2) poly_mapping2 = Identity(2) poly_mapping2.inverse = Mapping((0, 1, 0, 1)) model = input_rot_shift | rotation | scale | output_rot_shift | \ poly_mapping1 | x_poly_forward & y_poly_forward | poly_mapping2 f = AsdfFile() f.tree = {'model': model} f.write_to(outname)
def ote2asdf(otepcf, outname, ref_kw): """ ref_kw = common_reference_file_keywords('OTE', 'NIRSPEC OTE transform - CDP4') ote2asdf('Model/Ref_Files/CoordTransform/OTE.pcf', 'jwst_nirspec_ote_0001.asdf', ref_kw) """ with open(otepcf) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2 1') + 1].split() # this corresponds to modeling Rotation direction as is rotation_angle = float(lines[lines.index('*Rotation') + 1]) input_rot_center = lines[lines.index('*InputRotationCentre 2 1') + 1].split() output_rot_center = lines[lines.index('*OutputRotationCentre 2 1') + 1].split() mlinear = homothetic_det2sky(input_rot_center, rotation_angle, factors, output_rot_center) degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xlines = lines[xcoeff_index + 1].split('\t') xcoeff_backward = coeffs_from_pcf(degree, xlines) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1].split('\t') xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ylines = lines[ycoeff_index + 1].split('\t') ycoeff_backward = coeffs_from_pcf(degree, ylines) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ylines = lines[ycoeff_index + 1].split('\t') ycoeff_forward = coeffs_from_pcf(degree, ylines) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward output2poly_mapping = Identity(2, name='output_mapping') output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping') input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = model_poly | mlinear f = AsdfFile() f.tree = ref_kw.copy() f.tree['model'] = model f.add_history_entry("Build 6") f.write_to(outname) return model_poly, mlinear
def oteip_to_v23(reference_files): """ Transform from the OTEIP frame to the V2V3 frame. Parameters ---------- reference_files: dict Dictionary with reference files returned by CRDS. Returns ------- model : `~astropy.modeling.core.Model` model. Transform from OTEIP to V2V3. """ with AsdfFile.open(reference_files['ote']) as f: ote = f.tree['model'].copy() fore2ote_mapping = Identity(3, name='fore2ote_mapping') fore2ote_mapping.inverse = Mapping((0, 1, 2, 2)) # Convert the wavelength to microns return fore2ote_mapping | (ote & Identity(1) / Const1D(1e-6))
def oteip_to_v23(reference_files): """ Transform from the OTEIP frame to the V2V3 frame. Parameters ---------- reference_files: dict Dictionary with reference files returned by CRDS. Returns ------- model : `~astropy.modeling.core.Model` model. Transform from OTEIP to V2V3. """ with AsdfFile.open(reference_files['ote']) as f: ote = f.tree['model'].copy() fore2ote_mapping = Identity(3, name='fore2ote_mapping') fore2ote_mapping.inverse = Mapping((0, 1, 2, 2)) # Create the transform to v2/v3/lambda. The wavelength units up to this point are # meters as required by the pipeline but the desired output wavelength units is microns. # So we are going to Scale the spectral units by 1e6 (meters -> microns) return fore2ote_mapping | (ote & Scale(1e6))
def fore2asdf(pcffore, name=""): """ forward direction : msa 2 ote backward_direction: msa 2 fpa """ with open(pcffore) as f: lines = [l.strip() for l in f.readlines()] fore_det2sky = linear_from_pcf_det2sky(pcffore, name=name) fore_linear = fore_det2sky fore_linear.inverse = fore_det2sky.inverse & Identity(1) # compute the polynomial degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1:xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) # Polynomial Correction in x x_poly_backward = models.Polynomial2D(degree, name="{0}_x_back".format(name), **xcoeff_forward) xlines_distortion = lines[xcoeff_index + 22:xcoeff_index + 43] xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion) x_poly_backward_distortion = models.Polynomial2D( degree, name="{0}_x_backdist".format(name), **xcoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_x_backward = (Mapping((0, 1), n_inputs=3) | x_poly_backward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_backward_distortion) * \ (Mapping((2,)) | Identity(1))) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name="{0}_y_back".format(name), **ycoeff_forward) ylines_distortion = lines[ycoeff_index + 22:ycoeff_index + 43] ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion) y_poly_backward_distortion = models.Polynomial2D( degree, name="{0}_y_backdist".format(name), **ycoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_y_backward = (Mapping((0,1), n_inputs=3) | y_poly_backward) + \ ((Mapping((0, 1), n_inputs=3) | y_poly_backward_distortion) * \ (Mapping((2,)) | Identity(1) )) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf( degree, lines[xcoeff_index + 1:xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree, name="{0}_x_forw".format(name), **xcoeff_backward) xcoeff_backward_distortion = coeffs_from_pcf( degree, lines[xcoeff_index + 22:xcoeff_index + 43]) x_poly_forward_distortion = models.Polynomial2D( degree, name="{0}_x_forwdist".format(name), **xcoeff_backward_distortion) # the chromatic correction is done here # the input is Xmsa, Ymsa, lam model_x_forward = (Mapping((0,1), n_inputs=3) | x_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_forward_distortion) * \ (Mapping((2,)) | Identity(1))) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name="{0}_y_forw".format(name), **ycoeff_backward) ycoeff_backward_distortion = coeffs_from_pcf( degree, lines[ycoeff_index + 22:ycoeff_index + 43]) y_poly_forward_distortion = models.Polynomial2D( degree, name="{0}_y_forwdist".format(name), **ycoeff_backward_distortion) # do chromatic correction # the input is Xmsa, Ymsa, lam model_y_forward = (Mapping((0,1), n_inputs=3) | y_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | y_poly_forward_distortion) * \ (Mapping((2,)) | Identity(1))) #assign inverse transforms model_x = model_x_forward.copy() model_y = model_y_forward.copy() model_x.inverse = model_x_backward model_y.inverse = model_y_backward output2poly_mapping = Identity(2, name="{0}_outmap".format(name)) output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2]) input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name="{0}_inmap".format(name)) input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (model_x & model_y) | output2poly_mapping model = model_poly | fore_linear return model
def ifupost2asdf(ifupost_files, author, description, useafter): """ Create a reference file of type ``ifupost`` . Combines all IDT ``IFU-POST`` reference files in one ASDF file. forward direction : MSA to Collimator backward_direction: Collimator to MSA Parameters ---------- ifupost_files : list Names of all ``IFU-POST`` IDT reference files outname : str Name of output ``ASDF`` file """ ifupost_model = IFUPostModel() for fifu in ifupost_files: fifu_name = os.path.split(fifu)[1] n = int((fifu_name.split('IFU-POST_')[1]).split('.pcf')[0]) with open(fifu) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2') + 1].split() rotation_angle = float(lines[lines.index('*Rotation') + 1]) input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split() output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split() linear_sky2det = homothetic_sky2det(input_rot_center, rotation_angle, factors, output_rot_center, name='ifupost') degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1:xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_forward = models.Polynomial2D(degree, name='ifupost_x_forw', **xcoeff_forward) xlines_distortion = lines[xcoeff_index + 22:xcoeff_index + 43] xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion) x_poly_forward_distortion = models.Polynomial2D( degree, name="ifupost_x_forwdist", **xcoeff_forward_distortion) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='ifupost_y_forw', **ycoeff_forward) ylines_distortion = lines[ycoeff_index + 22:ycoeff_index + 43] ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion) y_poly_forward_distortion = models.Polynomial2D( degree, name="ifupost_y_forwdist", **ycoeff_forward_distortion) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf( degree, lines[xcoeff_index + 1:xcoeff_index + 22]) x_poly_backward = models.Polynomial2D(degree, name='ifupost_x_back', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='ifupost_y_back', **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward output2poly_mapping = Identity(2, name='ifupost_outmap') output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2]) input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name='ifupost_inmap') input2poly_mapping.inverse = Identity(2) model = { 'linear': linear_sky2det, 'xpoly': x_poly_forward, 'xpoly_distortion': x_poly_forward_distortion, 'ypoly': y_poly_forward, 'ypoly_distortion': y_poly_forward_distortion } name = "slice_{0}".format(n) setattr(ifupost_model, name, model) ifupost_model.meta.author = author ifupost_model.meta.description = description ifupost_model.meta.useafter = useafter ifupost_model.meta.pedigree = "GROUND" return ifupost_model
def ifupost2asdf(ifupost_files, outname, ref_kw): """ Create a reference file of type ``ifupost`` . Combines all IDT ``IFU-POST`` reference files in one ASDF file. forward direction : MSA to Collimator backward_direction: Collimator to MSA Parameters ---------- ifupost_files : list Names of all ``IFU-POST`` IDT reference files outname : str Name of output ``ASDF`` file """ fa = AsdfFile() fa.tree = ref_kw for fifu in ifupost_files: n = int((fifu.split('IFU-POST_')[1]).split('.pcf')[0]) fa.tree[n] = {} with open(fifu) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2') + 1].split() rotation_angle = float(lines[lines.index('*Rotation') + 1]) input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split() output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split() linear_sky2det = homothetic_sky2det(input_rot_center, rotation_angle, factors, output_rot_center) degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1:xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf( degree, lines[xcoeff_index + 1:xcoeff_index + 22]) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_backward) output2poly_mapping = Identity(2, name='output_mapping') output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping') input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | ( x_poly_forward & y_poly_forward) | output2poly_mapping model = linear_sky2det | model_poly fa.tree[n]['model'] = model fa.add_history_entry("Build 6") asdffile = fa.write_to(outname) return asdffile
def pcf2asdf(pcffile, outname, ref_file_kw): """ Create an asdf reference file with the transformation coded in a NIRSPEC Camera.pcf or Collimator*.pcf file. - forward (team): sky to detector - Shift inputs to input_rotation_center - Rotate inputs - Scale inputs - Shift inputs to output_rot_center - Apply polynomial distortion - backward_team (team definition) detector to sky - Apply polynomial distortion - Shift inputs to output_rot_center - Scale inputs - Rotate inputs - Shift inputs to input_rotation_center WCS implementation - forward: detector to sky - equivalent to backward_team - backward: sky to detector - equivalent to forward_team Parameters ---------- pcffile : str one of the NIRSPEC ".pcf" reference files provided by the IDT team. "pcf" stands for "polynomial coefficients fit" outname : str Name of reference file to be wriiten to disk. Returns ------- fasdf : AsdfFile AsdfFile object Examples -------- >>> pcf2asdf("Camera.pcf", "camera.asdf") """ linear_det2sky = linear_from_pcf_det2sky(pcffile) with open(pcffile) as f: lines = [l.strip() for l in f.readlines()] degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1:xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf( degree, lines[xcoeff_index + 1:xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward output2poly_mapping = Identity(2, name='output_mapping') output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping') input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = model_poly | linear_det2sky f = AsdfFile() f.tree = ref_file_kw.copy() f.add_history_entry("Build 6") f.tree['model'] = model f.write_to(outname)
def fore2asdf(pcffore, outname, ref_kw): """ forward direction : msa 2 ote backward_direction: msa 2 fpa """ with open(pcffore) as f: lines = [l.strip() for l in f.readlines()] fore_det2sky = linear_from_pcf_det2sky(pcffore) fore_linear = fore_det2sky fore_linear.inverse = fore_det2sky.inverse & Identity(1) # compute the polynomial degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1:xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) # Polynomial Correction in x x_poly_backward = models.Polynomial2D(degree, name="x_poly_backward", **xcoeff_forward) xlines_distortion = lines[xcoeff_index + 22:xcoeff_index + 43] xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion) x_poly_backward_distortion = models.Polynomial2D( degree, name="x_backward_distortion", **xcoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_x_backward = (Mapping((0, 1), n_inputs=3) | x_poly_backward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_backward_distortion) * \ (Mapping((2,)) | Identity(1))) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name="y_poly_backward", **ycoeff_forward) ylines_distortion = lines[ycoeff_index + 22:ycoeff_index + 43] ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion) y_poly_backward_distortion = models.Polynomial2D( degree, name="y_backward_distortion", **ycoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_y_backward = (Mapping((0,1), n_inputs=3) | y_poly_backward) + \ ((Mapping((0, 1), n_inputs=3) | y_poly_backward_distortion) * \ (Mapping((2,)) | Identity(1) )) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf( degree, lines[xcoeff_index + 1:xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree, name="x_poly_forward", **xcoeff_backward) xcoeff_backward_distortion = coeffs_from_pcf( degree, lines[xcoeff_index + 22:xcoeff_index + 43]) x_poly_forward_distortion = models.Polynomial2D( degree, name="x_forward_distortion", **xcoeff_backward_distortion) # the chromatic correction is done here # the input is Xmsa, Ymsa, lam model_x_forward = (Mapping((0,1), n_inputs=3) | x_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_forward_distortion) * \ (Mapping((2,)) | Identity(1))) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name="y_poly_forward", **ycoeff_backward) ycoeff_backward_distortion = coeffs_from_pcf( degree, lines[ycoeff_index + 22:ycoeff_index + 43]) y_poly_forward_distortion = models.Polynomial2D( degree, name="y_forward_distortion", **ycoeff_backward_distortion) # do chromatic correction # the input is Xmsa, Ymsa, lam model_y_forward = (Mapping((0,1), n_inputs=3) | y_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | y_poly_forward_distortion) * \ (Mapping((2,)) | Identity(1))) #assign inverse transforms model_x = model_x_forward.copy() model_y = model_y_forward.copy() model_x.inverse = model_x_backward model_y.inverse = model_y_backward output2poly_mapping = Identity(2, name="output_mapping") output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2]) input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name="input_mapping") input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (model_x & model_y) | output2poly_mapping model = model_poly | fore_linear f = AsdfFile() f.tree = ref_kw.copy() f.tree['model'] = model f.add_history_entry("Build 6") asdffile = f.write_to(outname) return asdffile
def pcf2asdf(pcffile, outname, ref_file_kw): """ Create an asdf reference file with the transformation coded in a NIRSPEC Camera.pcf or Collimator*.pcf file. - forward (team): sky to detector - Shift inputs to input_rotation_center - Rotate inputs - Scale inputs - Shift inputs to output_rot_center - Apply polynomial distortion - backward_team (team definition) detector to sky - Apply polynomial distortion - Shift inputs to output_rot_center - Scale inputs - Rotate inputs - Shift inputs to input_rotation_center WCS implementation - forward: detector to sky - equivalent to backward_team - backward: sky to detector - equivalent to forward_team Parameters ---------- pcffile : str one of the NIRSPEC ".pcf" reference files provided by the IDT team. "pcf" stands for "polynomial coefficients fit" outname : str Name of reference file to be wriiten to disk. Returns ------- fasdf : AsdfFile AsdfFile object Examples -------- >>> pcf2asdf("Camera.pcf", "camera.asdf") """ with open(pcffile) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2') + 1].split() scale = models.Scale(1 / float(factors[0]), name="x_scale") & \ models.Scale(1 / float(factors[1]), name="y_scale") rotation_angle = lines[lines.index('*Rotation') + 1] # Backward rotation is in the counter-clockwise direction as in modeling # Forward is clockwise backward_rotation = models.Rotation2D(float(rotation_angle), name='rotation') rotation = backward_rotation.copy() # Here the model is called "output_shift" but in the team version it is the "input_shift". input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split() output_offset = models.Shift(float(input_rot_center[0]), name='output_x_shift') & \ models.Shift(float(input_rot_center[1]), name='output_y_shift') # Here the model is called "input_shift" but in the team version it is the "output_shift". output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split() input_offset = models.Shift(-float(output_rot_center[0]), name='input_x_shift') & \ models.Shift(-float(output_rot_center[1]), name='input_y_shift') degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1: xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward output2poly_mapping = Identity(2, name='output_mapping') output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping') input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = model_poly | input_offset |scale |rotation |output_offset f = AsdfFile() f.tree = ref_file_kw.copy() f.tree['model'] = model f.write_to(outname)
def ote2asdf(otepcf, author, description, useafter): """ """ with open(otepcf) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2 1') + 1].split() # this corresponds to modeling Rotation direction as is rotation_angle = float(lines[lines.index('*Rotation') + 1]) input_rot_center = lines[lines.index('*InputRotationCentre 2 1') + 1].split() output_rot_center = lines[lines.index('*OutputRotationCentre 2 1') + 1].split() mlinear = homothetic_det2sky(input_rot_center, rotation_angle, factors, output_rot_center, name="ote") degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xlines = lines[xcoeff_index + 1].split('\t') xcoeff_backward = coeffs_from_pcf(degree, xlines) x_poly_forward = models.Polynomial2D(degree, name='ote_x_forw', **xcoeff_backward) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1].split('\t') xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_backward = models.Polynomial2D(degree, name='ote_x_back', **xcoeff_forward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ylines = lines[ycoeff_index + 1].split('\t') ycoeff_backward = coeffs_from_pcf(degree, ylines) y_poly_forward = models.Polynomial2D(degree, name='ote_y_forw', **ycoeff_backward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ylines = lines[ycoeff_index + 1].split('\t') ycoeff_forward = coeffs_from_pcf(degree, ylines) y_poly_backward = models.Polynomial2D(degree, name='ote_y_backw', **ycoeff_forward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward output2poly_mapping = Identity(2, name='ote_outmap') output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='ote_inmap') input2poly_mapping.inverse = Identity(2) # The Nirspec model returns values in degrees. # We are converting them to arcsec in order to use the same V2V3 to sky # transform as other instruments. unit_transform = models.Scale(3600) & models.Scale(3600) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = model_poly | mlinear | unit_transform ote_model = OTEModel() ote_model.model = model ote_model.meta.author = author ote_model.meta.description = description ote_model.meta.useafter = useafter ote_model.meta.pedigree = "GROUND" ote_model.meta.output_units = 'arcsec' return ote_model
def fore2asdf(pcffore, outname, ref_kw): """ forward direction : msa 2 ote backward_direction: msa 2 fpa """ with open(pcffore) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2') + 1].split() # factor==1/factor in backward msa2ote direction and == factor in ote2msa direction scale = models.Scale(1. / float(factors[0]), name='scale_x') & \ models.Scale(1 / float(factors[1]), name='scale_y') rotation_angle = lines[lines.index('*Rotation') + 1] rotation = models.Rotation2D(float(rotation_angle), name='rotation') input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split() output_offset = models.Shift(float(input_rot_center[0]), name="output_x_shift") & \ models.Shift(float(input_rot_center[1]), name="output_y_shift") output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split() input_offset = models.Shift(-float(output_rot_center[0]), name="input_x_shift") & \ models.Shift(-float(output_rot_center[1]), name="input_y_shift") degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1:xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) # Polynomial Correction in x x_poly_backward = models.Polynomial2D(degree, name="x_poly_backward", **xcoeff_forward) xlines_distortion = lines[xcoeff_index + 22:xcoeff_index + 43] xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion) x_poly_backward_distortion = models.Polynomial2D( degree, name="x_backward_distortion", **xcoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_x_backward = (Mapping((0, 1), n_inputs=3) | x_poly_backward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_backward_distortion) * Mapping((2,))) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name="y_poly_backward", **ycoeff_forward) ylines_distortion = lines[ycoeff_index + 22:ycoeff_index + 43] ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion) y_poly_backward_distortion = models.Polynomial2D( degree, name="y_backward_distortion", **ycoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_y_backward = (Mapping((0,1), n_inputs=3) | y_poly_backward) + \ ((Mapping((0, 1), n_inputs=3) | y_poly_backward_distortion) * Mapping((2,))) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf( degree, lines[xcoeff_index + 1:xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree, name="x_poly_forward", **xcoeff_backward) xcoeff_backward_distortion = coeffs_from_pcf( degree, lines[xcoeff_index + 22:xcoeff_index + 43]) x_poly_forward_distortion = models.Polynomial2D( degree, name="x_forward_distortion", **xcoeff_backward_distortion) # the chromatic correction is done here # the input is Xmsa, Ymsa, lam model_x_forward = (Mapping((0,1), n_inputs=3) | x_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_forward_distortion) * Mapping((2,))) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name="y_poly_forward", **ycoeff_backward) ycoeff_backward_distortion = coeffs_from_pcf( degree, lines[ycoeff_index + 22:ycoeff_index + 43]) y_poly_forward_distortion = models.Polynomial2D( degree, name="y_forward_distortion", **ycoeff_backward_distortion) # do chromatic correction # the input is Xmsa, Ymsa, lam model_y_forward = (Mapping((0,1), n_inputs=3) | y_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | y_poly_forward_distortion) * Mapping((2,))) #assign inverse transforms model_x = model_x_forward.copy() model_y = model_y_forward.copy() model_x.inverse = model_x_backward model_y.inverse = model_y_backward output2poly_mapping = Identity(2, name="output_mapping") output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2]) input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name="input_mapping") input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (model_x & model_y) | output2poly_mapping fore_linear = (input_offset | rotation | scale | output_offset) fore_linear_inverse = fore_linear.inverse fore_linear.inverse = fore_linear_inverse & Identity(1) model = model_poly | fore_linear f = AsdfFile() f.tree = ref_kw.copy() f.tree['model'] = model asdffile = f.write_to(outname) return asdffile
def ote2asdf(otepcf, outname, ref_kw): """ ref_kw = common_reference_file_keywords('OTE', 'NIRSPEC OTE transform - CDP4') ote2asdf('Model/Ref_Files/CoordTransform/OTE.pcf', 'jwst_nirspec_ote_0001.asdf', ref_kw) """ with open(otepcf) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2 1') + 1].split() scale = models.Scale(1 / float(factors[0]), name="x_scale") & \ models.Scale(1 / float(factors[1]), name="y_scale") # this corresponds to modeling Rotation direction as is rotation_angle = lines[lines.index('*Rotation') + 1] rotation = models.Rotation2D(float(rotation_angle), name='rotation') input_rot_center = lines[lines.index('*InputRotationCentre 2 1') + 1].split() output_offset = models.Shift(float(input_rot_center[0]), name='output_x_shift') & \ models.Shift(float(input_rot_center[1]), name='output_y_shift') # Here the model is called "input_shift" but in the team version it is the "output_shift". output_rot_center = lines[lines.index('*OutputRotationCentre 2 1') + 1].split() input_offset = models.Shift(-float(output_rot_center[0]), name='input_x_shift') & \ models.Shift(-float(output_rot_center[1]), name='input_y_shift') degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1].split('\t') xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ylines = lines[ycoeff_index + 1].split('\t') ycoeff_forward = coeffs_from_pcf(degree, ylines) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xlines = lines[xcoeff_index + 1].split('\t') xcoeff_backward = coeffs_from_pcf(degree, xlines) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ylines = lines[ycoeff_index + 1].split('\t') ycoeff_backward = coeffs_from_pcf(degree, ylines) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward mlinear = input_offset | rotation | scale | output_offset output2poly_mapping = Identity(2, name='output_mapping') output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping') input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = model_poly | mlinear f = AsdfFile() f.tree = ref_kw.copy() f.tree['model'] = model f.write_to(outname)
def fore2asdf(pcffore, outname, ref_kw): """ forward direction : msa 2 ote backward_direction: msa 2 fpa """ with open(pcffore) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2') + 1].split() # factor==1/factor in backward msa2ote direction and == factor in ote2msa direction scale = models.Scale(1. / float(factors[0]), name='scale_x') & \ models.Scale(1 / float(factors[1]), name='scale_y') rotation_angle = lines[lines.index('*Rotation') + 1] rotation = models.Rotation2D(float(rotation_angle), name='rotation') input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split() output_offset = models.Shift(float(input_rot_center[0]), name="output_x_shift") & \ models.Shift(float(input_rot_center[1]), name="output_y_shift") output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split() input_offset = models.Shift(-float(output_rot_center[0]), name="input_x_shift") & \ models.Shift(-float(output_rot_center[1]), name="input_y_shift") degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1: xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) # Polynomial Correction in x x_poly_backward = models.Polynomial2D(degree, name="x_poly_backward", **xcoeff_forward) xlines_distortion = lines[xcoeff_index + 22: xcoeff_index + 43] xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion) x_poly_backward_distortion = models.Polynomial2D(degree, name="x_backward_distortion", **xcoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_x_backward = (Mapping((0, 1), n_inputs=3) | x_poly_backward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_backward_distortion) * Mapping((2,))) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name="y_poly_backward", **ycoeff_forward) ylines_distortion = lines[ycoeff_index + 22: ycoeff_index + 43] ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion) y_poly_backward_distortion = models.Polynomial2D(degree, name="y_backward_distortion", **ycoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_y_backward = (Mapping((0,1), n_inputs=3) | y_poly_backward) + \ ((Mapping((0, 1), n_inputs=3) | y_poly_backward_distortion) * Mapping((2,))) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree,name="x_poly_forward", **xcoeff_backward) xcoeff_backward_distortion = coeffs_from_pcf(degree, lines[xcoeff_index + 22: xcoeff_index + 43]) x_poly_forward_distortion = models.Polynomial2D(degree, name="x_forward_distortion", **xcoeff_backward_distortion) # the chromatic correction is done here # the input is Xmsa, Ymsa, lam model_x_forward = (Mapping((0,1), n_inputs=3) | x_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_forward_distortion) * Mapping((2,))) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name="y_poly_forward",**ycoeff_backward) ycoeff_backward_distortion = coeffs_from_pcf(degree, lines[ycoeff_index + 22: ycoeff_index + 43]) y_poly_forward_distortion = models.Polynomial2D(degree, name="y_forward_distortion", **ycoeff_backward_distortion) # do chromatic correction # the input is Xmsa, Ymsa, lam model_y_forward = (Mapping((0,1), n_inputs=3) | y_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | y_poly_forward_distortion) * Mapping((2,))) #assign inverse transforms model_x = model_x_forward.copy() model_y = model_y_forward.copy() model_x.inverse = model_x_backward model_y.inverse = model_y_backward output2poly_mapping = Identity(2, name="output_mapping") output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2]) input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name="input_mapping") input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (model_x & model_y) | output2poly_mapping fore_linear = (input_offset | rotation | scale | output_offset) fore_linear_inverse = fore_linear.inverse fore_linear.inverse = fore_linear_inverse & Identity(1) model = model_poly | fore_linear f = AsdfFile() f.tree = ref_kw.copy() f.tree['model'] = model asdffile = f.write_to(outname) return asdffile
def pcf2model(pcffile, name=""): """ Create a model from a NIRSPEC Camera.pcf or Collimator*.pcf file. - forward (team): sky to detector - Shift inputs to input_rotation_center - Rotate inputs - Scale inputs - Shift inputs to output_rot_center - Apply polynomial distortion - backward_team (team definition) detector to sky - Apply polynomial distortion - Shift inputs to output_rot_center - Scale inputs - Rotate inputs - Shift inputs to input_rotation_center WCS implementation - forward: detector to sky - equivalent to backward_team - backward: sky to detector - equivalent to forward_team Parameters ---------- pcffile : str one of the NIRSPEC ".pcf" reference files provided by the IDT team. "pcf" stands for "polynomial coefficients fit" outname : str Name of reference file to be wriiten to disk. Returns ------- fasdf : `~astropy.modeling.core.Model` Model object. Examples -------- >>> pcf2asdf("Camera.pcf", "camera.asdf") """ linear_det2sky = linear_from_pcf_det2sky(pcffile, name=name) with open(pcffile) as f: lines = [l.strip() for l in f.readlines()] degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1:xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_backward = models.Polynomial2D(degree, name='{0}_x_backward'.format(name), **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='{0}_y_backward'.format(name), **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf( degree, lines[xcoeff_index + 1:xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree, name='{0}_x_forward'.format(name), **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='{0}_y_forward'.format(name), **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward output2poly_mapping = Identity(2, name='{0}_outmap'.format(name)) output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='{0}_inmap'.format(name)) input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = model_poly | linear_det2sky return model
def fore2asdf(pcffore, outname, ref_kw): """ forward direction : msa 2 ote backward_direction: msa 2 fpa """ with open(pcffore) as f: lines = [l.strip() for l in f.readlines()] fore_det2sky = linear_from_pcf_det2sky(pcffore) fore_linear = fore_det2sky fore_linear.inverse = fore_det2sky.inverse & Identity(1) # compute the polynomial degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1: xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) # Polynomial Correction in x x_poly_backward = models.Polynomial2D(degree, name="x_poly_backward", **xcoeff_forward) xlines_distortion = lines[xcoeff_index + 22: xcoeff_index + 43] xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion) x_poly_backward_distortion = models.Polynomial2D(degree, name="x_backward_distortion", **xcoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_x_backward = (Mapping((0, 1), n_inputs=3) | x_poly_backward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_backward_distortion) * \ (Mapping((2,)) | Identity(1))) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name="y_poly_backward", **ycoeff_forward) ylines_distortion = lines[ycoeff_index + 22: ycoeff_index + 43] ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion) y_poly_backward_distortion = models.Polynomial2D(degree, name="y_backward_distortion", **ycoeff_forward_distortion) # do chromatic correction # the input is Xote, Yote, lam model_y_backward = (Mapping((0,1), n_inputs=3) | y_poly_backward) + \ ((Mapping((0, 1), n_inputs=3) | y_poly_backward_distortion) * \ (Mapping((2,)) | Identity(1) )) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree,name="x_poly_forward", **xcoeff_backward) xcoeff_backward_distortion = coeffs_from_pcf(degree, lines[xcoeff_index + 22: xcoeff_index + 43]) x_poly_forward_distortion = models.Polynomial2D(degree, name="x_forward_distortion", **xcoeff_backward_distortion) # the chromatic correction is done here # the input is Xmsa, Ymsa, lam model_x_forward = (Mapping((0,1), n_inputs=3) | x_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | x_poly_forward_distortion) * \ (Mapping((2,)) | Identity(1))) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name="y_poly_forward",**ycoeff_backward) ycoeff_backward_distortion = coeffs_from_pcf(degree, lines[ycoeff_index + 22: ycoeff_index + 43]) y_poly_forward_distortion = models.Polynomial2D(degree, name="y_forward_distortion", **ycoeff_backward_distortion) # do chromatic correction # the input is Xmsa, Ymsa, lam model_y_forward = (Mapping((0,1), n_inputs=3) | y_poly_forward) + \ ((Mapping((0,1), n_inputs=3) | y_poly_forward_distortion) * \ (Mapping((2,)) | Identity(1))) #assign inverse transforms model_x = model_x_forward.copy() model_y = model_y_forward.copy() model_x.inverse = model_x_backward model_y.inverse = model_y_backward output2poly_mapping = Identity(2, name="output_mapping") output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2]) input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name="input_mapping") input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (model_x & model_y) | output2poly_mapping model = model_poly | fore_linear f = AsdfFile() f.tree = ref_kw.copy() f.tree['model'] = model asdffile = f.write_to(outname) return asdffile
def pcf2asdf(pcffile, outname, ref_file_kw): """ Create an asdf reference file with the transformation coded in a NIRSPEC Camera.pcf or Collimator*.pcf file. - forward (team): sky to detector - Shift inputs to input_rotation_center - Rotate inputs - Scale inputs - Shift inputs to output_rot_center - Apply polynomial distortion - backward_team (team definition) detector to sky - Apply polynomial distortion - Shift inputs to output_rot_center - Scale inputs - Rotate inputs - Shift inputs to input_rotation_center WCS implementation - forward: detector to sky - equivalent to backward_team - backward: sky to detector - equivalent to forward_team Parameters ---------- pcffile : str one of the NIRSPEC ".pcf" reference files provided by the IDT team. "pcf" stands for "polynomial coefficients fit" outname : str Name of reference file to be wriiten to disk. Returns ------- fasdf : AsdfFile AsdfFile object Examples -------- >>> pcf2asdf("Camera.pcf", "camera.asdf") """ linear_det2sky = linear_from_pcf_det2sky(pcffile) with open(pcffile) as f: lines = [l.strip() for l in f.readlines()] degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1: xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward output2poly_mapping = Identity(2, name='output_mapping') output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping') input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = model_poly | linear_det2sky f = AsdfFile() f.tree = ref_file_kw.copy() f.tree['model'] = model f.write_to(outname)
def pcf2asdf(pcffile, outname, ref_file_kw): """ Create an asdf reference file with the transformation coded in a NIRSPEC Camera.pcf or Collimator*.pcf file. - forward (team): sky to detector - Shift inputs to input_rotation_center - Rotate inputs - Scale inputs - Shift inputs to output_rot_center - Apply polynomial distortion - backward_team (team definition) detector to sky - Apply polynomial distortion - Shift inputs to output_rot_center - Scale inputs - Rotate inputs - Shift inputs to input_rotation_center WCS implementation - forward: detector to sky - equivalent to backward_team - backward: sky to detector - equivalent to forward_team Parameters ---------- pcffile : str one of the NIRSPEC ".pcf" reference files provided by the IDT team. "pcf" stands for "polynomial coefficients fit" outname : str Name of reference file to be wriiten to disk. Returns ------- fasdf : AsdfFile AsdfFile object Examples -------- >>> pcf2asdf("Camera.pcf", "camera.asdf") """ with open(pcffile) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2') + 1].split() scale = models.Scale(1 / float(factors[0]), name="x_scale") & \ models.Scale(1 / float(factors[1]), name="y_scale") rotation_angle = lines[lines.index('*Rotation') + 1] # Backward rotation is in the counter-clockwise direction as in modeling # Forward is clockwise backward_rotation = models.Rotation2D(float(rotation_angle), name='rotation') rotation = backward_rotation.copy() # Here the model is called "output_shift" but in the team version it is the "input_shift". input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split() output_offset = models.Shift(float(input_rot_center[0]), name='output_x_shift') & \ models.Shift(float(input_rot_center[1]), name='output_y_shift') # Here the model is called "input_shift" but in the team version it is the "output_shift". output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split() input_offset = models.Shift(-float(output_rot_center[0]), name='input_x_shift') & \ models.Shift(-float(output_rot_center[1]), name='input_y_shift') degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1:xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf( degree, lines[xcoeff_index + 1:xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf( degree, lines[ycoeff_index + 1:ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward output2poly_mapping = Identity(2, name='output_mapping') output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping') input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = model_poly | input_offset | scale | rotation | output_offset f = AsdfFile() f.tree = ref_file_kw.copy() f.tree['model'] = model f.write_to(outname)
def pcf2model(pcffile, name=""): """ Create a model from a NIRSPEC Camera.pcf or Collimator*.pcf file. - forward (team): sky to detector - Shift inputs to input_rotation_center - Rotate inputs - Scale inputs - Shift inputs to output_rot_center - Apply polynomial distortion - backward_team (team definition) detector to sky - Apply polynomial distortion - Shift inputs to output_rot_center - Scale inputs - Rotate inputs - Shift inputs to input_rotation_center WCS implementation - forward: detector to sky - equivalent to backward_team - backward: sky to detector - equivalent to forward_team Parameters ---------- pcffile : str one of the NIRSPEC ".pcf" reference files provided by the IDT team. "pcf" stands for "polynomial coefficients fit" outname : str Name of reference file to be wriiten to disk. Returns ------- fasdf : `~astropy.modeling.core.Model` Model object. Examples -------- >>> pcf2asdf("Camera.pcf", "camera.asdf") """ linear_det2sky = linear_from_pcf_det2sky(pcffile, name=name) with open(pcffile) as f: lines = [l.strip() for l in f.readlines()] degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1: xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_backward = models.Polynomial2D(degree, name='{0}_x_backward'.format(name), **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='{0}_y_backward'.format(name), **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22]) x_poly_forward = models.Polynomial2D(degree, name='{0}_x_forward'.format(name), **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='{0}_y_forward'.format(name), **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward output2poly_mapping = Identity(2, name='{0}_outmap'.format(name)) output2poly_mapping.inverse = Mapping([0, 1, 0, 1]) input2poly_mapping = Mapping([0, 1, 0, 1], name='{0}_inmap'.format(name)) input2poly_mapping.inverse = Identity(2) model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping model = model_poly | linear_det2sky return model