Download as pdf or txt
Download as pdf or txt
You are on page 1of 85

Espectro_MAGS_03052022 about:srcdoc

INTEGRAL FIELD SPECTROSCOPY


Integral field spectrographs (IFS) are instruments that allow us to carry out a spectral
study on a two-dimensional field of view, that is, analysis of cubes with 3 dimensions: two
spatial and one spectral. Its use is becoming more and more common since it allows
studying the morphology of large objects and their spectral properties simultaneously.

IFS is an important sub-discipline of astronomy with the proliferation of large aperture,


high-resolution telescopes where there is a need to study the spectra of extended objects
as a function of position, or of clusters of many discrete stars or point sources in a small
field. Such spectroscopic investigations have previously been carried out with long-slit
spectrographs in which the spectrum is dispersed perpendicular to the slit, and spatial
resolution is obtained in the dimension along the slit. Then by stepping the position of the
slit, the spectrum of points in the imaged field can be obtained, but the process is
comparatively slow, and wasteful of potentially restricted telescope time. Integral field
spectrographs are used to speed up such observations by simultaneously obtaining
spectra in a two-dimensional field. As the spatial resolution of telescopes in space (and
also of ground-based instruments using adaptive optics) has rapidly improved in recent
years, the need for such multiplexed instruments has become more and more pressing.

1. INTRODUCTION TO IFU DATA MANAGMENT


In [1]: import numpy as np
import matplotlib.pyplot as plt
import glob
from astropy.io import fits
from astropy.wcs import WCS
from astropy.utils.data import get_pkg_data_filename
from photutils.datasets import make_4gaussians_image
from photutils.centroids import centroid_com
from astropy.modeling import models, fitting
import os
import imageio

POINTS 1) - 2) - 3)
First, we load the FITS data cube to extract the information of the header.

In [2]: hdul = fits.open("ESO113-G032.fits")

In [3]: hdul.info()

Filename: ESO113-G032.fits
No. Name Ver Type Cards Dimensions Format
0 PRIMARY 1 PrimaryHDU 1532 ()
1 DATA 1 CompImageHDU 76 (408, 327, 3681) float32
2 STAT 1 CompImageHDU 48 (408, 327, 3681) float32

In [4]: hdu = hdul[1]

1 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [5]: hdu.header

Out[5]: XTENSION= 'IMAGE ' / IMAGE extension


BITPIX = -32 / number of bits per data pixel
NAXIS = 3 / number of data axes
NAXIS1 = 408 / length of data axis 1
NAXIS2 = 327 / length of data axis 2
NAXIS3 = 3681 / length of data axis 3
PCOUNT = 0 / required keyword; must = 0
GCOUNT = 1 / required keyword; must = 1
ZBLANK = -2147483647 / null value in the compressed integer arr
ay
EXTNAME = 'DATA ' / This extension contains data values
HDUCLASS= 'ESO ' / class name (ESO format)
HDUDOC = 'DICD ' / document with class description
HDUVERS = 'DICD version 6' / version number (according to spec v2.5.
1)
HDUCLAS1= 'IMAGE ' / Image data format
HDUCLAS2= 'DATA ' / this extension contains the data itself
ERRDATA = 'STAT ' / pointer to the variance extension
OBJECT = 'ASASSN14ig_1 (DATA)'
BUNIT = '10**(-20)*erg/s/cm**2/Angstrom'
CRPIX1 = 163.432850767289 / Pixel coordinate of reference point
CRPIX2 = 160.365262653969 / Pixel coordinate of reference point
CD1_1 = -5.55555555555556E-05 / Coordinate transformation matrix elemen
t
CD1_2 = 0. / Coordinate transformation matrix element
CD2_1 = 0. / Coordinate transformation matrix element
CD2_2 = 5.55555555555556E-05 / Coordinate transformation matrix element
CUNIT1 = 'deg ' / Units of coordinate increment and value
CUNIT2 = 'deg ' / Units of coordinate increment and value
CTYPE1 = 'RA---TAN' / Right ascension, gnomonic projection
CTYPE2 = 'DEC--TAN' / Declination, gnomonic projection
CSYER1 = 1.26809825762E-05 / [deg] Systematic error in coordinate
CSYER2 = 7.82119428274E-06 / [deg] Systematic error in coordinate
CRVAL1 = 19.025833
CRVAL2 = -61.62083
CTYPE3 = 'AWAV '
CUNIT3 = 'Angstrom'
CD3_3 = 1.25
CRPIX3 = 1.
CRVAL3 = 4749.810546875
CD1_3 = 0.
CD2_3 = 0.
CD3_1 = 0.
CD3_2 = 0.
COMMENT These data have been ZAPped!
ZAPVERS = '1.0 ' / ZAP version
ZAPZLVL = 'extSVD ' / ZAP zero level correction
ZAPCLEAN= T / ZAP NaN cleaning performed for calculati
on
ZAPCFTYP= 'weight ' / ZAP continuum filter type
ZAPCFWID= 20 / ZAP continuum filter size
ZAPNSEG = 11 / Number of segments used for ZAP SVD
ZAPSEG0 = '0:520 ' / spectrum segment (pixels)
ZAPNEV0 = 4 / number of eigenvals/spectra used
ZAPSEG1 = '521:880 ' / spectrum segment (pixels)
ZAPNEV1 = 6 / number of eigenvals/spectra used
ZAPSEG2 = '881:1352' / spectrum segment (pixels)
ZAPNEV2 = 5 / number of eigenvals/spectra used
ZAPSEG3 = '1353:1600' / spectrum segment (pixels)
ZAPNEV3 = 3 / number of eigenvals/spectra used

2 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

ZAPSEG4 = '1601:1960' / spectrum segment (pixels)


ZAPNEV4 = 2 / number of eigenvals/spectra used
ZAPSEG5 = '1961:2360' / spectrum segment (pixels)
ZAPNEV5 = 3 / number of eigenvals/spectra used
ZAPSEG6 = '2361:2812' / spectrum segment (pixels)
ZAPNEV6 = 8 / number of eigenvals/spectra used
ZAPSEG7 = '2813:3081' / spectrum segment (pixels)
ZAPNEV7 = 3 / number of eigenvals/spectra used
ZAPSEG8 = '3082:3184' / spectrum segment (pixels)
ZAPNEV8 = 2 / number of eigenvals/spectra used
ZAPSEG9 = '3185:3620' / spectrum segment (pixels)
ZAPNEV9 = 5 / number of eigenvals/spectra used
ZAPSEG10= '3621:3680' / spectrum segment (pixels)
ZAPNEV10= 5 / number of eigenvals/spectra used
HISTORY Image was compressed by CFITSIO using scaled integer quantizatio
n:
HISTORY Q = 8.000000 / quantized level scaling parameter
HISTORY 'SUBTRACTIVE_DITHER_1' / Pixel Quantization Algorithm
ZDITHER0= 2550 / dithering offset when quantizing floats
CHECKSUM= 'G5I7I3H4G3H4G3H4' / HDU checksum updated 2016-05-13T03:54:31
DATASUM = '735768872' / data unit checksum updated 2016-05-13T0
3:54:31

We can see that the values of the dimensions extracted from the FITS header coincide
with the dimensions and lengths of the data matrix, whose axes appear in the order: (z, y,
x)

In [6]: hdu.data.shape

Out[6]: (3681, 327, 408)

In [7]: hdu.data

