-
Notifications
You must be signed in to change notification settings - Fork 0
/
utilities.py
172 lines (131 loc) · 5.57 KB
/
utilities.py
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import requests
import numpy as np
import argparse
import warnings
from requests.exceptions import ConnectionError, ReadTimeout
# Are we using MPI? If yes, we must set up MPI runtime first
try:
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
def scatter_work(array, mpi_rank, mpi_size, root=0, dtype=np.int32):
""" will only work if MPI has been initialized by calling script.
array should only exist on root & be None elsewhere"""
if mpi_rank == root:
print(f"Scattering array to {mpi_size} ranks")
scatter_total = array.size
mod = scatter_total % mpi_size
if mod != 0:
print("Padding array for scattering...")
pad = -1 * np.ones(mpi_size - mod, dtype=dtype)
array = np.concatenate((array, pad))
scatter_total += mpi_size - mod
assert scatter_total % mpi_size == 0
assert scatter_total == array.size
else:
scatter_total = None
scatter_total = comm.bcast(scatter_total, root=root)
subset = np.empty(scatter_total//mpi_size, dtype=dtype)
comm.Scatter(array, subset, root=root)
return subset
except ImportError: # no mpi4py
warnings.warn("mpi4py not imported", RuntimeWarning)
# Helper functions
def get(path, params=None, fpath=""):
attempt = 1
connection_reset = False
# make HTTP GET request to path
headers = {"api-key":"5309619565f744f9248320a886c59bec"}
try:
r = requests.get(path, params=params, headers=headers)
status_code = r.status_code
except ConnectionError or ReadTimeout:
attempt += 1
connection_reset = True
status_code = None # dummy
while status_code==503 or status_code==502 or connection_reset: # Server Error; try again
attempt += 1
print(f"Error for {path}; attempt {attempt}", flush=True)
try:
r = requests.get(path, params=params, headers=headers)
status_code = r.status_code
connection_reset = False # break loop
except ConnectionError or ReadTimeout:
continue
# raise exception for other response codes that aren't HTTP SUCCESS (200)
r.raise_for_status()
if r.headers['content-type'] == 'application/json':
return r.json() # parse json responses automatically
if 'content-disposition' in r.headers:
filename = fpath + r.headers['content-disposition'].split("filename=")[1]
with open(filename, 'wb') as f:
f.write(r.content)
return filename # return the filename string
return r
def periodic_centering(x, center, boxsize):
quarter = boxsize/4
upper_qrt = boxsize-quarter
lower_qrt = quarter
if center > upper_qrt:
# some of our particles may have wrapped around to the left half
x[x < lower_qrt] += boxsize
elif center < lower_qrt:
# some of our particles may have wrapped around to the right half
x[x > upper_qrt] -= boxsize
return x - center
# Parse CLI arguments
parser = argparse.ArgumentParser(
description="Specify Illustris version, redshift, and analysis specifications."
)
parser.add_argument('z', type=float, choices=[0.0, 0.03, 0.1, 0.5], action="store",
help='Redshift; only 0.0 or 0.5 (or 0.03 or 0.1 for TNG) are currently supported')
#parser.add_argument('-p','--parent', action='store_true', dest='parent',
# help='Process parent sample')
parser.add_argument('--no-inst', action='store_false', dest='inst_sfr',
help='Exclude instantaneous SFR')
parser.add_argument('--no-dust', action='store_false', dest='dusty',
help='Exclude dust from spectra')
parser.add_argument('--tng', action='store_true', dest='tng',
help='Use Illustris TNG instead of original')
parser.add_argument('-l','--local', nargs='?', action='store', dest='local',
metavar='DIR',
help='Use a local copy of the full snapshot, stored in the specified directory. Default depends on "--tng": /mnt/xfs1/home/sgenel/myceph/PUBLIC/[Illustris-1, IllustrisTNG100]',
const='/mnt/xfs1/home/sgenel/myceph/PUBLIC/',
default=None)
parser.add_argument('-m','--gen-mocks', action='store_true', dest='mock',
help='Generate mock magnitudes using FSPS spectra instead of using FITS from the Illustris team')
args = parser.parse_args()
if not args.tng:
littleh = 0.704
omegaL = 0.7274
omegaM = 0.2726
if args.local == '/mnt/xfs1/home/sgenel/myceph/PUBLIC/':
args.local += 'Illustris-1/'
url_dset = "http://www.illustris-project.org/api/Illustris-1/"
if args.z==0.0:
snapnum = 135
folder = 'z00/'
elif args.z==0.5:
snapnum = 103
folder = 'z05/'
else:
littleh = 0.6774
omegaM = 0.2726
omegaL = 0.6911
if args.local == '/mnt/xfs1/home/sgenel/myceph/PUBLIC/':
args.local += 'IllustrisTNG100/'
url_dset = "http://www.tng-project.org/api/TNG100-1/"
if args.z==0.0:
snapnum = 99
folder = '/mnt/gs18/scratch/users/kopenhaf/z00_TNG/'
elif args.z==0.5:
snapnum = 67
folder = 'z05_TNG/'
elif args.z==0.1:
snapnum = 91
folder = 'z01_TNG/'
elif args.z==0.03:
snapnum = 96
folder = 'z003_TNG/'
url_sbhalos = url_dset + "snapshots/" + str(snapnum) + "/subhalos/"