File: plot-Spectrum.py

package info (click to toggle)
gyoto 2.0.2-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,444 kB
  • sloc: cpp: 42,330; sh: 4,512; python: 3,436; xml: 2,865; makefile: 691; ansic: 346
file content (135 lines) | stat: -rw-r--r-- 5,492 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import numpy as np
import math
import matplotlib.pyplot as plt
import pyfits as fits
import scipy.integrate as integrate
from scipy.special import kn
import time
from simpson import * # in ~/mypythonlib

image_file="gyoto_spectrum.fits"

image_cube = fits.getdata(image_file)

# Lower and upper values of the exponent of your frequency
# as chosen in the XML Spectrometer field.
low_freq_exp=11.
high_freq_exp=18.

convertSItoCGS=1e3 # SI to cgs conversion for I_nu (gyoto speaks in SI)

fov=500 # observer's field of view in µas, as specified
# in the XML FieldOfView field

# Sgr A* distance and mass
DD_kpc=8.1
MM_sunmass=4.1e6

# Choose whether to plot or not Sgr A* observed data
plotobsradio=1
plotobsIR=1
plotobsX=1

###################################################
############ End of input parameters ##############
############  Nothing to edit below  ##############
###################################################

kiloparsec_cgs  = 1e3*3.08e18
sunmass_cgs = 1.99e33
DD=DD_kpc*kiloparsec_cgs
MM=MM_sunmass*sunmass_cgs # M used only if unit_length=0

GG=6.67e-8;c2=2.99792458e10*2.99792458e10
GMoc2 = GG*MM/c2

angle=0.5*fov*1e-6/3600.*math.pi/180.

nbnuobs = image_cube.shape[0] # number of frequencies computed
npix = image_cube.shape[1] # number of pixels along one dimension of Screen

dfovreal=2*angle/npix # number of rad per pxl

spectrum = np.zeros(nbnuobs, dtype=float)

# Put in spectrum, for each frequency, the sum of all intensities
# over screen pixel, multiplied by the solid angle subtended by one pixel
for ii in range(0,nbnuobs):
    imnu = image_cube[ii,:,:]
    spectrum[ii] = mysimps2D(imnu,dfovreal,dfovreal)
    
spectrum*=convertSItoCGS

# Create the array containing the values of frequencies computed, in Hz
# Remember the frequencies are evenly separated in log space
nuobs = np.zeros(nbnuobs, dtype=float)
freq_exp_array = np.zeros(nbnuobs+1, dtype=float)
for ii in range(0,nbnuobs+1):
    freq_exp_array[ii] = low_freq_exp + ii*(high_freq_exp-low_freq_exp)/nbnuobs
for ii in range(1,nbnuobs+1):
    nuobs[ii-1] = 0.5*(pow(10,freq_exp_array[ii-1]) + pow(10,freq_exp_array[ii]))

plt.figure(0)
plt.clf()
plt.ion()

plt.loglog(nuobs,4*math.pi*DD*DD*nuobs*spectrum,color="red")
plt.xlabel('$\\nu$ (Hz)',fontsize=14)
plt.ylabel('$\\nu L_\\nu$ (erg/s)',fontsize=14)
plt.show()

# SgrA* observation

if plotobsradio==1:
    # RADIO
    # Data from Bower+15 Table 7
    # To these points, are added (last 4 points of the vector):
    # 2 points at 100GHz from Brinkerink+15 Fig. 2
    # 1 point at 492 GHz from Liu+16 (A&A 593 A44) see abstract
    # 1 point at 690GHz from Marrone+06
    nuobsdata=np.asarray([1.6,3.1,5.4,9.,14.,21.1,32.,40.9,218.,220.,231.9,233.8,341.6,343.6,351.7,353.6,216.8,223.9,238.2,266.8,274.,331.1,338.3,352.6,98.,108.,492.,690.])*1e9
    fluxobs=np.asarray([0.592,0.702,0.87,0.932,1.075,1.164,1.382,1.485,3.667,3.661,3.676,3.704,3.602,3.609,3.595,3.553,3.677,3.391,3.310,3.369,3.526,3.205,3.436,4.89,2.41,2.6,3.6,3.8])*1e-23 # Jy
    errobs=np.asarray([0.028,0.032,0.118,0.129,0.135,0.052,0.087,0.073,0.65,0.652,0.664,0.68,0.866,0.87,0.884,0.86,0.762,0.489,0.424,0.096,0.697,1.074,0.863,0.721,0.18,0.2,0.72,2.2])*1e-23
    plt.scatter(nuobsdata,4*math.pi*DD*DD*nuobsdata*fluxobs,color="black")
    plt.errorbar(nuobsdata,4*math.pi*DD*DD*nuobsdata*fluxobs,yerr=4*math.pi*DD*DD*nuobsdata*errobs,linestyle='None',ecolor="black",elinewidth=3)