Out[7]: array([[[-215.8359 , -219.7723 , -219.5378 , ..., -218.475 ,


-215.9456 , -218.69266 ],
[ -38.112885 , -37.364243 , -38.027794 , ..., -37.282764 ,
-37.943504 , -37.920567 ],
[ -33.940228 , -34.785103 , -33.8781 , ..., -34.59439 ,
-33.880043 , -33.757385 ],
...,
[-119.02344 , -117.67291 , -117.27055 , ..., -119.27467 ,
-117.31335 , -118.86346 ],
[-133.42072 , -134.71141 , -133.6905 , ..., -134.06303 ,
-133.19801 , -131.4975 ],
[ nan, nan, nan, ..., nan,
nan, nan]],

[[-347.43512 , -349.78287 , -349.19116 , ..., -349.50717 ,


-348.93216 , -350.05222 ],
[-101.304184 , -102.70685 , -101.412605 , ..., -102.60024 ,
-101.69965 , -102.51868 ],
[ -65.146576 , -65.37734 , -64.841484 , ..., -64.95744 ,
-65.057915 , -65.048965 ],
...,
[-134.69623 , -134.69054 , -133.29134 , ..., -134.67276 ,
-134.8572 , -134.74323 ],
[-139.36346 , -141.59515 , -140.82233 , ..., -141.97202 ,
-140.27368 , -139.938 ],
[ nan, nan, nan, ..., nan,
nan, nan]],

3 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

[[-173.35925 , -175.66917 , -174.69121 , ..., -174.34253 ,


-173.21748 , -177.03783 ],
[ -62.598484 , -63.52088 , -63.976437 , ..., -62.297646 ,
-62.86118 , -62.751877 ],
[-166.71217 , -165.40541 , -165.39174 , ..., -166.63652 ,
-165.48051 , -165.1993 ],
...,
[-129.09908 , -130.84445 , -130.0534 , ..., -130.68654 ,
-127.263336 , -129.46225 ],
[-129.36201 , -127.3563 , -126.314095 , ..., -127.25365 ,
-126.126724 , -127.54094 ],
[ nan, nan, nan, ..., nan,
nan, nan]],

...,

[[ -1.2075937, -1.2758688, -1.2759783, ..., -1.2881141,


-1.2077755, -1.2074475],
[ -95.817116 , -94.863625 , -96.54446 , ..., -95.89498 ,
-96.62679 , -95.30286 ],
[ -66.81522 , -66.62918 , -65.61556 , ..., -65.46269 ,
-65.254234 , -66.355774 ],
...,
[ -80.3428 , -80.47067 , -81.514206 , ..., -81.2835 ,
-82.40935 , -82.334335 ],
[ -92.77836 , -91.79916 , -93.21428 , ..., -92.813156 ,
-92.866005 , -94.094696 ],
[ nan, nan, nan, ..., nan,
nan, nan]],

[[ -1.209791 , -1.206715 , -1.2589569, ..., -1.1934549,


-1.2702491, -1.2031181],
[-101.14562 , -101.74823 , -101.69067 , ..., -102.431755 ,
-100.402756 , -101.44236 ],
[ -84.459 , -83.8521 , -84.283226 , ..., -84.18382 ,
-83.49875 , -83.686455 ],
...,
[ -75.29054 , -74.39532 , -73.90488 , ..., -74.65552 ,
-73.79733 , -74.06678 ],
[ -68.47975 , -68.29855 , -67.56838 , ..., -68.58483 ,
-69.20224 , -69.36284 ],
[ nan, nan, nan, ..., nan,
nan, nan]],

[[ -1.2230043, -1.2846082, -1.2854831, ..., -1.2612262,


-1.3031878, -1.3037122],
[-122.98372 , -124.73575 , -122.34265 , ..., -122.698 ,
-122.39894 , -122.69027 ],
[-117.90374 , -117.939804 , -117.33532 , ..., -117.16551 ,
-118.39706 , -116.71489 ],
...,
[ -67.0918 , -66.81059 , -66.725716 , ..., -67.12964 ,
-67.08692 , -66.780334 ],
[ -57.46631 , -55.799088 , -55.024452 , ..., -56.81322 ,
-57.04059 , -56.643593 ],
[ nan, nan, nan, ..., nan,
nan, nan]]], dtype=float32)

POINT 4)
In this point, we will represent several images of the galaxy at different wavelengths

4 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [8]: cdelt3 = hdu.header["CD3_3"]


crval3 = hdu.header["CRVAL3"]
naxis3 = hdu.header["NAXIS3"]
cdelt3, crval3, naxis3

Out[8]: (1.25, 4749.810546875, 3681)

In [9]: lon1000A = int(round(crval3 + cdelt3*1000, 0))


lon1750A = int(round(crval3 + cdelt3*1750, 0))
lon2500A = int(round(crval3 + cdelt3*2500, 0))
lon1000A, lon1750A, lon2500A

Out[9]: (6000, 6937, 7875)

In [10]: imlon1000 = hdu.data[1000, :, :]


imlon1750 = hdu.data[1750, :, :]
imlon2500 = hdu.data[2500, :, :]

In [11]: def imstats(arr):


"""Return the size, min, max, mean, median and std of an array

Parameters
----------
arr: array created from the median of each of the data in the list of an image

Returns
-------
result: size, min, max, mean, median and std of the array
"""

axis1, axis2 = arr.shape

return {'size': axis1*axis2, 'min': np.nanmin(arr), 'max': np.nanmax(

In [12]: stats1000 = imstats(imlon1000)


stats1750 = imstats(imlon1750)
stats2500 = imstats(imlon2500)

In [13]: fig = plt.figure(figsize=(14,18))


ax1 = fig.add_subplot(311)
ax2 = fig.add_subplot(312)
ax3 = fig.add_subplot(313)
ax1.imshow(imlon1000, origin='lower', vmin=stats1000['mean'] - 2*stats1000
vmax=stats1000['mean'] + 3*stats1000['std'], aspect='equal')
ax2.imshow(imlon1750, origin='lower', vmin=stats1000['mean'] - 2*stats1000
vmax=stats1000['mean'] + 3*stats1000['std'], aspect='equal')
ax3.imshow(imlon2500, origin='lower', vmin=stats1000['mean'] - 2*stats1000
vmax=stats1000['mean'] + 3*stats1000['std'], aspect='equal')
ax1.set_title("GALAXY IMAGE λ = "+str(lon1000A) + "Å", loc='center')
ax2.set_title("GALAXY IMAGE λ = "+str(lon1750A) + "Å", loc='center')
ax3.set_title("GALAXY IMAGE λ = "+str(lon2500A) + "Å", loc='center')
ax1.set_xlabel("Pixel")
ax1.set_ylabel("Pixel")
ax2.set_xlabel("Pixel")
ax2.set_ylabel("Pixel")
ax3.set_xlabel("Pixel")
ax3.set_ylabel("Pixel")
plt.show()

5 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

6 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

POINT 5)
Now, we represent the spectrum of different points of the data cube. The points we
choose are those marked with a cross in the following image:

In [14]: plt.figure("imlon2500", figsize=(7,5))


plt.imshow(imlon2500, origin='lower', vmin=stats1000['mean'] - 2*stats1000
vmax=stats1000['mean'] + 3*stats1000['std'], aspect='equal')
plt.colorbar(label="10^(-20)*erg/s/cm^2/Å")
plt.title("GALAXY IMAGE λ = "+str(lon2500A) + "Å", loc='center')
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.scatter(175, 180, color='purple', marker='X', linewidths=0.1)
plt.scatter(225, 150, color='black', marker='X', linewidths=0.1)
plt.scatter(300, 90, color='orange', marker='X', linewidths=0.1)
plt.show()

For the purple point, we define the x-axis and the y-axis as follows:

In [15]: espec175180 = hdu.data[:, 175, 180]


espec175180

Out[15]: array([63.722576, 56.02717 , 63.074566, ..., 44.32289 , 44.76627 ,


40.093647], dtype=float32)

In [16]: espec175180.shape

Out[16]: (3681,)

In [17]: ejex = np.arange(naxis3)


ejex

Out[17]: array([ 0, 1, 2, ..., 3678, 3679, 3680])

In [18]: X175180 = ejex*cdelt3 + crval3


X175180

7 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

Out[18]: array([4749.81054688, 4751.06054688, 4752.31054688, ..., 9347.31054688,


9348.56054688, 9349.81054688])

In [19]: Y175180 = espec175180


Y175180

Out[19]: array([63.722576, 56.02717 , 63.074566, ..., 44.32289 , 44.76627 ,


40.093647], dtype=float32)

In [20]: espec225150 = hdu.data[:, 225, 150]


espec225150

Out[20]: array([14.7912445, 8.12142 , 18.596222 , ..., 13.51149 , 17.561117 ,


18.56339 ], dtype=float32)

We do the same for the black and orange points

In [21]: espec225150 = hdu.data[:, 225, 150]


X225150 = ejex*cdelt3 + crval3
Y225150 = espec225150

In [22]: espec30090 = hdu.data[:, 300, 90]


X30090 = ejex*cdelt3 + crval3
Y30090 = espec30090

In [23]: fig = plt.figure(figsize=(12,25))


ax1 = fig.add_subplot(311)
ax2 = fig.add_subplot(312)
ax3 = fig.add_subplot(313)
ax1.plot(X175180, Y175180, linewidth=0.3, color='purple')
ax2.plot(X225150, Y225150, linewidth=0.3, color='black')
ax3.plot(X30090, Y30090, linewidth=0.3, color='orange')
ax1.set_title("SPECTRUM IN POSITION (175,180)", loc='center')
ax2.set_title("SPECTRUM IN POSITION (225,150)", loc='center')
ax3.set_title("SPECTRUM IN POSITION (300,90)", loc='center')
ax1.set_xlabel("Å", size=12)
ax2.set_xlabel("Å", size=12)
ax3.set_xlabel("Å", size=12)
ax1.set_ylabel("10^(-20)*erg/s/cm^2/Å", size=12)
ax2.set_ylabel("10^(-20)*erg/s/cm^2/Å", size=12)
ax3.set_ylabel("10^(-20)*erg/s/cm^2/Å", size=12)
plt.show()

8 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

9 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

POINT 6)
The next step is to plot a 'white' image (moment 0) of the data cube.

