Пример #1
0
 def test_nu_lambda(self):
     """
     Check that Bnu(nu, Te) * c/lmbda =  Blmbda(lmbda, Te)
     """
     nu = cst.c/lmbda
     x0 = rad.planck(lmbda*1.0e9, Te_eV, 'lambda')
     x1 = cst.c/lmbda**2 * rad.planck(nu, Te_eV, 'nu')
     assert_allclose(x0, x1)
Пример #2
0
 def test_nu_lambda(self):
     """
     Check that Bnu(nu, Te) * c/lmbda =  Blmbda(lmbda, Te)
     """
     nu = cst.c / lmbda
     x0 = rad.planck(lmbda * 1.0e9, Te_eV, 'lambda')
     x1 = cst.c / lmbda**2 * rad.planck(nu, Te_eV, 'nu')
     assert_allclose(x0, x1)
Пример #3
0
def plot_2D_map(fig, op, temp_val):
    from matplotlib.colors import LogNorm
    from hedp.rad import planck

    ax = [plt.subplot(1,3,idx+1) for idx in range(3)]
    groups = op[0]['groups']
    x = op[0]['rho']
    y = op[0]['temp']
    X, Y = np.meshgrid(x, y, indices='ij')
    Bnu = planck(groups[:-1], temp_val, 'nu_eV')
    Bnu /= np.sum(Bnu)
    Bnu_arr = np.tile(Bnu, (len(x), len(y))).reshape(op[0]['opp_mg'].shape)
    plt.suptitle('Opacity comparaison for a black body radiation at {0:.1f} eV'.format(temp_val))
    def norm(a,b):
      return np.fmax(a/b,b/a) - 1.0
    for var_idx, var in enumerate(['opp_mg', 'opr_mg', 'eps_mg']):
        err = norm(op[0][var], op[1][var])
        err = (err* Bnu_arr).sum(axis=-1)

        cs = ax[var_idx].pcolormesh(X, Y, err, norm=LogNorm(vmin=0.1, vmax=1e4))
        cb = plt.colorbar(cs, ax=ax[var_idx])
        ax[var_idx].set_title('Relative error for {0}'.format(var.replace('_','\_')))

    for axi in ax:
        axi.set_xscale('log')
        axi.set_yscale('log')
        axi.set_xlim(x.min(),x.max())
        axi.set_ylim(y.min(),y.max())
        axi.set_xlabel(r'$\rho$ [g.cm$^{-3}$]')
        axi.set_ylabel(r'Te [eV]')
    return fig
Пример #4
0
 def test_iplanck(self):
     """
     Check that iBlambda(lmbda, Blambda(lmbda, x)) = x
     """
     Flux = rad.planck(lmbda * 1.0e9, Te_eV, 'lambda')
     Flux = Flux * 1.0e-9  #to W.m⁻².sr⁻¹.nm⁻¹
     Tout = rad.iplanck(lmbda * 1.0e9, Flux)
     assert_allclose(Tout, Te_eV)
Пример #5
0
 def test_iplanck(self):
     """
     Check that iBlambda(lmbda, Blambda(lmbda, x)) = x
     """
     Flux = rad.planck(lmbda*1.0e9, Te_eV, 'lambda')
     Flux = Flux*1.0e-9 #to W.m⁻².sr⁻¹.nm⁻¹
     Tout = rad.iplanck(lmbda*1.0e9, Flux)
     assert_allclose(Tout, Te_eV)
Пример #6
0
def _se_calibration_goi(lmbda,
                        F,
                        transmission,
                        detectorsize,
                        gain,
                        timewindow,
                        tele=None,
                        method='explicit'):
    """
    Compute the calibration for a streaked self emission system.

    This function calculates the number of electrons ejected by the
    photocathode in a SOP configuration.

    Parameters:
    -----------
      - lmbda [ndarray]: wavelenght (nm) array
      - F  [float]:  F number of the first lens
      - gain [float]: Gain of the GOI
      - timewindow [float]: Time window [s]
      - transmission  [ndarray]:    Total transmission of the optical system, including the
                      filter (same shape as the nu) 
      - detectorsize  [float] Size of a pixel in spatial direction in μm

    Returns:
    --------
      - Flux_norm [float]: photon flux (W.m⁻².sr⁻¹.nm⁻¹.counts⁻¹)

    """
    solid_angle = np.pi / (4 * F**2)  # solid angle of the first optics in sr
    # Données Sophie [Joule/count] GOI S20
    K_Jcounts = 1.2e-19  # J
    K_Jcounts = K_Jcounts / (goi_sens(gain, "S20") / goi_sens(5, "S20"))
    # Surface on the target for 1px (m^2)
    S_px = (detectorsize * 1e-6)**2
    # Transmission at 420 nm
    # Approximate width of the filter system ( ~10 nm):
    if method == 'explicit':
        Tr_max = np.max(transmission)
        dlmbda = np.abs(np.trapz(transmission, lmbda) / Tr_max)  # nm

        Flux_coeff = K_Jcounts / (S_px * solid_angle * timewindow * Tr_max *
                                  dlmbda)
        return Flux_coeff

    elif method == 'implicit':
        K = (S_px * solid_angle * timewindow) / K_Jcounts

        counts = K * np.trapz(
                transmission[np.newaxis,:]\
                *planck(lmbda[np.newaxis,:], tele[:,np.newaxis]),
                dx=np.diff(lmbda*1e-9)[0], axis=1)
        return counts
