예제 #1
0
 def calc(*args):
     progress.visible = True
     if monochromatic_toggle.value is True:
         psf = instrument.calcPSF(
             monochromatic=monochromatic_wavelength.value * 1e-6,
             display=True,
             outfile=OUTPUT_FILENAME,
             overwrite=True)
     else:
         source = poppy.specFromSpectralType(source_selection.value)
         _log.debug("Got source type {}: {}".format(source_selection.value,
                                                    source))
         psf = instrument.calcPSF(source=source,
                                  display=True,
                                  outfile=OUTPUT_FILENAME,
                                  overwrite=True)
     fig, (ax_oversamp, ax_detsamp) = plt.subplots(1, 2, figsize=(12, 4))
     title1 = "PSF sim for {}, {}\n".format(instrument.name,
                                            instrument.filter)
     poppy.display_PSF(psf,
                       ax=ax_oversamp,
                       title=title1 + "Oversampled PSF")
     poppy.display_PSF(psf,
                       ax=ax_detsamp,
                       ext='DET_SAMP',
                       title=title1 + 'Detector pixel sampled PSF')
     progress.visible = None
     download_link.visible = True
예제 #2
0
 def calc(*args):
     progress.visible = True
     if monochromatic_toggle.value is True:
         psf = instrument.calc_psf(
             monochromatic=monochromatic_wavelength.value * 1e-6,
             display=True,
             outfile=OUTPUT_FILENAME,
             overwrite=True
         )
     else:
         source = poppy.specFromSpectralType(source_selection.value)
         _log.debug("Got source type {}: {}".format(source_selection.value, source))
         psf = instrument.calc_psf(
             source=source,
             display=True,
             outfile=OUTPUT_FILENAME,
             overwrite=True
         )
     fig, (ax_oversamp, ax_detsamp) = plt.subplots(1, 2,figsize=(12, 4))
     title1 = "PSF sim for {}, {}\n".format(instrument.name, instrument.filter)
     poppy.display_PSF(psf, ax=ax_oversamp,
                       title=title1+"Oversampled PSF")
     poppy.display_PSF(psf, ax=ax_detsamp, ext='DET_SAMP',
                       title=title1+'Detector pixel sampled PSF')
     progress.visible = None
     download_link.visible = True
예제 #3
0
    def ev_plotspectrum(self):
        "Event handler for Plot Spectrum "
        self._updateFromGUI()

        print("Spectral type is "+self.sptype)
        print("Selected instrument tab is "+self.iname)
        print("Selected instrument filter is "+self.filter)


        plt.clf()

        ax1 = plt.subplot(311)
        spectrum = poppy.specFromSpectralType(self.sptype)
        synplot(spectrum)
        ax1.set_ybound(1e-6, 1e8) # hard coded for now
        ax1.yaxis.set_major_locator(matplotlib.ticker.LogLocator(base=1000))
        legend_font = matplotlib.font_manager.FontProperties(size=10)
        ax1.legend(loc='lower right', prop=legend_font)


        ax2 = plt.subplot(312, sharex=ax1)
        ax2.set_ybound(0,1.1)
        band = self.inst._getSynphotBandpass(self.inst.filter) #pysynphot.ObsBandpass(obsname)
        band.name = "%s %s" % (self.iname, self.inst.filter)
        synplot(band) #, **kwargs)
        legend_font = matplotlib.font_manager.FontProperties(size=10)
        plt.legend(loc='lower right', prop=legend_font)

        ax2.set_ybound(0,1.1)


        ax3 = plt.subplot(313, sharex=ax1)
        if self.nlambda is None:
            # Automatically determine number of appropriate wavelengths.
            # Make selection based on filter configuration file
            try:
                nlambda = self.inst._filters[self.filter].default_nlambda
            except KeyError:
                nlambda=10
        else:
            nlambda = self.nlambda
        ax1.set_xbound(0.1, 100)
        plt.draw()
        waves, weights = self.inst._getWeights(spectrum, nlambda=nlambda)

        wave_step = waves[1]-waves[0]
        plot_waves = np.concatenate( ([waves[0]-wave_step], waves, [waves[-1]+wave_step])) * 1e6
        plot_weights = np.concatenate(([0], weights,[0]))


        plt.ylabel("Weight")
        plt.xlabel("Wavelength [$\mu$m]")

        ax3.plot(plot_waves, plot_weights,  drawstyle='steps-mid')

        ax1.set_xbound(0.1, 100)

        self._refresh_window()
예제 #4
0
파일: tkgui.py 프로젝트: mperrin/webbpsf
    def ev_plotspectrum(self):
        "Event handler for Plot Spectrum "
        self._updateFromGUI()

        print("Spectral type is "+self.sptype)
        print("Selected instrument tab is "+self.iname)
        print("Selected instrument filter is "+self.filter)


        plt.clf()

        ax1 = plt.subplot(311)
        spectrum = poppy.specFromSpectralType(self.sptype)
        synplot(spectrum)
        ax1.set_ybound(1e-6, 1e8) # hard coded for now
        ax1.yaxis.set_major_locator(matplotlib.ticker.LogLocator(base=1000))
        legend_font = matplotlib.font_manager.FontProperties(size=10)
        ax1.legend(loc='lower right', prop=legend_font)


        ax2 = plt.subplot(312, sharex=ax1)
        ax2.set_ybound(0,1.1)
        band = self.inst._get_synphot_bandpass(self.inst.filter) #pysynphot.ObsBandpass(obsname)
        band.name = "%s %s" % (self.iname, self.inst.filter)
        synplot(band) #, **kwargs)
        legend_font = matplotlib.font_manager.FontProperties(size=10)
        plt.legend(loc='lower right', prop=legend_font)

        ax2.set_ybound(0,1.1)


        ax3 = plt.subplot(313, sharex=ax1)
        if self.nlambda is None:
            # Automatically determine number of appropriate wavelengths.
            # Make selection based on filter configuration file
            try:
                nlambda = self.inst._filters[self.filter].default_nlambda
            except KeyError:
                nlambda=10
        else:
            nlambda = self.nlambda
        ax1.set_xbound(0.1, 100)
        plt.draw()
        waves, weights = self.inst._getWeights(spectrum, nlambda=nlambda)

        wave_step = waves[1]-waves[0]
        plot_waves = np.concatenate( ([waves[0]-wave_step], waves, [waves[-1]+wave_step])) * 1e6
        plot_weights = np.concatenate(([0], weights,[0]))


        plt.ylabel("Weight")
        plt.xlabel("Wavelength [$\mu$m]")

        ax3.plot(plot_waves, plot_weights,  drawstyle='steps-mid')

        ax1.set_xbound(0.1, 100)

        self._refresh_window()
예제 #5
0
파일: obssim.py 프로젝트: sosey/webbpsf
    def addPointSource(self,
                       sptype_or_spectrum,
                       name="unnamed source",
                       separation=0.0,
                       PA=0.0,
                       normalization=None):
        """ Add a point source to the list for a given scene

        Parameters
        -----------
        sptype_or_spectrum : string or pysynphot.Spectrum
            spectrum of the source
        name : str
            descriptive string
        separation : float
            arcsec
        PA : float
            deg from N
        normalization : scalar or tuple TBD
            Simple version: this is a float to multiply the PSF by.
            Complex version: Probably tuple of arguments to spectrum.renorm().



        How normalization works:
            First the PSF for that source is calculated, using calcPSF(norm='first')
            i.e. the input intensity through the telescope pupil is set to 1.
            The resulting output PSF total counts will be proportional to the
            throughput through the OTE+SI (including filters, coronagraphs etc)

            Then we apply the normalization:
                1) if it's just a number, we just multiply by it.
                2) if it's something else: Then we use a separate bandpass object and parameters
                   passed in here to figure out the overall normalization, and apply that as a
                   multiplicative factor to the resulting PSF itself?
        """
        if type(sptype_or_spectrum) is str:
            spectrum = poppy.specFromSpectralType(sptype_or_spectrum)
        else:
            spectrum = sptype_or_spectrum

        self.sources.append({
            'spectrum': sptype_or_spectrum,
            'separation': separation,
            'PA': PA,
            'normalization': normalization,
            'name': name
        })
예제 #6
0
파일: tkgui.py 프로젝트: mperrin/webbpsf
    def ev_calc_psf(self):
        "Event handler for PSF Calculations"
        self._updateFromGUI()

        if _HAS_PYSYNPHOT:
            source = poppy.specFromSpectralType(self.sptype)
        else:
            source=None # generic flat spectrum

        self.PSF_HDUlist = self.inst.calc_psf(source=source,
                detector_oversample= self.detector_oversampling,
                fft_oversample=self.fft_oversampling,
                fov_arcsec = self.FOV,  nlambda = self.nlambda, display=True)
        #self.PSF_HDUlist.display()
        for w in ['Display PSF', 'Display profiles', 'Save PSF As...']:
           self.widgets[w].state(['!disabled'])
        self._refresh_window()
        _log.info("PSF calculation complete")