In [24]: imblan = np.sum(hdu.data, axis=0)


imblan.shape

Out[24]: (327, 408)

In [25]: statsimblan = imstats(imblan)


statsimblan

Out[25]: {'size': 133416,


'min': -213020.14,
'max': 3555271.0,
'mean': 21459.107,
'median': 1738.8191,
'std': 98809.64}

In [26]: plt.figure("imblan", figsize=(8,6))


plt.imshow(imblan, origin='lower', vmin=statsimblan['mean'] - 1*statsimblan
vmax=statsimblan['mean'] + 3*statsimblan['std'])
plt.title("WHITE IMAGE")
plt.colorbar(label="10^(-20)*erg/s/cm^2")
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.show()

10 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

We want the distance in arcseconds to the center of the galaxy to appear on the x-axis
and on the y-axis.

To obtain the coordinates of the center of the galaxy, we consult the RA and Dec
coordinates of the galaxy in the NED catalog and transform them to coordinates in the
image using the information in the header and the WCS function of the astropy package.

In [27]: RA = 19.020583
Dec = -61.622167

In [28]: w = WCS(hdu.header)
w

Out[28]: WCS Keywords

Number of WCS axes: 3


CTYPE : 'RA---TAN' 'DEC--TAN' 'AWAV'
CRVAL : 19.025833 -61.62083 4.749810546875e-07
CRPIX : 163.432850767289 160.365262653969 1.0
CD1_1 CD1_2 CD1_3 : -5.55555555555556e-05 0.0 0.0
CD2_1 CD2_2 CD2_3 : 0.0 5.55555555555556e-05 0.0
CD3_1 CD3_2 CD3_3 : 0.0 0.0 1.25e-10
NAXIS : 408 327 3681

In [29]: x = w.wcs_world2pix([[RA,Dec,0]], 0)
x

Out[29]: array([[ 207.34717447, 135.29745218, -3799.8484375 ]])

In [30]: pixx = x[0][0]


pixx

Out[30]: 207.34717446772342

In [31]: pixy = x[0][1]


pixy

Out[31]: 135.29745217887802

In [32]: plt.figure("imblan", figsize=(8,6))


imagenb = plt.imshow(imblan, origin='lower', vmin=statsimblan['mean'] - 1
vmax=statsimblan['mean'] + 3*statsimblan['std'])
imagenb
plt.title("WHITE IMAGE AND NED CENTER")
plt.scatter(pixx, pixy, color='red', marker='X', linewidths=0.1)
plt.colorbar(imagenb, label="10^(-20)*erg/s/cm^2")
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.show()

11 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

As you can see in the previous image, the center of the image has to be recalculated. To
do this, we use the function " centroid_com" from photutils

In [33]: boxx1 = 200


boxx2 = 250
boxy1 = 130
boxy2 = 160
centx1, centy1 = centroid_com(imblan[boxy1:boxy2, boxx1:boxx2])
print((centx1, centy1))

(22.810965082072382, 14.358467617381883)

In [34]: pixxcent = centx1 + boxx1


pixycent = centy1 + boxy1
pixxcent, pixycent

Out[34]: (222.81096508207239, 144.35846761738188)

In [35]: plt.figure("imblan", figsize=(8,6))


plt.imshow(imblan, origin='lower', vmin=statsimblan['mean'] - 1*statsimblan
vmax=statsimblan['mean'] + 3*statsimblan['std'])
plt.title("WHITE IMAGE, NED CENTER AND CENTROID")
plt.scatter(pixx, pixy, color='red', marker='X', linewidths=0.1)
plt.scatter(pixxcent, pixycent, color='green', marker='X', linewidths=0.1
plt.colorbar(label="10^(-20)*erg/s/cm^2")
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.show()

12 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

Now, we change the axis.

In [36]: fig, ax = plt.subplots(1, 1, figsize=(8,6))


img = ax.imshow(imblan, origin='lower', vmin=statsimblan['mean'] - 1 * statsimblan
vmax=statsimblan['mean'] + 3 * statsimblan['std'])
x_label_list = [-223, -173, -123, -73, -23, 27, 77, 127, 177]
ax.set_xticks([0,50,100,150,200,250,300,350,400])
ax.set_xticklabels(x_label_list)
y_label_list = [-144, -94, -44, 6, 56, 106, 156]
ax.set_yticks([0,50,100,150,200,250,300])
ax.set_yticklabels(y_label_list)
plt.title("WHITE IMAGE WITH DIFFERENT AXIS")
plt.colorbar(img, label="10^(-20)*erg/s/cm^2/Å")
plt.xlabel("Distance (pixels) to the galaxy center")
plt.ylabel("Distance (pixels) to the galaxy center");

13 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [37]: cd1_1 = hdu.header["CD1_1"]


cd2_2 = hdu.header["CD2_2"]
cd1_1, cd2_2

Out[37]: (-5.55555555555556e-05, 5.55555555555556e-05)

In [38]: arcsecx = [round(num * cd1_1 * 3600, 2) for num in x_label_list]


arcsecy = [round(num * cd2_2 * 3600, 2) for num in y_label_list]
arcsecx, arcsecy

Out[38]: ([44.6, 34.6, 24.6, 14.6, 4.6, -5.4, -15.4, -25.4, -35.4],
[-28.8, -18.8, -8.8, 1.2, 11.2, 21.2, 31.2])

In [39]: fig, ax = plt.subplots(1, 1, figsize=(8,6))


img = ax.imshow(imblan, origin='lower', vmin=statsimblan['mean'] - 1 * statsimblan
vmax=statsimblan['mean'] + 3 * statsimblan['std'])
x_label_list = arcsecx
ax.set_xticks([0,50,100,150,200,250,300,350,400])
ax.set_xticklabels(x_label_list)
y_label_list = arcsecy
ax.set_yticks([0,50,100,150,200,250,300])
ax.set_yticklabels(y_label_list)
plt.title("WHITE IMAGE WITH DIFFERENT AXIS")
plt.colorbar(img, label="10^(-20)*erg/s/cm^2/Å")
plt.xlabel("Distance (arcsec) to the galaxy center")
plt.ylabel("Distance (arcsec) to the galaxy center");

POINT 7)
In this part, we will plot an image r-band and i-band pf the galaxy in magnitudes

In [40]: r1 = int(round((5000 - crval3) / cdelt3, 0))


r1

Out[40]: 200

14 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [41]: r2 = int(round((7500 - crval3) / cdelt3, 0))


r2

Out[41]: 2200

In [42]: imr = np.sum(hdu.data[r1:r2, :, :], axis=0)


imr