Пример #7
0
    def test_planck_integral(self):
        """
        Check that \int Bnu dθdφdν = σT⁴
        """

        Te = 200.0  # quad integration fails if the temperature is too big
        Te_eV = Te / eV2K

        sigma = physical_constants['Stefan-Boltzmann constant'][0]
        x0 = sigma * Te**4
        x1, x1_err = quad(lambda x: rad.planck(x, Te_eV, 'nu'), 0, 1.0e17)
        # 1e17 Hz max should be well enough for 200 eV
        # np.infinty doesn't work as integration bound (I probably don't
        # know enough about quad parameters)
        assert_allclose(x0, x1 * np.pi)
Пример #8
0
    def test_planck_integral(self):
        """
        Check that \int Bnu dθdφdν = σT⁴
        """

        Te = 200.0  # quad integration fails if the temperature is too big
        Te_eV = Te/eV2K

        sigma = physical_constants['Stefan-Boltzmann constant'][0]
        x0 = sigma*Te**4
        x1, x1_err = quad(lambda x: rad.planck(x, Te_eV, 'nu'), 0, 1.0e17)
        # 1e17 Hz max should be well enough for 200 eV
        # np.infinty doesn't work as integration bound (I probably don't
        # know enough about quad parameters)
        assert_allclose(x0, x1*np.pi)
Пример #9
0
Файл: sop.py Проект: fimay/hedp
def _se_calibration_goi(lmbda, F, transmission, detectorsize, gain, timewindow, tele=None, method="explicit"):
    """
    Compute the calibration for a streaked self emission system.

    This function calculates the number of electrons ejected by the
    photocathode in a SOP configuration.

    Parameters:
    -----------
      - lmbda [ndarray]: wavelenght (nm) array
      - F  [float]:  F number of the first lens
      - gain [float]: Gain of the GOI
      - timewindow [float]: Time window [s]
      - transmission  [ndarray]:    Total transmission of the optical system, including the
                      filter (same shape as the nu) 
      - detectorsize  [float] Size of a pixel in spatial direction in μm

    Returns:
    --------
      - Flux_norm [float]: photon flux (W.m⁻².sr⁻¹.nm⁻¹.counts⁻¹)

    """
    solid_angle = np.pi / (4 * F ** 2)  # solid angle of the first optics in sr
    # Données Sophie [Joule/count] GOI S20
    K_Jcounts = 1.2e-19  # J
    K_Jcounts = K_Jcounts / (goi_sens(gain, "S20") / goi_sens(5, "S20"))
    # Surface on the target for 1px (m^2)
    S_px = (detectorsize * 1e-6) ** 2
    # Transmission at 420 nm
    # Approximate width of the filter system ( ~10 nm):
    if method == "explicit":
        Tr_max = np.max(transmission)
        dlmbda = np.abs(np.trapz(transmission, lmbda) / Tr_max)  # nm

        Flux_coeff = K_Jcounts / (S_px * solid_angle * timewindow * Tr_max * dlmbda)
        return Flux_coeff

    elif method == "implicit":
        K = (S_px * solid_angle * timewindow) / K_Jcounts

        counts = K * np.trapz(
            transmission[np.newaxis, :] * planck(lmbda[np.newaxis, :], tele[:, np.newaxis]),
            dx=np.diff(lmbda * 1e-9)[0],
            axis=1,
        )
        return counts