예제 #7
0
    def ev_calcPSF(self):
        "Event handler for PSF Calculations"
        self._updateFromGUI()

        if _HAS_PYSYNPHOT:
            source = poppy.specFromSpectralType(self.sptype)
        else:
            source=None # generic flat spectrum

        self.PSF_HDUlist = self.inst.calcPSF(source=source,
                detector_oversample= self.detector_oversampling,
                fft_oversample=self.fft_oversampling,
                fov_arcsec = self.FOV,  nlambda = self.nlambda, display=True)
        #self.PSF_HDUlist.display()
        for w in ['Display PSF', 'Display profiles', 'Save PSF As...']:
           self.widgets[w].state(['!disabled'])
        self._refresh_window()
        _log.info("PSF calculation complete")
예제 #8
0
 def calc(*args):
     progress.visible = True
     if monochromatic_toggle.value is True:
         psf = instrument.calcPSF(
             monochromatic=monochromatic_wavelength.value * 1e-6,
             display=True,
             outfile=OUTPUT_FILENAME,
             overwrite=True)
     else:
         source = poppy.specFromSpectralType(source_selection.value)
         _log.debug("Got source type {}: {}".format(source_selection.value,
                                                    source))
         psf = instrument.calcPSF(source=source,
                                  display=True,
                                  outfile=OUTPUT_FILENAME,
                                  overwrite=True)
     fig, (ax_oversamp, ax_detsamp) = plt.subplots(1, 2)
     poppy.display_PSF(psf, ax=ax_oversamp)
     poppy.display_PSF(psf, ax=ax_detsamp, ext='DET_SAMP')
     progress.visible = None
     download_link.visible = True
예제 #9
0
    def addPointSource(self, sptype_or_spectrum, name="unnamed source", separation=0.0, PA=0.0, normalization=None):
        """ Add a point source to the list for a given scene

        Parameters
        -----------
        sptype_or_spectrum : string or pysynphot.Spectrum
            spectrum of the source
        name : str
            descriptive string
        separation : float
            arcsec
        PA : float
            deg from N
        normalization : scalar or tuple TBD
            Simple version: this is a float to multiply the PSF by.
            Complex version: Probably tuple of arguments to spectrum.renorm(). 



        How normalization works:  
            First the PSF for that source is calculated, using calcPSF(norm='first')
            i.e. the input intensity through the telescope pupil is set to 1. 
            The resulting output PSF total counts will be proportional to the 
            throughput through the OTE+SI (including filters, coronagraphs etc)

            Then we apply the normalization:
                1) if it's just a number, we just multiply by it.
                2) if it's something else: Then we use a separate bandpass object and parameters 
                   passed in here to figure out the overall normalization, and apply that as a 
                   multiplicative factor to the resulting PSF itself?
        """
        if type(sptype_or_spectrum) is str:
            spectrum = poppy.specFromSpectralType(sptype_or_spectrum)
        else:
            spectrum = sptype_or_spectrum

        self.sources.append(   {'spectrum': sptype_or_spectrum, 'separation': separation, 'PA': PA, 
            'normalization': normalization, 'name': name})
예제 #10
0
 def calc(*args):
     progress.visible = True
     if monochromatic_toggle.value is True:
         psf = instrument.calc_psf(
             monochromatic=monochromatic_wavelength.value * 1e-6,
             display=True,
             outfile=OUTPUT_FILENAME,
             overwrite=True
         )
     else:
         source = poppy.specFromSpectralType(source_selection.value)
         _log.debug("Got source type {}: {}".format(source_selection.value, source))
         psf = instrument.calc_psf(
             source=source,
             display=True,
             outfile=OUTPUT_FILENAME,
             overwrite=True
         )
     fig, (ax_oversamp, ax_detsamp) = plt.subplots(1, 2)
     poppy.display_PSF(psf, ax=ax_oversamp)
     poppy.display_PSF(psf, ax=ax_detsamp, ext='DET_SAMP')
     progress.visible = None
     download_link.visible = True
예제 #11
0
파일: utils.py 프로젝트: ARKA1112/jwst-1
def combine_transmission(filt, SRC):
    """
    Short Summary
    -------------
    Combine the transmission of the filter and the spectral type

    Parameters
    ----------
    filt: 1D array
        bandpass

    SRC: string
        spectral type string, e.g. A0V

    Returns
    -------
    transmissionlist: list
    """

    filt_wls = np.zeros(len(filt))
    filt_wght = np.zeros(len(filt))
    for ii in range(len(filt)):
        filt_wls[ii] = filt[ii][1]  # in m
        filt_wght[ii] = filt[ii][0]
    src = specFromSpectralType(SRC)

    # converts t angstrom for pysynphot
    src = src.resample(np.array(filt_wls) * 1.0e10)

    specwavl, specwghts = src.getArrays()
    totalwght = specwghts * filt_wght
    transmissionlist = []

    for ii in range(len(filt_wls)):
        transmissionlist.append((totalwght[ii], filt_wls[ii]))
    return transmissionlist
예제 #12
0
def show_notebook_interface_wfi(instrument):
    # Widget related imports.
    # (Currently not a hard dependency for the full webbpsf package, so we import
    # within the function.)
    import ipywidgets as widgets
    from IPython.display import display, clear_output
    from matplotlib import pyplot as plt

    try:
        import pysynphot
    except ImportError:
        raise ImportError("For now, PySynphot must be installed to use the notebook interface")

    # Clean up some warnings we know about so as not to scare the users
    import warnings
    from matplotlib.cbook import MatplotlibDeprecationWarning
    warnings.simplefilter('ignore', MatplotlibDeprecationWarning)
    warnings.simplefilter('ignore', fits.verify.VerifyWarning)

    def make_binding_for_attribute(attribute):
        def callback(trait_name, new_value):
            setattr(instrument, attribute, new_value)
        return callback

    filter_selection = widgets.ToggleButtons(
        options=instrument.filter_list,
        value=instrument.filter,
        description='Filter:'
    )
    filter_selection.on_trait_change(
        make_binding_for_attribute('filter'),
        name='selected_label'
    )
    display(filter_selection)

    monochromatic_wavelength = widgets.BoundedFloatText(
        value=0.76,
        min=0.6,
        max=2.0,
    )
    monochromatic_wavelength.disabled = True
    monochromatic_toggle = widgets.Checkbox(description='Monochromatic calculation?')

    def update_monochromatic(trait_name, new_value):
        filter_selection.disabled = new_value
        monochromatic_wavelength.disabled = not new_value

    monochromatic_toggle.on_trait_change(update_monochromatic, name='value')

    display(widgets.HTML(value='''<p style="padding: 1em 0;">
    <span style="font-style:italic; font-size:1.0em">
    Monochromatic calculations can be performed for any wavelength in the 0.6 to 2.0 &micro;m range.
    </span></p>'''))  # kludge
    monochromatic_controls = widgets.HBox(children=(
            monochromatic_toggle,
            widgets.HTML(value='<span style="display: inline-block; width: 0.6em;"></span>'),
            monochromatic_wavelength,
            widgets.HTML(value='<span style="display: inline-block; width: 0.25em;"></span> &micro;m '),
    ))
    display(monochromatic_controls)

    display(widgets.HTML(value="<hr>"))

    source_selection = widgets.Select(
        options=poppy.specFromSpectralType('', return_list=True),
        value='G0V',
        description="Source spectrum"
    )
    display(source_selection)
    display(widgets.HTML(value="<hr>"))

    sca_selection = widgets.Dropdown(
        options=instrument.detector_list,
        value=instrument.detector,
        description='Detector:'
    )
    sca_selection.on_trait_change(
        make_binding_for_attribute('detector'),
        name='selected_label'
    )
    display(sca_selection)

    detector_field_points = [
        ('Top left', (4.0, 4092.0)),
        ('Bottom left', (4.0, 4.0)),
        ('Center', (2048.0, 2048.0)),
        ('Top right', (4092.0, 4092.0)),
        ('Bottom right', (4092.0, 4.0)),
    ]
    # enforce ordering of buttons
    detector_field_point_labels = [a[0] for a in detector_field_points]
    detector_field_points = dict(detector_field_points)

    def set_field_position(trait_name, new_value):
        instrument.detector_position = detector_field_points[new_value]

    field_position = widgets.ToggleButtons(options=detector_field_point_labels, value='Center', description='Detector field point:')
    field_position.on_trait_change(set_field_position, name='selected_label')
    display(field_position)

    calculate_button = widgets.Button(
        description="Calculate PSF",
        width='10em',
        color='white',
        background_color='#00c403',
        border_color='#318732'
    )
    display_osys_button = widgets.Button(
        description="Display Optical System",
        width='13em',
        color='white',
        background_color='#005fc4',
        border_color='#224A75'
    )
    clear_button = widgets.Button(
        description="Clear Output",
        width='10em',
        color='white',
        background_color='#ed4747',
        border_color='#911C1C'
    )
    progress = widgets.HTML(value='<progress>')

    OUTPUT_FILENAME = 'psf.fits'
    DOWNLOAD_BUTTON_HTML = """
    <a class="btn btn-info" href="files/{}" target="_blank">
        Download FITS image from last calculation
    </a>
    """
    download_link = widgets.HTML(value=DOWNLOAD_BUTTON_HTML.format(OUTPUT_FILENAME))

    def disp(*args):
        progress.visible = True
        plt.figure(figsize=(12, 8))
        instrument.display()
        progress.visible = None

    def calc(*args):
        progress.visible = True
        if monochromatic_toggle.value is True:
            psf = instrument.calc_psf(
                monochromatic=monochromatic_wavelength.value * 1e-6,
                display=True,
                outfile=OUTPUT_FILENAME,
                overwrite=True
            )
        else:
            source = poppy.specFromSpectralType(source_selection.value)
            _log.debug("Got source type {}: {}".format(source_selection.value, source))
            psf = instrument.calc_psf(
                source=source,
                display=True,
                outfile=OUTPUT_FILENAME,
                overwrite=True
            )
        fig, (ax_oversamp, ax_detsamp) = plt.subplots(1, 2)
        poppy.display_PSF(psf, ax=ax_oversamp)
        poppy.display_PSF(psf, ax=ax_detsamp, ext='DET_SAMP')
        progress.visible = None
        download_link.visible = True

    def clear(*args):
        clear_output()
        progress.visible = None
        download_link.visible = None

    calculate_button.on_click(calc)
    display_osys_button.on_click(disp)
    clear_button.on_click(clear)
    display(widgets.HTML(value="<br/>"))  # kludge
    buttons = widgets.HBox(children=[calculate_button, display_osys_button, clear_button])
    display(buttons)

    # Insert the progress bar, hidden by default
    display(progress)
    progress.visible = None
    # and the download link
    display(download_link)
    download_link.visible = None