Out[42]: array([[ nan, nan, nan, ..., nan, nan,


nan],
[-96632.92 , -96668.86 , -96640.375, ..., -96642.55 , -96619.61 ,
-96647.43 ],
[-78527.664, -78559.13 , -78554.086, ..., -78522.734, -78527.57 ,
-78503.1 ],
...,
[-86331.21 , -86360.79 , -86326.27 , ..., -86309.36 , -86299.46 ,
-86301.21 ],
[-86997.875, -86996.29 , -87013.92 , ..., -86976.086, -86990.42 ,
-86936.17 ],
[ nan, nan, nan, ..., nan, nan,
nan]], dtype=float32)

In [43]: i1 = int(round((7000 - crval3) / cdelt3, 0))


i1

Out[43]: 1800

In [44]: i2 = int(round((8500 - crval3) / cdelt3, 0))


i2

Out[44]: 3000

In [45]: imi = np.sum(hdu.data[i1:i2, :, :], axis=0)


imi

Out[45]: array([[ -1498.2981, -1502.6221, -1501.0591, ..., -1498.3091,


-1497.5682, -1499.1038],
[-67762.67 , -67771.54 , -67754.19 , ..., -67738.63 ,
-67742.18 , -67725.02 ],
[-54929.28 , -54928.94 , -54931.715 , ..., -54915.08 ,
-54912.2 , -54908.84 ],
...,
[-59173.332 , -59211.695 , -59211.15 , ..., -59173.36 ,
-59191.414 , -59169.07 ],
[-52235.27 , -52259.184 , -52268.574 , ..., -52215.19 ,
-52224.668 , -52221.16 ],
[ nan, nan, nan, ..., nan,
nan, nan]], dtype=float32)

15 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [46]: imrmagn = -2.5 * np.log10(imr * 10**(-20) / 1500) - 21.1


imrmagn

/tmp/ipykernel_2596/4035657691.py:1: RuntimeWarning: invalid value encoun


tered in log10
imrmagn = -2.5 * np.log10(imr * 10**(-20) / 1500) - 21.1
Out[46]: array([[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
...,
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan]], dtype=float32)

In [47]: statsimrmagn = imstats(imrmagn)


statsimrmagn

Out[47]: {'size': 133416,


'min': 21.177725,
'max': 40.115166,
'mean': 27.338085,
'median': 27.301374,
'std': 2.078434}

In [48]: plt.figure("imrmagn", figsize=(8,6))


plt.imshow(imrmagn, origin='lower', vmin=statsimrmagn['mean'] - 2 * statsimrmagn
vmax=statsimrmagn['mean'] + 2 * statsimrmagn['std'])
plt.colorbar(label='Mag')
plt.title("R-BAND IMAGE")
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.show()

In [49]: imimagn = -2.5 * np.log10(imi * 10**(-20)/1500) - 21.1


imimagn

/tmp/ipykernel_2596/3344574617.py:1: RuntimeWarning: invalid value encoun


tered in log10
imimagn = -2.5 * np.log10(imi * 10**(-20)/1500) - 21.1

16 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

Out[49]: array([[nan, nan, nan, ..., nan, nan, nan],


[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
...,
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan]], dtype=float32)

In [50]: statsimimagn = imstats(imimagn)


statsimimagn

Out[50]: {'size': 133416,


'min': 21.586287,
'max': 40.790886,
'mean': 28.074045,
'median': 28.118425,
'std': 2.077306}

In [51]: plt.figure("imimagn", figsize=(8,6))


plt.imshow(imimagn, origin='lower', vmin=statsimimagn['mean'] - 2 * statsimimagn
vmax=statsimimagn['mean'] + 2 * statsimimagn['std'])
plt.title("I-BAND IMAGE")
plt.colorbar(label='Mag')
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.show()

In [52]: fig = plt.figure(figsize=(20,8))


ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(221)
ax1.imshow(imrmagn, origin='lower', vmin=statsimrmagn['mean'] - 2 * statsimrmagn
vmax=statsimrmagn['mean'] + 2 * statsimrmagn['std'])
ax2.imshow(imimagn, origin='lower', vmin=statsimimagn['mean'] - 2 * statsimimagn
vmax=statsimimagn['mean'] + 2 * statsimimagn['std'])
ax1.set_title("R-BAND IMAGE")
ax2.set_title("I-BAND IMAGE")
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.show()

17 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

POINT 8)
From the previous point, we obtain an image of color r-i

In [53]: imr_imagn = imrmagn - imimagn

In [54]: statsimr_imagn = imstats(imr_imagn)


statsimr_imagn

Out[54]: {'size': 133416,


'min': -9.070585,
'max': 9.751539,
'mean': -0.62366396,
'median': -0.6485863,
'std': 0.621028}

In [55]: plt.figure("imr_imagn", figsize=(8,6))


plt.imshow(imr_imagn, origin='lower', vmin=statsimr_imagn['mean'] - 0.75
plt.colorbar(label='Mag')
plt.title("R-I COLOR GALAXY IMAGE")
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.show()

18 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

If magnitude is big, signal is weaker and if the agnitude is small, signal is brighter. We
can observe in central zones: r-i > 0. It is mean that there are older stars or there are
more metallicity or dust. In external zones r-i < 0, so, there are youger stars.

POINT 9)
Now, we will obtain an image in Ha of the galaxy (decontaminated from the adjacent
continuum)

