ler 0.4.1__py3-none-any.whl → 0.4.3__py3-none-any.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.

Potentially problematic release.


This version of ler might be problematic. Click here for more details.

Files changed (35) hide show
  1. ler/__init__.py +26 -26
  2. ler/gw_source_population/__init__.py +1 -0
  3. ler/gw_source_population/cbc_source_parameter_distribution.py +1076 -818
  4. ler/gw_source_population/cbc_source_redshift_distribution.py +619 -295
  5. ler/gw_source_population/jit_functions.py +484 -9
  6. ler/gw_source_population/sfr_with_time_delay.py +107 -0
  7. ler/image_properties/image_properties.py +44 -13
  8. ler/image_properties/multiprocessing_routine.py +5 -209
  9. ler/lens_galaxy_population/__init__.py +2 -0
  10. ler/lens_galaxy_population/epl_shear_cross_section.py +0 -0
  11. ler/lens_galaxy_population/jit_functions.py +101 -9
  12. ler/lens_galaxy_population/lens_galaxy_parameter_distribution.py +817 -885
  13. ler/lens_galaxy_population/lens_param_data/density_profile_slope_sl.txt +5000 -0
  14. ler/lens_galaxy_population/lens_param_data/external_shear_sl.txt +2 -0
  15. ler/lens_galaxy_population/lens_param_data/number_density_zl_zs.txt +48 -0
  16. ler/lens_galaxy_population/lens_param_data/optical_depth_epl_shear_vd_ewoud.txt +48 -0
  17. ler/lens_galaxy_population/mp copy.py +554 -0
  18. ler/lens_galaxy_population/mp.py +736 -138
  19. ler/lens_galaxy_population/optical_depth.py +2248 -616
  20. ler/rates/__init__.py +1 -2
  21. ler/rates/gwrates.py +129 -75
  22. ler/rates/ler.py +257 -116
  23. ler/utils/__init__.py +2 -0
  24. ler/utils/function_interpolation.py +322 -0
  25. ler/utils/gwsnr_training_data_generator.py +233 -0
  26. ler/utils/plots.py +1 -1
  27. ler/utils/test.py +1078 -0
  28. ler/utils/utils.py +553 -125
  29. {ler-0.4.1.dist-info → ler-0.4.3.dist-info}/METADATA +22 -9
  30. ler-0.4.3.dist-info/RECORD +34 -0
  31. {ler-0.4.1.dist-info → ler-0.4.3.dist-info}/WHEEL +1 -1
  32. ler/rates/ler copy.py +0 -2097
  33. ler-0.4.1.dist-info/RECORD +0 -25
  34. {ler-0.4.1.dist-info → ler-0.4.3.dist-info/licenses}/LICENSE +0 -0
  35. {ler-0.4.1.dist-info → ler-0.4.3.dist-info}/top_level.txt +0 -0
ler/rates/ler.py CHANGED
@@ -4,6 +4,7 @@ This module contains the main class for calculating the rates of detectable grav
4
4
  """
5
5
 
6
6
  import os
7
+ # os.environ['OMP_NESTED'] = 'FALSE'
7
8
  import warnings
8
9
  warnings.filterwarnings("ignore")
9
10
  import logging
@@ -16,12 +17,6 @@ from ..lens_galaxy_population import LensGalaxyParameterDistribution
16
17
  from ..utils import load_json, append_json, get_param_from_json, batch_handler
17
18
 
18
19
 
19
- # # multiprocessing guard code
20
- # def main():
21
- # obj = LeR()
22
-
23
- # if __name__ == '__main__':
24
-
25
20
  class LeR(LensGalaxyParameterDistribution):
26
21
  """Class to sample of lensed and unlensed events and calculate it's rates. Please note that parameters of the simulated events are stored in json file but not as an attribute of the class. This saves RAM memory.
27
22
 
@@ -59,7 +54,7 @@ class LeR(LensGalaxyParameterDistribution):
59
54
  def snr_finder(gw_param_dict):
60
55
  ...
61
56
  return optimal_snr_dict
62
- where optimal_snr_dict.keys = ['optimal_snr_net']. Refer to `gwsnr` package's GWSNR.snr attribute for more details.
57
+ where optimal_snr_dict.keys = ['snr_net']. Refer to `gwsnr` package's GWSNR.snr attribute for more details.
63
58
  pdet_finder : `function`
64
59
  default pdet_finder = None.
65
60
  The rate calculation uses either the pdet_finder or the snr_finder to calculate the detectable events. The custom pdet finder function should follow the following signature:
@@ -76,6 +71,23 @@ class LeR(LensGalaxyParameterDistribution):
76
71
  interpolator_directory : `str`
77
72
  directory to store the interpolators.
78
73
  default interpolator_directory = './interpolator_pickle'. This is used for storing the various interpolators related to `ler` and `gwsnr` package.