예제 #13
0
def show_notebook_interface_jwst(instrument):
    """ Show Jupyter Notebook interface, for a JWST instrument

    Parameters
    -------------
    instrument : string or object
        either a webbpsf instrument object, e.g.  `NIRCam()`
        or the string name of an instrument.


    Example
    --------
    nc = webbpsf.NIRCam()
    webbpsf.show_notebook_interface(nc)
    """
    # Widget related imports.
    # (Currently not a hard dependency for the full webbpsf package, so we import
    # within the function.)
    import ipywidgets as widgets
    from IPython.display import display, clear_output
    from matplotlib import pyplot as plt


    if isinstance(instrument, str):
        instrument = Instrument(instrument)

    try:
        import pysynphot
    except ImportError:
        raise ImportError("For now, PySynphot must be installed to use the notebook interface")

    # Clean up some warnings we know about so as not to scare the users
    import warnings
    from matplotlib.cbook import MatplotlibDeprecationWarning
    warnings.simplefilter('ignore', MatplotlibDeprecationWarning)
    warnings.simplefilter('ignore', fits.verify.VerifyWarning)

    def make_binding_for_attribute(attribute):
        def callback(trait_name, new_value):
            if new_value == 'None':
                setattr(instrument, attribute, None)
            else:
                setattr(instrument, attribute, new_value)
        return callback

    display(widgets.HTML(value='''<p style="padding: 1em 0;">
    <span style="font-weight:bold; font-size:1.0em">
    Notebook Interface for {} PSF sims
    </span></p>'''.format(instrument.name)))


    filter_selection = widgets.Dropdown(
        options=instrument.filter_list,
        value=instrument.filter,
        description='Filter:')

    filter_selection.on_trait_change(
        make_binding_for_attribute('filter'),
        name='selected_label'
    )
    display(filter_selection)


    wl_bounds = (5., 30., 10.0) if instrument.name=='MIRI' else (0.6, 5.3, 2.0)
    monochromatic_wavelength = widgets.BoundedFloatText(
        value=wl_bounds[2],
        min=wl_bounds[0],
        max=wl_bounds[1],
    )
    monochromatic_wavelength.disabled = True
    monochromatic_toggle = widgets.Checkbox(description='Monochromatic calculation?')

    def update_monochromatic(trait_name, new_value):
        filter_selection.disabled = new_value
        monochromatic_wavelength.disabled = not new_value

    monochromatic_toggle.on_trait_change(update_monochromatic, name='value')

    display(widgets.HTML(value='''<p style="padding: 1em 0;">
    <span style="font-style:italic; font-size:1.0em">
    Monochromatic calculations can be performed for any wavelength in the {} to {} &micro;m range.
    </span></p>'''.format(*wl_bounds)))  # kludge
    monochromatic_controls = widgets.HBox(children=(
            monochromatic_toggle,
            widgets.HTML(value='<span style="display: inline-block; width: 0.6em;"></span>'),
            monochromatic_wavelength,
            widgets.HTML(value='<span style="display: inline-block; width: 0.25em;"></span> &micro;m '),
    ))
    display(monochromatic_controls)
    display(widgets.HTML(value="<hr>"))


    if instrument.name != 'FGS':
        image_selection = widgets.Dropdown(
            options=['None'] + instrument.image_mask_list,
            value=str(instrument.image_mask),
            description='Image Mask:')

        image_selection.on_trait_change(
            make_binding_for_attribute('image_mask'),
            name='selected_label'
        )
        display(image_selection)


        pupil_selection = widgets.Dropdown(
            options=['None'] + instrument.pupil_mask_list,
            value=str(instrument.pupil_mask),
            description='Pupil Mask: ')

        pupil_selection.on_trait_change(
            make_binding_for_attribute('pupil_mask'),
            name='selected_label'
        )
        display(pupil_selection)


    display(widgets.HTML(value="<hr>"))

    source_selection = widgets.Dropdown(
        options=poppy.specFromSpectralType('', return_list=True),
        value='G0V',
        description="Source spectrum"
    )
    display(source_selection)
    display(widgets.HTML(value="<hr>"))

    calculate_button = widgets.Button(
        description="Calculate PSF",
        width='10em',
        color='white',
        background_color='#00c403',
        border_color='#318732'
    )
    display_osys_button = widgets.Button(
        description="Display Optical System",
        width='13em',
        color='white',
        background_color='#005fc4',
        border_color='#224A75'
    )
    clear_button = widgets.Button(
        description="Clear Output",
        width='10em',
        color='white',
        background_color='#ed4747',
        border_color='#911C1C'
    )
    progress = widgets.HTML(value='<progress>')

    OUTPUT_FILENAME = 'psf.fits'
    DOWNLOAD_BUTTON_HTML = """
    <a class="btn btn-info" href="files/{}" target="_blank">
        Download FITS image from last calculation
    </a>
    """
    download_link = widgets.HTML(value=DOWNLOAD_BUTTON_HTML.format(OUTPUT_FILENAME))

    def disp(*args):
        progress.visible = True
        plt.figure(figsize=(12, 8))
        instrument.display()
        progress.visible = None

    def calc(*args):
        progress.visible = True
        if monochromatic_toggle.value is True:
            psf = instrument.calc_psf(
                monochromatic=monochromatic_wavelength.value * 1e-6,
                display=True,
                outfile=OUTPUT_FILENAME,
                overwrite=True
            )
        else:
            source = poppy.specFromSpectralType(source_selection.value)
            _log.debug("Got source type {}: {}".format(source_selection.value, source))
            psf = instrument.calc_psf(
                source=source,
                display=True,
                outfile=OUTPUT_FILENAME,
                overwrite=True
            )
        fig, (ax_oversamp, ax_detsamp) = plt.subplots(1, 2,figsize=(12, 4))
        title1 = "PSF sim for {}, {}\n".format(instrument.name, instrument.filter)
        poppy.display_PSF(psf, ax=ax_oversamp,
                          title=title1+"Oversampled PSF")
        poppy.display_PSF(psf, ax=ax_detsamp, ext='DET_SAMP',
                          title=title1+'Detector pixel sampled PSF')
        progress.visible = None
        download_link.visible = True

    def clear(*args):
        clear_output()
        progress.visible = None
        download_link.visible = None

    calculate_button.on_click(calc)
    display_osys_button.on_click(disp)
    clear_button.on_click(clear)
    display(widgets.HTML(value="<br/>"))  # kludge
    buttons = widgets.HBox(children=[calculate_button, display_osys_button, clear_button])
    display(buttons)

    # Insert the progress bar, hidden by default
    display(progress)
    progress.visible = None
    # and the download link
    display(download_link)
    download_link.visible = None