In [171… Ha = 6563

In [172… redshiftNED = 0.02900

In [173… longobs = Ha * (1 + redshiftNED)


longobs

Out[173]: 6753.326999999999

In [60]: h1 = int(round((longobs - crval3) / cdelt3 - 50, 0))


h1

Out[60]: 1553

In [61]: h2 = int(round((longobs - crval3) / cdelt3 + 50, 0))


h2

Out[61]: 1653

In [62]: imHacontam = np.sum(hdu.data[h1:h2, :, :], axis=0)


imHacontam

Out[62]: array([[ -124.60205, -124.35208, -124.73502, ..., -124.48516,


-125.4324 , -124.42489],
[-3380.2637 , -3383.405 , -3376.8872 , ..., -3380.8345 ,
-3379.8113 , -3386.7397 ],

19 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

[-2642.834 , -2647.149 , -2650.6877 , ..., -2644.732 ,


-2641.6907 , -2646.5186 ],
...,
[-2680.5095 , -2681.8645 , -2677.9316 , ..., -2680.2097 ,
-2676.9165 , -2676.136 ],
[-2937.2068 , -2944.86 , -2938.8364 , ..., -2939.3494 ,
-2941.281 , -2939.481 ],
[ nan, nan, nan, ..., nan,
nan, nan]], dtype=float32)

In [63]: caja1 = np.sum(hdu.data[(h1 - 100):h1, :, :], axis=0)


caja2 = np.sum(hdu.data[h2:(h2+100), :, :], axis=0)

In [64]: cajacont = (caja1 + caja2)/2


cajacont

Out[64]: array([[ nan, nan, nan, ..., nan, nan,


nan],
[-3978.2734, -3978.9167, -3974.1152, ..., -3979.8076, -3978.4778,
-3974.9888],
[-3270.2678, -3271.417 , -3265.008 , ..., -3269.1533, -3267.6694,
-3267.0933],
...,
[-3711.0723, -3712.9321, -3710.8364, ..., -3709.414 , -3706.2595,
-3706.6582],
[-3738.4575, -3736.6763, -3736.9495, ..., -3735.7422, -3736.669 ,
-3731.3242],
[ nan, nan, nan, ..., nan, nan,
nan]], dtype=float32)

In [65]: imHa = imHacontam - cajacont


imHa

Out[65]: array([[ nan, nan, nan, ..., nan, nan,


nan],
[ 598.00977, 595.5117 , 597.228 , ..., 598.97314, 598.6665 ,
588.249 ],
[ 627.43384, 624.26807, 614.3203 , ..., 624.4214 , 625.97876,
620.5747 ],
...,
[1030.5627 , 1031.0676 , 1032.9048 , ..., 1029.2043 , 1029.343 ,
1030.5222 ],
[ 801.25073, 791.81616, 798.11304, ..., 796.3928 , 795.38794,
791.84326],
[ nan, nan, nan, ..., nan, nan,
nan]], dtype=float32)

In [66]: statsimHa = imstats(imHa)


statsimHa

Out[66]: {'size': 133416,


'min': -2128.774,
'max': 6516.8438,
'mean': 93.05121,
'median': 24.941448,
'std': 233.3728}

In [67]: pixxHa = 117


pixyHa = 170

20 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [68]: plt.figure("imHa",figsize=(8,6))
plt.imshow(imHa, origin='lower', vmin=0, vmax=1000)
plt.scatter(pixxHa, pixyHa, color='red', marker='X', linewidths=0.1)
plt.title("GALAXY IMAGE Ha")
plt.colorbar(label="Counts")
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.show()

Using this map, we are going to represent the spectrum of some area of the galaxy rich
in ionized gas in ordet to identify different emission lines.

In [69]: especHa = hdu.data[:, pixyHa, pixxHa]


especHa

Out[69]: array([25.944199 , 28.78951 , 26.784466 , ..., 5.5326986, 6.9610977,


6.485795 ], dtype=float32)

In [70]: XHa = ejex*cdelt3 + crval3


XHa

Out[70]: array([4749.81054688, 4751.06054688, 4752.31054688, ..., 9347.31054688,


9348.56054688, 9349.81054688])

In [71]: YHa = especHa


YHa

Out[71]: array([25.944199 , 28.78951 , 26.784466 , ..., 5.5326986, 6.9610977,


6.485795 ], dtype=float32)

In [72]: OII = 3727


HeI = 4471
NIII = 6584
Ha = 6563
SII = 6731

In [73]: plt.figure("pixelHa", figsize=(10,6))


plt.plot(XHa, YHa, linewidth=0.5)
plt.show()

21 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

POINT 10)
In this last point of the first part of the practice, we will represent the spectrum of the
center of the galaxy, we will identify some emission or absorption line and from this we
will obtain the redshift of the galaxy.

In [74]: especHacent = hdu.data[:, int(round(pixycent,0)), int(round(pixxcent,0))]


especHacent

Out[74]: array([623.58344, 628.2549 , 638.4009 , ..., 772.9136 , 851.5552 ,


838.78186], dtype=float32)

In [75]: XHacent = ejex*cdelt3 + crval3


XHacent, len(XHacent)

Out[75]: (array([4749.81054688, 4751.06054688, 4752.31054688, ..., 9347.31054688,


9348.56054688, 9349.81054688]),
3681)

In [76]: YHacent = especHacent


YHacent, len(YHacent)

Out[76]: (array([623.58344, 628.2549 , 638.4009 , ..., 772.9136 , 851.5552 ,


838.78186], dtype=float32),
3681)

In [77]: plt.figure("pixelHacent", figsize=(10,6))


plt.plot(XHacent, YHacent, linewidth=0.5)
plt.show()

22 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [78]: plt.figure("pixelHacent", figsize=(10,6))


plt.plot(XHacent[1598:1610], YHacent[1598:1610], linewidth=0.5)
plt.show()

In [79]: g1 = models.Gaussian1D(amplitude=50., mean=6754, stddev=3.)


g2 = models.Polynomial1D(degree=1)
gg_init = g1 + g2
fit_g = fitting.LevMarLSQFitter()
g = fit_g(gg_init, XHacent[1598:1610], YHacent[1598:1610])
print(g)

Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=92.70216202, mean=6753.77333039, stddev=2.

23 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

1839786)>

[1]: <Polynomial1D(1, c0=2022.53799392, c1=-0.17441018)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1
_1
----------------- ----------------- ... ------------------
-------------------
92.70216202119018 6753.773330389299 ... 2022.5379939152156 -0.1744101
798161804

In [80]: plt.figure(figsize=(8,5))
plt.plot(XHacent[1578:1630], YHacent[1578:1630], '-')
plt.plot(XHacent[1578:1630], g(XHacent[1578:1630]), label='Gaussian')
plt.xlabel('Position')
plt.ylabel('Flux')
plt.legend(loc=2)

Out[80]: <matplotlib.legend.Legend at 0x7fbf63d11d00>

In [81]: Haobs = 6753.773330389299

In [82]: redshift = Haobs/Ha -1


redshift

Out[82]: 0.029068007068307145

In [83]: errorrelat = abs(redshiftNED - redshift) / redshift *100


errorrelat

Out[83]: 0.23395848276537398

Using another galaxy point of the external part of the galaxy, we will see that the redshift
increases due to the speed of rotation of the galaxy

In [84]: especHaext = hdu.data[:, int(round(pixyHa,0)), int(round(pixxHa,0))]


especHaext

Out[84]: array([25.944199 , 28.78951 , 26.784466 , ..., 5.5326986, 6.9610977,


6.485795 ], dtype=float32)

24 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [85]: XHaext = ejex*cdelt3 + crval3


XHaext, len(XHaext)

Out[85]: (array([4749.81054688, 4751.06054688, 4752.31054688, ..., 9347.31054688,


9348.56054688, 9349.81054688]),
3681)

In [86]: YHaext = especHaext


YHaext, len(YHaext)

Out[86]: (array([25.944199 , 28.78951 , 26.784466 , ..., 5.5326986, 6.9610977,


6.485795 ], dtype=float32),
3681)

In [87]: plt.figure("pixelHaext", figsize=(10,6))


plt.plot(XHaext, YHaext, linewidth=0.5)
plt.show()

In [88]: plt.figure("pixelHaext1", figsize=(10,6))


plt.plot(XHaext[1590:1614], YHaext[1590:1614], linewidth=0.5)
plt.show()

25 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [89]: u1 = models.Gaussian1D(amplitude=70., mean=6750, stddev=3.)


u2 = models.Polynomial1D(degree=1)
uu_init = u1 + u2
fit_u = fitting.LevMarLSQFitter()
u = fit_u(uu_init, XHaext[1590:1614], YHaext[1590:1614])
print(u)

Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=852.29121513, mean=6750.37799031, stddev=
1.22018373)>

[1]: <Polynomial1D(1, c0=595.55756133, c1=-0.08549405)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1_1
----------------- ----------------- ... ----------------
--------------------
852.2912151261564 6750.377990314309 ... 595.557561329687 -0.085494048
39394285

In [90]: plt.figure(figsize=(8,5))
plt.plot(XHaext[1590:1614], YHaext[1590:1614], '-')
plt.plot(XHaext[1590:1614], u(XHaext[1590:1614]), label='Gaussian')
plt.xlabel('Position')
plt.ylabel('Flux')
plt.legend(loc=2)

Out[90]: <matplotlib.legend.Legend at 0x7fbf636f3ca0>

26 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [91]: redshiftext = 6750.377990314309/Ha -1


redshiftext

Out[91]: 0.028550661330840832

In [92]: errorrelatext = abs(redshiftNED - redshiftext) / redshiftext *100


errorrelatext

Out[92]: 1.5738292852564766

2. GALACTIC KINEMATICS WITH IFU DATA

POINTS 1) - 2)
We are going to generate images of the galaxy around the line of Ha

In [93]: interv = np.arange(Haobs - 100, Haobs + 100, 2)


interv

Out[93]: array([6653.77333039, 6655.77333039, 6657.77333039, 6659.77333039,


6661.77333039, 6663.77333039, 6665.77333039, 6667.77333039,
6669.77333039, 6671.77333039, 6673.77333039, 6675.77333039,
6677.77333039, 6679.77333039, 6681.77333039, 6683.77333039,
6685.77333039, 6687.77333039, 6689.77333039, 6691.77333039,
6693.77333039, 6695.77333039, 6697.77333039, 6699.77333039,
6701.77333039, 6703.77333039, 6705.77333039, 6707.77333039,
6709.77333039, 6711.77333039, 6713.77333039, 6715.77333039,
6717.77333039, 6719.77333039, 6721.77333039, 6723.77333039,
6725.77333039, 6727.77333039, 6729.77333039, 6731.77333039,
6733.77333039, 6735.77333039, 6737.77333039, 6739.77333039,
6741.77333039, 6743.77333039, 6745.77333039, 6747.77333039,
6749.77333039, 6751.77333039, 6753.77333039, 6755.77333039,
6757.77333039, 6759.77333039, 6761.77333039, 6763.77333039,
6765.77333039, 6767.77333039, 6769.77333039, 6771.77333039,
6773.77333039, 6775.77333039, 6777.77333039, 6779.77333039,
6781.77333039, 6783.77333039, 6785.77333039, 6787.77333039,
6789.77333039, 6791.77333039, 6793.77333039, 6795.77333039,
6797.77333039, 6799.77333039, 6801.77333039, 6803.77333039,

27 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

6805.77333039, 6807.77333039, 6809.77333039, 6811.77333039,


6813.77333039, 6815.77333039, 6817.77333039, 6819.77333039,
6821.77333039, 6823.77333039, 6825.77333039, 6827.77333039,
6829.77333039, 6831.77333039, 6833.77333039, 6835.77333039,
6837.77333039, 6839.77333039, 6841.77333039, 6843.77333039,
6845.77333039, 6847.77333039, 6849.77333039, 6851.77333039])