Пример #10
0
def _sop_calibration(lmbda,
                     F,
                     transmission,
                     detectorsize,
                     slitwidth,
                     sweepspeed,
                     tele=None,
                     method='explicit'):
    """
    Compute the calibration for a streaked self emission system.

    This function calculates the number of electrons ejected by the
    photocathode in a SOP configuration.

    Parameters:
    -----------
      - lmbda [ndarray]: wavelenght (nm) array
      - F  [float]:  F number of the first lens
      - transmission  [ndarray]:    Total transmission of the optical system, including the
                      filter (same shape as the nu) 
      - detectorsize  [float] Size of a pixel in spatial direction in μm
      - slitwidth  [float]   Size of the slit in px
      - sweepspeed        Sweep speed of the streak [100ns, 50ns, etc]in pixel/ns
      - tele [ndarray]: plasma temperature [eV]

    Returns:
    --------
      if method == 'explicit':
        - Flux_norm [float]: photon flux (W.m⁻².sr⁻¹.nm⁻¹.counts⁻¹)
      elif method == 'implicit':
        - counts [ndarray]: counts value on CCD 
                          of the same shape as counts with the temperature
    """
    solid_angle = np.pi / (4 * F**2)  # solid angle of the first optics in sr
    # Données Tommaso [Joule/count] Streak S20
    K_Jcounts = 6.6434e-18  #
    # Normalize with streak sensitivity for the given wavelenght
    mstreak_sens = lambda lmbda: streak_sens(lmbda, 'hamamatsu', 'S20_2')[0]
    K_Jcounts = K_Jcounts

    # Surface on the target for 1px (m^2)
    S_px = (detectorsize * 1e-6)**2
    #tr_itp = interp1d(lmbda, transmission)
    # Transmission at 420 nm
    # Time spend on each pxl:
    # Streak slit 100um = 8px pour calibre :
    # This remains approximately true for this polar experiment
    t_px = slitwidth * sweepspeed / 1024.
    # Approximate width of the filter system ( ~10 nm):
    if method == 'explicit':
        max_idx = np.argmax(transmission)
        Tr_max = transmission[max_idx]  #tr_itp(420.)
        lmbda_max = lmbda[max_idx]
        dlmbda = np.abs(np.trapz(transmission, lmbda) / Tr_max)  # nm

        Flux_coeff = K_Jcounts/(S_px * solid_angle  * t_px * Tr_max * dlmbda *\
                                    mstreak_sens(lmbda_max)/mstreak_sens(532.))
        return Flux_coeff

    elif method == 'implicit':

        K = (S_px * solid_angle * t_px) / K_Jcounts

        counts = K * np.trapz(
                (transmission*mstreak_sens(lmbda)/mstreak_sens(532.))[np.newaxis,:]\
                *planck(lmbda[np.newaxis,:], tele[:,np.newaxis]),
                dx=np.diff(lmbda*1e-9)[0], axis=1)
        return counts
Пример #11
0
Файл: sop.py Проект: fimay/hedp
def _sop_calibration(lmbda, F, transmission, detectorsize, slitwidth, sweepspeed, tele=None, method="explicit"):
    """
    Compute the calibration for a streaked self emission system.

    This function calculates the number of electrons ejected by the
    photocathode in a SOP configuration.

    Parameters:
    -----------
      - lmbda [ndarray]: wavelenght (nm) array
      - F  [float]:  F number of the first lens
      - transmission  [ndarray]:    Total transmission of the optical system, including the
                      filter (same shape as the nu) 
      - detectorsize  [float] Size of a pixel in spatial direction in μm
      - slitwidth  [float]   Size of the slit in px
      - sweepspeed        Sweep speed of the streak [100ns, 50ns, etc]in pixel/ns
      - tele [ndarray]: plasma temperature [eV]

    Returns:
    --------
      if method == 'explicit':
        - Flux_norm [float]: photon flux (W.m⁻².sr⁻¹.nm⁻¹.counts⁻¹)
      elif method == 'implicit':
        - counts [ndarray]: counts value on CCD 
                          of the same shape as counts with the temperature
    """
    solid_angle = np.pi / (4 * F ** 2)  # solid angle of the first optics in sr
    # Données Tommaso [Joule/count] Streak S20
    K_Jcounts = 6.6434e-18  #
    # Normalize with streak sensitivity for the given wavelenght
    mstreak_sens = lambda lmbda: streak_sens(lmbda, "hamamatsu", "S20_2")[0]
    K_Jcounts = K_Jcounts

    # Surface on the target for 1px (m^2)
    S_px = (detectorsize * 1e-6) ** 2
    # tr_itp = interp1d(lmbda, transmission)
    # Transmission at 420 nm
    # Time spend on each pxl:
    # Streak slit 100um = 8px pour calibre :
    # This remains approximately true for this polar experiment
    t_px = slitwidth * sweepspeed / 1024.0
    # Approximate width of the filter system ( ~10 nm):
    if method == "explicit":
        max_idx = np.argmax(transmission)
        Tr_max = transmission[max_idx]  # tr_itp(420.)
        lmbda_max = lmbda[max_idx]
        dlmbda = np.abs(np.trapz(transmission, lmbda) / Tr_max)  # nm

        Flux_coeff = K_Jcounts / (
            S_px * solid_angle * t_px * Tr_max * dlmbda * mstreak_sens(lmbda_max) / mstreak_sens(532.0)
        )
        return Flux_coeff

    elif method == "implicit":

        K = (S_px * solid_angle * t_px) / K_Jcounts

        counts = K * np.trapz(
            (transmission * mstreak_sens(lmbda) / mstreak_sens(532.0))[np.newaxis, :]
            * planck(lmbda[np.newaxis, :], tele[:, np.newaxis]),
            dx=np.diff(lmbda * 1e-9)[0],
            axis=1,
        )
        return counts