예제 #14
0
파일: tkgui.py 프로젝트: mperrin/webbpsf
    def _create_widgets(self):
        """Create a nice GUI using the enhanced widget set provided by
        the ttk extension to Tkinter, available in Python 2.7 or newer
        """
        #---- create the GUIs
        insts = ['NIRCam', 'NIRSpec','NIRISS', 'MIRI',  'FGS']
        self.root = tk.Tk()
        self.root.geometry('+50+50')
        self.root.title("James Webb Space Telescope PSF Calculator")

        frame = ttk.Frame(self.root)
        #frame = ttk.Frame(self.root, padx=10,pady=10)

        #ttk.Label(frame, text='James Webb PSF Calculator' ).grid(row=0)

        #-- star
        lf = ttk.LabelFrame(frame, text='Source Properties')

        if _HAS_PYSYNPHOT:
            self._add_labeled_dropdown("SpType", lf, label='    Spectral Type:', values=poppy.specFromSpectralType("",return_list=True), default='G0V', width=25, position=(0,0), sticky='W')
            ttk.Button(lf, text='Plot spectrum', command=self.ev_plotspectrum).grid(row=0,column=2,sticky='E',columnspan=4)

        r = 1
        fr2 = ttk.Frame(lf)

        self._add_labeled_entry("source_off_r", fr2, label='    Source Position: r=', value='0.0', width=5, position=(r,0), sticky='W')
        self._add_labeled_entry("source_off_theta", fr2, label='arcsec,  PA=', value='0', width=3, position=(r,2), sticky='W')

        self.vars["source_off_centerpos"] = tk.StringVar()
        self.vars["source_off_centerpos"].set('corner')

        ttk.Label(fr2, text='deg, centered on ' ).grid(row=r, column=4)
        pixel = ttk.Radiobutton(fr2, text='pixel', variable=self.vars["source_off_centerpos"], value='pixel')
        pixel.grid(row=r, column=5)
        corner = ttk.Radiobutton(fr2, text='corner', variable=self.vars["source_off_centerpos"], value='corner')
        corner.grid(row=r, column=6)
        fr2.grid(row=r, column=0, columnspan=5, sticky='W')



        lf.columnconfigure(2, weight=1)
        lf.grid(row=1, sticky='E,W', padx=10,pady=5)

        #-- instruments
        lf = ttk.LabelFrame(frame, text='Instrument Config')
        notebook = ttk.Notebook(lf)
        self.widgets['tabset'] = notebook
        notebook.pack(fill='both')
        for iname,i in zip(insts, range(len(insts))):
            page = ttk.Frame(notebook)
            notebook.add(page,text=iname)
            notebook.select(i)  # make it active
            self.widgets[notebook.select()] = iname # save reverse lookup from meaningless widget "name" to string name
            if iname =='NIRCam':
                lframe = ttk.Frame(page)

                ttk.Label(lframe, text='Configuration Options for '+iname+',     module: ').grid(row=0, column=0, sticky='W')
                mname='NIRCam module'
                self.vars[mname] = tk.StringVar()
                self.widgets[mname] = ttk.Combobox(lframe, textvariable=self.vars[mname], width=2, state='readonly')
                self.widgets[mname].grid(row=0,column=1, sticky='W')
                self.widgets[mname]['values'] = ['A','B']
                self.widgets[mname].set('A')

                lframe.grid(row=0, columnspan=2, sticky='W')
            else:
                ttk.Label(page, text='Configuration Options for '+iname+"                      ").grid(row=0, columnspan=2, sticky='W')

            ttk.Button(page, text='Display Optics', command=self.ev_displayOptics ).grid(column=2, row=0, sticky='E', columnspan=3)


            #if  iname != 'TFI':
            self._add_labeled_dropdown(iname+"_filter", page, label='    Filter:', values=self.instrument[iname].filter_list, default=self.instrument[iname].filter, width=12, position=(1,0), sticky='W')
            #else:
                #ttk.Label(page, text='Etalon wavelength: ' , state='disabled').grid(row=1, column=0, sticky='W')
                #self.widgets[iname+"_wavelen"] = ttk.Entry(page, width=7) #, disabledforeground="#A0A0A0")
                #self.widgets[iname+"_wavelen"].insert(0, str(self.instrument[iname].etalon_wavelength))
                #self.widgets[iname+"_wavelen"].grid(row=1, column=1, sticky='W')
                #ttk.Label(page, text=' um' ).grid(row=1, column=2, sticky='W')

            #self.vars[iname+"_filter"] = tk.StringVar()
            #self.widgets[iname+"_filter"] = ttk.Combobox(page,textvariable =self.vars[iname+"_filter"], width=10, state='readonly')
            #self.widgets[iname+"_filter"]['values'] = self.instrument[iname].filter_list
            #self.widgets[iname+"_filter"].set(self.instrument[iname].filter)
            #self.widgets[iname+"_filter"]['readonly'] = True
            #ttk.Label(page, text='    Filter: ' ).grid(row=1, column=0)
            #self.widgets[iname+"_filter"].grid(row=1, column=1)


            #if hasattr(self.instrument[iname], 'ifu_wavelength'):
            if iname == 'NIRSpec' or iname =='MIRI':
                fr2 = ttk.Frame(page)
                #label = 'IFU' if iname !='TFI' else 'TF'
                ttk.Label(fr2, text='   IFU wavelen: ', state='disabled').grid(row=0, column=0)
                self.widgets[iname+"_ifu_wavelen"] = ttk.Entry(fr2, width=5) #, disabledforeground="#A0A0A0")
                self.widgets[iname+"_ifu_wavelen"].insert(0, str(self.instrument[iname].monochromatic))
                self.widgets[iname+"_ifu_wavelen"].grid(row=0, column=1)
                self.widgets[iname+"_ifu_wavelen"].state(['disabled'])
                ttk.Label(fr2, text=' um' , state='disabled').grid(row=0, column=2)
                fr2.grid(row=1,column=2, columnspan=6, sticky='E')

                iname2 = iname+"" # need to make a copy so the following lambda function works right:
                self.widgets[iname+"_filter"].bind('<<ComboboxSelected>>', lambda e: self.ev_update_ifu_label(iname2))


            if len(self.instrument[iname].image_mask_list) >0 :
                masks = self.instrument[iname].image_mask_list
                masks.insert(0, "")

                self._add_labeled_dropdown(iname+"_coron", page, label='    Coron:', values=masks,  width=12, position=(2,0), sticky='W')
                #self.vars[iname+"_coron"] = tk.StringVar()
                #self.widgets[iname+"_coron"] = ttk.Combobox(page,textvariable =self.vars[iname+"_coron"], width=10, state='readonly')
                #self.widgets[iname+"_coron"]['values'] = masks
                #ttk.Label(page, text='    Coron: ' ).grid(row=2, column=0)
                #self.widgets[iname+"_coron"].set(self.widgets[iname+"_coron"]['values'][0])
                #self.widgets[iname+"_coron"].grid(row=2, column=1)

                #fr2 = ttk.Frame(page)
                #self.vars[iname+"_cor_off_r"] = tk.StringVar()
                #self.vars[iname+"_cor_off_theta"] = tk.StringVar()
                #ttk.Label(fr2, text='target offset:  r=' ).grid(row=2, column=4)
                #self.widgets[iname+"_cor_off_r"] = ttk.Entry(fr2,textvariable =self.vars[iname+"_cor_off_r"], width=5)
                #self.widgets[iname+"_cor_off_r"].insert(0,"0.0")
                #self.widgets[iname+"_cor_off_r"].grid(row=2, column=5)
                #ttk.Label(fr2, text='arcsec,  PA=' ).grid(row=2, column=6)
                #self.widgets[iname+"_cor_off_theta"] = ttk.Entry(fr2,textvariable =self.vars[iname+"_cor_off_theta"], width=3)
                #self.widgets[iname+"_cor_off_theta"].insert(0,"0")
                #self.widgets[iname+"_cor_off_theta"].grid(row=2, column=7)
                #ttk.Label(fr2, text='deg' ).grid(row=2, column=8)
                #fr2.grid(row=2,column=3, sticky='W')


            if len(self.instrument[iname].image_mask_list) >0 :
                masks = self.instrument[iname].pupil_mask_list
                masks.insert(0, "")
                self._add_labeled_dropdown(iname+"_pupil", page, label='    Pupil:', values=masks,  width=12, position=(3,0), sticky='W')

                fr2 = ttk.Frame(page)
                self._add_labeled_entry(iname+"_pupilshift_x", fr2, label='  pupil shift in X:', value='0', width=3, position=(3,4), sticky='W')
                self._add_labeled_entry(iname+"_pupilshift_y", fr2, label=' Y:', value='0', width=3, position=(3,6), sticky='W')

                ttk.Label(fr2, text='% of pupil' ).grid(row=3, column=8)
                fr2.grid(row=3,column=3, sticky='W')


            ttk.Label(page, text='Configuration Options for the OTE').grid(row=4, columnspan=2, sticky='W')
            fr2 = ttk.Frame(page)

            opd_list =  self.instrument[iname].opd_list
            opd_list.insert(0,"Zero OPD (perfect)")
            #if os.getenv("WEBBPSF_ITM") or 1:
            if self._enable_opdserver:
                opd_list.append("OPD from ITM Server")
            default_opd = self.instrument[iname].pupilopd if self.instrument[iname].pupilopd is not None else "Zero OPD (perfect)"
            self._add_labeled_dropdown(iname+"_opd", fr2, label='    OPD File:', values=opd_list, default=default_opd, width=21, position=(0,0), sticky='W')

            self._add_labeled_dropdown(iname+"_opd_i", fr2, label=' # ', values= [str(i) for i in range(10)], width=3, position=(0,2), sticky='W')

            self.widgets[iname+"_opd_label"] = ttk.Label(fr2, text=' 0 nm RMS            ', width=35)
            self.widgets[iname+"_opd_label"].grid( column=4,sticky='W', row=0)

            self.widgets[iname+"_opd"].bind('<<ComboboxSelected>>',
                    lambda e: self.ev_update_OPD_labels() )
                    # The below code does not work, and I can't tell why. This only ever has iname = 'FGS' no matter which instrument.
                    # So instead brute-force it with the above to just update all 5.
                    #lambda e: self.ev_update_OPD_label(self.widgets[iname+"_opd"], self.widgets[iname+"_opd_label"], iname) )
            ttk.Button(fr2, text='Display', command=self.ev_displayOPD).grid(column=5,sticky='E',row=0)

            fr2.grid(row=5, column=0, columnspan=4,sticky='S')



            # ITM interface here - build the widgets now but they will be hidden by default until the ITM option is selected
            fr2 = ttk.Frame(page)
            self._add_labeled_entry(iname+"_coords", fr2, label='    Source location:', value='0, 0', width=12, position=(1,0), sticky='W')
            units_list = ['V1,V2 coords', 'detector pixels']
            self._add_labeled_dropdown(iname+"_coord_units", fr2, label='in:', values=units_list, default=units_list[0], width=11, position=(1,2), sticky='W')
            choose_list=['', 'SI center', 'SI upper left corner', 'SI upper right corner', 'SI lower left corner', 'SI lower right corner']
            self._add_labeled_dropdown(iname+"_coord_choose", fr2, label='or select:', values=choose_list, default=choose_list[0], width=21, position=(1,4), sticky='W')


            ttk.Label(fr2, text='    ITM output:').grid(row=2, column=0, sticky='W')
            self.widgets[iname+"_itm_output"] = ttk.Label(fr2, text='    - no file available yet -')
            self.widgets[iname+"_itm_output"].grid(row=2, column=1, columnspan=4, sticky='W')
            ttk.Button(fr2, text='Access ITM...', command=self.ev_launch_ITM_dialog).grid(column=5,sticky='E',row=2)


            fr2.grid(row=6, column=0, columnspan=4,sticky='SW')
            self.widgets[iname+"_itm_coords"] = fr2


        self.ev_update_OPD_labels()
        lf.grid(row=2, sticky='E,W', padx=10, pady=5)
        notebook.select(0)

        lf = ttk.LabelFrame(frame, text='Calculation Options')
        r =0
        self._add_labeled_entry('FOV', lf, label='Field of View:',  width=3, value='5', postlabel='arcsec/side', position=(r,0))
        r+=1
        self._add_labeled_entry('detector_oversampling', lf, label='Output Oversampling:',  width=3, value='2', postlabel='x finer than instrument pixels       ', position=(r,0))

        #self.vars['downsamp'] = tk.BooleanVar()
        #self.vars['downsamp'].set(True)
        #self.widgets['downsamp'] = ttk.Checkbutton(lf, text='Save in instr. pixel scale, too?', onvalue=True, offvalue=False,variable=self.vars['downsamp'])
        #self.widgets['downsamp'].grid(row=r, column=4, sticky='E')

        output_options=['Oversampled PSF only', 'Oversampled + Detector Res. PSFs', 'Mock full image from JWST DMS']
        self._add_labeled_dropdown("output_type", fr2, label='Output format:', values=output_options, default=output_options[1], width=31, position=(r,4), sticky='W')


        r+=1
        self._add_labeled_entry('fft_oversampling', lf, label='Coronagraph FFT Oversampling:',  width=3, value='2', postlabel='x finer than Nyquist', position=(r,0))
        r+=1
        self._add_labeled_entry('nlambda', lf, label='# of wavelengths:',  width=3, value='', position=(r,0), postlabel='Leave blank for autoselect')
        r+=1

        self._add_labeled_dropdown("jitter", lf, label='Jitter model:', values=  ['Just use OPDs', 'Gaussian - 7 mas rms', 'Gaussian - 30 mas rms'], width=20, position=(r,0), sticky='W', columnspan=2)
        r+=1
        self._add_labeled_dropdown("output_format", lf, label='Output Format:', values=  ['Oversampled image','Detector sampled image','Both as FITS extensions', 'Mock JWST DMS Output' ], width=30, position=(r,0), sticky='W', columnspan=2)
        #self._add_labeled_dropdown("jitter", lf, label='Jitter model:', values=  ['Just use OPDs', 'Gaussian blur', 'Accurate yet SLOW grid'], width=20, position=(r,0), sticky='W', columnspan=2)

        lf.grid(row=4, sticky='E,W', padx=10, pady=5)

        lf = ttk.Frame(frame)

        def addbutton(self,lf, text, command, pos, disabled=False):
            self.widgets[text] = ttk.Button(lf, text=text, command=command )
            self.widgets[text].grid(column=pos, row=0, sticky='E')
            if disabled:
                self.widgets[text].state(['disabled'])


        addbutton(self,lf,'Compute PSF', self.ev_calc_psf, 0)
        addbutton(self,lf,'Display PSF', self.ev_displayPSF, 1, disabled=True)
        addbutton(self,lf,'Display profiles', self.ev_displayProfiles, 2, disabled=True)
        addbutton(self,lf,'Save PSF As...', self.ev_SaveAs, 3, disabled=True)
        addbutton(self,lf,'More options...', self.ev_options, 4, disabled=False)

        ttk.Button(lf, text='Quit', command=self.quit).grid(column=5, row=0)
        lf.columnconfigure(2, weight=1)
        lf.columnconfigure(4, weight=1)
        lf.grid(row=5, sticky='E,W', padx=10, pady=15)

        frame.grid(row=0, sticky='N,E,S,W')
        frame.columnconfigure(0, weight=1)
        frame.rowconfigure(0, weight=1)
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
예제 #15
0
    def _create_widgets(self):
        """Create a nice GUI using the enhanced widget set provided by
        the ttk extension to Tkinter, available in Python 2.7 or newer
        """
        #---- create the GUIs
        insts = ['NIRCam', 'NIRSpec', 'NIRISS', 'MIRI', 'FGS']
        self.root = tk.Tk()
        self.root.geometry('+50+50')
        self.root.title("James Webb Space Telescope PSF Calculator")

        frame = ttk.Frame(self.root)
        #frame = ttk.Frame(self.root, padx=10,pady=10)

        #ttk.Label(frame, text='James Webb PSF Calculator' ).grid(row=0)

        #-- star
        lf = ttk.LabelFrame(frame, text='Source Properties')

        if _HAS_PYSYNPHOT:
            self._add_labeled_dropdown("SpType",
                                       lf,
                                       label='    Spectral Type:',
                                       values=poppy.specFromSpectralType(
                                           "", return_list=True),
                                       default='G0V',
                                       width=25,
                                       position=(0, 0),
                                       sticky='W')
            ttk.Button(lf, text='Plot spectrum',
                       command=self.ev_plotspectrum).grid(row=0,
                                                          column=2,
                                                          sticky='E',
                                                          columnspan=4)

        r = 1
        fr2 = ttk.Frame(lf)

        self._add_labeled_entry("source_off_r",
                                fr2,
                                label='    Source Position: r=',
                                value='0.0',
                                width=5,
                                position=(r, 0),
                                sticky='W')
        self._add_labeled_entry("source_off_theta",
                                fr2,
                                label='arcsec,  PA=',
                                value='0',
                                width=3,
                                position=(r, 2),
                                sticky='W')

        self.vars["source_off_centerpos"] = tk.StringVar()
        self.vars["source_off_centerpos"].set('corner')

        ttk.Label(fr2, text='deg, centered on ').grid(row=r, column=4)
        pixel = ttk.Radiobutton(fr2,
                                text='pixel',
                                variable=self.vars["source_off_centerpos"],
                                value='pixel')
        pixel.grid(row=r, column=5)
        corner = ttk.Radiobutton(fr2,
                                 text='corner',
                                 variable=self.vars["source_off_centerpos"],
                                 value='corner')
        corner.grid(row=r, column=6)
        fr2.grid(row=r, column=0, columnspan=5, sticky='W')

        lf.columnconfigure(2, weight=1)
        lf.grid(row=1, sticky='E,W', padx=10, pady=5)

        #-- instruments
        lf = ttk.LabelFrame(frame, text='Instrument Config')
        notebook = ttk.Notebook(lf)
        self.widgets['tabset'] = notebook
        notebook.pack(fill='both')
        for iname, i in zip(insts, range(len(insts))):
            page = ttk.Frame(notebook)
            notebook.add(page, text=iname)
            notebook.select(i)  # make it active
            self.widgets[notebook.select(
            )] = iname  # save reverse lookup from meaningless widget "name" to string name
            if iname == 'NIRCam':
                lframe = ttk.Frame(page)

                ttk.Label(lframe,
                          text='Configuration Options for ' + iname +
                          ',     module: ').grid(row=0, column=0, sticky='W')
                mname = 'NIRCam module'
                self.vars[mname] = tk.StringVar()
                self.widgets[mname] = ttk.Combobox(
                    lframe,
                    textvariable=self.vars[mname],
                    width=2,
                    state='readonly')
                self.widgets[mname].grid(row=0, column=1, sticky='W')
                self.widgets[mname]['values'] = ['A', 'B']
                self.widgets[mname].set('A')

                lframe.grid(row=0, columnspan=2, sticky='W')
            else:
                ttk.Label(page,
                          text='Configuration Options for ' + iname +
                          "                      ").grid(row=0,
                                                         columnspan=2,
                                                         sticky='W')

            ttk.Button(page,
                       text='Display Optics',
                       command=self.ev_displayOptics).grid(column=2,
                                                           row=0,
                                                           sticky='E',
                                                           columnspan=3)

            #if  iname != 'TFI':
            self._add_labeled_dropdown(
                iname + "_filter",
                page,
                label='    Filter:',
                values=self.instrument[iname].filter_list,
                default=self.instrument[iname].filter,
                width=12,
                position=(1, 0),
                sticky='W')
            #else:
            #ttk.Label(page, text='Etalon wavelength: ' , state='disabled').grid(row=1, column=0, sticky='W')
            #self.widgets[iname+"_wavelen"] = ttk.Entry(page, width=7) #, disabledforeground="#A0A0A0")
            #self.widgets[iname+"_wavelen"].insert(0, str(self.instrument[iname].etalon_wavelength))
            #self.widgets[iname+"_wavelen"].grid(row=1, column=1, sticky='W')
            #ttk.Label(page, text=' um' ).grid(row=1, column=2, sticky='W')

            #self.vars[iname+"_filter"] = tk.StringVar()
            #self.widgets[iname+"_filter"] = ttk.Combobox(page,textvariable =self.vars[iname+"_filter"], width=10, state='readonly')
            #self.widgets[iname+"_filter"]['values'] = self.instrument[iname].filter_list
            #self.widgets[iname+"_filter"].set(self.instrument[iname].filter)
            #self.widgets[iname+"_filter"]['readonly'] = True
            #ttk.Label(page, text='    Filter: ' ).grid(row=1, column=0)
            #self.widgets[iname+"_filter"].grid(row=1, column=1)

            #if hasattr(self.instrument[iname], 'ifu_wavelength'):
            if iname == 'NIRSpec' or iname == 'MIRI':
                fr2 = ttk.Frame(page)
                #label = 'IFU' if iname !='TFI' else 'TF'
                ttk.Label(fr2, text='   IFU wavelen: ',
                          state='disabled').grid(row=0, column=0)
                self.widgets[iname + "_ifu_wavelen"] = ttk.Entry(
                    fr2, width=5)  #, disabledforeground="#A0A0A0")
                self.widgets[iname + "_ifu_wavelen"].insert(
                    0, str(self.instrument[iname].monochromatic))
                self.widgets[iname + "_ifu_wavelen"].grid(row=0, column=1)
                self.widgets[iname + "_ifu_wavelen"].state(['disabled'])
                ttk.Label(fr2, text=' um', state='disabled').grid(row=0,
                                                                  column=2)
                fr2.grid(row=1, column=2, columnspan=6, sticky='E')

                iname2 = iname + ""  # need to make a copy so the following lambda function works right:
                self.widgets[iname + "_filter"].bind(
                    '<<ComboboxSelected>>',
                    lambda e: self.ev_update_ifu_label(iname2))

            if len(self.instrument[iname].image_mask_list) > 0:
                masks = self.instrument[iname].image_mask_list
                masks.insert(0, "")

                self._add_labeled_dropdown(iname + "_coron",
                                           page,
                                           label='    Coron:',
                                           values=masks,
                                           width=12,
                                           position=(2, 0),
                                           sticky='W')
                #self.vars[iname+"_coron"] = tk.StringVar()
                #self.widgets[iname+"_coron"] = ttk.Combobox(page,textvariable =self.vars[iname+"_coron"], width=10, state='readonly')
                #self.widgets[iname+"_coron"]['values'] = masks
                #ttk.Label(page, text='    Coron: ' ).grid(row=2, column=0)
                #self.widgets[iname+"_coron"].set(self.widgets[iname+"_coron"]['values'][0])
                #self.widgets[iname+"_coron"].grid(row=2, column=1)

                #fr2 = ttk.Frame(page)
                #self.vars[iname+"_cor_off_r"] = tk.StringVar()
                #self.vars[iname+"_cor_off_theta"] = tk.StringVar()
                #ttk.Label(fr2, text='target offset:  r=' ).grid(row=2, column=4)
                #self.widgets[iname+"_cor_off_r"] = ttk.Entry(fr2,textvariable =self.vars[iname+"_cor_off_r"], width=5)
                #self.widgets[iname+"_cor_off_r"].insert(0,"0.0")
                #self.widgets[iname+"_cor_off_r"].grid(row=2, column=5)
                #ttk.Label(fr2, text='arcsec,  PA=' ).grid(row=2, column=6)
                #self.widgets[iname+"_cor_off_theta"] = ttk.Entry(fr2,textvariable =self.vars[iname+"_cor_off_theta"], width=3)
                #self.widgets[iname+"_cor_off_theta"].insert(0,"0")
                #self.widgets[iname+"_cor_off_theta"].grid(row=2, column=7)
                #ttk.Label(fr2, text='deg' ).grid(row=2, column=8)
                #fr2.grid(row=2,column=3, sticky='W')

            if len(self.instrument[iname].image_mask_list) > 0:
                masks = self.instrument[iname].pupil_mask_list
                masks.insert(0, "")
                self._add_labeled_dropdown(iname + "_pupil",
                                           page,
                                           label='    Pupil:',
                                           values=masks,
                                           width=12,
                                           position=(3, 0),
                                           sticky='W')

                fr2 = ttk.Frame(page)
                self._add_labeled_entry(iname + "_pupilshift_x",
                                        fr2,
                                        label='  pupil shift in X:',
                                        value='0',
                                        width=3,
                                        position=(3, 4),
                                        sticky='W')
                self._add_labeled_entry(iname + "_pupilshift_y",
                                        fr2,
                                        label=' Y:',
                                        value='0',
                                        width=3,
                                        position=(3, 6),
                                        sticky='W')

                ttk.Label(fr2, text='% of pupil').grid(row=3, column=8)
                fr2.grid(row=3, column=3, sticky='W')

            ttk.Label(page, text='Configuration Options for the OTE').grid(
                row=4, columnspan=2, sticky='W')
            fr2 = ttk.Frame(page)

            opd_list = self.instrument[iname].opd_list
            opd_list.insert(0, "Zero OPD (perfect)")
            #if os.getenv("WEBBPSF_ITM") or 1:
            if self._enable_opdserver:
                opd_list.append("OPD from ITM Server")
            default_opd = self.instrument[iname].pupilopd if self.instrument[
                iname].pupilopd is not None else "Zero OPD (perfect)"
            self._add_labeled_dropdown(iname + "_opd",
                                       fr2,
                                       label='    OPD File:',
                                       values=opd_list,
                                       default=default_opd,
                                       width=21,
                                       position=(0, 0),
                                       sticky='W')

            self._add_labeled_dropdown(iname + "_opd_i",
                                       fr2,
                                       label=' # ',
                                       values=[str(i) for i in range(10)],
                                       width=3,
                                       position=(0, 2),
                                       sticky='W')

            self.widgets[iname + "_opd_label"] = ttk.Label(
                fr2, text=' 0 nm RMS            ', width=35)
            self.widgets[iname + "_opd_label"].grid(column=4,
                                                    sticky='W',
                                                    row=0)

            self.widgets[iname + "_opd"].bind(
                '<<ComboboxSelected>>', lambda e: self.ev_update_OPD_labels())
            # The below code does not work, and I can't tell why. This only ever has iname = 'FGS' no matter which instrument.
            # So instead brute-force it with the above to just update all 5.
            #lambda e: self.ev_update_OPD_label(self.widgets[iname+"_opd"], self.widgets[iname+"_opd_label"], iname) )
            ttk.Button(fr2, text='Display',
                       command=self.ev_displayOPD).grid(column=5,
                                                        sticky='E',
                                                        row=0)

            fr2.grid(row=5, column=0, columnspan=4, sticky='S')

            # ITM interface here - build the widgets now but they will be hidden by default until the ITM option is selected
            fr2 = ttk.Frame(page)
            self._add_labeled_entry(iname + "_coords",
                                    fr2,
                                    label='    Source location:',
                                    value='0, 0',
                                    width=12,
                                    position=(1, 0),
                                    sticky='W')
            units_list = ['V1,V2 coords', 'detector pixels']
            self._add_labeled_dropdown(iname + "_coord_units",
                                       fr2,
                                       label='in:',
                                       values=units_list,
                                       default=units_list[0],
                                       width=11,
                                       position=(1, 2),
                                       sticky='W')
            choose_list = [
                '', 'SI center', 'SI upper left corner',
                'SI upper right corner', 'SI lower left corner',
                'SI lower right corner'
            ]
            self._add_labeled_dropdown(iname + "_coord_choose",
                                       fr2,
                                       label='or select:',
                                       values=choose_list,
                                       default=choose_list[0],
                                       width=21,
                                       position=(1, 4),
                                       sticky='W')

            ttk.Label(fr2, text='    ITM output:').grid(row=2,
                                                        column=0,
                                                        sticky='W')
            self.widgets[iname + "_itm_output"] = ttk.Label(
                fr2, text='    - no file available yet -')
            self.widgets[iname + "_itm_output"].grid(row=2,
                                                     column=1,
                                                     columnspan=4,
                                                     sticky='W')
            ttk.Button(fr2,
                       text='Access ITM...',
                       command=self.ev_launch_ITM_dialog).grid(column=5,
                                                               sticky='E',
                                                               row=2)

            fr2.grid(row=6, column=0, columnspan=4, sticky='SW')
            self.widgets[iname + "_itm_coords"] = fr2

        self.ev_update_OPD_labels()
        lf.grid(row=2, sticky='E,W', padx=10, pady=5)
        notebook.select(0)

        lf = ttk.LabelFrame(frame, text='Calculation Options')
        r = 0
        self._add_labeled_entry('FOV',
                                lf,
                                label='Field of View:',
                                width=3,
                                value='5',
                                postlabel='arcsec/side',
                                position=(r, 0))
        r += 1
        self._add_labeled_entry(
            'detector_oversampling',
            lf,
            label='Output Oversampling:',
            width=3,
            value='2',
            postlabel='x finer than instrument pixels       ',
            position=(r, 0))

        #self.vars['downsamp'] = tk.BooleanVar()
        #self.vars['downsamp'].set(True)
        #self.widgets['downsamp'] = ttk.Checkbutton(lf, text='Save in instr. pixel scale, too?', onvalue=True, offvalue=False,variable=self.vars['downsamp'])
        #self.widgets['downsamp'].grid(row=r, column=4, sticky='E')

        output_options = [
            'Oversampled PSF only', 'Oversampled + Detector Res. PSFs',
            'Mock full image from JWST DMS'
        ]
        self._add_labeled_dropdown("output_type",
                                   fr2,
                                   label='Output format:',
                                   values=output_options,
                                   default=output_options[1],
                                   width=31,
                                   position=(r, 4),
                                   sticky='W')

        r += 1
        self._add_labeled_entry('fft_oversampling',
                                lf,
                                label='Coronagraph FFT Oversampling:',
                                width=3,
                                value='2',
                                postlabel='x finer than Nyquist',
                                position=(r, 0))
        r += 1
        self._add_labeled_entry('nlambda',
                                lf,
                                label='# of wavelengths:',
                                width=3,
                                value='',
                                position=(r, 0),
                                postlabel='Leave blank for autoselect')
        r += 1

        self._add_labeled_dropdown("jitter",
                                   lf,
                                   label='Jitter model:',
                                   values=[
                                       'Just use OPDs', 'Gaussian - 7 mas rms',
                                       'Gaussian - 30 mas rms'
                                   ],
                                   width=20,
                                   position=(r, 0),
                                   sticky='W',
                                   columnspan=2)
        r += 1
        self._add_labeled_dropdown("output_format",
                                   lf,
                                   label='Output Format:',
                                   values=[
                                       'Oversampled image',
                                       'Detector sampled image',
                                       'Both as FITS extensions',
                                       'Mock JWST DMS Output'
                                   ],
                                   width=30,
                                   position=(r, 0),
                                   sticky='W',
                                   columnspan=2)
        #self._add_labeled_dropdown("jitter", lf, label='Jitter model:', values=  ['Just use OPDs', 'Gaussian blur', 'Accurate yet SLOW grid'], width=20, position=(r,0), sticky='W', columnspan=2)

        lf.grid(row=4, sticky='E,W', padx=10, pady=5)

        lf = ttk.Frame(frame)

        def addbutton(self, lf, text, command, pos, disabled=False):
            self.widgets[text] = ttk.Button(lf, text=text, command=command)
            self.widgets[text].grid(column=pos, row=0, sticky='E')
            if disabled:
                self.widgets[text].state(['disabled'])

        addbutton(self, lf, 'Compute PSF', self.ev_calc_psf, 0)
        addbutton(self,
                  lf,
                  'Display PSF',
                  self.ev_displayPSF,
                  1,
                  disabled=True)
        addbutton(self,
                  lf,
                  'Display profiles',
                  self.ev_displayProfiles,
                  2,
                  disabled=True)
        addbutton(self, lf, 'Save PSF As...', self.ev_SaveAs, 3, disabled=True)
        addbutton(self,
                  lf,
                  'More options...',
                  self.ev_options,
                  4,
                  disabled=False)

        ttk.Button(lf, text='Quit', command=self.quit).grid(column=5, row=0)
        lf.columnconfigure(2, weight=1)
        lf.columnconfigure(4, weight=1)
        lf.grid(row=5, sticky='E,W', padx=10, pady=15)

        frame.grid(row=0, sticky='N,E,S,W')
        frame.columnconfigure(0, weight=1)
        frame.rowconfigure(0, weight=1)
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
예제 #16
0
def show_notebook_interface_wfi(instrument):
    # Widget related imports.
    # (Currently not a hard dependency for the full webbpsf package, so we import
    # within the function.)
    import ipywidgets as widgets
    from IPython.display import display, clear_output
    from matplotlib import pyplot as plt

    try:
        import pysynphot
    except ImportError:
        raise ImportError(
            "For now, PySynphot must be installed to use the notebook interface"
        )

    # Clean up some warnings we know about so as not to scare the users
    import warnings
    from matplotlib.cbook import MatplotlibDeprecationWarning
    warnings.simplefilter('ignore', MatplotlibDeprecationWarning)
    warnings.simplefilter('ignore', fits.verify.VerifyWarning)

    def make_binding_for_attribute(attribute):
        def callback(trait_name, new_value):
            setattr(instrument, attribute, new_value)

        return callback

    filter_selection = widgets.ToggleButtons(options=instrument.filter_list,
                                             value=instrument.filter,
                                             description='Filter:')
    filter_selection.on_trait_change(make_binding_for_attribute('filter'),
                                     name='selected_label')
    display(filter_selection)

    monochromatic_wavelength = widgets.BoundedFloatText(
        value=0.76,
        min=0.6,
        max=2.0,
    )
    monochromatic_wavelength.disabled = True
    monochromatic_toggle = widgets.Checkbox(
        description='Monochromatic calculation?')

    def update_monochromatic(trait_name, new_value):
        filter_selection.disabled = new_value
        monochromatic_wavelength.disabled = not new_value

    monochromatic_toggle.on_trait_change(update_monochromatic, name='value')

    display(
        widgets.HTML(value='''<p style="padding: 1em 0;">
    <span style="font-style:italic; font-size:1.0em">
    Monochromatic calculations can be performed for any wavelength in the 0.6 to 2.0 &micro;m range.
    </span></p>'''))  # kludge
    monochromatic_controls = widgets.HBox(children=(
        monochromatic_toggle,
        widgets.HTML(
            value='<span style="display: inline-block; width: 0.6em;"></span>'
        ),
        monochromatic_wavelength,
        widgets.HTML(
            value=
            '<span style="display: inline-block; width: 0.25em;"></span> &micro;m '
        ),
    ))
    display(monochromatic_controls)

    display(widgets.HTML(value="<hr>"))

    source_selection = widgets.Select(options=poppy.specFromSpectralType(
        '', return_list=True),
                                      value='G0V',
                                      description="Source spectrum")
    display(source_selection)
    display(widgets.HTML(value="<hr>"))

    sca_selection = widgets.Dropdown(options=instrument.detector_list,
                                     value=instrument.detector,
                                     description='Detector:')
    sca_selection.on_trait_change(make_binding_for_attribute('detector'),
                                  name='selected_label')
    display(sca_selection)

    detector_field_points = [
        ('Top left', (4.0, 4092.0)),
        ('Bottom left', (4.0, 4.0)),
        ('Center', (2048.0, 2048.0)),
        ('Top right', (4092.0, 4092.0)),
        ('Bottom right', (4092.0, 4.0)),
    ]
    # enforce ordering of buttons
    detector_field_point_labels = [a[0] for a in detector_field_points]
    detector_field_points = dict(detector_field_points)

    def set_field_position(trait_name, new_value):
        instrument.detector_position = detector_field_points[new_value]

    field_position = widgets.ToggleButtons(options=detector_field_point_labels,
                                           value='Center',
                                           description='Detector field point:')
    field_position.on_trait_change(set_field_position, name='selected_label')
    display(field_position)

    calculate_button = widgets.Button(description="Calculate PSF",
                                      width='10em',
                                      color='white',
                                      background_color='#00c403',
                                      border_color='#318732')
    display_osys_button = widgets.Button(description="Display Optical System",
                                         width='13em',
                                         color='white',
                                         background_color='#005fc4',
                                         border_color='#224A75')
    clear_button = widgets.Button(description="Clear Output",
                                  width='10em',
                                  color='white',
                                  background_color='#ed4747',
                                  border_color='#911C1C')
    progress = widgets.HTML(value='<progress>')

    OUTPUT_FILENAME = 'psf.fits'
    DOWNLOAD_BUTTON_HTML = """
    <a class="btn btn-info" href="files/{}" target="_blank">
        Download FITS image from last calculation
    </a>
    """
    download_link = widgets.HTML(
        value=DOWNLOAD_BUTTON_HTML.format(OUTPUT_FILENAME))

    def disp(*args):
        progress.visible = True
        plt.figure(figsize=(12, 8))
        instrument.display()
        progress.visible = None

    def calc(*args):
        progress.visible = True
        if monochromatic_toggle.value is True:
            psf = instrument.calcPSF(
                monochromatic=monochromatic_wavelength.value * 1e-6,
                display=True,
                outfile=OUTPUT_FILENAME,
                overwrite=True)
        else:
            source = poppy.specFromSpectralType(source_selection.value)
            _log.debug("Got source type {}: {}".format(source_selection.value,
                                                       source))
            psf = instrument.calcPSF(source=source,
                                     display=True,
                                     outfile=OUTPUT_FILENAME,
                                     overwrite=True)
        fig, (ax_oversamp, ax_detsamp) = plt.subplots(1, 2)
        poppy.display_PSF(psf, ax=ax_oversamp)
        poppy.display_PSF(psf, ax=ax_detsamp, ext='DET_SAMP')
        progress.visible = None
        download_link.visible = True

    def clear(*args):
        clear_output()
        progress.visible = None
        download_link.visible = None

    calculate_button.on_click(calc)
    display_osys_button.on_click(disp)
    clear_button.on_click(clear)
    display(widgets.HTML(value="<br/>"))  # kludge
    buttons = widgets.HBox(
        children=[calculate_button, display_osys_button, clear_button])
    display(buttons)

    # Insert the progress bar, hidden by default
    display(progress)
    progress.visible = None
    # and the download link
    display(download_link)
    download_link.visible = None