In [94]: intervalo = []
for inter in interv:
interr = int(round((inter - crval3) / cdelt3, 0))
intervalo.append(interr)

In [95]: filename = []
for num in intervalo:
imlon = hdu.data[num, :, :]
plt.figure("GIF", figsize=(4,4))
plt.imshow(imlon, origin='lower', vmin=0, vmax=500)
plt.colorbar(label="10^(-20)*erg/s/cm^2/Å")
plt.title("IMAGEN INTERVALO "+str(num), loc='center')
plt.savefig(str(num)+'.png')
filename.append(str(num)+'.png')
plt.show()

28 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

29 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

30 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

31 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

32 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

33 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

34 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

35 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

36 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

37 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

38 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

39 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

40 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

41 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

42 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

43 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

44 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

45 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

46 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

47 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

48 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

49 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

50 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

51 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

52 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

From the above images, we create a GIF

In [96]: with imageio.get_writer('Gif.gif', mode='I') as writer:


for name in filename:
image = imageio.imread(name)
writer.append_data(image)

POINT 3)
At this point we are going to compare the rotation curve obtained from the rotation
speeds of different points of the major axis of the galaxy and the rotation curve obtained
from a mass profile

In [97]: pixxcent, pixycent

Out[97]: (222.81096508207239, 144.35846761738188)

From the equation of the line that represents the major axis of the galaxy, we plot it and
we choose the points where we will measure the displacement spectrum of the line Ha.

In [98]: rx = np.linspace(-0,400,50)
ry = -0.67*rx + 293.64

In [99]: ptsx1 = [50, 75, 90, 110, 130, 150, 170, 180, 190, 200, 210, 220, 230, 240
ptsx = np.array(ptsx1)

53 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [100… ptsy = []
for num in ptsx:
ptsy.append(-0.67*num + 293.64)

In [101… plt.figure("Axis Points",figsize=(8,6))


plt.imshow(imHa, origin='lower', vmin=0, vmax=1000)
plt.plot(rx,ry, color='red')
for numx, numy in zip(ptsx, ptsy):
plt.scatter(numx, numy, color='orange', marker='X', s=70, linewidths=
plt.xlabel("Pixel")
plt.ylabel("Pixel")
plt.show()

In [102… especpts0 = hdu.data[:, int(round(ptsy[0],0)), int(round(ptsx[0],0))]


X0 = ejex*cdelt3 + crval3
Y0 = especpts0
plt.figure("pts0", figsize=(10,6))
plt.plot(X0, Y0, linewidth=0.5)
plt.show()

54 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

We represent the spectra of these points

In [103… k= 0
for numx, numy in zip(ptsx,ptsy):
especptsnum = hdu.data[:, int(round(numy,0)), int(round(numx,0))]
Xnum = ejex*cdelt3 + crval3
Ynum = especptsnum
print(k)
plt.figure("ptsnum", figsize=(10,6))
plt.plot(Xnum[1595:1610], Ynum[1595:1610], linewidth=0.5)
plt.show()
k += 1

55 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

56 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

57 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

58 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

59 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

10

11

60 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

12

13

61 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

14

15

62 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

16

17

63 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

18

19

64 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

Of the spectra represented above, we keep those that show an emission and an easily
identifiable Ha line and we fit the line with a Gaussian. In addition, we will save the
information of the observed wavelength for Ha.

In [104… k = 0
lista = [0, 5, 8, 12, 13, 14, 15, 17, 18, 19]
picoiz = []
xpicos = []
ypicos = []

for numx, numy in zip(ptsx,ptsy):


if k not in lista:
print(k)
especptsnum = hdu.data[:, int(round(numy,0)), int(round(numx,0))]
Xnum = ejex*cdelt3 + crval3
Ynum = especptsnum
print(np.max(Ynum[1596:1604]))
print(Xnum[Ynum==np.max(Ynum[1596:1604])])
u1 = models.Gaussian1D(amplitude=np.max(Ynum[1596:1604]),
mean=Xnum[Ynum==np.max(Ynum[1596:1604])],
stddev=5)
u2 = models.Polynomial1D(degree=1)
uu_init = u1 + u2
fit_u = fitting.LevMarLSQFitter()
u = fit_u(uu_init, Xnum[1596:1604], Ynum[1596:1604])
print(u)
plt.figure(figsize=(8,5))
plt.plot(Xnum[1596:1604], Ynum[1596:1604], '-')
plt.plot(Xnum[1596:1604], u(Xnum[1596:1604]), label='Gaussian')
plt.xlabel('Position')
plt.ylabel('Flux')
plt.legend(loc=2)
plt.show()
picoiz.append(u[0].mean.value)
xpicos.append(numx)
ypicos.append(numy)
k +=1

65 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

24.72435
[6748.56054688]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=17.83978537, mean=6748.57846318, stddev=1.
54187858)>

[1]: <Polynomial1D(1, c0=1756.46974924, c1=-0.25954663)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1
_1
------------------ ----------------- ... -----------------
--------------------
17.839785368052784 6748.578463184343 ... 1756.469749237891 -0.2595466
3470518363

2
50.00301
[6748.56054688]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=46.05024937, mean=6747.9778068, stddev=0.9
647453)>

[1]: <Polynomial1D(1, c0=1208.13545804, c1=-0.17736615)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1
_1
----------------- ----------------- ... ------------------
-------------------
46.05024937263077 6747.977806795217 ... 1208.1354580409843 -0.1773661
493894013

66 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

3
155.55742
[6747.31054688]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=153.08522735, mean=6747.82437212, stddev=
1.07312454)>

[1]: <Polynomial1D(1, c0=-860.97500514, c1=0.13041012)>


Parameters:
amplitude_0 mean_0 ... c0_1 c
1_1
------------------ ----------------- ... ------------------
-------------------
153.08522734578642 6747.824372119792 ... -860.9750051417967 0.1304101
1749976453

4
69.00148
[6748.56054688]

67 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=56.50158104, mean=6747.97712602, stddev=1.
16179561)>

[1]: <Polynomial1D(1, c0=-2694.14335, c1=0.40206763)>


Parameters:
amplitude_0 mean_0 ... c0_1 c
1_1
----------------- ----------------- ... -------------------
-------------------
56.50158103932964 6747.977126016808 ... -2694.1433500048292 0.4020676
3142852386

6
95.6998
[6748.56054688]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=56.9686582, mean=6747.93435168, stddev=1.0
4282218)>

[1]: <Polynomial1D(1, c0=78.94644489, c1=-0.00484499)>


Parameters:
amplitude_0 mean_0 ... c1_1
------------------ ----------------- ... ---------------------
56.968658198065064 6747.934351676839 ... -0.004844986732875787

68 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

7
71.04692
[6747.31054688]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=13.11105874, mean=6748.51348042, stddev=1.
70207595)>

[1]: <Polynomial1D(1, c0=-698.14224589, c1=0.11210329)>


Parameters:
amplitude_0 mean_0 ... c1_1
------------------ ------------------ ... -------------------
13.111058744172384 6748.5134804226645 ... 0.11210328965482261
WARNING: The fit may be unsuccessful; check fit_info['message'] for more
information. [astropy.modeling.fitting]

9
111.501816
[6748.56054688]

69 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

WARNING: The fit may be unsuccessful; check fit_info['message'] for more


information. [astropy.modeling.fitting]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=13.17062155, mean=6749.10370156, stddev=1.
2243582)>

