cosmic-popsynth 3.4.15__cp310-cp310-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,492 @@
1
+ #!/usr/bin/env python
2
+ # Code: cosmic-pop.py
3
+ # Version: 1
4
+ # Version changes: SAMPLE FIXED POPULATION OF BINARIES AND EVOLVE WITH BSE;
5
+ # COMPUTE RATES AND NUMBERS FOR EACH POPULATION ACCORDING
6
+ # TO FLAGS SET BY USER
7
+ #
8
+ # Edited on: 8 SEP 2015
9
+
10
+
11
+ ##############################################################################
12
+ # IMPORT ALL NECESSARY PYTHON PACKAGES
13
+ ##############################################################################
14
+ from collections import OrderedDict
15
+ import warnings
16
+ import argparse
17
+ import schwimmbad
18
+
19
+ import math
20
+ import random
21
+ import time
22
+ from time import sleep
23
+ import string
24
+ import os.path
25
+ import json
26
+
27
+ import numpy as np
28
+ import scipy.special as ss
29
+ import pandas as pd
30
+ import warnings
31
+
32
+ from cosmic.sample.initialbinarytable import InitialBinaryTable
33
+ from cosmic import Match, utils
34
+ from cosmic.evolve import Evolve
35
+
36
+ from schwimmbad import MultiPool, MPIPool
37
+
38
+ def str2bool(v):
39
+ if isinstance(v, bool):
40
+ return v
41
+ if v.lower() in ('yes', 'true', 't', 'y', '1'):
42
+ return True
43
+ elif v.lower() in ('no', 'false', 'f', 'n', '0'):
44
+ return False
45
+ else:
46
+ raise argparse.ArgumentTypeError('Boolean value expected.')
47
+
48
+ ###############################################################################
49
+ # DEFINE COMMANDLINE ARGUMENTS
50
+ ###############################################################################
51
+ def parse_commandline():
52
+ """Parse the arguments given on the command-line.
53
+ """
54
+ # Parse any inifile specification
55
+ # We make this parser with add_help=False so that
56
+ # it doesn't parse -h and print help.
57
+ conf_parser = argparse.ArgumentParser(
58
+ description=__doc__, # printed with -h/--help
59
+ # Don't mess with format of description
60
+ formatter_class=argparse.RawDescriptionHelpFormatter,
61
+ # Turn off help, so we print all options in response to -h
62
+ add_help=False
63
+ )
64
+ conf_parser.add_argument("--inifile",
65
+ help="Name of ini file of params",
66
+ metavar="FILE",)
67
+ args, remaining_argv = conf_parser.parse_known_args()
68
+
69
+ defaults = {}
70
+ if not (args.inifile is None and (('-h' in remaining_argv) or ('--help' in remaining_argv))):
71
+ BSEDict, seed_int, filters, convergence, sampling = utils.parse_inifile(args.inifile)
72
+ defaults.update(sampling)
73
+ defaults.update(filters)
74
+ defaults.update(convergence)
75
+ defaults.update({'seed' : seed_int})
76
+ defaults.update({'inifile' : args.inifile})
77
+
78
+ # Parse rest of arguments
79
+ # Don't suppress add_help here so it will handle -h
80
+ parser = argparse.ArgumentParser(
81
+ # Inherit options from config_parser
82
+ parents=[conf_parser]
83
+ )
84
+ parser.set_defaults(**defaults)
85
+ parser.add_argument("--final-kstar1",
86
+ help="Specify the final condition of kstar1 "
87
+ ", you want systems to end at for your samples",
88
+ required=True, type=int, nargs='+')
89
+ parser.add_argument("--final-kstar2",
90
+ help="Specify the final condition of kstar2, you want "
91
+ "systems to end at for your samples",
92
+ required=True, type=int, nargs='+')
93
+ parser.add_argument("--Niter",
94
+ help="Number of iterations of binaries "
95
+ "to try, will check ever Nstep for convergence",
96
+ type=int, default=10000000)
97
+ parser.add_argument("--Nstep",
98
+ help="Number of binaries to try before checking for "
99
+ "convergence, it will check ever Nstep binaries until "
100
+ "it reach Niter binaries", type=int, default=10000)
101
+ parser.add_argument("--max-wall-time", type=int, default=3155760,
102
+ help="Maximum wall time (seconds) for sampling binaries")
103
+ parser.add_argument("--binary_state", nargs='+', type=int)
104
+ parser.add_argument("--sampling_method")
105
+ parser.add_argument("--primary_model", help="Chooses the initial primary mass function from: salpeter55, kroupa93, kroupa01", type=str)
106
+ parser.add_argument("--binfrac_model", help="Chooses the binary fraction model from: a float between [0,1], vanHaaften, and offner22", type=float)
107
+ parser.add_argument("--ecc_model", help="Chooses the initial eccentricity distribution model from: thermal, uniform, and sana12", type=str)
108
+ parser.add_argument("--porb_model", help="Chooses the initial orbital period distribution model from: log_uniform and sana12", type=str)
109
+ parser.add_argument("--SF_start", help="Sets the time in the past when star formation initiates in Myr", type=float)
110
+ parser.add_argument("--SF_duration", help="Sets the duration of constant star formation in Myr", type=float)
111
+ parser.add_argument("--metallicity", type=float)
112
+ parser.add_argument("--convergence_params", nargs='+', help="specifies the list of parameters for which you"
113
+ " would like to track the distribution shapes for convergence")
114
+ parser.add_argument("--convergence_limits", type=json.loads, help="dictionary that can contain limits for convergence params")
115
+ parser.add_argument("--pop_select", help="Used in combination with the specified final_kstar1 and final_kstar2 values"
116
+ " to select the subpopulation of interest from the evolved population")
117
+ parser.add_argument("--match", type=float, help="provides the tolerance for the convergence calculation")
118
+ parser.add_argument("--apply_convergence_limits", type=str2bool, nargs='?',
119
+ const=True, default=False, help="filters the evolved binary population to contain"
120
+ " only the binaries that satsify the convergence limits")
121
+ parser.add_argument("--seed", type=int)
122
+ parser.add_argument("--verbose", action="store_true", default=False,
123
+ help="Run in Verbose Mode")
124
+ parser.add_argument("--complib",type=str,default="zlib",
125
+ help="HDFStore compression library")
126
+ parser.add_argument("--complevel",type=int,default=0,
127
+ help="HDFStore compression level")
128
+
129
+ group = parser.add_mutually_exclusive_group()
130
+ group.add_argument("-n", "--nproc",
131
+ help="number of processors", type=int, default=1)
132
+ group.add_argument("--mpi", dest="mpi", default=False,
133
+ action="store_true", help="Run with MPI.")
134
+
135
+ args = parser.parse_args(remaining_argv)
136
+
137
+ if len(args.final_kstar1) > 2 or len(args.final_kstar2) > 2:
138
+ raise parser.error('final kstar1 and final kstar2 '
139
+ 'must be either a single value or '
140
+ 'a range between two values.')
141
+
142
+ if (len(args.final_kstar1) == 2):
143
+ if (args.final_kstar1[0] >= args.final_kstar1[1]):
144
+ raise parser.error('Range provided for final-kstar1 invalid')
145
+
146
+ if (len(args.final_kstar2) == 2):
147
+ if (args.final_kstar2[0] >= args.final_kstar2[1]):
148
+ raise parser.error('Range provided for final-kstar2 invalid')
149
+
150
+ if (len(args.final_kstar2) == 1) and (len(args.final_kstar1) == 1):
151
+ if (args.final_kstar2 > args.final_kstar1):
152
+ raise parser.error('final-kstar1 must be greater than or equal to '
153
+ 'final-kstar2.')
154
+
155
+ return args
156
+
157
+ ###############################################################################
158
+ # BEGIN MAIN FUNCTION
159
+ ###############################################################################
160
+ if __name__ == '__main__':
161
+
162
+ # READ COMMANDLINE ARGUMENTS
163
+ ###########################################################################
164
+ args = parse_commandline()
165
+ pool = schwimmbad.choose_pool(mpi=args.mpi, processes=args.nproc)
166
+ if isinstance(pool, MPIPool):
167
+ if not pool.is_master():
168
+ pool.wait()
169
+ sys.exit(0)
170
+ nproc = len(pool.workers)
171
+ else:
172
+ nproc = args.nproc
173
+
174
+ # SET TIME TO TRACK COMPUTATION TIME
175
+ ###########################################################################
176
+ start_time = time.time()
177
+
178
+ # READ AND PARSE INIFILE
179
+ ###########################################################################
180
+ BSEDict, seed_int, filters, convergence, sampling = utils.parse_inifile(args.inifile)
181
+
182
+ # we now overwrite the inifile values with what was specified from the command line
183
+ # (which could mean not overwriting anything at all because they are populated
184
+ # by default from the inifile).
185
+ for argument in vars(args):
186
+ if argument in filters.keys():
187
+ if filters[argument] != getattr(args, argument):
188
+ warnings.warn("You are overriding the inifile value of {0}={1} "
189
+ "with {0}={2} from the commandline".format(argument, filters[argument], getattr(args, argument)))
190
+ filters[argument] = getattr(args, argument)
191
+
192
+ if argument in convergence.keys():
193
+ if convergence[argument] != getattr(args, argument):
194
+ warnings.warn("You are overriding the inifile value of {0}={1} "
195
+ "with {0}={2} from the commandline".format(argument, convergence[argument], getattr(args, argument)))
196
+ convergence[argument] = getattr(args, argument)
197
+
198
+ if argument in sampling.keys():
199
+ if (sampling[argument] == "independent") or (getattr(args, argument) == "independent"):
200
+ for model in ["primary_model", "porb_model", "ecc_model", "binfrac_model"]:
201
+ if (model not in sampling.keys()) and not (getattr(args, model)):
202
+ raise ValueError("You have selected the {0} sampler "
203
+ "but not specified a model for {1} "
204
+ "in the inifile or command line".format(sampling[argument], model))
205
+ if sampling[argument] != getattr(args, argument):
206
+ warnings.warn("You are overriding the inifile value of {0}={1} "
207
+ "with {0}={2} from the commandline".format(argument, sampling[argument], getattr(args, argument)))
208
+ sampling[argument] = getattr(args, argument)
209
+
210
+ if argument == 'seed':
211
+ if getattr(args, argument) != seed_int:
212
+ warnings.warn("You are overriding the inifile value of {0}={1} "
213
+ "with {0}={2} from the commandline".format(argument, seed_int, getattr(args, argument)))
214
+ seed_int = getattr(args, argument)
215
+
216
+ # Check that the values in BSEDict, filters, and convergence are valid
217
+ utils.error_check(BSEDict, filters, convergence, sampling)
218
+
219
+ if seed_int != 0:
220
+ np.random.seed(seed_int)
221
+ else:
222
+ np.random.seed(0)
223
+
224
+ # Set up final_kstar1 and final_kstar2 strings for saved data files
225
+ if len(args.final_kstar1) == 2:
226
+ kstar1_range = np.arange(args.final_kstar1[0], args.final_kstar1[1]+1)
227
+ kstar1_range_string = str(int(args.final_kstar1[0]))+'_'+str(int(args.final_kstar1[1]))
228
+ else:
229
+ kstar1_range = args.final_kstar1
230
+ kstar1_range_string = str(int(args.final_kstar1[0]))
231
+
232
+ if len(args.final_kstar2) == 2:
233
+ kstar2_range = np.arange(args.final_kstar2[0], args.final_kstar2[1]+1)
234
+ kstar2_range_string = str(int(args.final_kstar2[0]))+'_'+str(int(args.final_kstar2[1]))
235
+ else:
236
+ kstar2_range = args.final_kstar2
237
+ kstar2_range_string = str(int(args.final_kstar2[0]))
238
+
239
+ # Open the hdf5 file to store the fixed population data
240
+ try:
241
+ dat_store = pd.HDFStore('dat_kstar1_{0}_kstar2_{1}_SFstart_{2}_SFduration_{3}_metallicity_{4}.h5'.format(kstar1_range_string, kstar2_range_string, sampling['SF_start'], sampling['SF_duration'], sampling['metallicity']),complib=args.complib,complevel=args.complevel)
242
+ conv_save = pd.read_hdf(dat_store, 'conv')
243
+ log_file = open('log_kstar1_{0}_kstar2_{1}_SFstart_{2}_SFduration_{3}_metallicity_{4}.txt'.format(kstar1_range_string, kstar2_range_string, sampling['SF_start'], sampling['SF_duration'], sampling['metallicity']), 'a')
244
+ log_file.write('There are already: '+str(conv_save.shape[0])+' '+kstar1_range_string+'_'+kstar2_range_string+' binaries evolved\n')
245
+ log_file.write('\n')
246
+ total_mass_singles = np.max(pd.read_hdf(dat_store, 'mass_singles'))[0]
247
+ total_mass_binaries = np.max(pd.read_hdf(dat_store, 'mass_binaries'))[0]
248
+ total_mass_stars = np.max(pd.read_hdf(dat_store, 'mass_stars'))[0]
249
+ total_n_singles = np.max(pd.read_hdf(dat_store, 'n_singles'))[0]
250
+ total_n_binaries = np.max(pd.read_hdf(dat_store, 'n_binaries'))[0]
251
+ total_n_stars = np.max(pd.read_hdf(dat_store, 'n_stars'))[0]
252
+ idx = int(np.max(pd.read_hdf(dat_store, 'idx'))[0])
253
+ except:
254
+ conv_save = pd.DataFrame()
255
+ dat_store = pd.HDFStore('dat_kstar1_{0}_kstar2_{1}_SFstart_{2}_SFduration_{3}_metallicity_{4}.h5'.format(kstar1_range_string, kstar2_range_string, sampling['SF_start'], sampling['SF_duration'], sampling['metallicity']),complib=args.complib,complevel=args.complevel)
256
+ total_mass_singles = 0
257
+ total_mass_binaries = 0
258
+ total_mass_stars = 0
259
+ total_n_singles = 0
260
+ total_n_binaries = 0
261
+ total_n_stars = 0
262
+ idx = 0
263
+ log_file = open('log_kstar1_{0}_kstar2_{1}_SFstart_{2}_SFduration_{3}_metallicity_{4}.txt'.format(kstar1_range_string, kstar2_range_string, sampling['SF_start'], sampling['SF_duration'], sampling['metallicity']), 'w')
264
+
265
+ # save configuration settings to output file
266
+ configuration_settings = {'BSEDict' : BSEDict, 'filters' : filters,
267
+ 'convergence' : convergence, 'sampling' : sampling}
268
+
269
+ for k, v in configuration_settings.items():
270
+ for k1, v1 in v.items():
271
+ dat_store.put('config/{0}/{1}/'.format(k, k1), pd.Series(v1))
272
+ dat_store.put('config/rand_seed/', pd.Series(seed_int))
273
+
274
+ # Initialize the step counter and convergence array/list
275
+ Nstep = idx - np.mod(idx, args.Nstep)
276
+ match = np.zeros(len(convergence['convergence_params']))
277
+
278
+ # Simulate the fixed population
279
+ # This process is illustrated in Fig 1 of Breivik & Larson (2018)
280
+ steps = 0
281
+ bcm_filter_match = []
282
+ bpp_filter_match = []
283
+ initC_filter_match = []
284
+
285
+ # Warn about qmin and m2_min
286
+ if (hasattr(args, 'qmin')) & (hasattr(args, 'm2_min')):
287
+ warnings.warn(f"You have specified both qmin and m2_min. COSMIC will use qmin={args.qmin} to "
288
+ "determine the secondary masses in the initial sample.")
289
+
290
+ log_file.write("You have specified both qmin and m2_min.\n")
291
+ log_file.write("COSMIC will use qmin={} to determine the secondary masses in the initial sample.\n".format(args.qmin))
292
+
293
+ while (Nstep < args.Niter) & (np.max(match) > convergence['match']) & ((time.time() - start_time) < args.max_wall_time):
294
+ # Set random seed such that each iteration gets a unique, determinable seed
295
+ rand_seed = seed_int + Nstep
296
+ np.random.seed(rand_seed)
297
+
298
+ # Select the initial binary sample method from user input
299
+ if sampling['sampling_method'] == 'independent':
300
+ if hasattr(args,'qmin'):
301
+ init_samp_list = InitialBinaryTable.sampler(format_ = sampling['sampling_method'],
302
+ final_kstar1 = kstar1_range,
303
+ final_kstar2 = kstar2_range,
304
+ binfrac_model = args.binfrac_model,
305
+ primary_model = args.primary_model,
306
+ ecc_model = args.ecc_model,
307
+ porb_model = args.porb_model,
308
+ keep_singles = args.keep_singles,
309
+ SF_start = sampling['SF_start'],
310
+ SF_duration = sampling['SF_duration'],
311
+ met = sampling['metallicity'],
312
+ size = args.Nstep,
313
+ qmin = args.qmin,
314
+ params = args.inifile)
315
+ elif hasattr(args,'m2_min'):
316
+ init_samp_list = InitialBinaryTable.sampler(format_ = sampling['sampling_method'],
317
+ final_kstar1 = kstar1_range,
318
+ final_kstar2 = kstar2_range,
319
+ binfrac_model = args.binfrac_model,
320
+ primary_model = args.primary_model,
321
+ ecc_model = args.ecc_model,
322
+ porb_model = args.porb_model,
323
+ keep_singles = args.keep_singles,
324
+ SF_start = sampling['SF_start'],
325
+ SF_duration = sampling['SF_duration'],
326
+ met = sampling['metallicity'],
327
+ size = args.Nstep,
328
+ m2_min = args.m2_min,
329
+ params = args.inifile)
330
+ else:
331
+ raise ValueError("You must specify either qmin or m2_min in the",
332
+ " inifile if you are using the independent sampler")
333
+ IBT, mass_singles, mass_binaries, n_singles, n_binaries = init_samp_list
334
+
335
+ if sampling['sampling_method'] == 'multidim':
336
+ init_samp_list = InitialBinaryTable.sampler(format_ = sampling['sampling_method'],
337
+ final_kstar1 = kstar1_range,
338
+ final_kstar2 = kstar2_range,
339
+ keep_singles = args.keep_singles,
340
+ rand_seed = rand_seed,
341
+ nproc = args.nproc,
342
+ SF_start = sampling['SF_start'],
343
+ SF_duration = sampling['SF_duration'],
344
+ met = sampling['metallicity'],
345
+ size = args.Nstep,
346
+ pool=pool)
347
+ IBT, mass_singles, mass_binaries, n_singles, n_binaries = init_samp_list
348
+
349
+ # Log the total sampled mass from the initial binary sample
350
+ # for future Galactic occurence rate calculation
351
+ total_mass_singles += mass_singles
352
+ total_mass_binaries += mass_binaries
353
+ total_mass_stars += mass_singles + mass_binaries
354
+ total_n_singles += n_singles
355
+ total_n_binaries += n_binaries
356
+ total_n_stars += n_singles + 2*n_binaries
357
+
358
+ # Now that we have all these initial conditions
359
+ # let's create an Evolve class and evolve these systems
360
+
361
+ # check what kind of time resolution for the bcm array the user specified
362
+
363
+ # assume none
364
+ dtp = IBT['tphysf'].values
365
+
366
+ # check
367
+ if isinstance(filters['timestep_conditions'], str):
368
+ dtp_inifile = filters['timestep_conditions'].split('=')[-1]
369
+ try:
370
+ dtp = float(dtp_inifile)
371
+ except:
372
+ pass
373
+ filters['timestep_conditions'] = []
374
+
375
+ # Create a pool
376
+ bpp, bcm, initCond, kick_info = Evolve.evolve(initialbinarytable=IBT,
377
+ pool=pool,
378
+ BSEDict=BSEDict,
379
+ idx=idx,
380
+ dtp=dtp,
381
+ timestep_conditions=filters['timestep_conditions'])
382
+
383
+ # get any nans and pull them out for now
384
+ nans = np.isnan(bpp.sep)
385
+ if nans.any():
386
+ nan_bin_nums = np.unique(bpp[nans]["bin_num"].values)
387
+ initCond_nan = initCond.loc[initCond.bin_num.isin(nan_bin_nums)]
388
+ if pd.__version__<="2.0.0":
389
+ dat_store.append("nan_initC", initCond_nan)
390
+ else:
391
+ dat_store["nan_initC"] = initCond_nan
392
+ log_file.write(f"There are {len(nan_bin_nums)} NaNs stored in the datfile with key: 'nan_initC'")
393
+ log_file.write(f"These NaNs likely arise because you have pts1 = 0.001, try running with pts1 = 0.01")
394
+
395
+ bcm = bcm.loc[~bcm.bin_num.isin(nan_bin_nums)]
396
+ bpp = bpp.loc[~bpp.bin_num.isin(nan_bin_nums)]
397
+ initCond = initCond.loc[~initCond.bin_num.isin(nan_bin_nums)]
398
+ kick_info = kick_info.loc[~kick_info.bin_num.isin(nan_bin_nums)]
399
+
400
+ # Keep track of the index
401
+ idx = int(bcm.bin_num.max()+1)
402
+
403
+ # If dtp is not set, filter out first timestep in bcm
404
+ if np.all(dtp == IBT['tphysf'].values):
405
+ bcm = bcm.loc[bcm['tphys'].isin(dtp)]
406
+
407
+ # Now get the converging population and bin_nums for conv systems whic
408
+ # satisfy the convergence_limits
409
+ conv_filter, conv_lims_bin_num = utils.conv_select(bcm, bpp,
410
+ kstar1_range, kstar2_range,
411
+ convergence['pop_select'],
412
+ convergence['convergence_limits'])
413
+ if conv_filter.empty:
414
+ warnings.warn("After filtering for desired convegence systems there were no systems matching your request. It is possible you are suggesting incompatible bin_state choices and pop_select, e.g. bin_state=[0,1], pop_select='disruption'")
415
+ log_file.write("After filtering for desired convegence systems there were no systems matching your request. It is possible you are suggesting incompatible bin_state choices and pop_select, e.g. bin_state=[0,1], pop_select='disruption'")
416
+
417
+ bcm_filter = bcm.loc[bcm.bin_num.isin(conv_filter.bin_num)]
418
+ bpp_filter = bpp.loc[bpp.bin_num.isin(conv_filter.bin_num)]
419
+ initC_filter = initCond.loc[initCond.bin_num.isin(conv_filter.bin_num)]
420
+ kick_info_filter = kick_info.loc[kick_info.bin_num.isin(conv_filter.bin_num)]
421
+
422
+ # Filter the bin_state based on user specified filters
423
+ bcm_filter, bin_state_nums = utils.filter_bin_state(bcm_filter, bpp_filter, filters, kstar1_range, kstar2_range)
424
+ if bcm_filter.empty:
425
+ warnings.warn("After filtering the bcm array for desired systems there were no systems matching your request. It is possible you should up to the number of binaries provessed in each iteration, i.e. Nstep")
426
+ log_file.write("After filtering the bcm array for desired systems there were no systems matching your request. It is possible you should up to the number of binaries provessed in each iteration, i.e. Nstep\n")
427
+ initC_filter = initC_filter.loc[initC_filter.bin_num.isin(bcm_filter.bin_num)]
428
+ kick_info_filter = kick_info_filter.loc[kick_info_filter.bin_num.isin(bcm_filter.bin_num)]
429
+ bpp_filter = bpp_filter.loc[bpp_filter.bin_num.isin(bcm_filter.bin_num)]
430
+ conv_filter = conv_filter.loc[conv_filter.bin_num.isin(bcm_filter.bin_num)]
431
+
432
+ if convergence['apply_convergence_limits'] == True:
433
+ initC_filter = initC_filter.loc[initC_filter.bin_num.isin(conv_lims_bin_num)]
434
+ kick_info_filter = kick_info_filter.loc[kick_info_filter.bin_num.isin(conv_lims_bin_num)]
435
+ bpp_filter = bpp_filter.loc[bpp_filter.bin_num.isin(conv_lims_bin_num)]
436
+
437
+ conv_filter = conv_filter.loc[conv_filter.bin_num.isin(conv_lims_bin_num)]
438
+
439
+ # Filter the bcm and bpp arrays according to user specified filters
440
+ if len(bcm_filter_match) == 0:
441
+ bcm_filter_match = bcm_filter.copy()
442
+ bpp_filter_match = bpp_filter.copy()
443
+ initC_filter_match = initC_filter.copy()
444
+ conv_filter_match = conv_filter.copy()
445
+ kick_info_filter_match = kick_info_filter.copy()
446
+ else:
447
+ bcm_filter_match = pd.concat([bcm_filter_match,bcm_filter], ignore_index=True)
448
+ bpp_filter_match = pd.concat([bpp_filter_match,bpp_filter], ignore_index=True)
449
+ initC_filter_match = pd.concat([initC_filter_match,initC_filter], ignore_index=True)
450
+ kick_info_filter_match = pd.concat([kick_info_filter_match,kick_info_filter], ignore_index=True)
451
+ conv_filter_match = pd.concat([conv_filter_match,conv_filter.loc[conv_filter.bin_num.isin(conv_lims_bin_num)]], ignore_index=True)
452
+
453
+
454
+ if len(conv_filter_match) >= np.min([50, args.Niter]):
455
+ conv_save = pd.concat([conv_save, pd.DataFrame(conv_filter_match)], ignore_index=True)
456
+
457
+ # perform the convergence
458
+ if len(conv_save) == len(conv_filter_match):
459
+ match = Match.perform_convergence(convergence['convergence_params'],
460
+ conv_save,
461
+ conv_filter_match,
462
+ log_file)
463
+ else:
464
+ match = Match.perform_convergence(convergence['convergence_params'],
465
+ conv_save,
466
+ conv_save.loc[~conv_save.bin_num.isin(conv_filter_match.bin_num)],
467
+ log_file)
468
+
469
+ match_save = pd.DataFrame(np.atleast_2d(match), columns = convergence['convergence_params'])
470
+
471
+ # write the data and the logs!
472
+ mass_list = [total_mass_singles, total_mass_binaries, total_mass_stars]
473
+ n_list = [total_n_singles, total_n_binaries, total_n_stars]
474
+ utils.pop_write(dat_store, log_file, mass_list, n_list, bcm_filter_match,
475
+ bpp_filter_match, initC_filter_match, conv_filter_match, kick_info_filter_match,
476
+ bin_state_nums, match_save, idx)
477
+
478
+ # reset the bcm_filter DataFrame
479
+ bcm_filter_match = []
480
+ bpp_filter_match = []
481
+ initC_filter_match = []
482
+ conv_filter_match = []
483
+ kick_info_filter_match = []
484
+ log_file.write('\n')
485
+ Nstep += args.Nstep
486
+ log_file.flush()
487
+ # Close the data storage file
488
+ dat_store.close()
489
+
490
+ log_file.write('All done friend!')
491
+ log_file.close()
492
+
@@ -0,0 +1,56 @@
1
+ Metadata-Version: 2.1
2
+ Name: cosmic-popsynth
3
+ Version: 3.4.15
4
+ Summary: a Python-interfaced binary population synthesis suite
5
+ Author: Scott Coughlin, Michael Zevin, Carl L. Rodriguez, Tom Wagg
6
+ Author-Email: Katelyn Breivik <katie.breivik@gmail.com>
7
+ License: MIT License
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python
14
+ Requires-Python: >=3.9
15
+ Requires-Dist: numpy
16
+ Requires-Dist: scipy
17
+ Requires-Dist: astropy
18
+ Requires-Dist: configparser
19
+ Requires-Dist: tqdm
20
+ Requires-Dist: pandas
21
+ Requires-Dist: tables
22
+ Requires-Dist: h5py
23
+ Requires-Dist: schwimmbad
24
+ Requires-Dist: matplotlib
25
+ Requires-Dist: importlib-metadata
26
+ Description-Content-Type: text/markdown
27
+
28
+ # COSMIC
29
+ COSMIC (Compact Object Synthesis and Monte Carlo Investigation Code)
30
+
31
+ COSMIC is a rapid binary population synthesis suite with a special purpose of generating realistic compact binary populations. COSMIC can also be used to evolve binaries with BSE in a python environment.
32
+
33
+ COSMIC currently implements binary evolutionary processes using BSE ([Hurley+2002](https://ui.adsabs.harvard.edu/abs/2002MNRAS.329..897H/abstract)). Several modifications have been applied to BSE to account for recent updates to binary evolution especially important to compact binary formation (e.g. metallicity-dependent stellar winds or black hole natal kick strengths). For a detailed discussion of these modifications, see [Breivik et al 2020](https://ui.adsabs.harvard.edu/abs/2020ApJ...898...71B/abstract))
34
+
35
+ <https://cosmic-popsynth.github.io/>
36
+
37
+ # Release Status
38
+
39
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3561144.svg)](https://doi.org/10.5281/zenodo.3561144)
40
+
41
+
42
+ [![PyPI version](https://badge.fury.io/py/cosmic-popsynth.svg)](https://badge.fury.io/py/cosmic-popsynth)
43
+
44
+
45
+ # Installation
46
+
47
+ The easiest method to install cosmic is using pip directly:
48
+
49
+ ```
50
+ pip install cosmic-popsynth
51
+ ```
52
+
53
+ [![Unit Test COSMIC](https://github.com/COSMIC-PopSynth/COSMIC/actions/workflows/python-package.yml/badge.svg)](https://github.com/COSMIC-PopSynth/COSMIC/actions/workflows/python-package.yml)
54
+
55
+ [![codecov](https://codecov.io/gh/COSMIC-PopSynth/COSMIC/branch/develop/graph/badge.svg)](https://codecov.io/gh/COSMIC-PopSynth/COSMIC)
56
+
@@ -0,0 +1,36 @@
1
+ cosmic_popsynth-3.4.15.dist-info/RECORD,,
2
+ cosmic_popsynth-3.4.15.dist-info/WHEEL,sha256=PyQFRynAJoyZSY4x-mzpOdkkuaJ40di4hJqN3-yAcP4,93
3
+ cosmic_popsynth-3.4.15.dist-info/METADATA,sha256=m1FGAn58pArb9ebhRM_vYQRAMFe20VkjS129vWk3pNU,2400
4
+ cosmic/test_utils.py,sha256=cu07sgDFadwpe6haD1VUhOgWTE0Xvd81qI-ICYNPNVo,10990
5
+ cosmic/evolve.py,sha256=tLkuKMmemDSPT3-SoyKTip-sySTKsnXGW2kZs2Wwof8,26252
6
+ cosmic/test_sample.py,sha256=AGulj9hI9W5K1RxwHdrdUFCoj1rFSTQOIu1zHMN3ru8,26386
7
+ cosmic/_version.py,sha256=YxPSYkb32KAHoq-kPiPuqlFrLaIfXqV9SEtzEcDGHF4,23
8
+ cosmic/get_commit_hash.py,sha256=R7eN590I9Xvf558DrieWqYVGI6IpIO2V3GDVuH9CdwU,539
9
+ cosmic/plotting.py,sha256=4NpGJgjEtrxg3LvuTfOIdp0osIWBtgNDYVPBMI6dU0A,18907
10
+ cosmic/checkstate.py,sha256=Eyb6KYcEEKDCI3t-epShXAqaeTq2oT0KfOlviGndxmc,4580
11
+ cosmic/__init__.py,sha256=mPlQFBqAI80Ckz-cSOOayPcD1LM_kfpMUjpFx2RqaC4,1111
12
+ cosmic/test_match.py,sha256=newjWr01eANC-9FIsAG9Gb8oOmvw4fpvZY0or76_vik,708
13
+ cosmic/_commit_hash.py,sha256=p4DS3n0nDFOIWf0a9vtWJ23vQ4SnM8OfV6PzGhcdtIc,57
14
+ cosmic/utils.py,sha256=CUHfEDZsN6zjSwtWenGRdaPqivO57E1kVASa5KOhbz8,61580
15
+ cosmic/test_evolve.py,sha256=F-LMODGKmXDhRcoqKOYWHHQd207ce5POuPx8UoeQibQ,5280
16
+ cosmic/filter.py,sha256=uJdSuzcHavQ2mOd8vNsyMPQUA2krssz0Th5L1s3KG0A,6644
17
+ cosmic/_evolvebin.cpython-310-darwin.so,sha256=TwnNb0VFV_sTnlUHLf8ZTwgJnadvQsCvK_1A70BCPIc,464400
18
+ cosmic/Match.py,sha256=n3AAFJdzqUCCuv6QgVZ9a710_VS0y_J_2KzJkeJcCdU,6466
19
+ cosmic/.dylibs/libgfortran.5.dylib,sha256=LHjybIabdcc7EIzzZ_Plx63WCb5z6BDSNiWteTuDPCc,1874368
20
+ cosmic/.dylibs/libquadmath.0.dylib,sha256=Lp_3MTTbOFoZa9N7vG4DAlahShgFfcIMrwW6dQIdFC8,351952
21
+ cosmic/.dylibs/libgcc_s.1.1.dylib,sha256=HIyXoLmbUJZ8TEodlcV1I2ncFaTkFid3JK2YI3ShfAg,157616
22
+ cosmic/bse_utils/__init__.py,sha256=hfPCjPwlZoPkzdxBkT-jHQ_cLf_EoMPEwYqKmhrUFCI,740
23
+ cosmic/bse_utils/zcnsts.py,sha256=-bWhm8EHX_ndOrpE9VkHV7HoHBEFxHWsE0HBtIzWygI,22271
24
+ cosmic/bse_utils/zdata.py,sha256=P-mIAgR6TkM3Y_lJJB_14Ixox8xQk_oST2qNmbWvuSE,12884
25
+ cosmic/sample/__init__.py,sha256=4brmNSsRpbUpygR_zZH643h3Ng2MZH6rtaLodQjx--s,934
26
+ cosmic/sample/initialbinarytable.py,sha256=2RAXOiSsY7WOFeBCCrTjQ2gM5miF4ckPytvZUcSYFqY,8029
27
+ cosmic/sample/initialcmctable.py,sha256=uDVERPk0H28LZ9jG6pKMMj8inFhRM81iGH5XPsOIQv8,15082
28
+ cosmic/sample/cmc/elson.py,sha256=7vUdhwseIBtjmcC81sdgErymwuefZvIgw3hB07sRNSo,13488
29
+ cosmic/sample/cmc/__init__.py,sha256=InwIN6eI6q5BnfF8-VX3Ep8gxjtsOB9QdLmssKLs1uo,740
30
+ cosmic/sample/cmc/king.py,sha256=-56VTWLcsDQaDT96Z7acIJYAHkcgOhEjixyg2Y4Mk0M,8553
31
+ cosmic/sample/sampler/__init__.py,sha256=d7kSZRoxZgEa_5-6370YVxOqRY2N5Yzk9Ql2bdVFLKs,965
32
+ cosmic/sample/sampler/independent.py,sha256=mFGopOOtEaZ-qFYIb8gczLGX8Mmoi9Nse7SbJ3I-0JU,53379
33
+ cosmic/sample/sampler/multidim.py,sha256=M2rxiganP2blcyfv55Iso_UpsY8EyqN-KoYtEqDi-Ms,34804
34
+ cosmic/sample/sampler/cmc.py,sha256=xBJNFPW8OD0NHKevAWV2zcRfLFztM5WnUMbA7bNRack,15945
35
+ cosmic/sample/sampler/sampler.py,sha256=tO8wf8IwMcoXdHur5WC4OLgYbv468rHkeR43mjkKOK4,3953
36
+ cosmic_popsynth-3.4.15.data/scripts/cosmic-pop,sha256=184O-9Wd9PSn-LD2Sz759IZncoJeK-dUtAW6Y3bk_D4,27412
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: meson
3
+ Root-Is-Purelib: false
4
+ Tag: cp310-cp310-macosx_11_0_arm64