Quasar.py 4.99 KB
Newer Older
Fang Yuedong's avatar
Fang Yuedong committed
1
import galsim
Fang Yuedong's avatar
Fang Yuedong committed
2
3
import os
import sys
Fang Yuedong's avatar
Fang Yuedong committed
4
5
6
7
import numpy as np
import astropy.constants as cons
from astropy.table import Table
from scipy import interpolate
8
9
10

from ObservationSim.MockObject.MockObject import MockObject
from ObservationSim.MockObject._util import integrate_sed_bandpass, getNormFactorForSpecWithABMAG, getObservedSED, getABMAG
Fang Yuedong's avatar
Fang Yuedong committed
11

Fang Yuedong's avatar
Fang Yuedong committed
12

Fang Yuedong's avatar
Fang Yuedong committed
13
class Quasar(MockObject):
14
15
    def __init__(self, param, logger=None):
        super().__init__(param, logger=logger)
Fang Yuedong's avatar
Fang Yuedong committed
16
17
18
19
20
        if not hasattr(self, "mu"):
            if hasattr(self, "detA"):
                self.mu = 1./self.detA
            else:
                self.mu = 1.
Fang Yuedong's avatar
Fang Yuedong committed
21

Fang Yuedong's avatar
Fang Yuedong committed
22
    def load_SED(self, survey_type, sed_path=None, cosids=None, objtypes=None, sed_templates=None, normFilter=None, target_filt=None):
Fang Yuedong's avatar
Fang Yuedong committed
23
24
25
26
27
        '''
        --------------------------------------------------------------------
        (Deprecated) Left over codes from cycle-1 to cycle-3 implementations
        --------------------------------------------------------------------
        '''
Fang Yuedong's avatar
Fang Yuedong committed
28
29
30
31
        if survey_type == "photometric":
            norm_thr_rang_ids = normFilter['SENSITIVITY'] > 0.001
            if sed_templates is None:
                # Read SED data directly
Fang Yuedong's avatar
Fang Yuedong committed
32
33
34
                itype = objtypes[cosids == self.sed_type][0]
                sed_file = os.path.join(
                    sed_path, itype + "_ID%s.sed" % (self.sed_type))
Fang Yuedong's avatar
Fang Yuedong committed
35
36
37
38
39
40
41
42
43
                if not os.path.exists(sed_file):
                    raise ValueError("!!! No SED found.")
                sed_data = Table.read(sed_file, format="ascii")
                wave, flux = sed_data["observedLambda"].data, sed_data["observedFlux"].data
            else:
                # Load SED from templates
                sed_data = sed_templates[self.sed_type]
                # redshift, intrinsic extinction
                sed_data = getObservedSED(
Fang Yuedong's avatar
Fang Yuedong committed
44
45
46
                    sedCat=sed_data,
                    redshift=self.z,
                    av=self.param['av'],
Fang Yuedong's avatar
Fang Yuedong committed
47
48
                    redden=self.param['redden'])
                wave, flux = sed_data[0], sed_data[1]
Fang Yuedong's avatar
Fang Yuedong committed
49

Fang Yuedong's avatar
Fang Yuedong committed
50
            flux_photon = flux * (wave / (cons.h.value * cons.c.value)) * 1e-13
Fang Yuedong's avatar
Fang Yuedong committed
51
52
            sed_photon = Table(
                np.array([wave, flux_photon]).T, names=('WAVELENGTH', 'FLUX'))
Fang Yuedong's avatar
Fang Yuedong committed
53
54
            # Get scaling factor for SED
            sedNormFactor = getNormFactorForSpecWithABMAG(ABMag=self.param['mag_use_normal'],
Fang Yuedong's avatar
Fang Yuedong committed
55
56
57
58
59
60
61
                                                          spectrum=sed_photon,
                                                          norm_thr=normFilter,
                                                          sWave=np.floor(
                                                              normFilter[norm_thr_rang_ids][0][0]),
                                                          eWave=np.ceil(normFilter[norm_thr_rang_ids][-1][0]))
            sed_photon = np.array(
                [sed_photon['WAVELENGTH'], sed_photon['FLUX']*sedNormFactor]).T
Fang Yuedong's avatar
Fang Yuedong committed
62
            # Convert to galsim.SED object
Fang Yuedong's avatar
Fang Yuedong committed
63
64
65
66
            spec = galsim.LookupTable(x=np.array(sed_photon[:, 0]), f=np.array(
                sed_photon[:, 1]), interpolant='nearest')
            self.sed = galsim.SED(spec, wave_type='A',
                                  flux_type='1', fast=False)
Fang Yuedong's avatar
Fang Yuedong committed
67
            # Get magnitude
Fang Yuedong's avatar
Fang Yuedong committed
68
69
70
71
            interFlux = integrate_sed_bandpass(
                sed=self.sed, bandpass=target_filt.bandpass_full)
            self.param['mag_%s' % target_filt.filter_type] = getABMAG(
                interFlux=interFlux,
Fang Yuedong's avatar
Fang Yuedong committed
72
73
74
75
76
77
                bandpass=target_filt.bandpass_full)
            # print('mag_use_normal = ', self.param['mag_use_normal'])
            # print('mag_%s = '%target_filt.filter_type, self.param['mag_%s'%target_filt.filter_type])

        elif survey_type == "spectroscopic":
            if sed_templates is None:
Fang Yuedong's avatar
Fang Yuedong committed
78
79
                self.sedPhotons(sed_path=sed_path,
                                cosids=cosids, objtypes=objtypes)
Fang Yuedong's avatar
Fang Yuedong committed
80
81
82
            else:
                sed_data = sed_templates[self.sed_type]
                sed_data = getObservedSED(
Fang Yuedong's avatar
Fang Yuedong committed
83
84
85
                    sedCat=sed_data,
                    redshift=self.z,
                    av=self.param['av'],
Fang Yuedong's avatar
Fang Yuedong committed
86
87
88
89
90
91
                    redden=self.param['redden'])
                speci = interpolate.interp1d(sed_data[0], sed_data[1])
                lamb = np.arange(2500, 10001 + 0.5, 0.5)
                y = speci(lamb)
                # erg/s/cm2/A --> photo/s/m2/A
                all_sed = y * lamb / (cons.h.value * cons.c.value) * 1e-13
Fang Yuedong's avatar
Fang Yuedong committed
92
93
                self.sed = Table(
                    np.array([lamb, all_sed]).T, names=('WAVELENGTH', 'FLUX'))
Fang Yuedong's avatar
Fang Yuedong committed
94
95
96
97
98
99
100
101
102
103
104
105

    def unload_SED(self):
        """(Test) free up SED memory
        """
        del self.sed

    def getGSObj(self, psf, g1=0, g2=0, flux=None, filt=None, tel=None, exptime=150.):
        if flux == None:
            flux = self.getElectronFluxFilt(filt, tel, exptime)
        qso = galsim.Gaussian(sigma=1.e-8, flux=1.)
        qso = qso.withFlux(flux)
        final = galsim.Convolve(psf, qso)
Fang Yuedong's avatar
Fang Yuedong committed
106
        return final