[1]: <Polynomial1D(1, c0=-1627.37907277, c1=0.2557973)>


Parameters:
amplitude_0 mean_0 ... c0_1 c
1_1
----------------- ----------------- ... -------------------
-------------------
13.17062154504707 6749.103701559097 ... -1627.3790727733249 0.2557972
9750645464

10
207.97047
[6751.06054688]
WARNING: The fit may be unsuccessful; check fit_info['message'] for more
information. [astropy.modeling.fitting]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=57.02605901, mean=6752.36053354, stddev=2.
41665208)>

[1]: <Polynomial1D(1, c0=40855.38021669, c1=-6.02856235)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1
_1
------------------ ----------------- ... -----------------
-------------------
57.026059011277304 6752.360533536425 ... 40855.38021669042 -6.0285623
450894095

70 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

11
855.7881
[6752.31054688]
WARNING: The fit may be unsuccessful; check fit_info['message'] for more
information. [astropy.modeling.fitting]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=1084.60741999, mean=6755.88258424, stddev=
6.43488368)>

[1]: <Polynomial1D(1, c0=566972.38345037, c1=-83.97973594)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1_
1
------------------ ----------------- ... -----------------
------------------
1084.6074199902343 6755.882584236349 ... 566972.3834503656 -83.979735
93636236

16

71 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

45.271843
[6747.31054688]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=5.81390095, mean=6747.39186347, stddev=0.6
3452087)>

[1]: <Polynomial1D(1, c0=3089.66307122, c1=-0.45205913)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1
_1
----------------- ----------------- ... ------------------
--------------------
5.813900946334462 6747.391863473442 ... 3089.6630712243523 -0.4520591
2647139024
WARNING: The fit may be unsuccessful; check fit_info['message'] for more
information. [astropy.modeling.fitting]

In [105… picoiz

Out[105]: [6748.578463184343,
6747.977806795217,
6747.824372119792,
6747.977126016808,
6747.934351676839,
6748.5134804226645,
6749.103701559097,
6752.360533536425,
6755.882584236349,
6747.391863473442]

72 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [106… k = 0
lista1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16]
picodrch = []

for numx, numy in zip(ptsx,ptsy):


if k not in lista1:
print(k)
especptsnum = hdu.data[:, int(round(numy,0)), int(round(numx,0))]
Xnum = ejex*cdelt3 + crval3
Ynum = especptsnum
print(np.max(Ynum[1603:1610]))
print(Xnum[Ynum==np.max(Ynum[1603:1610])])
u1 = models.Gaussian1D(amplitude=np.max(Ynum[1603:1610]),
mean=Xnum[Ynum==np.max(Ynum[1603:1610])],
stddev=3)
u2 = models.Polynomial1D(degree=1)
uu_init = u1 + u2
fit_u = fitting.LevMarLSQFitter()
u = fit_u(uu_init, Xnum[1603:1610], Ynum[1603:1610])
print(u)
plt.figure(figsize=(8,5))
plt.plot(Xnum[1603:1610], Ynum[1603:1610], '-')
plt.plot(Xnum[1603:1610], u(Xnum[1603:1610]), label='Gaussian')
plt.xlabel('Position')
plt.ylabel('Flux')
plt.legend(loc=2)
plt.show()
picodrch.append(u[0].mean.value)
xpicos.append(numx)
ypicos.append(numy)

k +=1

12
307.05502
[6757.31054688]
WARNING: The fit may be unsuccessful; check fit_info['message'] for more
information. [astropy.modeling.fitting]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=42.27673651, mean=6756.72577737, stddev=1.
87786961)>

[1]: <Polynomial1D(1, c0=16692.70264111, c1=-2.43121512)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1_
1
----------------- ----------------- ... -----------------
-------------------
42.27673651360769 6756.725777368589 ... 16692.70264110552 -2.43121511
52488033

73 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

13
151.3778
[6757.31054688]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=37.29772175, mean=6756.79097317, stddev=2.
22543042)>

[1]: <Polynomial1D(1, c0=-17363.0848481, c1=2.58674046)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1_
1
----------------- ----------------- ... ------------------
-----------------
37.29772175273569 6756.790973170733 ... -17363.08484810428 2.58674046
1171636

14
89.37853
[6759.81054688]

74 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=250.3070151, mean=6762.61259878, stddev=6.
2819277)>

[1]: <Polynomial1D(1, c0=136732.16591607, c1=-20.2480045)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1
_1
------------------ ----------------- ... ------------------
------------------
250.30701510463666 6762.612598781777 ... 136732.16591607273 -20.24800
450103014
WARNING: The fit may be unsuccessful; check fit_info['message'] for more
information. [astropy.modeling.fitting]

17
68.876884
[6758.56054688]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=50.01911535, mean=6758.82547672, stddev=1.
21072994)>

[1]: <Polynomial1D(1, c0=9278.088914, c1=-1.36976639)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1_
1
----------------- ----------------- ... -----------------
-------------------
50.01911535106497 6758.825476715385 ... 9278.088914003745 -1.36976638
64078529
WARNING: The fit may be unsuccessful; check fit_info['message'] for more
information. [astropy.modeling.fitting]

75 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

18
60.633434
[6758.56054688]
Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=44.87934753, mean=6758.58640875, stddev=1.
26902184)>

[1]: <Polynomial1D(1, c0=-16.53154522, c1=0.00493193)>


Parameters:
amplitude_0 mean_0 ... c0_1 c
1_1
----------------- ----------------- ... -------------------
-------------------
44.87934752890668 6758.586408752306 ... -16.531545220268082 0.0049319
2832209487

19
48.678207
[6758.56054688]

76 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

Model: CompoundModel
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Expression: [0] + [1]
Components:
[0]: <Gaussian1D(amplitude=45.63633972, mean=6759.15444847, stddev=0.
95887503)>

[1]: <Polynomial1D(1, c0=-59.85256049, c1=0.01016069)>


Parameters:
amplitude_0 mean_0 ... c0_1 c1
_1
----------------- ----------------- ... ------------------
-------------------
45.63633972331001 6759.154448474017 ... -59.85256049224808 0.01016068
930366514