예제 #17
0
def show_notebook_interface_jwst(instrument):
    """ Show Jupyter Notebook interface, for a JWST instrument

    Parameters
    -------------
    instrument : string or object
        either a webbpsf instrument object, e.g.  `NIRCam()`
        or the string name of an instrument.


    Example
    --------
    nc = webbpsf.NIRCam()
    webbpsf.show_notebook_interface(nc)
    """
    # Widget related imports.
    # (Currently not a hard dependency for the full webbpsf package, so we import
    # within the function.)
    import ipywidgets as widgets
    from IPython.display import display, clear_output
    from matplotlib import pyplot as plt

    if isinstance(instrument, six.string_types):
        instrument = Instrument(instrument)

    try:
        import pysynphot
    except ImportError:
        raise ImportError(
            "For now, PySynphot must be installed to use the notebook interface"
        )

    # Clean up some warnings we know about so as not to scare the users
    import warnings
    from matplotlib.cbook import MatplotlibDeprecationWarning
    warnings.simplefilter('ignore', MatplotlibDeprecationWarning)
    warnings.simplefilter('ignore', fits.verify.VerifyWarning)

    def make_binding_for_attribute(attribute):
        def callback(trait_name, new_value):
            if new_value == 'None':
                setattr(instrument, attribute, None)
            else:
                setattr(instrument, attribute, new_value)

        return callback

    display(
        widgets.HTML(value='''<p style="padding: 1em 0;">
    <span style="font-weight:bold; font-size:1.0em">
    Notebook Interface for {} PSF sims
    </span></p>'''.format(instrument.name)))

    filter_selection = widgets.Dropdown(options=instrument.filter_list,
                                        value=instrument.filter,
                                        description='Filter:')

    filter_selection.on_trait_change(make_binding_for_attribute('filter'),
                                     name='selected_label')
    display(filter_selection)

    wl_bounds = (5., 30., 10.0) if instrument.name == 'MIRI' else (0.6, 5.3,
                                                                   2.0)
    monochromatic_wavelength = widgets.BoundedFloatText(
        value=wl_bounds[2],
        min=wl_bounds[0],
        max=wl_bounds[1],
    )
    monochromatic_wavelength.disabled = True
    monochromatic_toggle = widgets.Checkbox(
        description='Monochromatic calculation?')

    def update_monochromatic(trait_name, new_value):
        filter_selection.disabled = new_value
        monochromatic_wavelength.disabled = not new_value

    monochromatic_toggle.on_trait_change(update_monochromatic, name='value')

    display(
        widgets.HTML(value='''<p style="padding: 1em 0;">
    <span style="font-style:italic; font-size:1.0em">
    Monochromatic calculations can be performed for any wavelength in the {} to {} &micro;m range.
    </span></p>'''.format(*wl_bounds)))  # kludge
    monochromatic_controls = widgets.HBox(children=(
        monochromatic_toggle,
        widgets.HTML(
            value='<span style="display: inline-block; width: 0.6em;"></span>'
        ),
        monochromatic_wavelength,
        widgets.HTML(
            value=
            '<span style="display: inline-block; width: 0.25em;"></span> &micro;m '
        ),
    ))
    display(monochromatic_controls)
    display(widgets.HTML(value="<hr>"))

    if instrument.name != 'FGS':
        image_selection = widgets.Dropdown(options=['None'] +
                                           instrument.image_mask_list,
                                           value=str(instrument.image_mask),
                                           description='Image Mask:')

        image_selection.on_trait_change(
            make_binding_for_attribute('image_mask'), name='selected_label')
        display(image_selection)

        pupil_selection = widgets.Dropdown(options=['None'] +
                                           instrument.pupil_mask_list,
                                           value=str(instrument.pupil_mask),
                                           description='Pupil Mask: ')

        pupil_selection.on_trait_change(
            make_binding_for_attribute('pupil_mask'), name='selected_label')
        display(pupil_selection)

    display(widgets.HTML(value="<hr>"))

    source_selection = widgets.Dropdown(options=poppy.specFromSpectralType(
        '', return_list=True),
                                        value='G0V',
                                        description="Source spectrum")
    display(source_selection)
    display(widgets.HTML(value="<hr>"))

    calculate_button = widgets.Button(description="Calculate PSF",
                                      width='10em',
                                      color='white',
                                      background_color='#00c403',
                                      border_color='#318732')
    display_osys_button = widgets.Button(description="Display Optical System",
                                         width='13em',
                                         color='white',
                                         background_color='#005fc4',
                                         border_color='#224A75')
    clear_button = widgets.Button(description="Clear Output",
                                  width='10em',
                                  color='white',
                                  background_color='#ed4747',
                                  border_color='#911C1C')
    progress = widgets.HTML(value='<progress>')

    OUTPUT_FILENAME = 'psf.fits'
    DOWNLOAD_BUTTON_HTML = """
    <a class="btn btn-info" href="files/{}" target="_blank">
        Download FITS image from last calculation
    </a>
    """
    download_link = widgets.HTML(
        value=DOWNLOAD_BUTTON_HTML.format(OUTPUT_FILENAME))

    def disp(*args):
        progress.visible = True
        plt.figure(figsize=(12, 8))
        instrument.display()
        progress.visible = None

    def calc(*args):
        progress.visible = True
        if monochromatic_toggle.value is True:
            psf = instrument.calcPSF(
                monochromatic=monochromatic_wavelength.value * 1e-6,
                display=True,
                outfile=OUTPUT_FILENAME,
                overwrite=True)
        else:
            source = poppy.specFromSpectralType(source_selection.value)
            _log.debug("Got source type {}: {}".format(source_selection.value,
                                                       source))
            psf = instrument.calcPSF(source=source,
                                     display=True,
                                     outfile=OUTPUT_FILENAME,
                                     overwrite=True)
        fig, (ax_oversamp, ax_detsamp) = plt.subplots(1, 2, figsize=(12, 4))
        title1 = "PSF sim for {}, {}\n".format(instrument.name,
                                               instrument.filter)
        poppy.display_PSF(psf,
                          ax=ax_oversamp,
                          title=title1 + "Oversampled PSF")
        poppy.display_PSF(psf,
                          ax=ax_detsamp,
                          ext='DET_SAMP',
                          title=title1 + 'Detector pixel sampled PSF')
        progress.visible = None
        download_link.visible = True

    def clear(*args):
        clear_output()
        progress.visible = None
        download_link.visible = None

    calculate_button.on_click(calc)
    display_osys_button.on_click(disp)
    clear_button.on_click(clear)
    display(widgets.HTML(value="<br/>"))  # kludge
    buttons = widgets.HBox(
        children=[calculate_button, display_osys_button, clear_button])
    display(buttons)

    # Insert the progress bar, hidden by default
    display(progress)
    progress.visible = None
    # and the download link
    display(download_link)
    download_link.visible = None