Skip to content

Commit 01fced8

Browse files
committed
update
1 parent 08d1afb commit 01fced8

File tree

4 files changed

+240
-5
lines changed

4 files changed

+240
-5
lines changed

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@ jobs:
3737
name: artifact
3838
path: dist
3939

40-
- uses: pypa/gh-action-pypi-publish@v1.6.4
40+
- uses: pypa/gh-action-pypi-publish@v1.8.5
4141
with:
4242
password: ${{ secrets.pypi_password }}

README.md

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[![publish](https://github.com/amanmdesai/pygrc/actions/workflows/publish.yml/badge.svg)](https://github.com/amanmdesai/pygrc/actions/workflows/publish.yml)
55
[![test](https://github.com/amanmdesai/pygrc/actions/workflows/test.yaml/badge.svg)](https://github.com/amanmdesai/pygrc/actions/workflows/test.yaml)
66
[![PyPI Package latest release](https://img.shields.io/pypi/v/pygrc.svg)](https://pypi.python.org/pypi/pygrc)
7+
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7950550.svg)](https://doi.org/10.5281/zenodo.7950550)
78

89
## Author
910

@@ -14,6 +15,67 @@ Aman Desai
1415
A package to read and fit SPARC data for Galactic Rotation Curves
1516

1617

18+
Galaxy rotation curves are a class of plots which have velocity of the galactic objects on the y-axis and the x-axis represents their radial distances from the galactic center.
19+
20+
21+
## Analysis Steps
22+
23+
We present the pygrc package to simpify testing new models against data as well as to make galaxy rotation curve analysis accessible to undergraduates. At present, this package is designed to read the SPARC Data (in particular the data stored under newton models). We have used pandas for reading data, iminuit for fitting the data and matplotlib for plotting. The definition of model can be implemented by using functions defined in python language and by sharing these function via calls to pygrc package. The fitting procedure uses the least square approach as implemented in the iminuit package.
24+
25+
An example workflow to carry out analysis with pygrc is as follows:
26+
27+
- Read data from the SPARC Dataset - which gives among other things, the observed rotation velocity and the distance of the object from the center of the galaxy.
28+
29+
```python
30+
df = gr.Reader.read(filepath=<path to the file in double quotation>)
31+
```
32+
- (optional) Make some initial plots for visualization and understanding the SPARC data for the given galaxy.
33+
34+
```python
35+
gr.Plot().overlap(df,"Rad",["Vobs","Vgas","Vbul","Vdisk"],"observed velocity")
36+
```
37+
38+
- User needs to define mass distribution along with useful parameters (for example to define the mass density given in \ref{eq}, use:
39+
40+
```python
41+
def mass(r, M0, R0):
42+
return M0*(1- (1+(r/R0))*np.exp(-r/R0))
43+
```
44+
45+
- User then defines a model whose compatibility with data is to be checked in the following way:
46+
47+
```python
48+
def newton(r, M0, rc, R0,beta):
49+
G = 4.30e-6
50+
m = mass(r,M0, R0)
51+
f = G*m/r
52+
return np.sqrt(f)*10e-3
53+
```
54+
55+
- Fit the model with Data. First define the radius variable and its range. Then define the
56+
57+
58+
```python
59+
r = np.linspace(1e-5,df["Rad"].max(),2000)
60+
```
61+
62+
Then define the variables to fit and the initial values to be used as follows:
63+
64+
```python
65+
m_1=gr.Fit(df["Rad"],df["Vobs"],1.,1.,3,.35,1.)
66+
```
67+
68+
where initial parameters values are in the same order as defined in the function *newton*. In the next step we define the range to scan for the parameters as well as define the error steps and finally define which parameters needs to be scanned and which are taken as fixed.
69+
70+
```python
71+
m_1.fit_lsq(f, [(1e4,None),(1e-1,None),(1,10),(0.1,2),(0.1,2)],df['errV'],\\
72+
[False,False,True,True,True])
73+
```
74+
75+
\end{enumerate}
76+
77+
78+
1779
## Installation
1880

1981
```bash
@@ -42,8 +104,6 @@ df
42104
- 3. Some sample function
43105
```python
44106

45-
mond and mass function are based on Galaxies 2018, 6(3), 70; https://doi.org/10.3390/galaxies6030070
46-
47107
def mass(r, M0, R0):
48108
return M0*(1- (1+(r/R0))*np.exp(-r/R0))
49109

@@ -103,7 +163,7 @@ plt.savefig('1.pdf')
103163
```
104164

105165

106-
References:
166+
## References:
107167

108168
- SPARC Data can be obtained from here: http://astroweb.cwru.edu/SPARC/
109169
- Mond and Mass function are based on Galaxies 2018, 6(3), 70; https://doi.org/10.3390/galaxies6030070

notebooks/detail-example.ipynb

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "e375f8cb",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"import pygrc as gr\n",
11+
"import math\n",
12+
"import numpy as np\n",
13+
"import matplotlib.pyplot as plt"
14+
]
15+
},
16+
{
17+
"cell_type": "code",
18+
"execution_count": null,
19+
"id": "8332c16c",
20+
"metadata": {},
21+
"outputs": [],
22+
"source": [
23+
"galaxy = [\n",
24+
"\"NGC4217\",\n",
25+
"\"NGC5055\",\n",
26+
"\"NGC5585\",\n",
27+
"\"NGC6015\",\n",
28+
"\"NGC6503\",\n",
29+
"\"NGC7331\",\n",
30+
"]"
31+
]
32+
},
33+
{
34+
"cell_type": "code",
35+
"execution_count": null,
36+
"id": "a81f659b",
37+
"metadata": {
38+
"scrolled": false
39+
},
40+
"outputs": [],
41+
"source": [
42+
"df_all = []\n",
43+
"for g in galaxy:\n",
44+
" df = gr.Reader.read(filepath=\"../notebooks/data/\"+g+\"_rotmod.dat\")\n",
45+
" df_all.append(df)\n",
46+
" gr.Plot().overlap(df,\"Rad\",[\"Vobs\",\"Vgas\",\"Vbul\",\"Vdisk\"],\"Distance (kpc)\",\"Velocity\",g)"
47+
]
48+
},
49+
{
50+
"cell_type": "code",
51+
"execution_count": null,
52+
"id": "149622af",
53+
"metadata": {},
54+
"outputs": [],
55+
"source": [
56+
"r = np.linspace(0.01,50,2000)\n",
57+
"def mass(r, M0, R0):\n",
58+
"#def mass(r, M0, rc, R0,beta):\n",
59+
" #return M0*(np.sqrt(R0/rc)*(r/(r+rc)))**(3*beta)\n",
60+
" return M0*(1- (1+(r/R0))*np.exp(-r/R0))\n",
61+
"\n",
62+
"def mond(r, M0, rc, R0,b, beta):\n",
63+
" a = 1.2e-10\n",
64+
" G = 4.300e-6 #parsecs \n",
65+
" m = mass(r,M0, R0)\n",
66+
" f = (G*m/r)*(1 + b*(1+(r/rc)))#*10e-3\n",
67+
" return np.sqrt(f)*10e-3\n",
68+
"\n",
69+
"def newton(r, M0, rc, R0,beta):\n",
70+
" a = 1.2e-10\n",
71+
" G = 4.30e-6 #parsecs \n",
72+
" m = mass(r,M0, R0)\n",
73+
" f = G*m/r\n",
74+
" #f = (G*m/r)*(1/np.sqrt(2)) * np.sqrt(1 + np.sqrt(1 + (r**4) * (2*a/(G*m))**2))\n",
75+
" return np.sqrt(f)*10e-3"
76+
]
77+
},
78+
{
79+
"cell_type": "code",
80+
"execution_count": null,
81+
"id": "9ad18e72",
82+
"metadata": {},
83+
"outputs": [],
84+
"source": [
85+
"for df in df_all:\n",
86+
" print(df['Rad'].max())\n",
87+
" print(df['Rad'].min())"
88+
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"execution_count": null,
93+
"id": "d49750d3",
94+
"metadata": {},
95+
"outputs": [],
96+
"source": [
97+
"m_mond=[]\n",
98+
"m_newton=[]\n",
99+
"\n",
100+
"for df in df_all:\n",
101+
" m_mond.append(gr.Fit(df['Rad'],df['Vobs'],1.,1.,3,.35,1.))\n",
102+
" m_newton.append(gr.Fit(df['Rad'],df['Vobs'],1.,1.,3,1.))"
103+
]
104+
},
105+
{
106+
"cell_type": "code",
107+
"execution_count": null,
108+
"id": "7e2450de",
109+
"metadata": {},
110+
"outputs": [],
111+
"source": [
112+
"fit_mond = [0]*len(m_mond)\n",
113+
"fit_newton = [0]*len(m_newton)\n",
114+
"for i in range(len(m_mond)):\n",
115+
" fit_mond[i] = m_mond[i].fit_lsq(mond, [(1.,1e14),(1.,10.),(2.,5.),(0.1,2),(0.1,2)],df_all[i]['errV'],[False,False,True,True,True])\n",
116+
" fit_newton[i] = m_newton[i].fit_lsq(newton, [(1.,1e14),(1.,10.),(1,10),(0.1,2)],df_all[i]['errV'],[False,True,True,True])"
117+
]
118+
},
119+
{
120+
"cell_type": "code",
121+
"execution_count": null,
122+
"id": "f770703a",
123+
"metadata": {},
124+
"outputs": [],
125+
"source": [
126+
"for i in range(len(m_mond)):\n",
127+
" fig, ax =plt.subplots()\n",
128+
" gr.Plot().plot_grc(df_all[i],fit_mond[i],mond,'MOND',galaxy[i],ax)\n",
129+
" gr.Plot().plot_grc(df_all[i],fit_newton[i],newton,'Newton',galaxy[i],ax)\n",
130+
" plt.savefig(galaxy[i]+'_rad_vars_fit.pdf')"
131+
]
132+
},
133+
{
134+
"cell_type": "code",
135+
"execution_count": null,
136+
"id": "b4339cbf",
137+
"metadata": {},
138+
"outputs": [],
139+
"source": [
140+
"fit_mond[1].draw_mnprofile('M0', band=True)"
141+
]
142+
},
143+
{
144+
"cell_type": "code",
145+
"execution_count": null,
146+
"id": "d4aa72f7",
147+
"metadata": {},
148+
"outputs": [],
149+
"source": [
150+
"fit_mond[4].draw_mncontour('rc', 'M0',cl=[.67,.9,.95])"
151+
]
152+
}
153+
],
154+
"metadata": {
155+
"kernelspec": {
156+
"display_name": "Python 3 (ipykernel)",
157+
"language": "python",
158+
"name": "python3"
159+
},
160+
"language_info": {
161+
"codemirror_mode": {
162+
"name": "ipython",
163+
"version": 3
164+
},
165+
"file_extension": ".py",
166+
"mimetype": "text/x-python",
167+
"name": "python",
168+
"nbconvert_exporter": "python",
169+
"pygments_lexer": "ipython3",
170+
"version": "3.10.6"
171+
}
172+
},
173+
"nbformat": 4,
174+
"nbformat_minor": 5
175+
}

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="pygrc",
8-
version="0.2.0",
8+
version="0.3.0",
99
description= "A package to read SPARC data for Galactic Rotation Curves",
1010
author="Aman Desai",
1111
author_email="[email protected]",

0 commit comments

Comments
 (0)