In [107… picodrch

Out[107]: [6756.725777368589,
6756.790973170733,
6762.612598781777,
6758.825476715385,
6758.586408752306,
6759.154448474017]

In [108… picos = picoiz + picodrch


picos

Out[108]: [6748.578463184343,
6747.977806795217,
6747.824372119792,
6747.977126016808,
6747.934351676839,
6748.5134804226645,
6749.103701559097,
6752.360533536425,
6755.882584236349,
6747.391863473442,
6756.725777368589,
6756.790973170733,
6762.612598781777,
6758.825476715385,

77 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

6758.586408752306,
6759.154448474017]

We calculate the distance between the position of the points whose spectrum has been
adjusted by a gaussian and the galaxy center

In [109… distcentpix = []
for nx, ny in zip(xpicos, ypicos):
distancia = np.abs(((nx - pixxcent)**2 + (ny - pixycent)**2))**0.5
distcentpix.append(distancia)
distcentpix

Out[109]: [177.91943627536358,
159.86389695985258,
135.78984453946956,
111.71579211962937,
63.56768728404489,
51.53066107739732,
27.45660867508097,
15.419582496552911,
3.3825565478600317,
68.83960106935753,
8.654470129992974,
20.691496264465997,
32.72852245509839,
92.91365348672512,
116.98770590585221,
153.0987845360262]

We transform these distances to arcsec

In [110… distcentarcsec = []
for valor in distcentpix:
arcsec = valor * cd2_2 * 3600
distcentarcsec.append(arcsec)
distcentarcsec

Out[110]: [35.58388725507274,
31.97277939197054,
27.15796890789393,
22.34315842392589,
12.713537456808988,
10.30613221547947,
5.491321735016199,
3.0839164993105848,
0.6765113095720068,
13.767920213871516,
1.7308940259985963,
4.138299252893202,
6.545704491019683,
18.582730697345042,
23.39754118117046,
30.619756907205257]

We convert the units from seconds of arc to radians

In [111… distcentrad = []
for num in distcentarcsec:
radianes = num * 4.848e-6
distcentrad.append(radianes)
distcentrad

78 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

Out[111]: [0.00017251068541259264,
0.00015500403449227317,
0.00013166183326546977,
0.00010831963203919272,
6.163522959060997e-05,
4.9964128980644475e-05,
2.6621927771358533e-05,
1.4950827188657715e-05,
3.2797268288050888e-06,
6.674687719684911e-05,
8.391374238041194e-06,
2.0062474778026246e-05,
3.173357537246342e-05,
9.008907842072876e-05,
0.0001134312796463144,
0.0001484445814861311]

And now, we transform to km, taking into acount that the distance to the galaxy is
3.932e+21 km

In [112… distcentkm = []
for valor in distcentrad:
kilom = valor * 3.93e+21
distcentkm.append(kilom)
len(distcentkm), distcentkm

Out[112]: (16,
[6.77966993671489e+17,
6.091658555546336e+17,
5.174310047332962e+17,
4.256961539140274e+17,
2.4222645229109718e+17,
1.963590268939328e+17,
1.0462417614143904e+17,
5.8756750851424824e+16,
1.2889326437203998e+16,
2.62315227383617e+17,
3.2978100755501892e+16,
7.884552587764315e+16,
1.2471295121378125e+17,
3.54050078193464e+17,
4.4578492901001555e+17,
5.833872052404952e+17])

In [113… velobs = []
for pico in picos:
longreposo = np.abs((Haobs - pico)/Haobs)
velobs.append(longreposo * 3e+5)
velobs

Out[113]: [230.75399265689452,
257.434917219019,
264.25042617608693,
257.46515713269923,
259.36517677551643,
233.64050180514985,
207.4231071328851,
62.75588994899829,
93.6922403462714,
283.46229301818335,
131.14655326103656,
134.04252558443787,
392.6368843045594,

79 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

224.41438640025228,
213.79507991554044,
239.0271847222778]

In [114… del velobs[12]


del distcentkm[12]

In [115… len(velobs), len(distcentkm)

Out[115]: (15, 15)

In [116… velR = []
for vobs in velobs:
vr = vobs/np.sin(71 * np.pi / 180)
velR.append(vr)
len(velR), velR

Out[116]: (15,
[244.05019490032882,
272.26849251041307,
279.47671573622114,
272.30047486851856,
274.30997493742296,
247.10302667195816,
219.37496785973772,
66.37192707633531,
99.09085105692884,
299.79558343262676,
138.70330699522148,
141.76614721659493,
237.34529621272355,
226.1140980546326,
252.80009392810763])

In [141… plt.figure("V(R) Curve",figsize=(8,6))


plt.scatter(distcentkm, velR, color='black', marker='X', s=70, linewidths
plt.title("V(R) Curve")
plt.xlabel("Distance in Km")
plt.ylabel("V(R)")
plt.show()

80 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

We fit these data with a polynomial of degree 4

In [127… p = np.polyfit(distcentkm, velR, 5)


p

Out[127]: array([-7.06370790e-86, 1.19631194e-67, -6.88019312e-50, 1.41335111e-3


2,
-1.03714879e-16, 9.76715598e+01])

In [128… xajust = np.linspace(0e+17, 6.9e+17, 20)


xajust

Out[128]: array([0.00000000e+00, 3.63157895e+16, 7.26315789e+16, 1.08947368e+17,


1.45263158e+17, 1.81578947e+17, 2.17894737e+17, 2.54210526e+17,
2.90526316e+17, 3.26842105e+17, 3.63157895e+17, 3.99473684e+17,
4.35789474e+17, 4.72105263e+17, 5.08421053e+17, 5.44736842e+17,
5.81052632e+17, 6.17368421e+17, 6.53684211e+17, 6.90000000e+17])

In [129… yajust = np.poly1d(p)


yajust(xajust)

Out[129]: array([ 97.67155979, 109.45323923, 141.52229842, 180.92883711,


218.64599752, 249.03454823, 269.30746813, 278.99453027,
279.40688575, 273.10164769, 263.34647506, 253.5841566 ,
246.89719474, 245.47238946, 250.06542224, 259.46543991,
269.95963858, 274.79784752, 263.65711308, 222.10628258])

In [168… plt.figure("V(R) Curve",figsize=(10,8))


plt.plot(xajust, yajust(xajust), color='red', label='Fitted V(R) Curve')
plt.scatter(distcentkm, velR, color='black', marker='X', s=70, linewidths
plt.title("V(R) Curve")
plt.xlabel("Distance in Km")
plt.ylabel("V(R) (km/s)")
plt.legend(loc=5)
plt.show()

81 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

The last step is to use the information from the mass profile provided to derive the
rotation curve that would be obtained based on the existing visible matter.

In [153… pmdist = [0.95e+17, 1.62e+17, 2.26e+17, 2.90e+17, 3.54e+17, 4.21e+17, 4.85e+17


len(pmdist), pmdist

Out[153]: (10,
[9.5e+16,
1.62e+17,
2.26e+17,
2.9e+17,
3.54e+17,
4.21e+17,
4.85e+17,
5.48e+17,
6.13e+17,
6.8e+17])

In [154… pmmasa = [7.51e+40, 1.22e+41, 1.66e+41, 2.07e+41, 2.45e+41, 2.75e+41, 3.05e+41


len(pmmasa), pmmasa

Out[154]: (10,
[7.51e+40,
1.22e+41,
1.66e+41,
2.07e+41,
2.45e+41,
2.75e+41,
3.05e+41,
3.32e+41,
3.52e+41,
3.65e+41])

82 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [147… G = 6.67e-17

In [155… pmvel = []
for dist, masa in zip(pmdist, pmmasa):
masvel = (G * masa / dist*1000)**0.5/1000
pmvel.append(masvel)
len(pmvel), pmvel

Out[155]: (10,
[229.626011730287,
224.12243126811487,
221.34144527907577,
218.1971585516182,
214.8544376514739,
208.73160663984575,
204.8056659976532,
201.02111593336383,
195.70594181241702,
189.21470841970225])

In [156… pmvel.insert(0, 0)
len(pmvel), pmvel

Out[156]: (11,
[0,
229.626011730287,
224.12243126811487,
221.34144527907577,
218.1971585516182,
214.8544376514739,
208.73160663984575,
204.8056659976532,
201.02111593336383,
195.70594181241702,
189.21470841970225])

In [157… pmdist.insert(0, 0)
len(pmdist), pmdist

Out[157]: (11,
[0,
9.5e+16,
1.62e+17,
2.26e+17,
2.9e+17,
3.54e+17,
4.21e+17,
4.85e+17,
5.48e+17,
6.13e+17,
6.8e+17])

In [169… plt.figure("V mass profile",figsize=(10,8))


plt.scatter(pmdist, pmvel, color='black', marker='X', s=70, linewidths=0.1
plt.plot(pmdist, pmvel, color='orange', label='Visible Mass Curve ')
plt.title("V mass profile")
plt.xlabel("Distance in Km")
plt.ylabel("V mass profile (km/s)")
plt.legend(loc=5)
plt.show()

83 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

In [170… plt.figure("Comparison",figsize=(10,8))
plt.plot(pmdist, pmvel, color='orange', label='Visible Mass Curve')
plt.plot(xajust, yajust(xajust), color='red', label='Fitted V(R) Curve')
plt.scatter(distcentkm, velR, color='black', marker='X', s=70, linewidths
plt.title("V mass profile and V(R)")
plt.xlabel("Distance in Km")
plt.ylabel("V (km/s)")
plt.legend(loc=5)
plt.show()

84 of 85 5/19/22, 10:37
Espectro_MAGS_03052022 about:srcdoc

The difference between both curves is that the curve obtained from the mass profile does
not take into account the existence of dark matter, only the visible matter.

In [ ]:

85 of 85 5/19/22, 10:37

You might also like