if plotobsIR==1:
    # FIR point from Fellenberg+18 (upper lims)
    ll=np.asarray([160.,100.])*1e-6 # lambda in m
    c_SI=299792458.
    nuobsdata=c_SI/ll # nu in Hz
    fluxFIR=np.asarray([1.06,0.64])*1e-23 # Jy
    errFIR=np.asarray([0.24,0.4])*1e-23
    plt.scatter(nuobsdata,4*math.pi*DD*DD*nuobsdata*fluxFIR,color="black")
    plt.errorbar(nuobsdata,4*math.pi*DD*DD*nuobsdata*fluxFIR,yerr=4*math.pi*DD*DD*nuobsdata*errFIR,uplims=4*math.pi*DD*DD*nuobsdata*errFIR,linestyle='None',ecolor="black",elinewidth=3)

    # NIR points taken from Witzel+18
    ll=np.asarray([4.5,2.18])*1e-6 # lambda in m
    nuobsdata_IR=c_SI/ll # nu in Hz
    nnuLnu_IR_8d3kpc=np.asarray([3.2,2.6])*1e34
    nnuLnu_IR_DD=nnuLnu_IR_8d3kpc/8.3**2 * DD_kpc**2
    fluxobs_IR=nnuLnu_IR_DD/(nuobsdata_IR*4.*math.pi*DD**2) #cgs flux
    errobs_IR_8d3kpc=np.asarray([1.4,1.2])*1e34 # in nu*Lnu for 8.3kpc
    errobs_IR_DD=errobs_IR_8d3kpc/8.3**2 * DD_kpc**2
    errobs_IR=errobs_IR_DD/(nuobsdata_IR*4.*math.pi*DD**2) # cgs flux error
    plt.scatter(nuobsdata_IR,4*math.pi*DD*DD*nuobsdata_IR*fluxobs_IR,color="black")
    plt.errorbar(nuobsdata_IR,4*math.pi*DD*DD*nuobsdata_IR*fluxobs_IR,yerr=4*math.pi*DD*DD*nuobsdata_IR*errobs_IR,linestyle='None',ecolor="black",elinewidth=3)
    
if plotobsX==1:
    # From Baganoff+01: 2-10 keV integrated luminosity is 2.2[+0.4 -0.3]e33 erg/s
    numin=2. * 1e3*1.6e-19/6.62e-34 # in Hz
    numax=10. * 1e3*1.6e-19/6.62e-34
    luminosityX=2.2e33
    errlum_low=0.3e33
    errlum_high=0.4e33
    Gamma=2.2
    index=2.-Gamma
    integral=(numax**index/index - numin**index/index)
    Aavg=luminosityX/integral
    Ahigh=(luminosityX+errlum_high)/integral
    Alow=(luminosityX-errlum_low)/integral
    plt.plot([numin,numax],[Ahigh*numin**index,Alow*numax**index],color="black",linewidth=3)
    plt.plot([numin,numax],[Alow*numin**index,Ahigh*numax**index],color="black",linewidth=3)
    plt.plot([numin,numin],[Alow*numin**index,Ahigh*numin**index],color="black",linewidth=3)
    plt.plot([numax,numax],[Alow*numax**index,Ahigh*numax**index],color="black",linewidth=3)