74
+ create_new_interpolator : `bool` or `dict`
75
+ default create_new_interpolator = False.
76
+ if True, the all interpolators (including `gwsnr`'s)will be created again.
77
+ if False, the interpolators will be loaded from the interpolator_directory if they exist.
78
+ if dict, you can specify which interpolators to create new. Complete example (change any of them to True), create_new_interpolator = create_new_interpolator = dict(
79
+ redshift_distribution=dict(create_new=False, resolution=1000),
80
+ z_to_luminosity_distance=dict(create_new=False, resolution=1000),
81
+ velocity_dispersion=dict(create_new=False, resolution=1000),
82
+ axis_ratio=dict(create_new=False, resolution=1000),
83
+ optical_depth=dict(create_new=False, resolution=200),
84
+ z_to_Dc=dict(create_new=False, resolution=1000),
85
+ Dc_to_z=dict(create_new=False, resolution=1000),
86
+ angular_diameter_distance=dict(create_new=False, resolution=1000),
87
+ differential_comoving_volume=dict(create_new=False, resolution=1000),
88
+ Dl_to_z=dict(create_new=False, resolution=1000),
89
+ gwsnr=False,
90
+ )
79
91
  ler_directory : `str`
80
92
  directory to store the parameters.
81
93
  default ler_directory = './ler_data'. This is used for storing the parameters of the simulated events.
@@ -98,7 +110,7 @@ class LeR(LensGalaxyParameterDistribution):
98
110
 
99
111
  Instance Attributes
100
112
  ----------
101
- LeR class has the following attributes, \n
113
+ LeR class has the following attributes: \n
102
114
  +-------------------------------------+----------------------------------+
103
115
  | Atrributes | Type |
104
116
  +=====================================+==================================+
@@ -141,14 +153,14 @@ class LeR(LensGalaxyParameterDistribution):
141
153
 
142
154
  Instance Methods
143
155
  ----------
144
- LeR class has the following methods, \n
156
+ LeR class has the following methods:\n
145
157
  +-------------------------------------+----------------------------------+
146
158
  | Methods | Description |
147
159
  +=====================================+==================================+
148
160
  |:meth:`~class_initialization` | Function to initialize the |
149
161
  | | parent classes |
150
162
  +-------------------------------------+----------------------------------+
151
- |:meth:`~gwsnr_intialization` | Function to initialize the |
163
+ |:meth:`~gwsnr_initialization` | Function to initialize the |
152
164
  | | gwsnr class |
153
165
  +-------------------------------------+----------------------------------+
154
166
  |:meth:`~snr` | Function to get the snr with the |
@@ -194,7 +206,7 @@ class LeR(LensGalaxyParameterDistribution):
194
206
  | | ratio between lensed and |
195
207
  | | unlensed events. |
196
208
  +-------------------------------------+----------------------------------+
197
- |:meth:`~rate_comparision_with_rate_calculation |
209
+ |:meth:`~rate_comparison_with_rate_calculation` |
198
210
  +-------------------------------------+----------------------------------+
199
211
  | | Function to calculate rates for |
200
212
  | | unleesed and lensed events and |
@@ -437,11 +449,13 @@ class LeR(LensGalaxyParameterDistribution):
437
449
  list_of_detectors=None,
438
450
  json_file_names=None,
439
451
  interpolator_directory="./interpolator_pickle",
452
+ create_new_interpolator=False,
440
453
  ler_directory="./ler_data",
441
454
  verbose=True,
442
455
  **kwargs,
443
456
  ):
444
457
 
458
+ print("\nInitializing LeR class...\n")
445
459
  self.npool = npool
446
460
  self.z_min = z_min
447
461
  self.z_max = z_max
@@ -453,6 +467,7 @@ class LeR(LensGalaxyParameterDistribution):
453
467
  if json_file_names:
454
468
  self.json_file_names.update(json_file_names)
455
469
  self.interpolator_directory = interpolator_directory
470
+ kwargs["create_new_interpolator"] = create_new_interpolator
456
471
  self.ler_directory = ler_directory
457
472
  # create directory if not exists
458
473
  if not os.path.exists(ler_directory):
@@ -463,7 +478,7 @@ class LeR(LensGalaxyParameterDistribution):
463
478
  self.class_initialization(params=kwargs)
464
479
  # initialization self.snr and self.pdet from GWSNR class
465
480
  if not snr_finder and not pdet_finder:
466
- self.gwsnr_intialization(params=kwargs)
481
+ self.gwsnr_initialization(params=kwargs)
467
482
  self.gwsnr = True
468
483
  self.pdet = pdet_finder
469
484
  else:
@@ -475,15 +490,15 @@ class LeR(LensGalaxyParameterDistribution):
475
490
  # store all the ler input parameters
476
491
  self.store_ler_params(output_jsonfile=self.json_file_names["ler_params"])
477
492
 
478
- # if verbose, prevent anything from printing
493
+ # if not verbose, prevent anything from printing
479
494
  if verbose:
480
495
  initialization()
481
- self.print_all_params()
496
+ self.print_all_params_ler()
482
497
  else:
483
498
  with contextlib.redirect_stdout(None):
484
499
  initialization()
485
500
 
486
- def print_all_params(self):
501
+ def print_all_params_ler(self):
487
502
  """
488
503
  Function to print all the parameters.
489
504
  """
@@ -514,14 +529,15 @@ class LeR(LensGalaxyParameterDistribution):
514
529
  print("\n # LeR also takes LensGalaxyParameterDistribution class params as kwargs, as follows:")
515
530
  print(f"lens_type = '{self.gw_param_sampler_dict['lens_type']}',")
516
531
  print(f"lens_functions = {self.gw_param_sampler_dict['lens_functions']},")
517
- print(f"lens_priors = {self.gw_param_sampler_dict['lens_priors']},")
518
- print(f"lens_priors_params = {self.gw_param_sampler_dict['lens_priors_params']},")
532
+ print(f"lens_param_samplers = {self.gw_param_sampler_dict['lens_param_samplers']},")
533
+ print(f"lens_param_samplers_params = {self.gw_param_sampler_dict['lens_param_samplers_params']},")
519
534
 
520
535
  print("\n # LeR also takes ImageProperties class params as kwargs, as follows:")
521
536
  print(f"n_min_images = {self.n_min_images},")
522
537
  print(f"n_max_images = {self.n_max_images},")
523
- print(f"geocent_time_min = {self.geocent_time_min},")
524
- print(f"geocent_time_max = {self.geocent_time_max},")
538
+ print(f"time_window = {self.time_window},")
539
+ # print(f"geocent_time_min = {self.geocent_time_min},")
540
+ # print(f"geocent_time_max = {self.geocent_time_max},")
525
541
  print(f"lens_model_list = {self.lens_model_list},")
526
542
 
527
543
  if self.gwsnr:
@@ -585,14 +601,16 @@ class LeR(LensGalaxyParameterDistribution):
585
601
  print("axis_ratio_params = ", self.lens_param_samplers_params["axis_ratio"])
586
602
  print(f"axis_rotation_angle = '{self.lens_param_samplers['axis_rotation_angle']}'")
587
603
  print("axis_rotation_angle_params = ", self.lens_param_samplers_params["axis_rotation_angle"])
588
- print(f"shear = '{self.lens_param_samplers['shear']}'")
589
- print("shear_params = ", self.lens_param_samplers_params["shear"])
590
- print(f"mass_density_spectral_index = '{self.lens_param_samplers['mass_density_spectral_index']}'")
591
- print("mass_density_spectral_index_params = ", self.lens_param_samplers_params["mass_density_spectral_index"])
604
+ print(f"shear = '{self.lens_param_samplers['external_shear']}'")
605
+ print("shear_params = ", self.lens_param_samplers_params['external_shear'])
606
+ print(f"density_profile_slope = '{self.lens_param_samplers['density_profile_slope']}'")
607
+ print("density_profile_slope_params = ", self.lens_param_samplers_params["density_profile_slope"])
592
608
  # lens functions
593
609
  print("Lens functions:")
594
610
  print(f"strong_lensing_condition = '{self.lens_functions['strong_lensing_condition']}'")
595
611
  print(f"optical_depth = '{self.lens_functions['optical_depth']}'")
612
+ print(f"optical_depth_params = '{self.lens_functions_params['optical_depth']}'")
613
+ print(f"param_sampler_type = '{self.lens_functions['param_sampler_type']}'")
596
614
 
597
615
  @property
598
616
  def snr(self):
@@ -724,15 +742,18 @@ class LeR(LensGalaxyParameterDistribution):
724
742
  z_max=self.z_max,
725
743
  cosmology=self.cosmo,
726
744
  event_type=self.event_type,
727
- lens_type="epl_galaxy",
745
+ lens_type="epl_shear_galaxy",
728
746
  lens_functions= None,
729
- lens_priors=None,
730
- lens_priors_params=None,
747
+ lens_functions_params=None,
748
+ lens_param_samplers=None,
749
+ lens_param_samplers_params=None,
750
+ buffer_size=1000,
731
751
  # ImageProperties class params
732
752
  n_min_images=2,
733
753
  n_max_images=4,
734
- geocent_time_min=1126259462.4,
735
- geocent_time_max=1126259462.4+365*24*3600*20,
754
+ time_window=365*24*3600*20,
755
+ # geocent_time_min=1126259462.4,
756
+ # geocent_time_max=1126259462.4+365*24*3600*20,
736
757
  lens_model_list=['EPL_NUMBA', 'SHEAR'],
737
758
  # CBCSourceParameterDistribution class params
738
759
  source_priors=None,
@@ -756,13 +777,16 @@ class LeR(LensGalaxyParameterDistribution):
756
777
  event_type=input_params["event_type"],
757
778
  lens_type=input_params["lens_type"],
758
779
  lens_functions=input_params["lens_functions"],
759
- lens_priors=input_params["lens_priors"],
760
- lens_priors_params=input_params["lens_priors_params"],
780
+ lens_functions_params=input_params["lens_functions_params"],
781
+ lens_param_samplers=input_params["lens_param_samplers"],
782
+ lens_param_samplers_params=input_params["lens_param_samplers_params"],
761
783
  n_min_images=input_params["n_min_images"],
762
784
  n_max_images=input_params["n_max_images"],
763
- geocent_time_min=input_params["geocent_time_min"],
764
- geocent_time_max=input_params["geocent_time_max"],
785
+ time_window=input_params["time_window"],
786
+ # geocent_time_min=input_params["geocent_time_min"],
787
+ # geocent_time_max=input_params["geocent_time_max"],
765
788
  lens_model_list=input_params["lens_model_list"],
789
+ buffer_size=input_params["buffer_size"],
766
790
  source_priors=input_params["source_priors"],
767
791
  source_priors_params=input_params["source_priors_params"],
768
792
  spin_zero=input_params["spin_zero"],
@@ -773,11 +797,12 @@ class LeR(LensGalaxyParameterDistribution):
773
797
 
774
798
  self.gw_param_sampler_dict["source_priors"]=self.gw_param_samplers.copy()
775
799
  self.gw_param_sampler_dict["source_priors_params"]=self.gw_param_samplers_params.copy()
776
- self.gw_param_sampler_dict["lens_priors"]=self.lens_param_samplers.copy()
777
- self.gw_param_sampler_dict["lens_priors_params"]=self.lens_param_samplers_params.copy()
800
+ self.gw_param_sampler_dict["lens_param_samplers"]=self.lens_param_samplers.copy()
801
+ self.gw_param_sampler_dict["lens_param_samplers_params"]=self.lens_param_samplers_params.copy()
778
802
  self.gw_param_sampler_dict["lens_functions"]=self.lens_functions.copy()
803
+ self.gw_param_sampler_dict["lens_functions_params"]=self.lens_functions_params.copy()
779
804
 
780
- def gwsnr_intialization(self, params=None):
805
+ def gwsnr_initialization(self, params=None):
781
806
  """
782
807
  Function to initialize the GWSNR class from the `gwsnr` package.
783
808
 
@@ -789,29 +814,55 @@ class LeR(LensGalaxyParameterDistribution):
789
814
  from gwsnr import GWSNR
790
815
 
791
816
  # initialization of GWSNR class
817
+ if 'mminbh' in self.gw_param_samplers_params['source_frame_masses']:
818
+ min_bh_mass = self.gw_param_samplers_params['source_frame_masses']['mminbh']
819
+ else:
820
+ min_bh_mass = 2.0
821
+
822
+ if 'mmaxbh' in self.gw_param_samplers_params['source_frame_masses']:
823
+ max_bh_mass = self.gw_param_samplers_params['source_frame_masses']['mmaxbh']
824
+ else:
825
+ max_bh_mass = 200.0
792
826
  input_params = dict(
827
+ # General settings
793
828
  npool=self.npool,
794
- mtot_min=2.0,
795
- mtot_max=200,
829
+ snr_method="interpolation_aligned_spins",
830
+ snr_type="optimal_snr",
831
+ gwsnr_verbose=True,
832
+ multiprocessing_verbose=True,
833
+ pdet_kwargs=None,
834
+ # Settings for interpolation grid
835
+ mtot_min=min_bh_mass*2,
836
+ mtot_max=max_bh_mass*2*(1+self.z_max) if max_bh_mass*2*(1+self.z_max)<500.0 else 500.0,
796
837
  ratio_min=0.1,
797
838
  ratio_max=1.0,
798
- mtot_resolution=500,
799
- ratio_resolution=50,
839
+ spin_max=0.99,
840
+ mtot_resolution=200,
841
+ ratio_resolution=20,
842
+ spin_resolution=10,
843
+ batch_size_interpolation=1000000,
844
+ interpolator_dir="./interpolator_pickle",
845
+ create_new_interpolator=False,
846
+ # GW signal settings
800
847
  sampling_frequency=2048.0,
801
848
  waveform_approximant="IMRPhenomD",
849
+ frequency_domain_source_model='lal_binary_black_hole',
802
850
  minimum_frequency=20.0,
803
- snr_type="interpolation",
851
+ reference_frequency=None,
852
+ duration_max=None,
853
+ duration_min=None,
854
+ fixed_duration=None,
855
+ mtot_cut=False,
856
+ # Detector settings
804
857
  psds=None,
805
858
  ifos=None,
806
- interpolator_dir=self.interpolator_directory,
807
- create_new_interpolator=False,
808
- gwsnr_verbose=False,
809
- multiprocessing_verbose=True,
810
- mtot_cut=True,
811
- pdet=False,
812
- snr_th=8.0,
813
- snr_th_net=8.0,
859
+ noise_realization=None, # not implemented yet
860
+ # ANN settings
814
861
  ann_path_dict=None,
862
+ # Hybrid SNR recalculation settings
863
+ snr_recalculation=False,
864
+ snr_recalculation_range=[6,14],
865
+ snr_recalculation_waveform_approximant="IMRPhenomXPHM",
815
866
  )
816
867
  # if self.event_type == "BNS":
817
868
  # input_params["mtot_max"]= 18.
@@ -820,37 +871,63 @@ class LeR(LensGalaxyParameterDistribution):
820
871
  if key in input_params:
821
872
  input_params[key] = value
822
873
  self.snr_calculator_dict = input_params
874
+
875
+ # dealing with create_new_interpolator param
876
+ if isinstance(input_params["create_new_interpolator"], bool):
877
+ pass
878
+ elif isinstance(input_params["create_new_interpolator"], dict):
879
+ # check input_params["gwsnr"] exists
880
+ if "gwsnr" in input_params["create_new_interpolator"]:
881
+ if isinstance(input_params["create_new_interpolator"]["gwsnr"], bool):
882
+ input_params["create_new_interpolator"] = input_params["create_new_interpolator"]["gwsnr"]
883
+ else:
884
+ raise ValueError("create_new_interpolator['gwsnr'] should be a boolean.")
885
+ else:
886
+ input_params["create_new_interpolator"] = False
887
+
888
+ # initialization of GWSNR class
823
889
  gwsnr = GWSNR(
824
- npool=input_params["npool"],
825
- mtot_min=input_params["mtot_min"],
826
- mtot_max=input_params["mtot_max"],
827
- ratio_min=input_params["ratio_min"],
828
- ratio_max=input_params["ratio_max"],
829
- mtot_resolution=input_params["mtot_resolution"],
830
- ratio_resolution=input_params["ratio_resolution"],
831
- sampling_frequency=input_params["sampling_frequency"],
832
- waveform_approximant=input_params["waveform_approximant"],
833
- minimum_frequency=input_params["minimum_frequency"],
834
- snr_type=input_params["snr_type"],
835
- psds=input_params["psds"],
836
- ifos=input_params["ifos"],
837
- interpolator_dir=input_params["interpolator_dir"],
838
- # create_new_interpolator=input_params["create_new_interpolator"],
839
- gwsnr_verbose=input_params["gwsnr_verbose"],
840
- multiprocessing_verbose=input_params["multiprocessing_verbose"],
841
- mtot_cut=input_params["mtot_cut"],
842
- pdet=input_params["pdet"],
843
- snr_th=input_params["snr_th"],
844
- snr_th_net=input_params["snr_th_net"],
845
- ann_path_dict=input_params["ann_path_dict"],
846
- )
890
+ npool=input_params["npool"],
891
+ snr_method=input_params["snr_method"],
892
+ snr_type=input_params["snr_type"],
893
+ gwsnr_verbose=input_params["gwsnr_verbose"],
894
+ multiprocessing_verbose=input_params["multiprocessing_verbose"],
895
+ pdet_kwargs=input_params["pdet_kwargs"],
896
+ mtot_min=input_params["mtot_min"],
897
+ mtot_max=input_params["mtot_max"],
898
+ ratio_min=input_params["ratio_min"],
899
+ ratio_max=input_params["ratio_max"],
900
+ spin_max=input_params["spin_max"],
901
+ mtot_resolution=input_params["mtot_resolution"],
902
+ ratio_resolution=input_params["ratio_resolution"],
903
+ spin_resolution=input_params["spin_resolution"],
904
+ batch_size_interpolation=input_params["batch_size_interpolation"],
905
+ interpolator_dir=input_params["interpolator_dir"],
906
+ create_new_interpolator=input_params["create_new_interpolator"],
907
+ sampling_frequency=input_params["sampling_frequency"],
908
+ waveform_approximant=input_params["waveform_approximant"],
909
+ frequency_domain_source_model=input_params["frequency_domain_source_model"],
910
+ minimum_frequency=input_params["minimum_frequency"],
911
+ reference_frequency=input_params["reference_frequency"],
912
+ duration_max=input_params["duration_max"],
913
+ duration_min=input_params["duration_min"],
914
+ fixed_duration=input_params["fixed_duration"],
915
+ mtot_cut=input_params["mtot_cut"],
916
+ psds=input_params["psds"],
917
+ ifos=input_params["ifos"],
918
+ noise_realization=input_params["noise_realization"],
919
+ ann_path_dict=input_params["ann_path_dict"],
920
+ snr_recalculation=input_params["snr_recalculation"],
921
+ snr_recalculation_range=input_params["snr_recalculation_range"],
922
+ snr_recalculation_waveform_approximant=input_params["snr_recalculation_waveform_approximant"],
923
+ )
847
924
 
848
- self.snr = gwsnr.snr
925
+ self.snr = gwsnr.optimal_snr
849
926
  self.list_of_detectors = gwsnr.detector_list
850
- self.snr_bilby = gwsnr.compute_bilby_snr
927
+ self.snr_bilby = gwsnr.optimal_snr_with_inner_product
851
928
  self.snr_calculator_dict["mtot_max"] = gwsnr.mtot_max
852
929
  self.snr_calculator_dict["psds"] = gwsnr.psds_list
853
- #self.pdet = gwsnr.pdet
930
+ self.pdet = gwsnr.pdet
854
931
 
855
932
  def store_ler_params(self, output_jsonfile="ler_params.json"):
856
933
  """
@@ -888,12 +965,12 @@ class LeR(LensGalaxyParameterDistribution):
888
965
  for key, value in snr_calculator_dict.items():
889
966
  snr_calculator_dict[key] = str(value)
890
967
  parameters_dict.update({"snr_calculator_dict": snr_calculator_dict})
891
-
892
- file_name = output_jsonfile
893
- append_json(self.ler_directory+"/"+file_name, parameters_dict, replace=True)
894
968
  except:
895
969
  # if snr_calculator is custom function
896
970
  pass
971
+
972
+ file_name = output_jsonfile
973
+ append_json(self.ler_directory+"/"+file_name, parameters_dict, replace=True)
897
974
 
898
975
  def unlensed_cbc_statistics(
899
976
  self, size=None, resume=False, save_batch=False, output_jsonfile=None,
@@ -910,7 +987,7 @@ class LeR(LensGalaxyParameterDistribution):
910
987
  resume = False (default) or True.
911
988
  if True, the function will resume from the last batch.
912
989
  save_batch : `bool`
913
- if True, the function will save the parameters in batches. if False, the function will save all the parameters at the end of sampling. save_batch=False is faster.
990
+ if True, the function will save the parameters in batches. if False (default), the function will save all the parameters at the end of sampling. save_batch=False is faster.
914
991
  output_jsonfile : `str`
915
992
  json file name for storing the parameters.
916
993
  default output_jsonfile = 'unlensed_params.json'. Note that this file will be stored in the self.ler_directory.
@@ -931,7 +1008,7 @@ class LeR(LensGalaxyParameterDistribution):
931
1008
  output_jsonfile = output_jsonfile or self.json_file_names["unlensed_param"]
932
1009
  self.json_file_names["unlensed_param"] = output_jsonfile
933
1010
  output_path = os.path.join(self.ler_directory, output_jsonfile)
934
- print(f"unlensed params will be store in {output_path}")
1011
+ print(f"unlensed params will be stored in {output_path}")
935
1012
 
936
1013
  unlensed_param = batch_handler(
937
1014
  size=size,
@@ -972,10 +1049,11 @@ class LeR(LensGalaxyParameterDistribution):
972
1049
  # get gw params
973
1050
  print("sampling gw source params...")
974
1051
  unlensed_param = self.sample_gw_parameters(size=size)
1052
+
975
1053
  # Get all of the signal to noise ratios
976
1054
  if self.snr:
977
1055
  print("calculating snrs...")
978
- snrs = self.snr(gw_param_dict=unlensed_param)
1056
+ snrs = self.snr(gw_param_dict=unlensed_param.copy())
979
1057
  unlensed_param.update(snrs)
980
1058
  elif self.pdet:
981
1059
  print("calculating pdet...")
@@ -1112,7 +1190,7 @@ class LeR(LensGalaxyParameterDistribution):
1112
1190
  dictionary of unlensed GW source parameters.
1113
1191
  """
1114
1192
 
1115
- snr_param = unlensed_param["optimal_snr_net"]
1193
+ snr_param = unlensed_param["snr_net"]
1116
1194
  idx_detectable = (snr_param > snr_threshold_recalculation[0]) & (snr_param < snr_threshold_recalculation[1])
1117
1195
  # reduce the size of the dict
1118
1196
  for key, value in unlensed_param.items():
@@ -1146,20 +1224,20 @@ class LeR(LensGalaxyParameterDistribution):
1146
1224
  """
1147
1225
 
1148
1226
  if self.snr:
1149
- if "optimal_snr_net" not in unlensed_param:
1150
- raise ValueError("'optimal_snr_net' not in unlensed param dict provided")
1227
+ if "snr_net" not in unlensed_param:
1228
+ raise ValueError("'snr_net' not in unlensed param dict provided")
1151
1229
  if detectability_condition == "step_function":
1152
- print("given detectability_condition == 'step_function'")
1153
- param = unlensed_param["optimal_snr_net"]
1230
+ #print("given detectability_condition == 'step_function'")
1231
+ param = unlensed_param["snr_net"]
1154
1232
  threshold = snr_threshold
1155
1233
  elif detectability_condition == "pdet":
1156
- print("given detectability_condition == 'pdet'")
1157
- param = 1 - norm.cdf(snr_threshold - unlensed_param["optimal_snr_net"])
1234
+ #print("given detectability_condition == 'pdet'")
1235
+ param = 1 - norm.cdf(snr_threshold - unlensed_param["snr_net"])
1158
1236
  unlensed_param["pdet_net"] = param
1159
1237
  threshold = pdet_threshold
1160
1238
  elif self.pdet:
1161
1239
  if "pdet_net" in unlensed_param:
1162
- print("given detectability_condition == 'pdet'")
1240
+ #print("given detectability_condition == 'pdet'")
1163
1241
  param = unlensed_param["pdet_net"]
1164
1242
  threshold = pdet_threshold
1165
1243
  else:
@@ -1375,11 +1453,12 @@ class LeR(LensGalaxyParameterDistribution):
1375
1453
  # check for invalid samples
1376
1454
  idx = lensed_param["n_images"] < 2
1377
1455
 
1378
- if np.sum(idx) == 0:
1379
- break
1380
- else:
1381
- print(f"Invalid sample found. Resampling {np.sum(idx)} lensed events...")
1382
- size = np.sum(idx)
1456
+ # if np.sum(idx) == 0:
1457
+ # break
1458
+ # else:
1459
+ # print(f"Invalid sample found. Resampling {np.sum(idx)} lensed events...")
1460
+ # size = np.sum(idx)
1461
+ break
1383
1462
 
1384
1463
  # Get all of the signal to noise ratios
1385
1464
  if self.snr:
@@ -1488,6 +1567,8 @@ class LeR(LensGalaxyParameterDistribution):
1488
1567
  # find index of detectable events
1489
1568
  snr_hit = self._find_detectable_index_lensed(lensed_param, snr_threshold, pdet_threshold, num_img, detectability_condition, combine_image_snr=combine_image_snr, snr_cut_for_combine_image_snr=snr_cut_for_combine_image_snr)
1490
1569
 
1570
+ # select according to time delay
1571
+
1491
1572
  # montecarlo integration
1492
1573
  total_rate = self.rate_function(np.sum(snr_hit), total_events, param_type="lensed")
1493
1574
 
@@ -1556,10 +1637,10 @@ class LeR(LensGalaxyParameterDistribution):
1556
1637
  snr_threshold_recalculation_max, _ = self._check_snr_threshold_lensed(snr_threshold_recalculation[1], num_img)
1557
1638
 
1558
1639
  # check optimal_snr_net is provided in dict
1559
- if "optimal_snr_net" not in lensed_param:
1640
+ if "snr_net" not in lensed_param:
1560
1641
  raise ValueError("optimal_snr_net not provided in lensed_param dict. Exiting...")
1561
1642
 
1562
- snr_param = lensed_param["optimal_snr_net"]
1643
+ snr_param = lensed_param["snr_net"]
1563
1644
  snr_param = -np.sort(-snr_param, axis=1) # sort snr in descending order
1564
1645
 
1565
1646
  # for each row: choose a threshold and check if the number of images above threshold. Sum over the images. If sum is greater than num_img, then snr_hit = True
@@ -1614,11 +1695,11 @@ class LeR(LensGalaxyParameterDistribution):
1614
1695
  boolean array to store the result of the threshold condition.
1615
1696
  """
1616
1697
 
1617
- print(f"given detectability_condition == {detectability_condition}")
1698
+ #print(f"given detectability_condition == {detectability_condition}")
1618
1699
  if detectability_condition == "step_function":
1619
- if "optimal_snr_net" not in lensed_param:
1620
- raise ValueError("'optimal_snr_net' not in lensed parm dict provided")
1621
- snr_param = lensed_param["optimal_snr_net"]
1700
+ if "snr_net" not in lensed_param:
1701
+ raise ValueError("'snr_net' not in lensed parm dict provided")
1702
+ snr_param = lensed_param["snr_net"]
1622
1703
  snr_param = -np.sort(-snr_param, axis=1) # sort snr in descending order
1623
1704
  snr_hit = np.full(len(snr_param), True) # boolean array to store the result of the threshold condition
1624
1705
 
@@ -1634,6 +1715,7 @@ class LeR(LensGalaxyParameterDistribution):
1634
1715
  for i, snr_th in enumerate(snr_threshold):
1635
1716
  idx_max = idx_max + num_img[i]
1636
1717
  snr_hit = snr_hit & (np.sum((snr_param[:,j:idx_max] > snr_th), axis=1) >= num_img[i])
1718
+ # select according to time delays
1637
1719
  j = idx_max
1638
1720
  else:
1639
1721
  # sqrt of the the sum of the squares of the snr of the images
@@ -1643,12 +1725,12 @@ class LeR(LensGalaxyParameterDistribution):
1643
1725
 
1644
1726
  elif detectability_condition == "pdet":
1645
1727
  if "pdet_net" not in lensed_param:
1646
- if "optimal_snr_net" not in lensed_param:
1647
- raise ValueError("'optimal_snr_net' or 'pdet_net' not in lensed parm dict provided")
1728
+ if "snr_net" not in lensed_param:
1729
+ raise ValueError("'snr_net' or 'pdet_net' not in lensed parm dict provided")
1648
1730
  else:
1649
- print("calculating pdet using 'optimal_snr_net'...")
1731
+ print("calculating pdet using 'snr_net'...")
1650
1732
  # pdet dimension is (size, n_max_images)
1651
- snr_param = lensed_param["optimal_snr_net"]
1733
+ snr_param = lensed_param["snr_net"]
1652
1734
  snr_param = -np.sort(-snr_param, axis=1) # sort snr in descending order
1653
1735
 
1654
1736
  # column index beyong np.sum(num_img)-1 are not considered
@@ -1670,7 +1752,7 @@ class LeR(LensGalaxyParameterDistribution):
1670
1752
 
1671
1753
  return snr_hit
1672
1754
 
1673
- def rate_comparision_with_rate_calculation(
1755
+ def rate_comparison_with_rate_calculation(
1674
1756
  self,
1675
1757
  unlensed_param=None,
1676
1758
  snr_threshold_unlensed=8.0,
@@ -1733,7 +1815,7 @@ class LeR(LensGalaxyParameterDistribution):
1733
1815
  >>> ler = LeR()
1734
1816
  >>> ler.unlensed_cbc_statistics();
1735
1817
  >>> ler.lensed_cbc_statistics();
1736
- >>> rate_ratio, unlensed_param, lensed_param = ler.rate_comparision_with_rate_calculation()
1818
+ >>> rate_ratio, unlensed_param, lensed_param = ler.rate_comparison_with_rate_calculation()
1737
1819
  """
1738
1820
 
1739
1821
  # call json_file_ler_param and add the results
@@ -1807,13 +1889,17 @@ class LeR(LensGalaxyParameterDistribution):
1807
1889
  self,
1808
1890
  size=100,
1809
1891
  batch_size=None,
1892
+ stopping_criteria=dict(
1893
+ relative_diff_percentage=0.5,
1894
+ number_of_last_batches_to_check=4,
1895
+ ),
1810
1896
  snr_threshold=8.0,
1811
1897
  pdet_threshold=0.5,
1812
1898
  resume=False,
1813
1899
  output_jsonfile="n_unlensed_param_detectable.json",
1814
1900
  meta_data_file="meta_unlensed.json",
1815
1901
  detectability_condition="step_function",
1816
- trim_to_size=True,
1902
+ trim_to_size=False,
1817
1903
  snr_recalculation=False,
1818
1904
  snr_threshold_recalculation=[4, 12],
1819
1905
  ):
@@ -1873,7 +1959,8 @@ class LeR(LensGalaxyParameterDistribution):
1873
1959
  n, events_total, output_path, meta_data_path, buffer_file, batch_size = self._initial_setup_for_n_event_selection(meta_data_file, output_jsonfile, resume, batch_size)
1874
1960
 
1875
1961
  # loop until n samples are collected
1876
- while n < size:
1962
+ continue_condition = True
1963
+ while continue_condition:
1877
1964
  # disable print statements
1878
1965
  with contextlib.redirect_stdout(None):
1879
1966
  self.dict_buffer = None # this is used to store the sampled unlensed_param in batches when running the sampling_routine
@@ -1898,7 +1985,31 @@ class LeR(LensGalaxyParameterDistribution):
1898
1985
  total_rate = self.rate_function(n, events_total, param_type="unlensed", verbose=False)
1899
1986
 
1900
1987
  # bookmark
1901
- self._append_meta_data(meta_data_path, n, events_total, total_rate)
1988
+ buffer_dict = self._append_meta_data(meta_data_path, n, events_total, total_rate)
1989
+
1990
+ if isinstance(stopping_criteria, dict):
1991
+ total_rates = np.array(buffer_dict['total_rate'])
1992
+ limit = stopping_criteria['relative_diff_percentage']
1993
+ num_a = stopping_criteria['number_of_last_batches_to_check']
1994
+ if len(total_rates)>num_a:
1995
+ num_a = int(-1*(num_a))
1996
+ # num_b = int(num_a)
1997
+ percentage_diff = np.abs((total_rates[num_a:]-total_rates[-1])/total_rates[-1])*100
1998
+ print(f"percentage difference for the last {abs(num_a)} batches = {percentage_diff}")
1999
+ if np.any(percentage_diff>limit):
2000
+ continue_condition &= True
2001
+ else:
2002
+ print(rf"stopping criteria of rate relative difference of {limit}% reached. If you want to collect more events, reduce stopping_criteria['relative_diff_percentage'] or put stopping_criteria=None.")
2003
+ continue_condition &= False
2004
+
2005
+ if isinstance(size, int):
2006
+ if n<size:
2007
+ continue_condition |= True
2008
+ else:
2009
+ print(rf"Given size={size} reached")
2010
+ continue_condition |= False
2011
+ if stopping_criteria is None:
2012
+ continue_condition &= False
1902
2013
 
1903
2014
  print(f"stored detectable unlensed params in {output_path}")
1904
2015
  print(f"stored meta data in {meta_data_path}")
@@ -1926,6 +2037,10 @@ class LeR(LensGalaxyParameterDistribution):
1926
2037
  def selecting_n_lensed_detectable_events(
1927
2038
  self,
1928
2039
  size=100,
2040
+ stopping_criteria=dict(
2041
+ relative_diff_percentage=0.5,
2042
+ number_of_last_batches_to_check=4,
2043
+ ),
1929
2044
  batch_size=None,
1930
2045
  snr_threshold=[8.0,8.0],
1931
2046
  pdet_threshold=0.5,
@@ -1936,7 +2051,7 @@ class LeR(LensGalaxyParameterDistribution):
1936
2051
  detectability_condition="step_function",
1937
2052
  output_jsonfile="n_lensed_params_detectable.json",
1938
2053
  meta_data_file="meta_lensed.json",
1939
- trim_to_size=True,
2054
+ trim_to_size=False,
1940
2055
  nan_to_num=False,
1941
2056
  snr_recalculation=False,
1942
2057
  snr_threshold_recalculation=[[4,4],[12,12]],
@@ -2005,7 +2120,8 @@ class LeR(LensGalaxyParameterDistribution):
2005
2120
  # re-analyse the provided snr_threshold and num_img
2006
2121
  snr_threshold, num_img = self._check_snr_threshold_lensed(snr_threshold, num_img)
2007
2122
 
2008
- while n < size:
2123
+ continue_condition = True
2124
+ while continue_condition:
2009
2125
  # disable print statements
2010
2126
  with contextlib.redirect_stdout(None):
2011
2127
  self.dict_buffer = None # this is used to store the sampled lensed_param in batches when running the sampling_routine
@@ -2030,7 +2146,30 @@ class LeR(LensGalaxyParameterDistribution):
2030
2146
  total_rate = self.rate_function(n, events_total, param_type="lensed", verbose=False)
2031
2147
 
2032
2148
  # save meta data
2033
- self._append_meta_data(meta_data_path, n, events_total, total_rate)
2149
+ buffer_dict = self._append_meta_data(meta_data_path, n, events_total, total_rate)
2150
+
2151
+ if isinstance(stopping_criteria, dict):
2152
+ total_rates = np.array(buffer_dict['total_rate'])
2153
+ limit = stopping_criteria['relative_diff_percentage']
2154
+ num_a = stopping_criteria['number_of_last_batches_to_check']
2155
+
2156
+ if len(total_rates)>num_a:
2157
+ num_a = int(-1*(num_a))
2158
+ # num_b = int(num_a)
2159
+ percentage_diff = np.abs((total_rates[num_a:]-total_rates[-1])/total_rates[-1])*100
2160
+ print(f"percentage difference for the last {abs(num_a)} batches = {percentage_diff}")
2161
+ if np.any(percentage_diff>limit):
2162
+ continue_condition &= True
2163
+ else:
2164
+ print(rf"stopping criteria of rate relative difference of {limit}% reached. If you want to collect more events, reduce stopping_criteria['relative_diff_percentage']")
2165
+ continue_condition &= False
2166
+
2167
+ if isinstance(size, int):
2168
+ if n<size:
2169
+ continue_condition |= True
2170
+ else:
2171
+ print(rf"Given size={size} reached")
2172
+ continue_condition |= False
2034
2173
 
2035
2174
  print(f"storing detectable lensed params in {output_path}")
2036
2175
  print(f"storing meta data in {meta_data_path}")
@@ -2050,7 +2189,7 @@ class LeR(LensGalaxyParameterDistribution):
2050
2189
  meta = get_param_from_json(meta_data_path)
2051
2190
  data["detectable_lensed_rate_per_year"] = meta["total_rate"][-1]
2052
2191
  data["detectability_condition_lensed"] = detectability_condition
2053
- append_json(self.ler_directory+"/"+self.json_file_names["ler_params"], data, replace=True)
2192
+ buffer_dict = append_json(self.ler_directory+"/"+self.json_file_names["ler_params"], data, replace=True)
2054
2193
 
2055
2194
  return param_final
2056
2195
 
@@ -2198,12 +2337,14 @@ class LeR(LensGalaxyParameterDistribution):
2198
2337
 
2199
2338
  if os.path.exists(meta_data_path):
2200
2339
  try:
2201
- append_json(meta_data_path, meta_data, replace=False)
2340
+ dict_ = append_json(meta_data_path, meta_data, replace=False)
2202
2341
  except:
2203
- append_json(meta_data_path, meta_data, replace=True)
2342
+ dict_ = append_json(meta_data_path, meta_data, replace=True)
2204
2343
  else:
2205
- append_json(meta_data_path, meta_data, replace=True)
2344
+ dict_ = append_json(meta_data_path, meta_data, replace=True)
2206
2345
 
2207
2346
  print("collected number of detectable events = ", n)
2208
2347
  print("total number of events = ", events_total)
2209
- print(f"total rate (yr^-1): {total_rate}")
2348
+ print(f"total rate (yr^-1): {total_rate}")
2349
+
2350
+ return dict_