diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 4f12b4a0..705fc2e6 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: [3.8, 3.9] + python: ['3.9','3.10'] toxenv: [test, test-alldeps, test-astropydev] steps: - name: Check out repository diff --git a/.gitignore b/.gitignore index ababfd94..288aab86 100644 --- a/.gitignore +++ b/.gitignore @@ -170,5 +170,3 @@ zdm/untitled10.py *.DS_Store papers/H0_I/Analysis/Real/minicube_real.src - - diff --git a/papers/F/Analysis/CRACO/Cloud/OutputMini/nautilus_craco_mini.yaml b/papers/F/Analysis/CRACO/Cloud/OutputMini/nautilus_craco_mini.yaml new file mode 100644 index 00000000..bbd22a88 --- /dev/null +++ b/papers/F/Analysis/CRACO/Cloud/OutputMini/nautilus_craco_mini.yaml @@ -0,0 +1,80 @@ +# 25 processors on mini for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: xavier-zdm-craco-full-3rd-10 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "25" + memory: "8Gi" # + ephemeral-storage: 50Gi # + limits: + cpu: "27" + memory: "12Gi" + ephemeral-storage: 100Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB/FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd papers/F/Analysis/CRACO/Cloud; + python run_craco_full.py -n 25 -t 25 -b 1; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/mini/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/CRACO/Cloud/OutputMini1.0/nautilus_craco_mini.yaml b/papers/F/Analysis/CRACO/Cloud/OutputMini1.0/nautilus_craco_mini.yaml new file mode 100644 index 00000000..bbd22a88 --- /dev/null +++ b/papers/F/Analysis/CRACO/Cloud/OutputMini1.0/nautilus_craco_mini.yaml @@ -0,0 +1,80 @@ +# 25 processors on mini for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: xavier-zdm-craco-full-3rd-10 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "25" + memory: "8Gi" # + ephemeral-storage: 50Gi # + limits: + cpu: "27" + memory: "12Gi" + ephemeral-storage: 100Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB/FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd papers/F/Analysis/CRACO/Cloud; + python run_craco_full.py -n 25 -t 25 -b 1; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/mini/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/CRACO/Cloud/nautilus_craco_full_logF.yaml b/papers/F/Analysis/CRACO/Cloud/nautilus_craco_full_logF.yaml new file mode 100644 index 00000000..f0d6f971 --- /dev/null +++ b/papers/F/Analysis/CRACO/Cloud/nautilus_craco_full_logF.yaml @@ -0,0 +1,81 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: x-zdm-craco-full-logf +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "21" + memory: "8Gi" # + ephemeral-storage: 50Gi # + limits: + cpu: "23" + memory: "12Gi" + ephemeral-storage: 100Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd papers/F/Analysis/CRACO/Cloud; + mkdir Output; + python run_craco_full_logF.py -n 21 -t 21 -b 1; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/full/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/CRACO/Cloud/nautilus_craco_mini_logF.yaml b/papers/F/Analysis/CRACO/Cloud/nautilus_craco_mini_logF.yaml new file mode 100644 index 00000000..eee30a1d --- /dev/null +++ b/papers/F/Analysis/CRACO/Cloud/nautilus_craco_mini_logF.yaml @@ -0,0 +1,80 @@ +# 25 processors on mini for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jay-zdm-craco-mini-logf +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "25" + memory: "8Gi" # + ephemeral-storage: 50Gi # + limits: + cpu: "27" + memory: "12Gi" + ephemeral-storage: 100Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout logF; + python setup.py develop; + cd papers/F/Analysis/CRACO/Cloud; + python run_craco_mini_logF.py -n 25 -t 25 -b 1; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/mini/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/CRACO/Cloud/run_craco_H0_logF.py b/papers/F/Analysis/CRACO/Cloud/run_craco_H0_logF.py new file mode 100644 index 00000000..8403c574 --- /dev/null +++ b/papers/F/Analysis/CRACO/Cloud/run_craco_H0_logF.py @@ -0,0 +1,133 @@ +""" +This script generates the `.csv` files for a 2D synthetic likelihood cube using the CRACO data (only H0 and log_{10}F). +""" + +# It should be possible to remove all the matplotlib calls from this +# but in the current implementation it is not removed. +import argparse +import numpy as np +import os, sys +from pkg_resources import resource_filename + +from concurrent.futures import ProcessPoolExecutor +import subprocess + +from zdm import iteration as it +from zdm import io + +from IPython import embed + + +def main( + pargs, + pfile: str, + oproot: str, + NFRB: int = None, + iFRB: int = 0, + outdir: str = "Output", +): + + # Generate the folder? + if not os.path.isdir(outdir): + os.mkdir(outdir) + + ############## Load up ############## + input_dict = io.process_jfile(pfile) + + # Deconstruct the input_dict + state_dict, cube_dict, vparam_dict = it.parse_input_dict(input_dict) + + npoints = np.array([item["n"] for key, item in vparam_dict.items()]) + ntotal = int(np.prod(np.abs(npoints))) + + # Total number of CPUs to be running on this Cube + total_ncpu = pargs.ncpu if pargs.total_ncpu is None else pargs.total_ncpu + batch = 1 if pargs.batch is None else pargs.batch + + nper_cpu = ntotal // total_ncpu + if int(ntotal / total_ncpu) != nper_cpu: + raise IOError(f"Ncpu={total_ncpu} must divide evenly into ntotal={ntotal}") + + survey_file = os.path.join( + resource_filename("zdm", "craco"), "MC_F", "Surveys", "F_0.32_survey" + ) + commands = [] + for kk in range(pargs.ncpu): + line = [] + # Which CPU is running out of the total? + iCPU = (batch - 1) * pargs.ncpu + kk + outfile = os.path.join(outdir, oproot.replace(".csv", f"{iCPU+1}.csv")) + # Command + line = [ + "zdm_build_cube", + "-n", + f"{iCPU+1}", + "-m", + f"{nper_cpu}", + "-o", + f"{outfile}", + "-s", + f"{survey_file}", + "--clobber", + "-p", + f"{pfile}", + ] + # NFRB? + if NFRB is not None: + line += [f"--NFRB", f"{NFRB}"] + # iFRB? + if iFRB > 0: + line += [f"--iFRB", f"{iFRB}"] + # Finish + # line += ' & \n' + commands.append(line) + + # Launch em! + processes = [] + + for command in commands: + # Popen + print(f"Running this command: {' '.join(command)}") + pw = subprocess.Popen(command) + processes.append(pw) + + # Wait on em! + for pw in processes: + pw.wait() + + print("All done!") + + +def parse_option(): + # test for command-line arguments here + parser = argparse.ArgumentParser() + parser.add_argument( + "-n", + "--ncpu", + type=int, + required=True, + help="Number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-t", + "--total_ncpu", + type=int, + required=False, + help="Total number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-b", "--batch", type=int, default=1, required=False, help="Batch number" + ) + # parser.add_argument('--NFRB',type=int,required=False,help="Number of FRBs to analzye") + # parser.add_argument('--iFRB',type=int,default=0,help="Initial FRB to run from") + args = parser.parse_args() + + return args + + +if __name__ == "__main__": + # get the argument of training. + pfile = "../Cubes/craco_H0_logF_cube.json" + oproot = "craco_H0_logF.csv" + pargs = parse_option() + main(pargs, pfile, oproot, NFRB=100, iFRB=100) diff --git a/papers/F/Analysis/CRACO/Cloud/run_craco_full_logF.py b/papers/F/Analysis/CRACO/Cloud/run_craco_full_logF.py new file mode 100644 index 00000000..7c4cdb3b --- /dev/null +++ b/papers/F/Analysis/CRACO/Cloud/run_craco_full_logF.py @@ -0,0 +1,132 @@ +""" +This script generates the `.csv` files for a synthetic likelihood cube using the CRACO data (see Baptista+23) +""" + +# It should be possible to remove all the matplotlib calls from this +# but in the current implementation it is not removed. +import argparse +import numpy as np +import os, sys +from pkg_resources import resource_filename + +from concurrent.futures import ProcessPoolExecutor +import subprocess + +from zdm import iteration as it +from zdm import io + +from IPython import embed + + +def main( + pargs, + pfile: str, + oproot: str, + NFRB: int = None, + iFRB: int = 0, + outdir: str = "Output", +): + + # Generate the folder? + if not os.path.isdir(outdir): + os.mkdir(outdir) + + ############## Load up ############## + input_dict = io.process_jfile(pfile) + + # Deconstruct the input_dict + state_dict, cube_dict, vparam_dict = it.parse_input_dict(input_dict) + + npoints = np.array([item["n"] for key, item in vparam_dict.items()]) + ntotal = int(np.prod(np.abs(npoints))) + + # Total number of CPUs to be running on this Cube + total_ncpu = pargs.ncpu if pargs.total_ncpu is None else pargs.total_ncpu + batch = 1 if pargs.batch is None else pargs.batch + + nper_cpu = ntotal // total_ncpu + if int(ntotal / total_ncpu) != nper_cpu: + raise IOError(f"Ncpu={total_ncpu} must divide evenly into ntotal={ntotal}") + + survey_file = os.path.join(resource_filename('zdm', 'craco'), + 'MC_F', 'Surveys', 'F_0.32_survey') + commands = [] + for kk in range(pargs.ncpu): + line = [] + # Which CPU is running out of the total? + iCPU = (batch - 1) * pargs.ncpu + kk + outfile = os.path.join(outdir, oproot.replace(".csv", f"{iCPU+1}.csv")) + # Command + line = [ + "zdm_build_cube", + "-n", + f"{iCPU+1}", + "-m", + f"{nper_cpu}", + "-o", + f"{outfile}", + "-s", + f"{survey_file}", + "--clobber", + "-p", + f"{pfile}", + ] + # NFRB? + if NFRB is not None: + line += [f"--NFRB", f"{NFRB}"] + # iFRB? + if iFRB > 0: + line += [f"--iFRB", f"{iFRB}"] + # Finish + # line += ' & \n' + commands.append(line) + + # Launch em! + processes = [] + + for command in commands: + # Popen + print(f"Running this command: {' '.join(command)}") + pw = subprocess.Popen(command) + processes.append(pw) + + # Wait on em! + for pw in processes: + pw.wait() + + print("All done!") + + +def parse_option(): + # test for command-line arguments here + parser = argparse.ArgumentParser() + parser.add_argument( + "-n", + "--ncpu", + type=int, + required=True, + help="Number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-t", + "--total_ncpu", + type=int, + required=False, + help="Total number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-b", "--batch", type=int, default=1, required=False, help="Batch number" + ) + # parser.add_argument('--NFRB',type=int,required=False,help="Number of FRBs to analzye") + # parser.add_argument('--iFRB',type=int,default=0,help="Initial FRB to run from") + args = parser.parse_args() + + return args + + +if __name__ == "__main__": + # get the argument of training. + pfile = "../Cubes/craco_full_cube.json" + oproot = "craco_full.csv" + pargs = parse_option() + main(pargs, pfile, oproot, NFRB=100, iFRB=100) diff --git a/papers/F/Analysis/CRACO/Cloud/run_craco_mini_logF.py b/papers/F/Analysis/CRACO/Cloud/run_craco_mini_logF.py new file mode 100644 index 00000000..64b1174b --- /dev/null +++ b/papers/F/Analysis/CRACO/Cloud/run_craco_mini_logF.py @@ -0,0 +1,132 @@ +""" +This script generates the `.csv` files for a miniature synthetic likelihood cube using the CRACO data. +""" + +# It should be possible to remove all the matplotlib calls from this +# but in the current implementation it is not removed. +import argparse +import numpy as np +import os, sys +from pkg_resources import resource_filename + +from concurrent.futures import ProcessPoolExecutor +import subprocess + +from zdm import iteration as it +from zdm import io + +from IPython import embed + + +def main( + pargs, + pfile: str, + oproot: str, + NFRB: int = None, + iFRB: int = 0, + outdir: str = "Output", +): + + # Generate the folder? + if not os.path.isdir(outdir): + os.mkdir(outdir) + + ############## Load up ############## + input_dict = io.process_jfile(pfile) + + # Deconstruct the input_dict + state_dict, cube_dict, vparam_dict = it.parse_input_dict(input_dict) + + npoints = np.array([item["n"] for key, item in vparam_dict.items()]) + ntotal = int(np.prod(np.abs(npoints))) + + # Total number of CPUs to be running on this Cube + total_ncpu = pargs.ncpu if pargs.total_ncpu is None else pargs.total_ncpu + batch = 1 if pargs.batch is None else pargs.batch + + nper_cpu = ntotal // total_ncpu + if int(ntotal / total_ncpu) != nper_cpu: + raise IOError(f"Ncpu={total_ncpu} must divide evenly into ntotal={ntotal}") + + survey_file = os.path.join(resource_filename('zdm', 'craco'), + 'MC_F', 'Surveys', 'F_0.32_survey') + commands = [] + for kk in range(pargs.ncpu): + line = [] + # Which CPU is running out of the total? + iCPU = (batch - 1) * pargs.ncpu + kk + outfile = os.path.join(outdir, oproot.replace(".csv", f"{iCPU+1}.csv")) + # Command + line = [ + "zdm_build_cube", + "-n", + f"{iCPU+1}", + "-m", + f"{nper_cpu}", + "-o", + f"{outfile}", + "-s", + f"{survey_file}", + "--clobber", + "-p", + f"{pfile}", + ] + # NFRB? + if NFRB is not None: + line += [f"--NFRB", f"{NFRB}"] + # iFRB? + if iFRB > 0: + line += [f"--iFRB", f"{iFRB}"] + # Finish + # line += ' & \n' + commands.append(line) + + # Launch em! + processes = [] + + for command in commands: + # Popen + print(f"Running this command: {' '.join(command)}") + pw = subprocess.Popen(command) + processes.append(pw) + + # Wait on em! + for pw in processes: + pw.wait() + + print("All done!") + + +def parse_option(): + # test for command-line arguments here + parser = argparse.ArgumentParser() + parser.add_argument( + "-n", + "--ncpu", + type=int, + required=True, + help="Number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-t", + "--total_ncpu", + type=int, + required=False, + help="Total number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-b", "--batch", type=int, default=1, required=False, help="Batch number" + ) + # parser.add_argument('--NFRB',type=int,required=False,help="Number of FRBs to analzye") + # parser.add_argument('--iFRB',type=int,default=0,help="Initial FRB to run from") + args = parser.parse_args() + + return args + + +if __name__ == "__main__": + # get the argument of training. + pfile = "../Cubes/craco_mini_cube_logF.json" + oproot = "craco_mini.csv" + pargs = parse_option() + main(pargs, pfile, oproot, NFRB=100, iFRB=100) diff --git a/papers/F/Analysis/CRACO/Contour/pdelta.py b/papers/F/Analysis/CRACO/Contour/pdelta.py new file mode 100644 index 00000000..47b387e8 --- /dev/null +++ b/papers/F/Analysis/CRACO/Contour/pdelta.py @@ -0,0 +1,67 @@ +""" +Plots p(Delta = DM_cosmic / ) at a fixed redshift for different F values. +""" +import numpy as np +import zdm +import matplotlib.pyplot as plt +from frb.dm import cosmic +from zdm.pcosmic import pcosmic, get_mean_DM +from zdm.parameters import State +import scipy.stats + +# Grabs the C_0 spline from the cosmic module to ensure p(Delta) is centered at 1 +fC0 = cosmic.grab_C0_spline() + +def makePDeltaPlot_F(deltas, F, z, outfile=None): + """ + Plots p(Delta = DM_cosmic / ) at a fixed redshift for a single F value. + """ + + # Calculate sigma_DM + sigma = F / np.sqrt(z) + + # Grab C_0 spline + C0 = fC0(sigma) + + # Calculate p(Delta) + pdelta = zdm.pcosmic.pcosmic(deltas, z, F, C0) + + # Plot + fig, ax = plt.subplots(dpi=200) + ax.plot(deltas, pdelta, c="k") + if outfile is None: + outfile = f"pdelta_{F}_{z}.png" + ax.set_xlabel(r"$\Delta$") + ax.set_ylabel(r"$p(\Delta)$") + ax.set_title(f"F={F}, z={z}") + plt.savefig(outfile) + + +def makePDeltaPlot_varyF(deltas, Fs, z, colors, outfile=None): + """ + Plots p(Delta = DM_cosmic / ) at a fixed redshift for different F values. + """ + fig, ax = plt.subplots(figsize=(5, 4), dpi=200) + + for i, F in enumerate(Fs): + sigma = F / np.sqrt(z) + C0 = fC0(sigma) + pdelta = zdm.pcosmic.pcosmic(deltas, z, F, C0) + ax.plot(deltas, pdelta, c=colors[i], label=f"F = {F}") + + if outfile is None: + outfile = f"pdelta_test.png" + ax.set_xlabel(r"$\Delta$") + ax.set_ylabel(r"$p(\Delta)$") + ax.set_title(f"z={z}") + ax.legend() + plt.savefig(outfile, bbox_inches="tight") + +makePDeltaPlot_F(np.linspace(0.01, 2.5, 100), 0.32, 1) +makePDeltaPlot_F(np.linspace(0.01, 2.5, 100), 0.01, 1) +makePDeltaPlot_F(np.linspace(0.01, 2.5, 100), 1, 1) + +makePDeltaPlot_varyF( + np.linspace(0.01, 2.5, 300), [0.01, 0.9], z=0.5, colors=["r", "orange"], +) + diff --git a/papers/F/Analysis/CRACO/Cubes/craco_H0_F_cube.json b/papers/F/Analysis/CRACO/Cubes/craco_H0_F_cube.json new file mode 100644 index 00000000..752075cf --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_H0_F_cube.json @@ -0,0 +1,38 @@ +{ + "state": { + "energy": { + "luminosity_function": 3 + }, + "FRBdemo": { + "alpha_method": 1 + }, + "cosmo": { + "fix_Omega_b_h2": true + } + }, + "cube": { + "parameter_order": [ + "lC", + "F", + "H0" + ] + }, + "F": { + "DC": "IGM", + "min": 0.01, + "max": 1.0, + "n": 50 + }, + "H0": { + "DC": "cosmo", + "min": 55.0, + "max": 80.0, + "n": 50 + }, + "lC": { + "DC": "FRBdemo", + "min": -0.911, + "max": -0.911, + "n": -1 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/Cubes/craco_H0_F_state.json b/papers/F/Analysis/CRACO/Cubes/craco_H0_F_state.json new file mode 100644 index 00000000..38ba399e --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_H0_F_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.32 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/Cubes/craco_H0_logF_cube.json b/papers/F/Analysis/CRACO/Cubes/craco_H0_logF_cube.json new file mode 100644 index 00000000..f38e519c --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_H0_logF_cube.json @@ -0,0 +1,38 @@ +{ + "state": { + "energy": { + "luminosity_function": 3 + }, + "FRBdemo": { + "alpha_method": 1 + }, + "cosmo": { + "fix_Omega_b_h2": true + } + }, + "cube": { + "parameter_order": [ + "lC", + "logF", + "H0" + ] + }, + "logF": { + "DC": "IGM", + "min": -2, + "max": 0, + "n": 50 + }, + "H0": { + "DC": "cosmo", + "min": 55.0, + "max": 80.0, + "n": 50 + }, + "lC": { + "DC": "FRBdemo", + "min": -0.911, + "max": -0.911, + "n": -1 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/Cubes/craco_H0_logF_state.json b/papers/F/Analysis/CRACO/Cubes/craco_H0_logF_state.json new file mode 100644 index 00000000..6eb48772 --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_H0_logF_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "logF": 0.32 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 3 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/Cubes/craco_full_cube.json b/papers/F/Analysis/CRACO/Cubes/craco_full_cube.json new file mode 100644 index 00000000..929506d8 --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_full_cube.json @@ -0,0 +1,52 @@ +{ + "state": { + "energy": { + "luminosity_function": 3 + }, + "FRBdemo": { + "alpha_method": 1 + }, + "cosmo": { + "fix_Omega_b_h2": true + } + }, + "cube": { + "parameter_order": [ + "lC", + "lmean", + "lsigma", + "logF", + "H0" + ] + }, + "H0": { + "DC": "cosmo", + "min": 60.0, + "max": 80.0, + "n": 21 + }, + "lmean": { + "DC": "host", + "min": 1.7, + "max": 2.5, + "n": 10 + }, + "lsigma": { + "DC": "host", + "min": 0.2, + "max": 0.9, + "n": 10 + }, + "logF": { + "DC": "IGM", + "min": -1.7, + "max": 0, + "n": 30 + }, + "lC": { + "DC": "FRBdemo", + "min": -0.911, + "max": -0.911, + "n": -1 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/Cubes/craco_lm_F_cube.json b/papers/F/Analysis/CRACO/Cubes/craco_lm_F_cube.json new file mode 100644 index 00000000..47d0574f --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_lm_F_cube.json @@ -0,0 +1,38 @@ +{ + "state": { + "energy": { + "luminosity_function": 2 + }, + "FRBdemo": { + "alpha_method": 1 + }, + "cosmo": { + "fix_Omega_b_h2": true + } + }, + "cube": { + "parameter_order": [ + "lC", + "F", + "lmean" + ] + }, + "F": { + "DC": "IGM", + "min": 0.01, + "max": 1.0, + "n": 50 + }, + "lmean": { + "DC": "host", + "min": 1.7, + "max": 2.5, + "n": 50 + }, + "lC": { + "DC": "FRBdemo", + "min": -0.911, + "max": -0.911, + "n": -1 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/Cubes/craco_lm_F_state.json b/papers/F/Analysis/CRACO/Cubes/craco_lm_F_state.json new file mode 100644 index 00000000..38ba399e --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_lm_F_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.32 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/Cubes/craco_mini_cube.json b/papers/F/Analysis/CRACO/Cubes/craco_mini_cube.json new file mode 100644 index 00000000..03ab4f3c --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_mini_cube.json @@ -0,0 +1,80 @@ +{ + "state": { + "energy": { + "luminosity_function": 2 + }, + "FRBdemo": { + "alpha_method": 1 + }, + "cosmo": { + "fix_Omega_b_h2": true + } + }, + "cube": { + "parameter_order": [ + "lC", + "sfr_n", + "lmean", + "lsigma", + "F", + "alpha", + "lEmax", + "gamma", + "H0" + ] + }, + "lEmax": { + "DC": "energy", + "min": 40.5, + "max": 42.5, + "n": 10 + }, + "H0": { + "DC": "cosmo", + "min": 55.0, + "max": 80.0, + "n": 25 + }, + "alpha": { + "DC": "energy", + "min": 0.2, + "max": 2.0, + "n": 3 + }, + "gamma": { + "DC": "energy", + "min": -0.5, + "max": -1.5, + "n": 5 + }, + "sfr_n": { + "DC": "FRBdemo", + "min": 0.0, + "max": 3.0, + "n": 20 + }, + "lmean": { + "DC": "host", + "min": 1.7, + "max": 2.5, + "n": 5 + }, + "lsigma": { + "DC": "host", + "min": 0.3, + "max": 0.7, + "n": 5 + }, + "F": { + "DC": "IGM", + "min": 0.01, + "max": 0.99, + "n": 20 + }, + "lC": { + "DC": "FRBdemo", + "min": -0.911, + "max": -0.911, + "n": -1 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/Cubes/craco_mini_cube_logF.json b/papers/F/Analysis/CRACO/Cubes/craco_mini_cube_logF.json new file mode 100644 index 00000000..3a9fdde2 --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_mini_cube_logF.json @@ -0,0 +1,80 @@ +{ + "state": { + "energy": { + "luminosity_function": 3 + }, + "FRBdemo": { + "alpha_method": 1 + }, + "cosmo": { + "fix_Omega_b_h2": true + } + }, + "cube": { + "parameter_order": [ + "lC", + "sfr_n", + "alpha", + "lEmax", + "lmean", + "lsigma", + "logF", + "gamma", + "H0" + ] + }, + "lEmax": { + "DC": "energy", + "min": 40.5, + "max": 42.5, + "n": 12 + }, + "H0": { + "DC": "cosmo", + "min": 55.0, + "max": 80.0, + "n": 25 + }, + "alpha": { + "DC": "energy", + "min": 0.2, + "max": 2.0, + "n": 3 + }, + "gamma": { + "DC": "energy", + "min": -0.5, + "max": -1.5, + "n": 8 + }, + "sfr_n": { + "DC": "FRBdemo", + "min": 0.0, + "max": 3.0, + "n": 20 + }, + "lmean": { + "DC": "host", + "min": 1.7, + "max": 2.5, + "n": 5 + }, + "lsigma": { + "DC": "host", + "min": 0.3, + "max": 0.7, + "n": 5 + }, + "logF": { + "DC": "IGM", + "min": -1.7, + "max": 0, + "n": 20 + }, + "lC": { + "DC": "FRBdemo", + "min": -0.911, + "max": -0.911, + "n": -1 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/Cubes/craco_mini_cube_old.json b/papers/F/Analysis/CRACO/Cubes/craco_mini_cube_old.json new file mode 100644 index 00000000..cedf3118 --- /dev/null +++ b/papers/F/Analysis/CRACO/Cubes/craco_mini_cube_old.json @@ -0,0 +1,80 @@ +{ + "state": { + "energy": { + "luminosity_function": 2 + }, + "FRBdemo": { + "alpha_method": 1 + }, + "cosmo": { + "fix_Omega_b_h2": true + } + }, + "cube": { + "parameter_order": [ + "lC", + "sfr_n", + "alpha", + "lEmax", + "lmean", + "lsigma", + "F", + "gamma", + "H0" + ] + }, + "lEmax": { + "DC": "energy", + "min": 40.5, + "max": 42.5, + "n": 10 + }, + "H0": { + "DC": "cosmo", + "min": 55.0, + "max": 80.0, + "n": 25 + }, + "alpha": { + "DC": "energy", + "min": 0.2, + "max": 2.0, + "n": 3 + }, + "gamma": { + "DC": "energy", + "min": -0.5, + "max": -1.5, + "n": 5 + }, + "sfr_n": { + "DC": "FRBdemo", + "min": 0.0, + "max": 3.0, + "n": 20 + }, + "lmean": { + "DC": "host", + "min": 1.7, + "max": 2.5, + "n": 5 + }, + "lsigma": { + "DC": "host", + "min": 0.3, + "max": 0.7, + "n": 5 + }, + "F": { + "DC": "IGM", + "min": 0.01, + "max": 0.99, + "n": 20 + }, + "lC": { + "DC": "FRBdemo", + "min": -0.911, + "max": -0.911, + "n": -1 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/make_ll_2D_F.py b/papers/F/Analysis/CRACO/make_ll_2D_F.py new file mode 100644 index 00000000..fbb9f290 --- /dev/null +++ b/papers/F/Analysis/CRACO/make_ll_2D_F.py @@ -0,0 +1,142 @@ +""" +This script creates 2D likelihood plots given a `.npz` cube. +""" +import numpy as np +import os +import zdm +from zdm import analyze_cube as ac + +from matplotlib import pyplot as plt +from IPython import embed + +def main(verbose=False): + + # output directory + opdir="2d_figs/" + if not os.path.exists(opdir): + os.mkdir(opdir) + + # loads the cube + CubeFile='Cubes/craco_full_cube.npz' + if os.path.exists(CubeFile): + data=np.load(CubeFile) + else: + print("Could not file cube output file ",CubeFile) + print("Please obtain it from [repository]") + exit() + + if verbose: + print("Data file contains the following items") + for thing in data: + print(thing) + + lst = data.files + lldata=data["ll"] + params=data["params"] + + def get_param_values(data,params): + """ + Gets the unique values of the data from a cube output + Currently the parameter order is hard-coded + + """ + param_vals=[] + for param in params: + col=data[param] + unique=np.unique(col) + param_vals.append(unique) + return param_vals + + param_vals=get_param_values(data, params) + + # builds uvals list + uvals=[] + latexnames=[] + for ip,param in enumerate(data["params"]): + # switches for alpha + if param=="alpha": + uvals.append(data[param]*-1.) + else: + uvals.append(data[param]) + if param=="alpha": + latexnames.append('$\\alpha$') + ialpha=ip + elif param=="lEmax": + latexnames.append('$\\log_{10} E_{\\rm max}$') + elif param=="H0": + latexnames.append('$H_0$') + elif param=="gamma": + latexnames.append('$\\gamma$') + elif param=="sfr_n": + latexnames.append('$n_{\\rm sfr}$') + elif param=="lmean": + latexnames.append('$\\mu_{\\rm host}$') + elif param=="lsigma": + latexnames.append('$\\sigma_{\\rm host}$') + elif param=="logF": + latexnames.append('$\\log_{10} F$') + + #latexnames=['$\\log_{10} E_{\\rm max}$','$H_0$','$\\alpha$','$\\gamma$','$n_{\\rm sfr}$','$\\mu_{\\rm host}$','$\\sigma_{\\rm host}$'] + + list2=[] + vals2=[] + # gets Bayesian posteriors + deprecated,uw_vectors,wvectors=ac.get_bayesian_data(data["ll"]) + for i,vec in enumerate(uw_vectors): + n=np.argmax(vec) + val=uvals[i][n] + if params[i] != "logF": + list2.append(params[i]) + vals2.append(val) + else: + iF=i + + ###### NOTATION ##### + # uw: unweighted + # wH0: weighted according to H0 knowledged + # f: fixed other parameters + # B: best-fit + + ############## 2D plots at best-fit valuess ########## + + # gets the slice corresponding to the best-fit values of all other parameters + # this is 1D, so is our limit on H0 keeping all others fixed + for i,item in enumerate(list2): + + list3=np.concatenate((list2[0:i],list2[i+1:])) + vals3=np.concatenate((vals2[0:i],vals2[i+1:])) + array=ac.get_slice_from_parameters(data,list3,vals3) + + # log to lin space + array[np.isnan(array)] = -1e99 + array -= np.nanmax(array) + array = 10**array + array /= np.sum(array) + + # now have array for slice covering best-fit values + if i < iF: + modi=i + else: + modi=i+1 + #array=array.T + array=array.swapaxes(0,1) + savename=opdir+"/lls_"+params[iF]+"_"+params[modi]+".png" + +# if (latexnames[modi] == '$\\gamma$'): +# embed(header="gamma") + +# if (latexnames[modi] == '$H_0$'): +# embed(header="H0") + + if params[modi]=="alpha": + #switches order of array in alpha dimension + array=np.flip(array,axis=0) + ac.make_2d_plot(array,latexnames[modi],latexnames[iF], + -param_vals[modi],param_vals[iF], + savename=savename,norm=1) + else: + ac.make_2d_plot(array,latexnames[modi],latexnames[iF], + param_vals[modi],param_vals[iF], + savename=savename,norm=1) + +main() \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/py/craco_qck_explore.py b/papers/F/Analysis/CRACO/py/craco_qck_explore.py new file mode 100644 index 00000000..2beab5b7 --- /dev/null +++ b/papers/F/Analysis/CRACO/py/craco_qck_explore.py @@ -0,0 +1,144 @@ +""" +Generates 1D likelihood PDFs of each parameter from a `.npz` cube. + +The only argument in running the file corresponds to a hard-coded location of the `.npz` cube file. +""" +# imports +from importlib import reload +import numpy as np +import sys, os + +from zdm import analyze_cube +from zdm import iteration as it +from zdm import io +from zdm.craco import loading + +from IPython import embed + + +# sys.path.append(os.path.abspath("../../Figures/py")) + + +def main(pargs): + jroot = None + + if pargs.run == "F": + # 2D cube run with H0 and F + scube = "H0_F" + outdir = "H0_F/" + elif pargs.run == "H0_logF": + # 2D cube run with H0 and logF + scube = "H0_logF" + outdir = "H0_logF/" + # Main # + elif pargs.run == "logF_full": + # Full CRACO likelihood cube + scube = "full" + outdir = "logF_Full/" + + if jroot is None: + jroot = scube + + # Load + npdict = np.load(f"Cubes/craco_{scube}_cube.npz") + + ll_cube = npdict["ll"] + + # Deal with Nan + ll_cube[np.isnan(ll_cube)] = -1e99 + params = npdict["params"] + + # Cube parameters + ############## Load up ############## + pfile = f"Cubes/craco_{jroot}_cube.json" + input_dict = io.process_jfile(pfile) + + # Deconstruct the input_dict + state_dict, cube_dict, vparam_dict = it.parse_input_dict(input_dict) + + latexnames = [] + for ip, param in enumerate(npdict["params"]): + if param == "alpha": + latexnames.append("$\\alpha$") + ialpha = ip + elif param == "lEmax": + latexnames.append("$\\log_{10} E_{\\rm max}$") + elif param == "H0": + latexnames.append("$H_0$") + elif param == "gamma": + latexnames.append("$\\gamma$") + elif param == "sfr_n": + latexnames.append("$n_{\\rm sfr}$") + elif param == "lmean": + latexnames.append("$\\mu_{\\rm host}$") + elif param == "lsigma": + latexnames.append("$\\sigma_{\\rm host}$") + elif param == "logF": + latexnames.append("$\\log_{10} F$") + + units = [] + for ip, param in enumerate(npdict["params"]): + if param == "alpha": + units.append(" ") + ialpha = ip + elif param == "lEmax": + units.append("[$\rm erg$]") + elif param == "H0": + units.append(r"[$\rm km \, s^{-1} \, Mpc^{-1}$]") + elif param == "gamma": + units.append("") + elif param == "sfr_n": + units.append(" ") + elif param == "lmean": + units.append(r"[$\rm pc \, cm^{-3}$]") + elif param == "lsigma": + units.append(r"[$\rm pc \, cm^{-3}$]") + elif param == "logF": + units.append(" ") + + # Run Bayes + + # Offset by max + ll_cube = ll_cube - np.max(ll_cube) + + uvals, vectors, wvectors = analyze_cube.get_bayesian_data(ll_cube) + + analyze_cube.do_single_plots( + uvals, + vectors, + None, + params, + vparams_dict=vparam_dict, + outdir=outdir, + compact=True, + latexnames=latexnames, + units=units, + dolevels=True, + ) + print(f"Wrote figures to {outdir}") + + +def parse_option(): + """ + This is a function used to parse the arguments in the training. + + Returns: + args: (dict) dictionary of the arguments. + """ + import argparse + + parser = argparse.ArgumentParser("Slurping the cubes") + parser.add_argument("run", type=str, help="Run to slurp") + # parser.add_argument('--debug', default=False, action='store_true', + # help='Debug?') + args = parser.parse_args() + + return args + + +# Command line execution +if __name__ == "__main__": + pargs = parse_option() + main(pargs) + +# python py/craco_qck_explore.py logF_full \ No newline at end of file diff --git a/papers/F/Analysis/CRACO/py/slurp_craco_cubes.py b/papers/F/Analysis/CRACO/py/slurp_craco_cubes.py new file mode 100644 index 00000000..0e9a6a66 --- /dev/null +++ b/papers/F/Analysis/CRACO/py/slurp_craco_cubes.py @@ -0,0 +1,58 @@ +""" +Script to intake the `.csv` files from the CRACO runs and convert them to a single `.npz` file. + +The only argument in running the file corresponds to a hard-coded location of the `.csv` files and the cube `.json` file. +""" + +from zdm import analyze_cube + + +def main(pargs): + + if pargs.run == "logF": + # 2D cube run with H0 and logF + input_file = "Cubes/craco_H0_logF_cube.json" + prefix = "Cloud/Output_logF_test/craco_H0_logF" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_H0_logF_cube.npz", nsurveys + ) + + elif pargs.run == "logF_full": + # Full CRACO likelihood cube + input_file = "Cubes/craco_full_cube.json" + prefix = "Cloud/OutputFull/craco_full" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_full_cube.npz", nsurveys + ) + +def parse_option(): + """ + This is a function used to parse the arguments in the training. + + Returns: + args: (dict) dictionary of the arguments. + """ + import argparse + + parser = argparse.ArgumentParser("Slurping the cubes") + parser.add_argument("run", type=str, help="Run to slurp") + # parser.add_argument('--debug', default=False, action='store_true', + # help='Debug?') + args = parser.parse_args() + + return args + + +# Command line execution +if __name__ == "__main__": + + pargs = parse_option() + main(pargs) + +# python py/slurp_craco_cubes.py logF_full diff --git a/papers/F/Analysis/Real/Cloud/Output/explore.ipynb b/papers/F/Analysis/Real/Cloud/Output/explore.ipynb new file mode 100644 index 00000000..b52518b2 --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/Output/explore.ipynb @@ -0,0 +1,465 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "from astropy.table import Table\n", + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "vals = []\n", + "for k in np.arange(1, 42):\n", + " tab = pd.read_csv(f\"craco_real{k}.csv\")\n", + " vals.append(sum(np.isnan(tab.lls)))" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ True, True, True, True, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False])" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.array(vals) > 0" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "tab = pd.read_csv(f\"craco_real1.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
nH0lmeanlsigmalogFlClls0P_zDM0P_n0P_s0...P_s4N4llsP_zDMP_nP_sp_zgDMp_DMp_DMgzp_z
0060.01.7000000.2-1.72.412375-150.355133-86.329631-1.797206-62.228297...-26.3791649.442576NaNNaN-6.123600NaN-211.176497-62.387925-219.814898-53.749524
1160.01.7888890.2-1.72.418278-149.731656-85.704369-1.785950-62.241338...-26.3659259.549078NaNNaN-6.080360NaN-210.749395-61.915611-218.903642-53.761364
2260.01.8777780.2-1.72.425524-148.826293-84.981855-1.772805-62.071634...-26.3579179.681300NaNNaN-6.029858NaN-211.785455-61.390719-219.400900-53.775275
3360.01.9666670.2-1.72.434399-147.673101-84.104550-1.757618-61.810933...-26.3602719.845472NaNNaN-5.971685NaN-214.298092-60.839795-221.346279-53.791607
4460.02.0555560.2-1.72.445238-146.468667-83.000852-1.740289-61.727526...-26.37802210.049250NaNNaN-5.905850NaN-218.258692-60.314226-224.762105-53.810813
..................................................................
2995299560.02.1444440.90.02.500145-139.054689-75.620953-1.776816-61.656920...-26.94532810.936534-443.862832-287.552319-5.883120-150.427394-49.987567-60.875459-57.321778-53.541248
2996299660.02.2333330.90.02.514051-138.821522-75.333358-1.765720-61.722445...-26.99059211.159802-443.328568-286.941858-5.845273-150.541437-50.078597-60.752544-57.264777-53.566364
2997299760.02.3222220.90.02.528841-138.633355-75.093866-1.754253-61.785236...-27.03569811.399571-442.904304-286.442321-5.808792-150.653191-50.176227-60.656788-57.239071-53.593944
2998299860.02.4111110.90.02.544492-138.490891-74.903018-1.742441-61.845431...-27.08038011.656140-442.594830-286.058200-5.774229-150.762400-50.280046-60.589403-57.245302-53.624146
2999299960.02.5000000.90.02.560976-138.394547-74.761062-1.730315-61.903170...-27.12442711.929738-442.404069-285.793032-5.742150-150.868887-50.389680-60.551345-57.283896-53.657129
\n", + "

3000 rows × 39 columns

\n", + "
" + ], + "text/plain": [ + " n H0 lmean lsigma logF lC lls0 P_zDM0 \\\n", + "0 0 60.0 1.700000 0.2 -1.7 2.412375 -150.355133 -86.329631 \n", + "1 1 60.0 1.788889 0.2 -1.7 2.418278 -149.731656 -85.704369 \n", + "2 2 60.0 1.877778 0.2 -1.7 2.425524 -148.826293 -84.981855 \n", + "3 3 60.0 1.966667 0.2 -1.7 2.434399 -147.673101 -84.104550 \n", + "4 4 60.0 2.055556 0.2 -1.7 2.445238 -146.468667 -83.000852 \n", + "... ... ... ... ... ... ... ... ... \n", + "2995 2995 60.0 2.144444 0.9 0.0 2.500145 -139.054689 -75.620953 \n", + "2996 2996 60.0 2.233333 0.9 0.0 2.514051 -138.821522 -75.333358 \n", + "2997 2997 60.0 2.322222 0.9 0.0 2.528841 -138.633355 -75.093866 \n", + "2998 2998 60.0 2.411111 0.9 0.0 2.544492 -138.490891 -74.903018 \n", + "2999 2999 60.0 2.500000 0.9 0.0 2.560976 -138.394547 -74.761062 \n", + "\n", + " P_n0 P_s0 ... P_s4 N4 lls P_zDM \\\n", + "0 -1.797206 -62.228297 ... -26.379164 9.442576 NaN NaN \n", + "1 -1.785950 -62.241338 ... -26.365925 9.549078 NaN NaN \n", + "2 -1.772805 -62.071634 ... -26.357917 9.681300 NaN NaN \n", + "3 -1.757618 -61.810933 ... -26.360271 9.845472 NaN NaN \n", + "4 -1.740289 -61.727526 ... -26.378022 10.049250 NaN NaN \n", + "... ... ... ... ... ... ... ... \n", + "2995 -1.776816 -61.656920 ... -26.945328 10.936534 -443.862832 -287.552319 \n", + "2996 -1.765720 -61.722445 ... -26.990592 11.159802 -443.328568 -286.941858 \n", + "2997 -1.754253 -61.785236 ... -27.035698 11.399571 -442.904304 -286.442321 \n", + "2998 -1.742441 -61.845431 ... -27.080380 11.656140 -442.594830 -286.058200 \n", + "2999 -1.730315 -61.903170 ... -27.124427 11.929738 -442.404069 -285.793032 \n", + "\n", + " P_n P_s p_zgDM p_DM p_DMgz p_z \n", + "0 -6.123600 NaN -211.176497 -62.387925 -219.814898 -53.749524 \n", + "1 -6.080360 NaN -210.749395 -61.915611 -218.903642 -53.761364 \n", + "2 -6.029858 NaN -211.785455 -61.390719 -219.400900 -53.775275 \n", + "3 -5.971685 NaN -214.298092 -60.839795 -221.346279 -53.791607 \n", + "4 -5.905850 NaN -218.258692 -60.314226 -224.762105 -53.810813 \n", + "... ... ... ... ... ... ... \n", + "2995 -5.883120 -150.427394 -49.987567 -60.875459 -57.321778 -53.541248 \n", + "2996 -5.845273 -150.541437 -50.078597 -60.752544 -57.264777 -53.566364 \n", + "2997 -5.808792 -150.653191 -50.176227 -60.656788 -57.239071 -53.593944 \n", + "2998 -5.774229 -150.762400 -50.280046 -60.589403 -57.245302 -53.624146 \n", + "2999 -5.742150 -150.868887 -50.389680 -60.551345 -57.283896 -53.657129 \n", + "\n", + "[3000 rows x 39 columns]" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tab" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "9731a3b7ebb41545a410367c249afbc4842fd5740da82f1bd29e6ac1d7253e6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/papers/F/Analysis/Real/Cloud/nautilus_real_cube.yaml b/papers/F/Analysis/Real/Cloud/nautilus_real_cube.yaml new file mode 100644 index 00000000..0b0aa215 --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/nautilus_real_cube.yaml @@ -0,0 +1,84 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "20" + memory: "64Gi" # + ephemeral-storage: 128Gi # + limits: + cpu: "30" + memory: "80Gi" + ephemeral-storage: 200Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_craco_real.py -n 41 -t 41 -b 1; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/real/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cloud/nautilus_real_mini.yaml b/papers/F/Analysis/Real/Cloud/nautilus_real_mini.yaml new file mode 100644 index 00000000..dfc52acf --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/nautilus_real_mini.yaml @@ -0,0 +1,85 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf-mini-v2 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "21" + memory: "16Gi" # + ephemeral-storage: 50Gi # + limits: + cpu: "23" + memory: "24Gi" + ephemeral-storage: 100Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_real_mini.py -n 5 -t 5 -b 1; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/full/ --recursive --force; + sleep 600; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cloud/run_craco_real.py b/papers/F/Analysis/Real/Cloud/run_craco_real.py new file mode 100644 index 00000000..fbbb2a47 --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/run_craco_real.py @@ -0,0 +1,134 @@ +""" +This script generates the `.csv` files for the likelihood cube using real FRB observations (see Baptista+23) +""" +# It should be possible to remove all the matplotlib calls from this +# but in the current implementation it is not removed. +import argparse +import numpy as np +import os, sys +from pkg_resources import resource_filename + +from concurrent.futures import ProcessPoolExecutor +import subprocess + +from zdm import iteration as it +from zdm import io + +from IPython import embed + + +def main( + pargs, pfile: str, oproot: str, outdir: str = "Output", +): + + # Generate the folder? + if not os.path.isdir(outdir): + os.mkdir(outdir) + + ############## Load up ############## + input_dict = io.process_jfile(pfile) + + # Deconstruct the input_dict + state_dict, cube_dict, vparam_dict = it.parse_input_dict(input_dict) + + npoints = np.array([item["n"] for key, item in vparam_dict.items()]) + ntotal = int(np.prod(np.abs(npoints))) + + # Total number of CPUs to be running on this Cube + total_ncpu = pargs.ncpu if pargs.total_ncpu is None else pargs.total_ncpu + batch = 1 if pargs.batch is None else pargs.batch + + nper_cpu = ntotal // total_ncpu + if int(ntotal / total_ncpu) != nper_cpu: + raise IOError(f"Ncpu={total_ncpu} must divide evenly into ntotal={ntotal}") + + start = pargs.start + end = pargs.end + + commands = [] + + nums = range(pargs.ncpu) + + # Restrict to subset of CPUs if specified + if (start > 0) and (end > 0): + nums = np.arange(start-1, end, dtype="int") + + for kk in nums: + line = [] + # Which CPU is running out of the total? + iCPU = (batch - 1) * pargs.ncpu + kk + outfile = os.path.join(outdir, oproot.replace(".csv", f"{iCPU+1}.csv")) + # Command + line = [ + "python", + "../py/build_real_cube.py", + "-n", + f"{iCPU+1}", + "-m", + f"{nper_cpu}", + "-o", + f"{outfile}", + "--clobber", + "-p", + f"{pfile}", + ] + # Finish + # line += ' & \n' + commands.append(line) + + # Launch em! + processes = [] + + for command in commands: + # Popen + print(f"Running this command: {' '.join(command)}") + pw = subprocess.Popen(command) + processes.append(pw) + + # Wait on em! + for pw in processes: + pw.wait() + + print("All done!") + + +def parse_option(): + # test for command-line arguments here + parser = argparse.ArgumentParser() + parser.add_argument( + "-n", + "--ncpu", + type=int, + required=True, + help="Number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-t", + "--total_ncpu", + type=int, + required=False, + help="Total number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-b", "--batch", type=int, default=1, required=False, help="Batch number" + ) + + # Optional restriction to subset of cube + parser.add_argument( + "-s", "--start", type=int, default=0, required=False, help="csv to start on", + ) + parser.add_argument( + "-e", "--end", type=int, default=0, required=False, help="csv to end on (inclusive)", + ) + + args = parser.parse_args() + + return args + + +if __name__ == "__main__": + # get the argument of training. + pfile = "../Cubes/craco_real_cube.json" + oproot = "craco_real.csv" + pargs = parse_option() + main(pargs, pfile, oproot) diff --git a/papers/F/Analysis/Real/Cloud/run_real_mini.py b/papers/F/Analysis/Real/Cloud/run_real_mini.py new file mode 100644 index 00000000..24497f7a --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/run_real_mini.py @@ -0,0 +1,116 @@ +""" +This script generates the `.csv` files for a smaller likelihood cube using real FRB observations (see Baptista+23) +""" +# It should be possible to remove all the matplotlib calls from this +# but in the current implementation it is not removed. +import argparse +import numpy as np +import os, sys +from pkg_resources import resource_filename + +from concurrent.futures import ProcessPoolExecutor +import subprocess + +from zdm import iteration as it +from zdm import io + +from IPython import embed + + +def main( + pargs, pfile: str, oproot: str, outdir: str = "Output", +): + + # Generate the folder? + if not os.path.isdir(outdir): + os.mkdir(outdir) + + ############## Load up ############## + input_dict = io.process_jfile(pfile) + + # Deconstruct the input_dict + state_dict, cube_dict, vparam_dict = it.parse_input_dict(input_dict) + + npoints = np.array([item["n"] for key, item in vparam_dict.items()]) + ntotal = int(np.prod(np.abs(npoints))) + + # Total number of CPUs to be running on this Cube + total_ncpu = pargs.ncpu if pargs.total_ncpu is None else pargs.total_ncpu + batch = 1 if pargs.batch is None else pargs.batch + + nper_cpu = ntotal // total_ncpu + if int(ntotal / total_ncpu) != nper_cpu: + raise IOError(f"Ncpu={total_ncpu} must divide evenly into ntotal={ntotal}") + + commands = [] + for kk in range(pargs.ncpu): + line = [] + # Which CPU is running out of the total? + iCPU = (batch - 1) * pargs.ncpu + kk + outfile = os.path.join(outdir, oproot.replace(".csv", f"{iCPU+1}.csv")) + # Command + line = [ + "python", + "../py/build_real_cube.py", + "-n", + f"{iCPU+1}", + "-m", + f"{nper_cpu}", + "-o", + f"{outfile}", + "--clobber", + "-p", + f"{pfile}", + ] + # Finish + # line += ' & \n' + commands.append(line) + + # Launch em! + processes = [] + + for command in commands: + # Popen + print(f"Running this command: {' '.join(command)}") + pw = subprocess.Popen(command) + processes.append(pw) + + # Wait on em! + for pw in processes: + exit_code = pw.wait() + print(exit_code) + + print("All done!") + + +def parse_option(): + # test for command-line arguments here + parser = argparse.ArgumentParser() + parser.add_argument( + "-n", + "--ncpu", + type=int, + required=True, + help="Number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-t", + "--total_ncpu", + type=int, + required=False, + help="Total number of CPUs to run on (might be split in batches)", + ) + parser.add_argument( + "-b", "--batch", type=int, default=1, required=False, help="Batch number" + ) + args = parser.parse_args() + + return args + + +if __name__ == "__main__": + # get the argument of training. + pfile = "../Cubes/real_mini_cube.json" + oproot = "mini_real.csv" + pargs = parse_option() + main(pargs, pfile, oproot) diff --git a/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b1.yaml b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b1.yaml new file mode 100644 index 00000000..66e3d357 --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b1.yaml @@ -0,0 +1,84 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf-b1 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "6" + memory: "64Gi" # + ephemeral-storage: 64Gi # + limits: + cpu: "8" + memory: "80Gi" + ephemeral-storage: 80Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_craco_real.py -t 41 -n 41 -s 1 -e 5; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/real/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b2.yaml b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b2.yaml new file mode 100644 index 00000000..633b07c3 --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b2.yaml @@ -0,0 +1,84 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf-b2 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "6" + memory: "64Gi" # + ephemeral-storage: 64Gi # + limits: + cpu: "8" + memory: "80Gi" + ephemeral-storage: 80Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_real_craco_block.py -s 6 -e 10; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/real/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b3.yaml b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b3.yaml new file mode 100644 index 00000000..9ac642a1 --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b3.yaml @@ -0,0 +1,84 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf-b3 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "6" + memory: "64Gi" # + ephemeral-storage: 64Gi # + limits: + cpu: "8" + memory: "80Gi" + ephemeral-storage: 80Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_real_craco_block.py -s 11 -e 15; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/real/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b4.yaml b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b4.yaml new file mode 100644 index 00000000..0ce3cb1c --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b4.yaml @@ -0,0 +1,84 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf-b4 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "6" + memory: "64Gi" # + ephemeral-storage: 64Gi # + limits: + cpu: "8" + memory: "80Gi" + ephemeral-storage: 80Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_real_craco_block.py -s 16 -e 20; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/real/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b5.yaml b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b5.yaml new file mode 100644 index 00000000..1d962539 --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b5.yaml @@ -0,0 +1,84 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf-b5 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "6" + memory: "64Gi" # + ephemeral-storage: 64Gi # + limits: + cpu: "8" + memory: "80Gi" + ephemeral-storage: 80Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_real_craco_block.py -s 21 -e 25; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/real/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b6.yaml b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b6.yaml new file mode 100644 index 00000000..a7b2a806 --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b6.yaml @@ -0,0 +1,84 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf-b6 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "6" + memory: "64Gi" # + ephemeral-storage: 64Gi # + limits: + cpu: "8" + memory: "80Gi" + ephemeral-storage: 80Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_real_craco_block.py -s 26 -e 30; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/real/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b7.yaml b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b7.yaml new file mode 100644 index 00000000..b21430f5 --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b7.yaml @@ -0,0 +1,84 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf-b7 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "6" + memory: "64Gi" # + ephemeral-storage: 64Gi # + limits: + cpu: "8" + memory: "80Gi" + ephemeral-storage: 80Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_real_craco_block.py -s 31 -e 35; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/real/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b8.yaml b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b8.yaml new file mode 100644 index 00000000..00396b5c --- /dev/null +++ b/papers/F/Analysis/Real/Cloud/yamls/nautilus_real_cube_b8.yaml @@ -0,0 +1,84 @@ +# 21 processors on full for Varying F +# kubectl exec -it test-pod -- /bin/bash +apiVersion: batch/v1 +kind: Job +metadata: + name: jb-zdm-craco-real-logf-b8 +spec: + backoffLimit: 0 + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - k8s-chase-ci-01.noc.ucsb.edu + - key: nvidia.com/gpu.product + operator: In + values: + - NVIDIA-GeForce-GTX-1080-Ti + containers: + - name: container + image: localhost:30081/profxj/zdm_docker:latest # UPDATE + imagePullPolicy: Always + resources: + requests: + cpu: "6" + memory: "64Gi" # + ephemeral-storage: 64Gi # + limits: + cpu: "8" + memory: "80Gi" + ephemeral-storage: 80Gi + #nvidia.com/gpu: "1" # See docs to exlude certain types + command: ["/bin/bash", "-c"] + args: + - cd FRB; + git fetch; + git pull; + python setup.py develop; + cd ../ne2001; + python setup.py develop; + cd ../zdm; + git fetch; + git checkout varying_F; + python setup.py develop; + cd zdm/data/Surveys; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp s3://zdm/Surveys . --recursive --force; + cd ../../..; + cd papers/F/Analysis/Real/Cloud; + mkdir Output; + python run_real_craco_block.py -s 36 -e 41; + aws --endpoint http://rook-ceph-rgw-nautiluss3.rook s3 cp Output s3://zdm/Cubes/F/real/ --recursive --force; + env: + - name: "ENDPOINT_URL" + value: "http://rook-ceph-rgw-nautiluss3.rook" + - name: "S3_ENDPOINT" + value: "rook-ceph-rgw-nautiluss3.rook" + volumeMounts: + - name: prp-s3-credentials + mountPath: "/root/.aws/credentials" + subPath: "credentials" + - name: ephemeral + mountPath: "/tmp" + - name: "dshm" + mountPath: "/dev/shm" + nodeSelector: + nautilus.io/disktype: nvme + restartPolicy: Never + volumes: + # Secrets file for nautilus s3 credentials .aws/credentials and .s3cfg + - name: prp-s3-credentials + secret: + secretName: prp-s3-credentials + # Shared memory (necessary for Python's multiprocessing.shared_memory module to work) + - name: dshm + emptyDir: + medium: Memory + # Ephemeral storage + - name: ephemeral + emptyDir: {} diff --git a/papers/F/Analysis/Real/Cubes/craco_real_cube.json b/papers/F/Analysis/Real/Cubes/craco_real_cube.json new file mode 100644 index 00000000..03e29078 --- /dev/null +++ b/papers/F/Analysis/Real/Cubes/craco_real_cube.json @@ -0,0 +1,52 @@ +{ + "state": { + "energy": { + "luminosity_function": 3 + }, + "FRBdemo": { + "alpha_method": 1 + }, + "cosmo": { + "fix_Omega_b_h2": true + } + }, + "cube": { + "parameter_order": [ + "lC", + "lmean", + "lsigma", + "logF", + "H0" + ] + }, + "H0": { + "DC": "cosmo", + "min": 60.0, + "max": 100.0, + "n": 41 + }, + "lmean": { + "DC": "host", + "min": 1.7, + "max": 2.5, + "n": 10 + }, + "lsigma": { + "DC": "host", + "min": 0.2, + "max": 0.9, + "n": 10 + }, + "logF": { + "DC": "IGM", + "min": -1.7, + "max": 0, + "n": 30 + }, + "lC": { + "DC": "FRBdemo", + "min": -0.911, + "max": -0.911, + "n": -1 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/Real/Cubes/craco_real_state.json b/papers/F/Analysis/Real/Cubes/craco_real_state.json new file mode 100644 index 00000000..6eb48772 --- /dev/null +++ b/papers/F/Analysis/Real/Cubes/craco_real_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "logF": 0.32 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 3 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/Real/Cubes/real_mini_cube.json b/papers/F/Analysis/Real/Cubes/real_mini_cube.json new file mode 100644 index 00000000..9e2fcefb --- /dev/null +++ b/papers/F/Analysis/Real/Cubes/real_mini_cube.json @@ -0,0 +1,38 @@ +{ + "state": { + "energy": { + "luminosity_function": 3 + }, + "FRBdemo": { + "alpha_method": 1 + }, + "cosmo": { + "fix_Omega_b_h2": true + } + }, + "cube": { + "parameter_order": [ + "lC", + "logF", + "H0" + ] + }, + "H0": { + "DC": "cosmo", + "min": 60.0, + "max": 80.0, + "n": 5 + }, + "logF": { + "DC": "IGM", + "min": -1.7, + "max": 0, + "n": 5 + }, + "lC": { + "DC": "FRBdemo", + "min": -0.911, + "max": -0.911, + "n": -1 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/Real/Cubes/real_mini_state.json b/papers/F/Analysis/Real/Cubes/real_mini_state.json new file mode 100644 index 00000000..6eb48772 --- /dev/null +++ b/papers/F/Analysis/Real/Cubes/real_mini_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "logF": 0.32 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 3 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/papers/F/Analysis/Real/make_ll_2D_F.py b/papers/F/Analysis/Real/make_ll_2D_F.py new file mode 100644 index 00000000..dfd12a19 --- /dev/null +++ b/papers/F/Analysis/Real/make_ll_2D_F.py @@ -0,0 +1,153 @@ +""" +This script creates 2D likelihood plots given a `.npz` cube. +""" +import numpy as np +import os +import zdm +from zdm import analyze_cube as ac + +from matplotlib import pyplot as plt +from IPython import embed + + +def main(verbose=False): + # output directory + opdir = "2d_figs/" + if not os.path.exists(opdir): + os.mkdir(opdir) + + CubeFile = "Cubes/craco_real_cube.npz" + if os.path.exists(CubeFile): + data = np.load(CubeFile) + else: + print("Could not file cube output file ", CubeFile) + print("Please obtain it from [repository]") + exit() + + if verbose: + print("Data file contains the following items") + for thing in data: + print(thing) + + lst = data.files + lldata = data["ll"] + params = data["params"] + + def get_param_values(data, params): + """ + Gets the unique values of the data from a cube output + Currently the parameter order is hard-coded + + """ + param_vals = [] + for param in params: + col = data[param] + unique = np.unique(col) + param_vals.append(unique) + return param_vals + + param_vals = get_param_values(data, params) + + # builds uvals list + uvals = [] + latexnames = [] + for ip, param in enumerate(data["params"]): + # switches for alpha + if param == "alpha": + uvals.append(data[param] * -1.0) + else: + uvals.append(data[param]) + if param == "alpha": + latexnames.append("$\\alpha$") + ialpha = ip + elif param == "lEmax": + latexnames.append("$\\log_{10} E_{\\rm max}$") + elif param == "H0": + latexnames.append("$H_0$") + elif param == "gamma": + latexnames.append("$\\gamma$") + elif param == "sfr_n": + latexnames.append("$n_{\\rm sfr}$") + elif param == "lmean": + latexnames.append("$\\mu_{\\rm host}$") + elif param == "lsigma": + latexnames.append("$\\sigma_{\\rm host}$") + elif param == "logF": + latexnames.append("$\\log_{10} F$") + + # latexnames=['$\\log_{10} E_{\\rm max}$','$H_0$','$\\alpha$','$\\gamma$','$n_{\\rm sfr}$','$\\mu_{\\rm host}$','$\\sigma_{\\rm host}$'] + + list2 = [] + vals2 = [] + # gets Bayesian posteriors + deprecated, uw_vectors, wvectors = ac.get_bayesian_data(data["ll"]) + for i, vec in enumerate(uw_vectors): + n = np.argmax(vec) + val = uvals[i][n] + if params[i] != "logF": + list2.append(params[i]) + vals2.append(val) + else: + iF = i + + ###### NOTATION ##### + # uw: unweighted + # wH0: weighted according to H0 knowledged + # f: fixed other parameters + # B: best-fit + + ############## 2D plots at best-fit valuess ########## + + # gets the slice corresponding to the best-fit values of all other parameters + # this is 1D, so is our limit on H0 keeping all others fixed + for i, item in enumerate(list2): + list3 = np.concatenate((list2[0:i], list2[i + 1 :])) + vals3 = np.concatenate((vals2[0:i], vals2[i + 1 :])) + array = ac.get_slice_from_parameters(data, list3, vals3) + + # log to lin space + array[np.isnan(array)] = -1e99 + array -= np.nanmax(array) + array = 10**array + array /= np.sum(array) + + # now have array for slice covering best-fit values + if i < iF: + modi = i + else: + modi = i + 1 + # array=array.T + array = array.swapaxes(0, 1) + savename = opdir + "/lls_" + params[iF] + "_" + params[modi] + ".png" + + # if (latexnames[modi] == '$\\gamma$'): + # embed(header="gamma") + + # if (latexnames[modi] == '$H_0$'): + # embed(header="H0") + + if params[modi] == "alpha": + # switches order of array in alpha dimension + array = np.flip(array, axis=0) + ac.make_2d_plot( + array, + latexnames[modi], + latexnames[iF], + -param_vals[modi], + param_vals[iF], + savename=savename, + norm=1, + ) + else: + ac.make_2d_plot( + array, + latexnames[modi], + latexnames[iF], + param_vals[modi], + param_vals[iF], + savename=savename, + norm=1, + ) + + +main() diff --git a/papers/F/Analysis/Real/make_survey_contrib_fig.py b/papers/F/Analysis/Real/make_survey_contrib_fig.py new file mode 100644 index 00000000..0807abc5 --- /dev/null +++ b/papers/F/Analysis/Real/make_survey_contrib_fig.py @@ -0,0 +1,194 @@ +""" +This is a script used to produce figures for the survey contributions for each parameter in the cube. +""" + +import numpy as np +import os +import zdm +from zdm import analyze_cube as ac + +from matplotlib import pyplot as plt +import scipy +from IPython import embed + + +def main(verbose=False): + ######### other results #### + Planck_H0 = 67.66 + Planck_sigma = 0.5 + Reiss_H0 = 73.04 + Reiss_sigma = 1.42 + + # output directory + opdir = "Figure7/" + if not os.path.exists(opdir): + os.mkdir(opdir) + + CubeFile = "Cubes/craco_real_cube.npz" + if os.path.exists(CubeFile): + data = np.load(CubeFile) + else: + print("Could not file cube output file ", CubeFile) + print("Please obtain it from [repository]") + exit() + + # builds uvals list + uvals = [] + latexnames = [] + for ip, param in enumerate(data["params"]): + # switches for alpha + if param == "alpha": + uvals.append(data[param] * -1.0) + else: + uvals.append(data[param]) + if param == "alpha": + latexnames.append("$\\alpha$") + ialpha = ip + elif param == "lEmax": + latexnames.append("$\\log_{10} E_{\\rm max}$") + elif param == "H0": + latexnames.append("$H_0$") + elif param == "gamma": + latexnames.append("$\\gamma$") + elif param == "sfr_n": + latexnames.append("$n_{\\rm sfr}$") + elif param == "lmean": + latexnames.append("$\\mu_{\\rm host}$") + elif param == "lsigma": + latexnames.append("$\\sigma_{\\rm host}$") + elif param == "logF": + latexnames.append("$\\log_{10} F$") + + # 1D plots by surveys s only + contributions = [ + data["lls0"], + data["lls2"], + data["lls3"], + data["lls1"], + data["lls4"], + ] + labels = [ + "CRAFT/FE", + "CRAFT/ICS 900 MHz", + "CRAFT/ICS 1.3 GHz", + "CRAFT/ICS 1.6 GHz", + "Parkes/Mb", + ] # correct + + colors = ["blue", "green", "orange", "purple", "red"] + linestyles = ["-", ":", "--", "-", "-."] + make_1d_plots_by_contribution( + data, + contributions, + labels, + prefix="Figure7/by_survey_", + colors=colors, + linestyles=linestyles, + ) # ,latexnames=latexnames) + exit() + + +def make_1d_plots_by_contribution( + data, + contributions, + labels, + prefix="", + fig_exten=".png", + log=False, + splines=True, + latexnames=None, + units=None, + linestyles=None, + colors=None, +): + """ + contributions: list of vectors giving various likelihood terms + args: + splines (bool): draw cubic splines + Labels: lists labels stating what these are + latexnames: latex for x and p(X) + units: appends units to x axis but not p(X) + """ + ######################### 1D plots, split by terms ################ + all_uvals = [] + all_vectors = [] + all_wvectors = [] + combined = data["pzDM"] + data["pDM"] + + # gets 1D Bayesian curves for each contribution + for datatype in contributions: + uvals, vectors, wvectors = ac.get_bayesian_data(datatype) + all_uvals.append(uvals) + all_vectors.append(vectors) + all_wvectors.append(wvectors) + params = data["params"] + + # gets unique values for each axis + param_vals = [] + param_list = [data["H0"], data["lmean"], data["lsigma"], data["logF"]] + xlatexnames = [ + "H_0 {\\rm [km\,s^{-1}\,Mpc^{-1}]}", + "\\mu_{\\rm host} {\\rm [pc\,cm^{-3}]}", + "\\sigma_{\\rm host}", + "\\log_{10} F", + ] + ylatexnames = [ + "H_0", + "\\mu_{\\rm host}", + "\\sigma_{\\rm host}", + "\\log_{10} F", + ] + + for col in param_list: + unique = np.unique(col) + param_vals.append(unique) + # assigns different plotting styles to help distinguish curves + if linestyles is None: + linestyles = ["-", "--", "-.", ":", "-", "--", "-.", ":", "-", "--", "-.", ":"] + if colors is None: + colors = plt.rcParams["axes.prop_cycle"].by_key()["color"] + for which in np.arange(len(param_list)): + plt.figure(dpi=300) + plt.xlabel("$" + xlatexnames[which] + "$") + plt.ylabel("$p(" + ylatexnames[which] + ")$") + xvals = param_vals[which] + + for idata, vectors in enumerate(all_vectors): + # print(which, idata, len(vectors[which]), len(xvals)) + if splines: + xdata = np.linspace(xvals[0], xvals[-1], 100) + f = scipy.interpolate.interp1d( + xvals, np.log(vectors[which]), kind="cubic" + ) + ydata = np.exp(f(xdata)) + plt.plot( + xdata, + ydata, + label=labels[idata], + linestyle=linestyles[idata], + color=colors[idata], + ) + plt.scatter( + xvals, vectors[which], color=plt.gca().lines[-1].get_color() + ) + else: + ydata = vectors[which] + xdata = xvals + # print(labels[idata]," has values ",vector) + plt.plot( + xdata, + ydata, + label=labels[idata], + linestyle=linestyles[idata], + color=colors[idata], + ) + + if log: + plt.yscale("log") + # plt.ylim(np.max(vector)*1e-3,np.max(vector)) #improve this + plt.legend() + plt.savefig(prefix + params[which] + fig_exten, dpi=200) + plt.close() + + +main() diff --git a/papers/F/Analysis/Real/py/build_real_cube.py b/papers/F/Analysis/Real/py/build_real_cube.py new file mode 100644 index 00000000..6580dce2 --- /dev/null +++ b/papers/F/Analysis/Real/py/build_real_cube.py @@ -0,0 +1,70 @@ +""" Build a log-likelihood cube for zdm for Real FRBs! +""" + +# It should be possible to remove all the matplotlib calls from this +# but in the current implementation it is not removed. +import argparse +import numpy as np +import os + +from zdm import iteration as it +from zdm import io +from zdm import real_loading + +from IPython import embed + +def main(pargs): + + + # Clobber? + if pargs.clobber and os.path.isfile(pargs.opfile): + os.remove(pargs.opfile) + + ############## Load up ############## + input_dict=io.process_jfile(pargs.pfile) + + # Deconstruct the input_dict + state_dict, cube_dict, vparam_dict = it.parse_input_dict(input_dict) + + # State + state = real_loading.set_state() + state.update_param_dict(state_dict) + + ############## Initialise ############## + surveys, grids = real_loading.surveys_and_grids(init_state=state) + + # Write state to disk + state_file = pargs.pfile.replace('cube.json', 'state.json') + state.write(state_file) + + # Set what portion of the Cube we are generating + run=pargs.number + howmany=pargs.howmany + opfile=pargs.opfile + + # checks to see if the file is already there, and how many iterations have been performed + starti=it.check_cube_opfile(run, howmany, opfile) + print("starti is ",starti) + if starti==howmany: + print("Done everything!") + pass + # + it.cube_likelihoods(grids, surveys, vparam_dict, cube_dict, + run, howmany, opfile, starti=starti) + + +def parse_args(options=None): + # test for command-line arguments here + parser = argparse.ArgumentParser() + parser.add_argument('-n','--number',type=int,required=True,help="nth iteration, beginning at 0") + parser.add_argument('-m','--howmany',type=int,required=True,help="number m to iterate at once") + parser.add_argument('-p','--pfile',type=str, required=True,help="File defining parameter ranges") + parser.add_argument('-o','--opfile',type=str,required=True,help="Output file for the data") + parser.add_argument('--clobber', default=False, action='store_true', + help="Clobber output file?") + args = parser.parse_args() + return args + +if __name__ == "__main__": + pargs = parse_args() + main(pargs) \ No newline at end of file diff --git a/papers/F/Analysis/Real/py/craco_qck_explore.py b/papers/F/Analysis/Real/py/craco_qck_explore.py new file mode 100644 index 00000000..dc93350a --- /dev/null +++ b/papers/F/Analysis/Real/py/craco_qck_explore.py @@ -0,0 +1,135 @@ +""" +Generates 1D likelihood PDFs of each parameter from a `.npz` cube. + +The only argument in running the file corresponds to a hard-coded location of the `.npz` cube file. +""" + +# imports +from importlib import reload +import numpy as np +import sys, os + +from zdm import analyze_cube +from zdm import iteration as it +from zdm import io +from zdm.craco import loading + +from IPython import embed + + +# sys.path.append(os.path.abspath("../../Figures/py")) + + +def main(pargs): + jroot = None + scube = None + if pargs.run == "real": + scube = "real" + outdir = "real/" + + if jroot is None: + jroot = scube + + # Load + npdict = np.load(f"Cubes/craco_{scube}_cube.npz") + + ll_cube = npdict["ll"] + + # Deal with Nan + ll_cube[np.isnan(ll_cube)] = -1e99 + params = npdict["params"] + + # Cube parameters + ############## Load up ############## + pfile = f"Cubes/craco_{jroot}_cube.json" + input_dict = io.process_jfile(pfile) + + # Deconstruct the input_dict + state_dict, cube_dict, vparam_dict = it.parse_input_dict(input_dict) + + latexnames = [] + for ip, param in enumerate(npdict["params"]): + if param == "alpha": + latexnames.append("$\\alpha$") + ialpha = ip + elif param == "lEmax": + latexnames.append("$\\log_{10} E_{\\rm max}$") + elif param == "H0": + latexnames.append("$H_0$") + elif param == "gamma": + latexnames.append("$\\gamma$") + elif param == "sfr_n": + latexnames.append("$n_{\\rm sfr}$") + elif param == "lmean": + latexnames.append("$\\mu_{\\rm host}$") + elif param == "lsigma": + latexnames.append("$\\sigma_{\\rm host}$") + elif param == "logF": + latexnames.append("$\\log_{10} F$") + + units = [] + for ip, param in enumerate(npdict["params"]): + if param == "alpha": + units.append(" ") + ialpha = ip + elif param == "lEmax": + units.append("[$\rm erg$]") + elif param == "H0": + units.append(r"[$\rm km \, s^{-1} \, Mpc^{-1}$]") + elif param == "gamma": + units.append("") + elif param == "sfr_n": + units.append(" ") + elif param == "lmean": + units.append(r"[$\rm pc \, cm^{-3}$]") + elif param == "lsigma": + units.append(r"[$\rm pc \, cm^{-3}$]") + elif param == "logF": + units.append(" ") + + # Run Bayes + + # Offset by max + ll_cube = ll_cube - np.max(ll_cube) + + uvals, vectors, wvectors = analyze_cube.get_bayesian_data(ll_cube) + + analyze_cube.do_single_plots( + uvals, + vectors, + None, + params, + vparams_dict=vparam_dict, + outdir=outdir, + compact=True, + latexnames=latexnames, + units=units, + dolevels=True, + ) + print(f"Wrote figures to {outdir}") + + +def parse_option(): + """ + This is a function used to parse the arguments in the training. + + Returns: + args: (dict) dictionary of the arguments. + """ + import argparse + + parser = argparse.ArgumentParser("Slurping the cubes") + parser.add_argument("run", type=str, help="Run to slurp") + # parser.add_argument('--debug', default=False, action='store_true', + # help='Debug?') + args = parser.parse_args() + + return args + + +# Command line execution +if __name__ == "__main__": + pargs = parse_option() + main(pargs) + +# python py/craco_qck_explore.py mini diff --git a/papers/F/Analysis/Real/py/slurp_craco_cubes.py b/papers/F/Analysis/Real/py/slurp_craco_cubes.py new file mode 100644 index 00000000..094836dc --- /dev/null +++ b/papers/F/Analysis/Real/py/slurp_craco_cubes.py @@ -0,0 +1,179 @@ +""" +Script to intake the `.csv` files from the CRACO runs and convert them to a single `.npz` file. + +The only argument in running the file corresponds to a hard-coded location of the `.csv` files and the cube `.json` file. +""" + +from zdm import analyze_cube + + +def main(pargs): + + if pargs.run == "Emax": + # Emax + input_file = "Cubes/craco_H0_Emax_cube.json" + prefix = "Cubes/tmp" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_H0_Emax_cube.npz", nsurveys + ) + + elif pargs.run == "F": + # Emax + input_file = "Cubes/craco_H0_F_cube.json" + prefix = "Cloud/Output/craco_H0_F" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_H0_F_cube.npz", nsurveys + ) + + elif pargs.run == "logF": + # Emax + input_file = "Cubes/craco_H0_logF_cube.json" + prefix = "Cloud/Output_logF_test/craco_H0_logF" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_H0_logF_cube.npz", nsurveys + ) + + elif pargs.run == "logF_full": + # Emax + input_file = "Cubes/craco_full_cube.json" + prefix = "Cloud/OutputFull/craco_full" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_full_cube.npz", nsurveys + ) + + elif pargs.run == "lmF": + # Emax + input_file = "Cubes/craco_lm_F_cube.json" + prefix = "Cloud/Output/craco_lm_F" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_lm_F_cube.npz", nsurveys + ) + + elif pargs.run == "mini": + # Emax + input_file = "Cubes/craco_mini_cube.json" + # prefix = 'Cubes/craco_mini' + prefix = "Cloud/OutputMini/craco_mini" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_mini_cube.npz", nsurveys + ) + elif pargs.run == "submini": + # Emax + input_file = "Cubes/craco_submini_cube.json" + prefix = "Cubes/craco_submini_cube" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_submini_cube.npz", nsurveys + ) + + elif pargs.run == "sfrEmax": + # Emax + input_file = "Cubes/craco_sfr_Emax_cube.json" + prefix = "Cubes/craco_sfr_Emax_cube" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_sfr_Emax_cube.npz", nsurveys + ) + + elif pargs.run == "alphaEmax": + # Emax + input_file = "Cubes/craco_alpha_Emax_cube.json" + prefix = "Cubes/craco_alpha_Emax_cube" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_alpha_Emax_cube.npz", nsurveys + ) + elif pargs.run == "full": + # Emax + input_file = "Cubes/craco_full_cube.json" + prefix = "Cubes/craco_full" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_full_cube.npz", nsurveys + ) + elif pargs.run == "another_full": + # Emax + input_file = "Cubes/craco_full_cube.json" + prefix = "Cubes/craco_400_full" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_400_full_cube.npz", nsurveys + ) + elif pargs.run == "third_full": + # Emax + input_file = "Cubes/craco_full_cube.json" + prefix = "Cubes/craco_3rd_full" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_3rd_full_cube.npz", nsurveys + ) + elif pargs.run == "real": + # Emax + input_file = "Cubes/craco_real_cube.json" + prefix = "Cloud/Output/craco_real" + nsurveys = 1 + + # Run it + analyze_cube.slurp_cube( + input_file, prefix, "Cubes/craco_real_cube.npz", nsurveys + ) + + +def parse_option(): + """ + This is a function used to parse the arguments in the training. + + Returns: + args: (dict) dictionary of the arguments. + """ + import argparse + + parser = argparse.ArgumentParser("Slurping the cubes") + parser.add_argument("run", type=str, help="Run to slurp") + # parser.add_argument('--debug', default=False, action='store_true', + # help='Debug?') + args = parser.parse_args() + + return args + + +# Command line execution +if __name__ == "__main__": + + pargs = parse_option() + main(pargs) + +# python py/slurp_craco_cubes.py mini +# python py/slurp_craco_cubes.py another_full + +# python py/slurp_craco_cubes.py F diff --git a/papers/F/Analysis/py/analy_F_I.py b/papers/F/Analysis/py/analy_F_I.py new file mode 100644 index 00000000..e9f2ecd0 --- /dev/null +++ b/papers/F/Analysis/py/analy_F_I.py @@ -0,0 +1,15 @@ +""" +Helper function to load the default survey and grid for CRACO with F parameter +""" + +from zdm.craco import loading + +# Load the default survey and grid with F +fiducial_survey = "../MC_F/Surveys/F_0.32_survey" + +def craco_mc_survey_grid(iFRB=100): + """ Load the default MonteCarlo survey+grid for CRACO """ + survey, grid = loading.survey_and_grid( + survey_name=fiducial_survey, NFRB=100, lum_func=2, iFRB=iFRB + ) + return survey, grid diff --git a/papers/F/Analysis/py/makeCornerPlot.ipynb b/papers/F/Analysis/py/makeCornerPlot.ipynb new file mode 100644 index 00000000..835f3603 --- /dev/null +++ b/papers/F/Analysis/py/makeCornerPlot.ipynb @@ -0,0 +1,243 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import os\n", + "import zdm\n", + "import scipy\n", + "from zdm import analyze_cube as ac\n", + "from IPython import embed\n", + "import matplotlib.pyplot as plt\n", + "\n", + "real_data = False\n", + "\n", + "cube = \"../CRACO/Cubes/craco_full_cube.npz\"\n", + "if real_data:\n", + " cube = \"../Real/Cubes/craco_real_cube.npz\"\n", + "\n", + "data = np.load(cube)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "ivalues, lls, wlls = ac.get_bayesian_data(data['ll'])\n", + "\n", + "pH0_idx = np.where(data[\"params\"] == \"H0\")[0][0]\n", + "pH0 = lls[pH0_idx]\n", + "H0s = data[\"H0\"]\n", + "\n", + "plmean_idx = np.where(data[\"params\"] == \"lmean\")[0][0]\n", + "plmean = lls[plmean_idx]\n", + "lmeans = data[\"lmean\"]\n", + "\n", + "plsigma_idx = np.where(data[\"params\"] == \"lsigma\")[0][0]\n", + "plsigma = lls[plsigma_idx]\n", + "lsigmas = data[\"lsigma\"]\n", + "\n", + "plogF_idx = np.where(data[\"params\"] == \"logF\")[0][0]\n", + "plogF = lls[plogF_idx]\n", + "logFs = data[\"logF\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jaybaptista/Desktop/UCSC/code.tmp/zdm/zdm/analyze_cube.py:570: RuntimeWarning: All-NaN slice encountered\n", + " wthemax = np.nanmax(wlls)\n" + ] + } + ], + "source": [ + "uvals, ijs, arrays, warrays = ac.get_2D_bayesian_data(data['ll'])\n", + "\n", + "p = (1-0.68)/2\n", + "\n", + "def getInterpolatedLimits(x, y, p=(1-0.68)/2, nbins=400):\n", + " f = scipy.interpolate.interp1d(x, y, kind='cubic')\n", + " xs = np.linspace(np.min(x), np.max(x), nbins)\n", + " ys = f(xs)\n", + " x_lower, x_upper, _, _ = ac.extract_limits(xs, ys, p)\n", + " return x_lower, x_upper\n", + "\n", + "H0_lower, H0_upper = getInterpolatedLimits(H0s, lls[pH0_idx], p)\n", + "lmean_lower, lmean_upper = getInterpolatedLimits(lmeans, lls[plmean_idx], p)\n", + "lsigma_lower, lsigma_upper = getInterpolatedLimits(lsigmas, lls[plsigma_idx], p)\n", + "F_lower, F_upper = getInterpolatedLimits(logFs, lls[plogF_idx], p)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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GiKUBwAAAAAAAAAAAA0RygMAAAAAAAAAAICGCOUBAAAAAAAAAABAQ4TyAAAAAAAAAAAAoCFCeQAAAAAAAAAAANAQoTwAAAAAAAAAAABoiFAeAAAAAAAAAAAANEQoDwAAAAAAAAAAABoilAcAAAAAAAAAAAANEcoDAAAAAAAAAACAhgjlAQAAAAAAAAAAQEOE8gAAAAAAAAAAAKAhQnkAAAAAAAAAAADQEKE8AAAAAAAAAAAAaIhQHgAAAAAAAAAAADREKA8AAAAAAAAAAAAaIpQHAAAAAAAAAAAADRHKAwAAAAAAAAAAgIYI5QEAAAAAAAAAAEBDhPIAAAAAAAAAAACgIUJ5AAAAAAAAAAAA0BChPAAAAAAAAAAAAGiIUB4AAAAAAAAAAAA0RCgPAAAAAAAAAAAAGiKUBwAAAAAAAAAAAA0RygMAAAAAAAAAAICGCOUBAAAAAAAAAABAQ4TyAAAAAAAAAAAAoCFCeQAAAAAAAAAAANAQoTwAAAAAAAAAAABoiFAeAAAAAAAAAAAANEQoDwAAAAAAAAAAABoilAcAAAAAAAAAAAANEcoDAAAAAAAAAACAhgjlAQAAAAAAAAAAQEOE8gAAAAAAAAAAAKAhQnkAAAAAAAAAAADQEKE8AAAAAAAAAAAAaIhQHgAAAAAAAAAAADREKA8AAAAAAAAAAAAaIpQHAAAAAAAAAAAADRHKAwAAAAAAAAAAgIYI5QEAAAAAAAAAAEBDhPIAAAAAAAAAAACgIUJ5AAAAAAAAAAAA0BChPAAAAAAAAAAAAGiIUB4AAAAAAAAAAAA0RCgPAAAAAAAAAAAAGiKUBwAAAAAAAAAAAA0RygMAAAAAAAAAAICGCOUBAAAAAAAAAABAQ4TyAAAAAAAAAAAAoCFCeQAAAAAAAAAAANAQoTwAAAAAAAAAAABoiFAeAAAAAAAAAAAANEQoDwAAAAAAAAAAABoilAcAAAAAAAAAAAANEcoDAAAAAAAAAACAhgjlAQAAAAAAAAAAQEOE8gAAAAAAAAAAAKAhQnkAAAAAAAAAAADQEKE8AAAAAAAAAAAAaIhQHgAAAAAAAAAAADREKA8AAAAAAAAAAAAaIpQHAAAAAAAAAAAADRHKAwAAAAAAAAAAgIYI5QEAAAAAAAAAAEBDhPIAAAAAAAAAAACgIUJ5AAAAAAAAAAAA0BChPAAAAAAAAAAA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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure(figsize=(10,10), dpi=300)\n", + "\n", + "nparams = len(data[\"params\"])\n", + "params = data[\"params\"]\n", + "\n", + "params_tex = [\n", + " r\"$H_0$\",\n", + " r\"$\\mu_{\\rm host}$\",\n", + " r\"$\\sigma_{\\rm host}$\",\n", + " r\"$\\log_{10} F$\",\n", + "]\n", + "\n", + "# Diagonals\n", + "for k, param in enumerate(params):\n", + " param_idx = np.where(data[\"params\"] == param)[0][0]\n", + " param_ax = fig.add_subplot(4, 4, (5*k)+1)\n", + " dparam = data[param][1] - data[param][0]\n", + " param_ax.bar(data[param], lls[param_idx], width=dparam, facecolor=\"None\", edgecolor=\"black\")\n", + " param_ax.set_box_aspect(1)\n", + "\n", + " if k > 0:\n", + " param_ax.set_yticklabels([])\n", + "\n", + " if k < nparams-1:\n", + " param_ax.set_xticklabels([])\n", + "\n", + " if k == nparams-1:\n", + " param_ax.set_xlabel(params_tex[-1])\n", + "\n", + "# Off-diagonals\n", + "# H0 and lmean\n", + "ax_H0_lmean = fig.add_subplot(4, 4, 5)\n", + "ax_H0_lmean.imshow(arrays[0].T, origin=\"lower\", aspect=\"auto\", extent=[data[\"H0\"][0], data[\"H0\"][-1], data[\"lmean\"][0], data[\"lmean\"][-1]])\n", + "ax_H0_lmean.set_box_aspect(1)\n", + "ax_H0_lmean.set_ylabel(params_tex[1])\n", + "ax_H0_lmean.set_xticklabels([])\n", + "ax_H0_lmean.axvline(H0_lower, color=\"red\", linestyle=\"--\")\n", + "ax_H0_lmean.axvline(H0_upper, color=\"red\", linestyle=\"--\")\n", + "ax_H0_lmean.axhline(lmean_lower, color=\"red\", linestyle=\"--\")\n", + "ax_H0_lmean.axhline(lmean_upper, color=\"red\", linestyle=\"--\")\n", + "\n", + "# H0 and lsigma\n", + "ax_H0_lsigma = fig.add_subplot(4, 4, 9)\n", + "ax_H0_lsigma.imshow(arrays[1].T, origin=\"lower\", aspect=\"auto\", extent=[data[\"H0\"][0], data[\"H0\"][-1], data[\"lsigma\"][0], data[\"lsigma\"][-1]])\n", + "ax_H0_lsigma.set_box_aspect(1)\n", + "ax_H0_lsigma.set_ylabel(params_tex[2])\n", + "ax_H0_lsigma.set_xticklabels([])\n", + "ax_H0_lsigma.axvline(H0_lower, color=\"red\", linestyle=\"--\")\n", + "ax_H0_lsigma.axvline(H0_upper, color=\"red\", linestyle=\"--\")\n", + "ax_H0_lsigma.axhline(lsigma_lower, color=\"red\", linestyle=\"--\")\n", + "ax_H0_lsigma.axhline(lsigma_upper, color=\"red\", linestyle=\"--\")\n", + "\n", + "# H0 and logF\n", + "ax_H0_logF = fig.add_subplot(4, 4, 13)\n", + "ax_H0_logF.imshow(arrays[2].T, origin=\"lower\", aspect=\"auto\", extent=[data[\"H0\"][0], data[\"H0\"][-1], data[\"logF\"][0], data[\"logF\"][-1]])\n", + "ax_H0_logF.set_box_aspect(1)\n", + "ax_H0_logF.set_xlabel(params_tex[0])\n", + "ax_H0_logF.set_ylabel(params_tex[3])\n", + "ax_H0_logF.axvline(H0_lower, color=\"red\", linestyle=\"--\")\n", + "ax_H0_logF.axvline(H0_upper, color=\"red\", linestyle=\"--\")\n", + "ax_H0_logF.axhline(F_lower, color=\"red\", linestyle=\"--\")\n", + "ax_H0_logF.axhline(F_upper, color=\"red\", linestyle=\"--\")\n", + "\n", + "# lmean and lsigma\n", + "ax_lmean_lsigma = fig.add_subplot(4, 4, 10)\n", + "ax_lmean_lsigma.imshow(arrays[3].T, origin=\"lower\", aspect=\"auto\", extent=[data[\"lmean\"][0], data[\"lmean\"][-1], data[\"lsigma\"][0], data[\"lsigma\"][-1]])\n", + "ax_lmean_lsigma.set_box_aspect(1)\n", + "ax_lmean_lsigma.set_xticklabels([])\n", + "ax_lmean_lsigma.set_yticklabels([])\n", + "ax_lmean_lsigma.axvline(lmean_lower, color=\"red\", linestyle=\"--\")\n", + "ax_lmean_lsigma.axvline(lmean_upper, color=\"red\", linestyle=\"--\")\n", + "ax_lmean_lsigma.axhline(lsigma_lower, color=\"red\", linestyle=\"--\")\n", + "ax_lmean_lsigma.axhline(lsigma_upper, color=\"red\", linestyle=\"--\")\n", + "\n", + "# lmean and logF\n", + "ax_lmean_logF = fig.add_subplot(4, 4, 14)\n", + "ax_lmean_logF.imshow(arrays[4].T, origin=\"lower\", aspect=\"auto\", extent=[data[\"lmean\"][0], data[\"lmean\"][-1], data[\"logF\"][0], data[\"logF\"][-1]])\n", + "ax_lmean_logF.set_box_aspect(1)\n", + "ax_lmean_logF.set_xlabel(params_tex[1])\n", + "ax_lmean_logF.set_yticklabels([])\n", + "ax_lmean_logF.axvline(lmean_lower, color=\"red\", linestyle=\"--\")\n", + "ax_lmean_logF.axvline(lmean_upper, color=\"red\", linestyle=\"--\")\n", + "ax_lmean_logF.axhline(F_lower, color=\"red\", linestyle=\"--\")\n", + "ax_lmean_logF.axhline(F_upper, color=\"red\", linestyle=\"--\")\n", + "\n", + "# lsigma and logF\n", + "ax_lsigma_logF = fig.add_subplot(4, 4, 15)\n", + "ax_lsigma_logF.imshow(arrays[5].T, origin=\"lower\", aspect=\"auto\", extent=[data[\"lsigma\"][0], data[\"lsigma\"][-1], data[\"logF\"][0], data[\"logF\"][-1]])\n", + "ax_lsigma_logF.set_box_aspect(1)\n", + "ax_lsigma_logF.set_xlabel(params_tex[2])\n", + "ax_lsigma_logF.set_yticklabels([])\n", + "ax_lsigma_logF.axvline(lsigma_lower, color=\"red\", linestyle=\"--\")\n", + "ax_lsigma_logF.axvline(lsigma_upper, color=\"red\", linestyle=\"--\")\n", + "ax_lsigma_logF.axhline(F_lower, color=\"red\", linestyle=\"--\")\n", + "ax_lsigma_logF.axhline(F_upper, color=\"red\", linestyle=\"--\")\n", + "\n", + "plt.subplots_adjust(hspace = 0.1, wspace = 0.02)\n", + "if real_data:\n", + " fig.text(0.5, 0.9, \"Observed Constraints\", ha=\"center\", size=16)\n", + "else:\n", + " fig.text(0.5, 0.9, \"Synthetic Constraints\", ha=\"center\", size=16)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/papers/F/Analysis/py/plotF_wH0Prior.py b/papers/F/Analysis/py/plotF_wH0Prior.py new file mode 100644 index 00000000..d99bc664 --- /dev/null +++ b/papers/F/Analysis/py/plotF_wH0Prior.py @@ -0,0 +1,237 @@ +""" +This is a script to produce limit plots for a cube. + +The plots produced with priors on H0 are stored in folders prefixed with "wH0". +Plots generated with the synthetic CRACO cube are suffixed with "_forecast", while +plots generated with the real observation cube are suffixed with "_measured". +Plots showing PDFs with and without priors are infixed with "others". + +- The priors on H0 are: + a) Planck + b) Reiss + c) No prior + +""" + +import numpy as np +import os +import zdm +from zdm import analyze_cube as ac + +from matplotlib import pyplot as plt + + +def main(cube_path, outdir="./", verbose=False): + ######### sets the values of H0 for priors ##### + Planck_H0 = 67.4 + Planck_sigma = 0.5 + Reiss_H0 = 73.04 + Reiss_sigma = 1.42 + + ##### loads cube data ##### + data = np.load(cube_path) + if verbose: + for thing in data: + print(thing) + print(data["params"]) + + # gets values of cube parameters + # param_vals=get_param_values(data,verbose) + + # gets latex names + uvals, latexnames = get_names_values(data) + + ################ single plots, no priors ############ + deprecated, uw_vectors, wvectors = ac.get_bayesian_data(data["ll"]) + ac.do_single_plots( + uvals, + uw_vectors, + None, + data["params"], + tag="", + log=False, + logspline=False, + # kind="linear", + truth=None, + dolevels=True, + latexnames=latexnames, + outdir=outdir, + ) + + ########### H0 data for fixed values of other parameters ########### + # extracts best-fit values + list1 = [] + vals1 = [] + list2 = [] + vals2 = [] + vals3 = [] + for i, vec in enumerate(uw_vectors): + n = np.argmax(vec) # selects the most likely value + val = uvals[i][n] + if data["params"][i] == "H0": + # enables us to select a slice corresponding to particular H0 values + list1.append(data["params"][i]) + vals1.append(Reiss_H0) + + vals3.append(Planck_H0) + + iH0 = i # setting index for Hubble + else: + # enables us to select a slice correspondng to the best-fit values of all other params + # i.e. ignoring uncertainty in them + list2.append(data["params"][i]) + vals2.append(val) + + # gets the slice corresponding to specific values of H0 + Reiss_H0_selection = ac.get_slice_from_parameters(data, list1, vals1, verbose=True) + Planck_H0_selection = ac.get_slice_from_parameters(data, list1, vals3, verbose=True) + + # will have Bayesian limits on all parameters over everything but H0 + deprecated, ReissH0_vectors, deprecated = ac.get_bayesian_data(Reiss_H0_selection) + deprecated, PlanckH0_vectors, deprecated = ac.get_bayesian_data(Planck_H0_selection) + + # gets the slice corresponding to the best-fit values of all other parameters + # this is 1D, so is our limit on H0 keeping all others fixed + pH0_fixed = ac.get_slice_from_parameters(data, list2, vals2) + + ####### 1D plots for prior on H0 ######## + # generates plots for our standard prior on H0 only + # applies a prior on H0, which is flat between systematic differences, then falls off as a Gaussian either side + H0_dim = np.where(data["params"] == "H0")[0][0] + wlls = ac.apply_H0_prior( + data["ll"], H0_dim, data["H0"], Planck_H0, Planck_sigma, Reiss_H0, Reiss_sigma + ) + deprecated, wH0_vectors, wvectors = ac.get_bayesian_data(wlls) + ac.do_single_plots( + uvals, + wH0_vectors, + None, + data["params"], + tag="wH0_", + truth=None, + dolevels=True, + latexnames=latexnames, + logspline=False, + outdir=outdir, + ) + + # now do this with others... + # builds others... + others = [] + for i, p in enumerate(data["params"]): + if i == iH0: + oset = None + others.append(oset) + else: + if i < iH0: + modi = i + else: + modi = i - 1 + oset = [uw_vectors[i], ReissH0_vectors[modi], PlanckH0_vectors[modi]] + others.append(oset) + + # generates plots for our standard prior on H0, Planck and SN1a values, and no prior also + ac.do_single_plots( + uvals, + wH0_vectors, + None, + data["params"], + tag="wH0_others_", + truth=None, + dolevels=True, + latexnames=latexnames, + logspline=False, + others=others, + others_labels=["No Prior", r"$H_0 = 73.04$", r"$H_0 = 67.4$"], + outdir=outdir, + ) + + # ############## 2D plots for total likelihood ########### + # # these are for nor priors on anything + # baduvals, ijs, arrays, warrays = ac.get_2D_bayesian_data(data["ll"]) + # for which, array in enumerate(arrays): + # i = ijs[which][0] + # j = ijs[which][1] + + # savename = "2D/lls_" + data["params"][i] + "_" + data["params"][j] + ".png" + # ac.make_2d_plot( + # array, latexnames[i], latexnames[j], uvals[i], uvals[j], savename=savename + # ) + # # ac.make_2d_plot(array,latexnames[i],latexnames[j], + # # param_vals[i],param_vals[j], + # # savename=savename) + # if False and data["params"][i] == "H0": + # savename = ( + # "normed2D/lls_" + data["params"][j] + "_" + data["params"][i] + ".png" + # ) + + # ac.make_2d_plot( + # array.T, + # latexnames[j], + # latexnames[i], + # uvals[j], + # uvals[i], + # savename=savename, + # norm=1, + # ) + + +def get_names_values(data): + """ + Gets a list of latex names and corrected parameter values + """ + # builds uvals list + uvals = [] + latexnames = [] + for ip, param in enumerate(data["params"]): + # switches for alpha + if param == "alpha": + uvals.append(data[param] * -1.0) + else: + uvals.append(data[param]) + if param == "alpha": + latexnames.append("$\\alpha$") + ialpha = ip + elif param == "lEmax": + latexnames.append("$\\log_{10} E_{\\rm max}$") + elif param == "H0": + latexnames.append("$H_0$") + elif param == "gamma": + latexnames.append("$\\gamma$") + elif param == "sfr_n": + latexnames.append("$n_{\\rm sfr}$") + elif param == "lmean": + latexnames.append("$\\mu_{\\rm host}$") + elif param == "lsigma": + latexnames.append("$\\sigma_{\\rm host}$") + elif param == "logF": + latexnames.append("$\\log F$") + return uvals, latexnames + + +def get_param_values(data, verbose=False): + """ + Returns the unique cube values for each parameter in the cube + + Input: + data cube (tuple from reading the .npz) + + Output: + list of numpy arrays for each parameter giving their values + """ + # gets unique values for each axis + param_vals = [] + + # for col in param_list: + for col in data["params"]: + # unique=np.unique(col) + unique = np.unique(data[col]) + param_vals.append(unique) + if verbose: + print("For parameter ", col, " cube values are ", unique) + return param_vals + + +# Real Cube Data +main("../Real/Cubes/craco_real_cube.npz", "measured/") +main("../CRACO/Cubes/craco_full_cube.npz", "forecast/") diff --git a/papers/F/Analysis/py/plotHWHM.py b/papers/F/Analysis/py/plotHWHM.py new file mode 100644 index 00000000..b4c1baa2 --- /dev/null +++ b/papers/F/Analysis/py/plotHWHM.py @@ -0,0 +1,167 @@ +""" +Obtains the lower "half-width half-max" of the log PDFs for the old and new cubes to compare how +much the constraint on F improves after addition of the 2022 FRBs. +""" + +import numpy as np +import os +import zdm +import scipy +from zdm import analyze_cube as ac +from IPython import embed +import matplotlib.pyplot as plt + + +def main(): + # Load cubes + cube_old = "../CRACO/Cubes/craco_full_cube.npz" + cube = "../Real/Cubes/craco_real_cube.npz" + + # Get PDFs of the old cube + funcs, interp_mins, interp_maxs = getlogPDFs(cube_old) + _, _, _, flogF = funcs + _, _, _, logF_min = interp_mins + _, _, _, logF_max = interp_maxs + res = 1e3 + logFs = np.linspace(logF_min, logF_max, int(res)) + + probs_old = np.exp(flogF(logFs)) + max_prob_old = np.max(probs_old) + max_F_old = logFs[np.argmax(probs_old)] + + # Find the half-max points + sort_idx_old = np.argsort(np.abs(probs_old - (max_prob_old / 2))) + half_max_Fs_old = logFs[sort_idx_old[1]] + + # Get PDFs of the new cube + funcs, interp_mins, interp_maxs = getlogPDFs(cube) + _, _, _, flogF = funcs + _, _, _, logF_min = interp_mins + _, _, _, logF_max = interp_maxs + + probs = np.exp(flogF(logFs)) + max_prob = np.max(probs) + max_F = logFs[np.argmax(probs)] + + # Find the half-max points + sort_idx = np.argsort(np.abs(probs - (max_prob / 2))) + half_max_Fs = logFs[sort_idx[3]] + + print( + "Left-sided half-width half-max for old cube: ", + np.abs(max_F_old - np.min(half_max_Fs_old)), + ) + print( + "Left-sided half-width half-max for new cube: ", + np.abs(max_F - np.min(half_max_Fs)), + ) + + plt.figure() + # old cube + plt.plot(logFs, probs_old, color="red", label="Before 2022 FRBs") + plt.scatter(half_max_Fs_old, probs_old[sort_idx_old[1]]) + # plt.scatter(max_F_old, max_prob_old) + plt.axhline(max_prob_old / 2, color="red", alpha=0.5, ls="--") + + # new cube + + plt.plot(logFs, probs, color="blue", label="After 2022 FRBs") + plt.scatter(half_max_Fs, probs[sort_idx[3]]) + # plt.scatter(max_F, max_prob) + plt.axhline(max_prob / 2, color="blue", alpha=0.5, ls="--") + + plt.legend() + + plt.xlabel(r"$\log_{10} F$") + plt.ylabel(r"$p(\log_{10} F)$") + + plt.text( + 0.05, + 0.75, + f"LWHM (old) = {np.round(np.abs(max_F_old - np.min(half_max_Fs_old)), 3)} \ + \nLWHM (new) = {np.round(np.abs(max_F - np.min(half_max_Fs)), 3)}", + transform=plt.gca().transAxes, + ) + + plt.savefig("diagnostic_2.png") + plt.close() + + # embed(header="end of main") + # + + +def getlogPDFs(cube): + """ + Returns the log PDFs of the cubes with a flat prior H0. + """ + + ######### sets the values of H0 for priors ##### + Planck_H0 = 67.4 + Planck_sigma = 0.5 + Reiss_H0 = 73.04 + Reiss_sigma = 1.42 + ######### + + data = np.load(cube) + + uvals, latexnames = get_names_values(data) + + H0_dim = np.where(data["params"] == "H0")[0][0] + wlls = ac.apply_H0_prior( + data["ll"], H0_dim, data["H0"], Planck_H0, Planck_sigma, Reiss_H0, Reiss_sigma + ) + deprecated, wH0_vectors, wvectors = ac.get_bayesian_data(wlls) + + nonnorm_pdfs = [] + pdf_mins = [] + pdf_maxs = [] + + for i, vals in enumerate(uvals): + ymax = np.max(wH0_vectors[i]) + temp = np.where((wH0_vectors[i] > 0.0) & (np.isfinite(wH0_vectors[i]))) + + f = scipy.interpolate.interp1d( + vals[temp], np.log(wH0_vectors[i][temp]), kind="cubic" + ) + # remember to exponentiate output from f + nonnorm_pdfs.append(f) + pdf_mins.append(np.min(vals[temp])) + pdf_maxs.append(np.max(vals[temp])) + + return nonnorm_pdfs, pdf_mins, pdf_maxs + + +def get_names_values(data): + """ + Gets a list of latex names and corrected parameter values + """ + # builds uvals list + uvals = [] + latexnames = [] + for ip, param in enumerate(data["params"]): + # switches for alpha + if param == "alpha": + uvals.append(data[param] * -1.0) + else: + uvals.append(data[param]) + if param == "alpha": + latexnames.append("$\\alpha$") + ialpha = ip + elif param == "lEmax": + latexnames.append("$\\log_{10} E_{\\rm max}$") + elif param == "H0": + latexnames.append("$H_0$") + elif param == "gamma": + latexnames.append("$\\gamma$") + elif param == "sfr_n": + latexnames.append("$n_{\\rm sfr}$") + elif param == "lmean": + latexnames.append("$\\mu_{\\rm host}$") + elif param == "lsigma": + latexnames.append("$\\sigma_{\\rm host}$") + elif param == "logF": + latexnames.append("$\\log F$") + return uvals, latexnames + + +main() diff --git a/papers/F/Analysis/py/plotHubble_wFPrior.py b/papers/F/Analysis/py/plotHubble_wFPrior.py new file mode 100644 index 00000000..e7364697 --- /dev/null +++ b/papers/F/Analysis/py/plotHubble_wFPrior.py @@ -0,0 +1,196 @@ +""" +This is a script to produce limit plots for a cube with priors on F + +The plots produced with priors on F are stored in folders prefixed with "wF". +Plots generated with the synthetic CRACO cube are suffixed with "_forecast", while +plots generated with the real observation cube are suffixed with "_measured". +Plots showing PDFs with and without priors are infixed with "others". + +- The priors on F are: + a) a Gaussian prior (with 20% error on F) + b) No prior + +""" + +import numpy as np +import os +import zdm +from zdm import analyze_cube as ac + +from matplotlib import pyplot as plt + + +def main(cube_path, outdir="./", verbose=False): + ######### sets the values of F for priors ##### + F_0 = np.log10(0.32) + F_sigma = np.abs(0.2 * F_0) # error of 20% on F + + data = np.load(cube_path) + if verbose: + for thing in data: + print(thing) + print(data["params"]) + + # gets values of cube parameters + # param_vals=get_param_values(data,verbose) + + # gets latex names + uvals, latexnames = get_names_values(data) + + ################ single plots, no priors ############ + deprecated, uw_vectors, wvectors = ac.get_bayesian_data(data["ll"]) + ac.do_single_plots( + uvals, + uw_vectors, + None, + data["params"], + tag="", + log=False, + logspline=False, + # kind="linear", + truth=None, + dolevels=True, + latexnames=latexnames, + outdir=outdir, + ) + + ########### F data for fixed values of other parameters ########### + # extracts best-fit values + list1 = [] + vals1 = [] + list2 = [] + vals2 = [] + vals3 = [] + for i, vec in enumerate(uw_vectors): + n = np.argmax(vec) # selects the most likely value + val = uvals[i][n] + if data["params"][i] == "logF": + # enables us to select a slice corresponding to particular F values + list1.append(data["params"][i]) + vals1.append(F_0) + iF = i # setting index for F param + else: + # enables us to select a slice correspondng to the best-fit values of all other params + # i.e. ignoring uncertainty in them + list2.append(data["params"][i]) + vals2.append(val) + + # gets the slice corresponding to specific values of F + F_0_selection = ac.get_slice_from_parameters(data, list1, vals1, verbose=True) + + # will have Bayesian limits on all parameters over everything but F + deprecated, F_vectors, deprecated = ac.get_bayesian_data(F_0_selection) + + ####### 1D plots for prior on F ######## + # generates plots for our standard prior on F only + # applies a prior on F, which is a Gaussian + F_dim = np.where(data["params"] == "logF")[0][0] + + wlls = ac.apply_F_prior(data["ll"], F_dim, data["logF"], F_0, F_sigma) + + deprecated, wF_vectors, wvectors = ac.get_bayesian_data(wlls) + + ac.do_single_plots( + uvals, + wF_vectors, + None, + data["params"], + tag="wF_", + truth=None, + dolevels=True, + latexnames=latexnames, + logspline=False, + outdir=outdir, + ) + + # now do this with others... + # builds others... + others = [] + for i, p in enumerate(data["params"]): + if i == iF: + oset = None + others.append(oset) + else: + if i < iF: + modi = i + else: + modi = i - 1 + oset = [uw_vectors[i]] + others.append(oset) + + # generates plots for our standard prior on F values, and no prior also + ac.do_single_plots( + uvals, + wF_vectors, + None, + data["params"], + tag="wF_others_", + truth=None, + dolevels=True, + latexnames=latexnames, + logspline=False, + others=others, + outdir=outdir, + others_labels=["No prior", "Prior on $F$"], + ) + + +def get_names_values(data): + """ + Gets a list of latex names and corrected parameter values + """ + # builds uvals list + uvals = [] + latexnames = [] + for ip, param in enumerate(data["params"]): + # switches for alpha + if param == "alpha": + uvals.append(data[param] * -1.0) + else: + uvals.append(data[param]) + if param == "alpha": + latexnames.append("$\\alpha$") + ialpha = ip + elif param == "lEmax": + latexnames.append("$\\log_{10} E_{\\rm max}$") + elif param == "H0": + latexnames.append("$H_0$") + elif param == "gamma": + latexnames.append("$\\gamma$") + elif param == "sfr_n": + latexnames.append("$n_{\\rm sfr}$") + elif param == "lmean": + latexnames.append("$\\mu_{\\rm host}$") + elif param == "lsigma": + latexnames.append("$\\sigma_{\\rm host}$") + elif param == "logF": + latexnames.append("$\\log F$") + return uvals, latexnames + + +def get_param_values(data, verbose=False): + """ + Returns the unique cube values for each parameter in the cube + + Input: + data cube (tuple from reading the .npz) + + Output: + list of numpy arrays for each parameter giving their values + """ + # gets unique values for each axis + param_vals = [] + + # for col in param_list: + for col in data["params"]: + # unique=np.unique(col) + unique = np.unique(data[col]) + param_vals.append(unique) + if verbose: + print("For parameter ", col, " cube values are ", unique) + return param_vals + + +# Real Cube Data +main("../Real/Cubes/craco_real_cube.npz", "measured/") +main("../CRACO/Cubes/craco_full_cube.npz", "forecast/") diff --git a/papers/F/Figures/py/figs_compare.py b/papers/F/Figures/py/figs_compare.py new file mode 100644 index 00000000..5a510c09 --- /dev/null +++ b/papers/F/Figures/py/figs_compare.py @@ -0,0 +1,180 @@ +import os, sys +import numpy as np + +from matplotlib import pyplot as plt +from scipy.interpolate import interp1d + +from frb.dm import igm as figm +from frb.figures import utils as fig_utils + +from zdm import figures, pcosmic + +sys.path.append(os.path.abspath("../Analysis/py")) +sys.path.append(os.path.abspath("../../Analysis/py")) +import analy_F_I + +from astropy.cosmology import FlatLambdaCDM + + +def fig_varyF( + outfile, + Fs, + H0s, + lmeans, + lsigmas, + zmax=2.3, + DMmax=1500, + Aconts=[0.05], + lcolors=["b"], + lstyles=["-"], + labels=[""], + zticks=None, + ylim=None, + iFRB=0, + show_FRBs=True, + plotMacquart=True, +): + survey, grid = analy_F_I.craco_mc_survey_grid(iFRB=iFRB) + + fiducial_F = grid.state.IGM.logF + fiducial_H0 = grid.state.cosmo.H0 + fiducial_lmean = grid.state.host.lmean + fiducial_lsigma = grid.state.host.lsigma + + fig, ax = plt.subplots(dpi=300) + + ax.set_xlabel("z") + ax.set_ylabel("${\\rm DM}_{\\rm EG}$") + + legend_lines = [] + + for F, H0, lmean, lsigma, lstyle, color in zip( + Fs, H0s, lmeans, lsigmas, lstyles, lcolors + ): + vparams = {} + + if F is None: + F = fiducial_F + if H0 is None: + H0 = fiducial_H0 + if lmean is None: + lmean = fiducial_lmean + if lsigma is None: + lsigma = fiducial_lsigma + + vparams["logF"] = F + vparams["H0"] = H0 + vparams["lmean"] = lmean + vparams["lsigma"] = lsigma + + grid.update(vparams) + + full_zDMgrid, zvals, dmvals = ( + grid.rates.copy(), + grid.zvals.copy(), + grid.dmvals.copy(), + ) + + zvals, dmvals, zDMgrid = figures.proc_pgrid( + full_zDMgrid, zvals, (0, zmax), dmvals, (0, DMmax) + ) + + alevels = figures.find_Alevels(full_zDMgrid, Aconts) + + plt.sca(ax) + + tvals, ticks = figures.ticks_pgrid(zvals, these_vals=zticks) + plt.xticks(tvals, ticks) + + tvals, ticks = figures.ticks_pgrid(dmvals, fmt="int") + plt.yticks(tvals, ticks) + + cs = ax.contour( + zDMgrid.T, levels=alevels, origin="lower", colors=[color], linestyles=lstyle + ) + + leg, _ = cs.legend_elements() + legend_lines.append(leg[0]) + + ### TEST + # Interpolators + f_DM = interp1d( + dmvals, np.arange(dmvals.size), fill_value="extrapolate", bounds_error=False + ) + f_z = interp1d( + zvals, np.arange(zvals.size), fill_value="extrapolate", bounds_error=False + ) + + cosmo = FlatLambdaCDM( + H0=grid.state.cosmo.H0, + Ob0=grid.state.cosmo.Omega_b, + Om0=grid.state.cosmo.Omega_m, + ) + + if plotMacquart: + dms, zeval = figm.average_DM(3.0, cumul=True, cosmo=cosmo) + l_mqr = ax.plot(f_z(zeval), f_DM(dms), ls="--", c=color, alpha=0.5) + + print("F = ", F, "H0 = ", H0, "lmean = ", lmean, "lsigma = ", lsigma) + + # put down FRBs + FRBZ = survey.frbs["Z"] + FRBDM = survey.DMEGs + + ddm = dmvals[1] - dmvals[0] + dz = zvals[1] - zvals[0] + nz, ndm = zDMgrid.shape + + ##### add FRB host galaxies at some DM/redshift ##### + if (FRBZ is not None) and show_FRBs: + iDMs = FRBDM / ddm + iZ = FRBZ / dz + # Restrict to plot range + gd = (FRBDM < DMmax) & (FRBZ < zmax) + ax.plot(iZ[gd], iDMs[gd], "ko", linestyle="", markersize=2.0) + + ax.legend(legend_lines, labels, loc="lower right") + + # Fontsize + fig_utils.set_fontsize(ax, 16.0) + + fig.tight_layout() + plt.savefig(outfile, dpi=300, bbox_inches="tight") + plt.close() + print(f"Wrote: {outfile}") + + +# fig_varyF( +# "fig_varyF_H0_compare.png", +# Fs=[-0.57, -0.37, None], +# H0s=[69.02, 77.14, None], +# lmeans=[None, None, None], +# lsigmas=[None, None, None], +# lcolors=["r", "b", "k"], +# lstyles=["-", "-", "--"], +# labels=["Synthetic", "Real", "Fiducial"], +# DMmax=2500, +# Aconts=[0.01], +# show_FRBs=False, +# zmax=3, +# ) + +# 95th ptile +fig_varyF( + "degeneracy/fig_H0_F_Degeneracy.png", + Fs=[None, np.log10(0.82)], + H0s=[None, 55], + lmeans=[None, None], + lsigmas=[None, None], + lcolors=["b", "r"], + lstyles=["-", "-"], + labels=[ + r"$H_0$ = 67.66, $\log_{10} F =$ -0.49", + r"$H_0$ = 55, $\log_{10} F =$ -0.086", + ], + DMmax=1800, + Aconts=[0.025], + show_FRBs=False, + zmax=2.3, + plotMacquart=False, +) diff --git a/papers/F/Figures/py/figs_zdm_F_I.py b/papers/F/Figures/py/figs_zdm_F_I.py new file mode 100644 index 00000000..5d6d65ce --- /dev/null +++ b/papers/F/Figures/py/figs_zdm_F_I.py @@ -0,0 +1,630 @@ +import os, sys +import numpy as np + +from matplotlib import pyplot as plt +from scipy.interpolate import interp1d + +from frb.dm import igm as figm +from frb.figures import utils as fig_utils + +from zdm import figures, pcosmic + +sys.path.append(os.path.abspath("../Analysis/py")) +sys.path.append(os.path.abspath("../../Analysis/py")) +import analy_F_I + +from astropy.cosmology import FlatLambdaCDM + + +def fig_craco_varyF_zDM( + outfile, + zmax=2.3, + DMmax=1500, + norm=2, + other_param="Emax", + Aconts=[0.05], + fuss_with_ticks: bool = False, + suppress_DM_host=False, + iFRB=0, + show_FRBS=True, +): + """_summary_ + + Args: + outfile (_type_): _description_ + zmax (float, optional): _description_. Defaults to 2.3. + DMmax (int, optional): _description_. Defaults to 1500. + norm (int, optional): _description_. Defaults to 2. + other_param (str, optional): _description_. Defaults to 'Emax'. + Aconts (list, optional): _description_. Defaults to [0.05]. + fuss_with_ticks (bool, optional): _description_. Defaults to False. + """ + # Generate the grid + survey, grid = analy_F_I.craco_mc_survey_grid(iFRB=iFRB) + + fiducial_Emax = grid.state.energy.lEmax + fiducial_H0 = grid.state.cosmo.H0 + fiducial_lmean = grid.state.host.lmean + fiducial_lsigma = grid.state.host.lsigma + + plt.figure(dpi=300) + ax1 = plt.axes() + + plt.sca(ax1) + + plt.xlabel("z") + plt.ylabel("${\\rm DM}_{\\rm EG}$") + + if other_param == "Emax": + F_values = [0.01, 0.3, 0.7, 0.9] + other_values = [0.0, 0.0, 0.0, -0.1] + lstyles = ["-", "-", "-", ":"] + zticks = [0.5, 1.0, 1.5, 2.0] + ylim = (0.0, DMmax) + elif other_param == "H0": + F_values = [0.01, 0.3, 0.7, 0.9] + other_values = [fiducial_H0, fiducial_H0, fiducial_H0, fiducial_H0] + lstyles = ["-", "-", "-", ":"] + zticks, ylim = None, None + elif other_param == "lmean": + F_values = [0.01, 0.32, 0.7, 0.32] + other_values = [0.0, 1.0, 0.0, 3.0] + lstyles = ["-", "-", "-", ":"] + zticks, ylim = None, None + + # Loop on grids + legend_lines = [] + labels = [] + for F, scl, lstyle, clr in zip( + F_values, other_values, lstyles, ["b", "k", "r", "gray"] + ): + # Update grid + vparams = {} + vparams["logF"] = F + + # Sets the log-normal distribution for DM_host to ~0. + if suppress_DM_host: + vparams["lmean"] = 1e-3 + vparams["lsigma"] = 0.1 + + if other_param == "Emax": + vparams["lEmax"] = fiducial_Emax + scl + elif other_param == "H0": + vparams["H0"] = scl + elif other_param == "lmean": + vparams["lsigma"] = fiducial_lsigma + vparams["lmean"] = scl + + grid.update(vparams) + + # Unpack + full_zDMgrid, zvals, dmvals = ( + grid.rates.copy(), + grid.zvals.copy(), + grid.dmvals.copy(), + ) + + # currently this is "per cell" - now to change to "per DM" + # normalises the grid by the bin width, i.e. probability per bin, not probability density + + # checks against zeros for a log-plot + + zvals, dmvals, zDMgrid = figures.proc_pgrid( + full_zDMgrid, zvals, (0, zmax), dmvals, (0, DMmax) + ) + + # Contours + alevels = figures.find_Alevels(full_zDMgrid, Aconts) + + # Sets the x and y ticks + tvals, ticks = figures.ticks_pgrid(zvals, these_vals=zticks) # , fmt='str4') + plt.xticks(tvals, ticks) + tvals, ticks = figures.ticks_pgrid(dmvals, fmt="int") # , fmt='str4') + plt.yticks(tvals, ticks) + + ax = plt.gca() + cs = ax.contour( + zDMgrid.T, levels=alevels, origin="lower", colors=[clr], linestyles=lstyle + ) + leg, _ = cs.legend_elements() + legend_lines.append(leg[0]) + + # Label + if other_param == "Emax": + labels.append( + r"$\\log_\{10\} F = $" + + f"{F}, log " + + r"$E_{\rm max}$" + + f"= {vparams['lEmax']}" + ) + elif other_param == "H0": + labels.append(r"$\log_\{10\} F = " + f"{F}, H0 = {vparams['H0']}") + elif other_param == "lmean": + labels.append(r"$\log_\{10\} F = " + f"{F}, $\mu =$ {vparams['lmean']}") + + ###### gets decent axis labels, down to 1 decimal place ####### + ax = plt.gca() + + # Interpolators + f_DM = interp1d( + dmvals, np.arange(dmvals.size), fill_value="extrapolate", bounds_error=False + ) + f_z = interp1d( + zvals, np.arange(zvals.size), fill_value="extrapolate", bounds_error=False + ) + + cosmo = FlatLambdaCDM( + H0=grid.state.cosmo.H0, + Ob0=grid.state.cosmo.Omega_b, + Om0=grid.state.cosmo.Omega_m, + ) + dms, zeval = figm.average_DM(2.0, cumul=True, cosmo=cosmo) + + l_mqr = ax.plot(f_z(zeval), f_DM(dms), "k--") + + legend_lines.append(l_mqr[0]) + labels.append("Macquart Relation") + + ax.legend(legend_lines, labels, loc="lower right") + + # put the FRBs in + + FRBZ = survey.frbs["Z"] + FRBDM = survey.DMEGs + + # Cut down grid + zvals, dmvals, zDMgrid = figures.proc_pgrid( + full_zDMgrid, zvals, (0, zmax), dmvals, (0, DMmax) + ) + ddm = dmvals[1] - dmvals[0] + dz = zvals[1] - zvals[0] + nz, ndm = zDMgrid.shape + + ##### add FRB host galaxies at some DM/redshift ##### + if (FRBZ is not None) and show_FRBS: + iDMs = FRBDM / ddm + iZ = FRBZ / dz + # Restrict to plot range + gd = (FRBDM < DMmax) & (FRBZ < zmax) + ax.plot(iZ[gd], iDMs[gd], "ko", linestyle="", markersize=2.0) + + # Fontsize + fig_utils.set_fontsize(ax, 16.0) + + # Ticks + if fuss_with_ticks: + labels = [item.get_text() for item in ax.get_xticklabels()] + for i in np.arange(len(labels)): + labels[i] = labels[i][0:4] + ax.set_xticklabels(labels) + labels = [item.get_text() for item in ax.get_yticklabels()] + for i in np.arange(len(labels)): + if "." in labels[i]: + labels[i] = labels[i].split(".")[0] + ax.set_yticklabels(labels) + ax.yaxis.labelpad = 0 + + # Finish + plt.tight_layout() + plt.savefig(outfile, dpi=300, bbox_inches="tight") + plt.close() + print(f"Wrote: {outfile}") + + +### + + +def fig_varyF( + outfile, + zmax=2.3, + DMmax=1500, + other_param="lmean", + Aconts=[0.05], + F_values=[None], + other_values=[None], + lcolors=["b"], + lstyles=["-"], + zticks=None, + ylim=None, + iFRB=0, + show_FRBs=True, +): + survey, grid = analy_F_I.craco_mc_survey_grid(iFRB=iFRB) + + fiducial_F = grid.state.IGM.logF + fiducial_Emax = grid.state.energy.lEmax + fiducial_H0 = grid.state.cosmo.H0 + fiducial_lmean = grid.state.host.lmean + fiducial_lsigma = grid.state.host.lsigma + + fig, ax = plt.subplots(dpi=200) + + ax.set_xlabel("z") + ax.set_ylabel("${\\rm DM}_{\\rm EG}$") + + legend_lines = [] + labels = [] + + for F, other, lstyle, color in zip(F_values, other_values, lstyles, lcolors): + vparams = {} + + if F is None: + F = fiducial_F + + vparams["logF"] = F + + if other_param == "H0": + if other == None: + other = fiducial_H0 + vparams["H0"] = other + elif other_param == "Emax": + if other == None: + other = fiducial_Emax + vparams["Emax"] = other + other = fiducial_Emax + elif other_param == "lmean": + if other == None: + other = fiducial_lmean + vparams["lmean"] = other + other = fiducial_lmean + + grid.update(vparams) + + full_zDMgrid, zvals, dmvals = ( + grid.rates.copy(), + grid.zvals.copy(), + grid.dmvals.copy(), + ) + + zvals, dmvals, zDMgrid = figures.proc_pgrid( + full_zDMgrid, zvals, (0, zmax), dmvals, (0, DMmax) + ) + + alevels = figures.find_Alevels(full_zDMgrid, Aconts) + + plt.sca(ax) + + tvals, ticks = figures.ticks_pgrid(zvals, these_vals=zticks) + plt.xticks(tvals, ticks) + + tvals, ticks = figures.ticks_pgrid(dmvals, fmt="int") + plt.yticks(tvals, ticks) + + cs = ax.contour( + zDMgrid.T, levels=alevels, origin="lower", colors=[color], linestyles=lstyle + ) + + leg, _ = cs.legend_elements() + legend_lines.append(leg[0]) + + ### TEST + # Interpolators + f_DM = interp1d( + dmvals, np.arange(dmvals.size), fill_value="extrapolate", bounds_error=False + ) + f_z = interp1d( + zvals, np.arange(zvals.size), fill_value="extrapolate", bounds_error=False + ) + + cosmo = FlatLambdaCDM( + H0=grid.state.cosmo.H0, + Ob0=grid.state.cosmo.Omega_b, + Om0=grid.state.cosmo.Omega_m, + ) + + dms, zeval = figm.average_DM(2.0, cumul=True, cosmo=cosmo) + + l_mqr = ax.plot(f_z(zeval), f_DM(dms), ls="--", c=color, alpha=0.5) + + #### TEST END + + if other_param == "Emax": + labels.append( + r"$\\log_\{10\} F = $" + + f"{F}, log " + + r"$E_{\rm max}$" + + f"= {vparams['lEmax']}" + ) + elif other_param == "H0": + labels.append(r"$\log_{10} F = $" + f"{F}, H0 = {vparams['H0']}") + elif other_param == "lmean": + labels.append(r"$\log_{10} F = $" + f"{F}, $\mu =$ {vparams['lmean']}") + + # # Interpolators + # f_DM = interp1d( + # dmvals, np.arange(dmvals.size), fill_value="extrapolate", bounds_error=False + # ) + # f_z = interp1d( + # zvals, np.arange(zvals.size), fill_value="extrapolate", bounds_error=False + # ) + + # cosmo = FlatLambdaCDM( + # H0=grid.state.cosmo.H0, + # Ob0=grid.state.cosmo.Omega_b, + # Om0=grid.state.cosmo.Omega_m, + # ) + + # dms, zeval = figm.average_DM(2.0, cumul=True, cosmo=cosmo) + + # l_mqr = ax.plot(f_z(zeval), f_DM(dms), "k--") + + # legend_lines.append(l_mqr[0]) + # labels.append("Macquart Relation") + + # put down FRBs + + FRBZ = survey.frbs["Z"] + FRBDM = survey.DMEGs + + ddm = dmvals[1] - dmvals[0] + dz = zvals[1] - zvals[0] + nz, ndm = zDMgrid.shape + + ##### add FRB host galaxies at some DM/redshift ##### + if (FRBZ is not None) and show_FRBs: + iDMs = FRBDM / ddm + iZ = FRBZ / dz + # Restrict to plot range + gd = (FRBDM < DMmax) & (FRBZ < zmax) + ax.plot(iZ[gd], iDMs[gd], "ko", linestyle="", markersize=2.0) + + ax.legend(legend_lines, labels, loc="lower right") + + # Fontsize + fig_utils.set_fontsize(ax, 16.0) + + fig.tight_layout() + plt.savefig(outfile, dpi=300, bbox_inches="tight") + plt.close() + print(f"Wrote: {outfile}") + + +### + + +def fig_craco_fiducial_F( + outfile="fig_craco_fiducial_F.png", + zmax=2.5, + DMmax=2500, + show_Macquart=False, + log=True, + label="$\\log_{10} \; p(DM_{\\rm EG},z)$", + Aconts=[0.01, 0.1, 0.5], + cmap="jet", + show=False, + figsize=None, + vmnx=(None, None), + grid=None, + survey=None, + F=-0.49, + H0=None, + iFRB=0, + suppress_DM_host=False, + show_FRBs=True, +): + """ + Very complicated routine for plotting 2D zdm grids + Args: + zDMgrid ([type]): [description] + zvals ([type]): [description] + dmvals ([type]): [description] + zmax (int, optional): [description]. Defaults to 1. + DMmax (int, optional): [description]. Defaults to 1000. + norm (int, optional): [description]. Defaults to 0. + log (bool, optional): [description]. Defaults to True. + label (str, optional): [description]. Defaults to '$\log_{10}p(DM_{\rm EG},z)$'. + project (bool, optional): [description]. Defaults to False. + conts (bool, optional): [description]. Defaults to False. + FRBZ ([type], optional): [description]. Defaults to None. + FRBDM ([type], optional): [description]. Defaults to None. + Aconts (bool, optional): [description]. Defaults to False. + Macquart (state, optional): state object. Used to generat the Maquart relation. + Defaults to None. + title (str, optional): [description]. Defaults to "Plot". + H0 ([type], optional): [description]. Defaults to None. + showplot (bool, optional): [description]. Defaults to False. + """ + # Generate the grid + if grid is None or survey is None: + survey, grid = analy_F_I.craco_mc_survey_grid(iFRB=iFRB) + + fiducial_H0 = grid.state.cosmo.H0 + + if H0 is None: + H0 = fiducial_H0 + + vparams = {"H0": H0, "logF": F} + + if suppress_DM_host: + # Sets the log-normal distribution for DM_host to ~0. + vparams["lmean"] = 1e-3 + vparams["lsigma"] = 0.1 + + grid.update(vparams) + + # Unpack + full_zDMgrid, zvals, dmvals = grid.rates, grid.zvals, grid.dmvals + FRBZ = survey.frbs["Z"] + FRBDM = survey.DMEGs + + ##### imshow of grid ####### + fsize = 14.0 + plt.figure(figsize=figsize) + ax1 = plt.axes() + plt.sca(ax1) + + plt.xlabel("z") + plt.ylabel("${\\rm DM}_{\\rm EG}$") + # plt.title(title+str(H0)) + + # Cut down grid + zvals, dmvals, zDMgrid = figures.proc_pgrid( + full_zDMgrid, zvals, (0, zmax), dmvals, (0, DMmax) + ) + ddm = dmvals[1] - dmvals[0] + dz = zvals[1] - zvals[0] + nz, ndm = zDMgrid.shape + + # Contours + alevels = figures.find_Alevels(full_zDMgrid, Aconts, log=True) + + # Ticks + tvals, ticks = figures.ticks_pgrid(zvals) # , fmt='str4') + plt.xticks(tvals, ticks) + tvals, ticks = figures.ticks_pgrid(dmvals, fmt="int") # , fmt='str4') + plt.yticks(tvals, ticks) + + # Image + im = plt.imshow( + zDMgrid.T, + cmap=cmap, + origin="lower", + vmin=vmnx[0], + vmax=vmnx[1], + interpolation="None", + aspect="auto", + ) + + styles = ["--", "-.", ":"] + ax = plt.gca() + cs = ax.contour( + zDMgrid.T, levels=alevels, origin="lower", colors="white", linestyles=styles + ) + + ax = plt.gca() + + ax.set_title(rf"$\log_{{10}} F = {F}$, $H_0$ = {H0}") + + muDMhost = np.log(10**grid.state.host.lmean) + sigmaDMhost = np.log(10**grid.state.host.lsigma) + meanHost = np.exp(muDMhost + sigmaDMhost**2 / 2.0) + medianHost = np.exp(muDMhost) + print(f"Host: mean={meanHost}, median={medianHost}") + plt.ylim(0, ndm - 1) + plt.xlim(0, nz - 1) + zmax = zvals[-1] + nz = zvals.size + # DMbar, zeval = igm.average_DM(zmax, cumul=True, neval=nz+1) + DM_cosmic = pcosmic.get_mean_DM(zvals, grid.state) + + # idea is that 1 point is 1, hence... + zeval = zvals / dz + DMEG_mean = (DM_cosmic + meanHost) / ddm + DMEG_median = (DM_cosmic + medianHost) / ddm + + # Check median + f_median = interp1d(zvals, DM_cosmic + medianHost, fill_value="extrapolate") + eval_DMEG = f_median(FRBZ) + above = FRBDM > eval_DMEG + print(f"There are {np.sum(above)/len(FRBZ)} above the median") + + if show_Macquart: + plt.plot( + zeval, + DMEG_mean, + color="gray", + linewidth=2, + label="Macquart relation (mean)", + ) + # plt.plot( + # zeval, + # DMEG_median, + # color="gray", + # linewidth=2, + # ls="--", + # label="Macquart relation (median)", + # ) + l = plt.legend(loc="lower right", fontsize=12) + # l=plt.legend(bbox_to_anchor=(0.2, 0.8),fontsize=8) + # for text in l.get_texts(): + # text.set_color("white") + + # limit to a reasonable range if logscale + if log and vmnx[0] is None: + themax = zDMgrid.max() + themin = int(themax - 4) + themax = int(themax) + plt.clim(themin, themax) + + ##### add FRB host galaxies at some DM/redshift ##### + if (FRBZ is not None) and show_FRBs: + iDMs = FRBDM / ddm + iZ = FRBZ / dz + # Restrict to plot range + gd = (FRBDM < DMmax) & (FRBZ < zmax) + plt.plot(iZ[gd], iDMs[gd], "ko", linestyle="", markersize=2.0) + + cbar = plt.colorbar(im, fraction=0.046, shrink=1.2, aspect=15, pad=0.05) + cbar.set_label(label) + + fig_utils.set_fontsize(ax, fsize) + + plt.tight_layout() + + if show: + plt.show() + else: + plt.savefig(outfile, dpi=300) + print(f"Wrote: {outfile}") + plt.close() + + +### tests + +# logfs = [-1.5, -1.5, -1.5] +# h0s = [62.5, 64, 67] + + +# for h0, logF in zip(h0s, logfs): +# fig_craco_fiducial_F( +# f"diagnostic/fig_craco_logF_{logF}_H0_{h0}.png", +# show_Macquart=True, +# F=logF, +# H0=h0, +# suppress_DM_host=False, +# ) + +# fig_varyF( +# "fig_varyF_H0_compare.png", +# other_param="H0", +# F_values=[-0.57, -.37], +# other_values=[69.02, 77.14], +# lcolors=["r", "b"], +# lstyles=["-", "-"], +# DMmax=2500, +# Aconts=[0.01], +# show_FRBs=False, +# zmax=3 +# ) + +fig_craco_fiducial_F( + f"figs/fiducial_distribution.png", + show_Macquart=True, + H0=None, + suppress_DM_host=False, + iFRB=100, + show_FRBs=True, + Aconts=[0.025], +) + +fig_craco_fiducial_F( + f"figs/high_feedback_efficiency.png", + show_Macquart=False, + F=np.round(np.log10(0.01), 3), + H0=None, + suppress_DM_host=False, + iFRB=100, + show_FRBs=False, + Aconts=[0.025], +) + +fig_craco_fiducial_F( + f"figs/low_feedback_efficiency.png", + show_Macquart=False, + F=np.round(np.log10(0.9), 3), + H0=None, + suppress_DM_host=False, + iFRB=100, + show_FRBs=False, + Aconts=[0.025], +) diff --git a/papers/F/Tables/results.tex b/papers/F/Tables/results.tex new file mode 100644 index 00000000..55e42efd --- /dev/null +++ b/papers/F/Tables/results.tex @@ -0,0 +1,21 @@ +\newcommand{\Hubble}{\ensuremath{85.3_{-8.1}^{+9.4}}} +\newcommand{\fctH}{\ensuremath{69.2_{-4.9}^{+5.5}}} +\newcommand{\FnoPrior}{\ensuremath{ -0.75 _{-0.25}^{+0.33}}} +\newcommand{\fctFnoPrior}{\ensuremath{ -0.57 _{-0.16}^{+0.15}}} +\newcommand{\lmeannoPrior}{\ensuremath{ 2.44 _{-0.06}^{+0.06}}} +\newcommand{\lhostnoPrior}{\ensuremath{ 0.50 _{-0.06}^{+0.08}}} +\newcommand{\fctHwPrior}{\ensuremath{67.6_{-3.4}^{+3.5}}} +\newcommand{\fctlmeanwFPrior}{\ensuremath{2.2_{-0.1}^{+0.1}}} +\newcommand{\fctlhostwFPrior}{\ensuremath{0.5_{-0.1}^{+0.1}}} +\newcommand{\HwFPrior}{\ensuremath{80.2_{-7.1}^{+8.5}}} +\newcommand{\lmeanwFPrior}{\ensuremath{2.5_{-0.1}^{+0.1}}} +\newcommand{\lsigmawFPrior}{\ensuremath{0.5_{-0.1}^{+0.1}}} +\newcommand{\FwPrior}{\ensuremath{ -0.48 _{-0.18}^{+0.26}}} +\newcommand{\FCMB}{\ensuremath{ -0.48 _{-0.18}^{+0.26}}} +\newcommand{\FSNe}{\ensuremath{ -0.48 _{-0.18}^{+0.26}}} +\newcommand{\lmeanwHPrior}{\ensuremath{2.4_{-0.1}^{+0.1}}} +\newcommand{\lsigmawHPrior}{\ensuremath{0.5_{-0.1}^{+0.1}}} +\newcommand{\fctFwPrior}{\ensuremath{ -0.60 _{-0.1}^{+0.09}}} +\newcommand{\fctFCMB}{\ensuremath{ -0.60 _{-0.1}^{+0.09}}} +\newcommand{\fctFSNe}{\ensuremath{ -0.48 _{-0.18}^{+0.26}}} +\newcommand{\Flower}{\ensuremath{-0.86}} diff --git a/papers/F/Tables/tab_frbs.tex b/papers/F/Tables/tab_frbs.tex new file mode 100644 index 00000000..e49d5618 --- /dev/null +++ b/papers/F/Tables/tab_frbs.tex @@ -0,0 +1,25 @@ +\begin{table*} +\centering +\begin{minipage}{170mm} +\centering +\caption{New FRB detections detected in 2022 used in addition to the FRB surveys used in \citet{j22b}. The FRB name, SNR-maximizing DM, \dmism\ estimated using the NE2001 model of \citet{CordesLazio01}, central frequency of observation $\nu$, measured signal-to-noise ratio SNR, redshift $z$, and original reference. Where redshifts are not given, this is because (a): no voltage data were dumped, preventing radio localization; (b) optical follow-up observations are not yet complete; (c) Substantial Galactic extinction has challenged follow-up optical observations; (d) the host galaxy appears too distant to accurately measure a redshift. All FRBs referenced are from Shannon et al. (in prep.) with the exception of FRB20220610A \citep{ryder22}. \label{tab:frbs}} +\begin{tabular}{ccccccc} +\hline +Name & Survey & DM & \dmism & $\nu$ & SNR & $z$ \\ +& & (\dmunits) & (\dmunits) & (MHz) & & +\\ +\hline +20220725A& \icslow& 290.4& 30.7& 920.5& 12.7& 0.1926\\ +20220501C& \icslow& 449.5& 30.6& 863.5& 16.1& 0.381\\ +20211203C& \icslow& 636.2& 63.4& 920.5& 14.2& 0.34386\\ +\hline +20220918A& \icsmid& 656.8& 40.7& 1271.5& 26.4& --\\ +20220610A& \icsmid& 1458.1& 31.0& 1271.5& 29.8& 1.016\\ +20220531A& \icsmid& 727.0& 70.0& 1271.5& 9.7& --\\ +\hline +20221106A& \icshigh& 344.0& 34.8& 1631.5& 35.1& --\\ +20220105A& \icshigh& 583.0& 22.0& 1632.5& 9.8& 0.2785\\ +\hline +\hline\end{tabular} +\end{minipage} +\end{table*} diff --git a/papers/F/Tables/tab_model_params.tex b/papers/F/Tables/tab_model_params.tex new file mode 100644 index 00000000..9d8a4e65 --- /dev/null +++ b/papers/F/Tables/tab_model_params.tex @@ -0,0 +1,22 @@ +\begin{deluxetable}{cccccc} +\tablewidth{20pt} +\tablecaption{z-DM grid parameters \label{tab:fullcube}} +\tabletypesize{\normalsize} +\tablehead{ \colhead{Parameter} & + \colhead{Unit} & + \colhead{Fiducial} & + \colhead{Min} & + \colhead{Max} & + \colhead{N} }\startdata +$H_0$ &km s$^{-1}$ Mpc$^{-1}$ &67.66 &60.00 &80.00 &21 \\ +$$\log_{10} F$$ & &-0.49 &-1.70 &0.00 &30 \\ +$\mu_{\rm host}$ &pc cm$^{-3}$ &2.18 &1.70 &2.50 &10 \\ +$\sigma_{\rm host}$ &pc cm$^{-3}$ &0.48 &0.20 &0.90 &10 \\ +$\alpha$ & &0.65 &-- &-- &-- \\ +$\gamma$ & &-1.01 &-- &-- &-- \\ +$n_{\rm sfr}$ & &0.73 &-- &-- &-- \\ +$\log_{10} E_{\rm max}$ &erg &41.40 &-- &-- &-- \\ +\hline +\enddata +\tablecomments{This table indicates the parameters of the high-resolution grid run. Non-degenerate parameters are held to the fiducial values. $N$ is the number of cells between the minimum and maximum parameter values.} +\end{deluxetable} diff --git a/papers/F/Tables/tables_F.py b/papers/F/Tables/tables_F.py new file mode 100644 index 00000000..e61da5f8 --- /dev/null +++ b/papers/F/Tables/tables_F.py @@ -0,0 +1,380 @@ +# Module for Tables for the Baptista+23 paper +# Imports +import numpy as np +import os, sys +import pandas + + +from zdm.craco import loading +from zdm import survey +from zdm import parameters +from zdm import misc_functions +from zdm import io +from zdm import iteration as it + +from IPython import embed + +# Local +sys.path.append(os.path.abspath("../Analysis/py")) +import analy_F_I +import pandas as pd + + +def mktab_model_params(outfile="tab_model_params.tex", sub=False): + isurvey, grid = analy_F_I.craco_mc_survey_grid() + tb = pd.read_json("../Analysis/CRACO/Cubes/craco_full_cube.json") + + # Open + tbfil = open(outfile, "w") + + # Header + tbfil.write("\\begin{deluxetable}{cccccc} \n") + tbfil.write("\\tablewidth{20pt} \n") + tbfil.write("\\tablecaption{z-DM grid parameters \label{tab:fullcube}} \n") + tbfil.write("\\tabletypesize{\\normalsize} \n") + tbfil.write( + "\\tablehead{ \colhead{Parameter} & \n \colhead{Unit} & \n \colhead{Fiducial} & \n \colhead{Min} & \n \colhead{Max} & \n \colhead{N} }" + ) + tbfil.write("\\startdata \n") + + params_vary = ["H0", "logF", "lmean", "lsigma"] + params_fix = ["alpha", "gamma", "sfr_n", "lEmax"] + + for key in params_vary: + item = grid.state.params[key] + latex = getattr(grid.state, item).meta(key)["Notation"] + min_val = tb[key]["min"] + max_val = tb[key]["max"] + n_val = tb[key]["n"] + + line = "" + # Name + line += f"${latex}$ &" + # Unit + line += f"{getattr(grid.state, item).meta(key)['unit']} &" + # Fiducial + line += f"{getattr(getattr(grid.state, item), key):.2f} &" + # Min + line += f"{min_val:.2f} &" + # Max + line += f"{max_val:.2f} &" + # N + line += f"{n_val} \\\\ \n" + tbfil.write(line) + + for key in params_fix: + item = grid.state.params[key] + latex = getattr(grid.state, item).meta(key)["Notation"] + + line = "" + # Name + line += f"${latex}$ &" + # Unit + line += f"{getattr(grid.state, item).meta(key)['unit']} &" + # Fiducial + line += f"{getattr(getattr(grid.state, item), key):.2f} &" + # Min + line += f"-- &" + # Max + line += f"-- &" + # N + line += f"-- \\\\ \n" + tbfil.write(line) + + tbfil.write("\\hline \n") + tbfil.write("\\enddata \n") + tbfil.write( + "\\tablecomments{This table indicates the parameters of the high-resolution grid run. Non-degenerate parameters are held to the fiducial values. $N$ is the number of cells between the minimum and maximum parameter values.} \n" + ) + tbfil.write("\\end{deluxetable} \n") + tbfil.close() + + print("Wrote {:s}".format(outfile)) + + +def mktex_measurements(outfile="results.tex"): + # Open + tbfil = open(outfile, "w") + + # Files where measurements are stored + craco_no_prior = "../Analysis/CRACO/logF_Full/limits.dat" + real_no_prior = "../Analysis/Real/real/limits.dat" + + real_F_wH0prior_file = "../Analysis/py/wH0_others_measured/limits.dat" + real_F_CMB_file = ( + "../Analysis/py/wH0_others_measured/limits_others_$H_0 = 67.4$.dat" + ) + real_F_SNe_file = ( + "../Analysis/py/wH0_others_measured/limits_others_$H_0 = 73.04$.dat" + ) + + craco_F_wH0prior_file = "../Analysis/py/wH0_others_forecast/limits.dat" + craco_F_CMB_file = ( + "../Analysis/py/wH0_others_forecast/limits_others_$H_0 = 67.4$.dat" + ) + craco_F_SNe_file = ( + "../Analysis/py/wH0_others_forecast/limits_others_$H_0 = 73.04$.dat" + ) + + real_H0_wFprior_file = "../Analysis/py/wF_others_measured/limits.dat" + craco_H0_wFprior_file = "../Analysis/py/wF_others_forecast/limits.dat" + + def process_limits(lim, precision=1): + lower = str(round(float(lim[5:9]), precision)) + upper = str(round(float(lim[13:17]), precision)) + + return f"_{{-{lower}}}^{{+{upper}}}" + + # No Prior Measurements + + ############### H0 with no prior ############## + with open(craco_no_prior) as f: + craco_lines = f.readlines() + + with open(real_no_prior) as f: + real_lines = f.readlines() + + craco_H0 = str(round(float(craco_lines[0].split("&")[1]), 1)) + craco_H0_lim = process_limits(craco_lines[0].split("&")[-2]) + + # + real_H0 = str(round(float(real_lines[0].split("&")[1]), 1)) + real_H0_lim = process_limits(real_lines[0].split("&")[-2]) + + real_H0_tex = ( + f"\\newcommand{{\\Hubble}}{{\\ensuremath{{{real_H0}{real_H0_lim}}}}} \n" + ) + craco_H0_tex = ( + f"\\newcommand{{\\fctH}}{{\\ensuremath{{{craco_H0}{craco_H0_lim}}}}} \n" + ) + + tbfil.write(real_H0_tex) + tbfil.write(craco_H0_tex) + + ############### F with no prior ############### + craco_F = craco_lines[-1].split("&")[1] + craco_F_lim = process_limits(craco_lines[-1].split("&")[-2], 2) + + real_F = real_lines[-1].split("&")[1] + real_F_lim = process_limits(real_lines[-1].split("&")[-2], 2) + + real_F_tex = ( + f"\\newcommand{{\\FnoPrior}}{{\\ensuremath{{{real_F}{real_F_lim}}}}} \n" + ) + craco_F_tex = ( + f"\\newcommand{{\\fctFnoPrior}}{{\\ensuremath{{{craco_F}{craco_F_lim}}}}} \n" + ) + tbfil.write(real_F_tex) + tbfil.write(craco_F_tex) + + # Uses real data only # + ############### lmean with no prior ############## + real_lmean = real_lines[1].split("&")[1] + real_lmean_lim = process_limits(real_lines[1].split("&")[-2], 2) + real_lmean_tex = f"\\newcommand{{\\lmeannoPrior}}{{\\ensuremath{{{real_lmean}{real_lmean_lim}}}}} \n" + tbfil.write(real_lmean_tex) + + ############### lsigma with no prior ############## + real_lsigma = real_lines[2].split("&")[1] + real_lsigma_lim = process_limits(real_lines[2].split("&")[-2], 2) + real_lsigma_tex = f"\\newcommand{{\\lhostnoPrior}}{{\\ensuremath{{{real_lsigma}{real_lsigma_lim}}}}} \n" + tbfil.write(real_lsigma_tex) + + ### -------- Measurements with priors --------- ### + + ############### H0 with F prior ############### + + ## Synthetic Data ## + + with open(craco_H0_wFprior_file) as f: + craco_H0_wFprior_lines = f.readlines() + + craco_H0_wFprior = str(round(float(craco_H0_wFprior_lines[0].split("&")[1]), 1)) + craco_H0_wFprior_lim = process_limits(craco_H0_wFprior_lines[0].split("&")[-2]) + craco_H0_wFprior_tex = f"\\newcommand{{\\fctHwPrior}}{{\\ensuremath{{{craco_H0_wFprior}{craco_H0_wFprior_lim}}}}} \n" + + # craco_lmean_wFprior = str(round(float(craco_H0_wFprior_lines[1].split("&")[1]), 1)) + # craco_lmean_wFprior_lim = process_limits(craco_H0_wFprior_lines[1].split("&")[-2]) + # craco_lmean_wFprior_tex = f"\\newcommand{{\\fctlmeanwFPrior}}{{\\ensuremath{{{craco_lmean_wFprior}{craco_lmean_wFprior_lim}}}}} \n" + + # craco_lsigma_wFprior = str(round(float(craco_H0_wFprior_lines[2].split("&")[1]), 1)) + # craco_lsigma_wFprior_lim = process_limits(craco_H0_wFprior_lines[2].split("&")[-2]) + # craco_lsigma_wFprior_tex = f"\\newcommand{{\\fctlhostwFPrior}}{{\\ensuremath{{{craco_lsigma_wFprior}{craco_lsigma_wFprior_lim}}}}} \n" + + tbfil.write(craco_H0_wFprior_tex) + # tbfil.write(craco_lmean_wFprior_tex) + # tbfil.write(craco_lsigma_wFprior_tex) + + ## Real Data -- This doesn't make sense lol## + # with open(real_H0_wFprior_file) as f: + # real_H0_wFprior_lines = f.readlines() + + # real_H0_wFprior = str(round(float(real_H0_wFprior_lines[0].split("&")[1]), 1)) + # real_H0_wFprior_lim = process_limits(real_H0_wFprior_lines[0].split("&")[-2]) + # real_H0_wFprior_tex = f"\\newcommand{{\\HwFPrior}}{{\\ensuremath{{{real_H0_wFprior}{real_H0_wFprior_lim}}}}} \n" + + # real_lmean_wFprior = str(round(float(real_H0_wFprior_lines[1].split("&")[1]), 1)) + # real_lmean_wFprior_lim = process_limits(real_H0_wFprior_lines[1].split("&")[-2]) + # real_lmean_wFprior_tex = f"\\newcommand{{\\lmeanwFPrior}}{{\\ensuremath{{{real_lmean_wFprior}{real_lmean_wFprior_lim}}}}} \n" + + # real_lsigma_wFprior = str(round(float(real_H0_wFprior_lines[2].split("&")[1]), 1)) + # real_lsigma_wFprior_lim = process_limits(real_H0_wFprior_lines[2].split("&")[-2]) + # real_lsigma_wFprior_tex = f"\\newcommand{{\\lsigmawFPrior}}{{\\ensuremath{{{real_lsigma_wFprior}{real_lsigma_wFprior_lim}}}}} \n" + + # tbfil.write(real_H0_wFprior_tex) + # tbfil.write(real_lmean_wFprior_tex) + # tbfil.write(real_lsigma_wFprior_tex) + + ############### F with H0 prior ############### + # Measurements + # Uniform Prior + with open(real_F_wH0prior_file) as f: + real_F_wH0prior_lines = f.readlines() + + real_F_wH0prior = real_F_wH0prior_lines[-1].split("&")[1] + real_F_wH0prior_lim = process_limits(real_F_wH0prior_lines[-1].split("&")[-2], 2) + real_F_wH0prior_tex = f"\\newcommand{{\\FwHPrior}}{{\\ensuremath{{{real_lsigma_wFprior}{real_lsigma_wFprior_lim}}}}} \n" + + real_lmean_wH0prior = str(round(float(real_F_wH0prior_lines[1].split("&")[1]), 1)) + real_lmean_wH0prior_lim = process_limits(real_F_wH0prior_lines[1].split("&")[-2]) + real_lmean_wH0prior_tex = f"\\newcommand{{\\lmeanwHPrior}}{{\\ensuremath{{{real_lmean_wH0prior}{real_lmean_wH0prior_lim}}}}} \n" + + real_lsigma_wH0prior = str(round(float(real_F_wH0prior_lines[2].split("&")[1]), 1)) + real_lsigma_wH0prior_lim = process_limits(real_F_wH0prior_lines[2].split("&")[-2]) + real_lsigma_wH0prior_tex = f"\\newcommand{{\\lsigmawHPrior}}{{\\ensuremath{{{real_lsigma_wH0prior}{real_lsigma_wH0prior_lim}}}}} \n" + + # CMB + with open(real_F_CMB_file) as f: + real_F_CMB_lines = f.readlines() + + real_F_CMB = real_F_CMB_lines[0].split("&")[1] + real_F_CMB_lim = process_limits(real_F_CMB_lines[0].split("&")[-2], 2) + + # SNe + with open(real_F_SNe_file) as f: + real_F_SNe_lines = f.readlines() + + real_F_SNe = real_F_SNe_lines[0].split("&")[1] + real_F_SNe_lim = process_limits(real_F_SNe_lines[0].split("&")[-2], 2) + + real_F_wH0prior_tex = f"\\newcommand{{\\FwPrior}}{{\\ensuremath{{{real_F_wH0prior}{real_F_wH0prior_lim}}}}} \n" + real_F_CMB_tex = ( + f"\\newcommand{{\\FCMB}}{{\\ensuremath{{{real_F_CMB}{real_F_CMB_lim}}}}} \n" + ) + real_F_SNe_tex = ( + f"\\newcommand{{\\FSNe}}{{\\ensuremath{{{real_F_SNe}{real_F_SNe_lim}}}}} \n" + ) + + tbfil.write(real_F_wH0prior_tex) + tbfil.write(real_F_CMB_tex) + tbfil.write(real_F_SNe_tex) + + tbfil.write(real_lmean_wH0prior_tex) + tbfil.write(real_lsigma_wH0prior_tex) + + # Forecasts + with open(craco_F_wH0prior_file) as f: + craco_F_wH0prior_lines = f.readlines() + + craco_F_wH0prior = craco_F_wH0prior_lines[-1].split("&")[1] + craco_F_wH0prior_lim = process_limits(craco_F_wH0prior_lines[-1].split("&")[-2], 2) + + with open(craco_F_CMB_file) as f: + craco_F_CMB_lines = f.readlines() + + craco_F_CMB = craco_F_CMB_lines[0].split("&")[1] + craco_F_CMB_lim = process_limits(craco_F_CMB_lines[0].split("&")[-2], 2) + + with open(craco_F_SNe_file) as f: + craco_F_SNe_lines = f.readlines() + + craco_F_SNe = real_F_SNe_lines[0].split("&")[1] + craco_F_SNe_lim = process_limits(real_F_SNe_lines[0].split("&")[-2], 2) + + craco_F_wH0prior_tex = f"\\newcommand{{\\fctFwPrior}}{{\\ensuremath{{{craco_F_wH0prior}{craco_F_wH0prior_lim}}}}} \n" + craco_F_CMB_tex = f"\\newcommand{{\\fctFCMB}}{{\\ensuremath{{{craco_F_CMB}{craco_F_CMB_lim}}}}} \n" + craco_F_SNe_tex = f"\\newcommand{{\\fctFSNe}}{{\\ensuremath{{{craco_F_SNe}{craco_F_SNe_lim}}}}} \n" + + tbfil.write(craco_F_wH0prior_tex) + tbfil.write(craco_F_CMB_tex) + tbfil.write(craco_F_SNe_tex) + + # Lower limit on F + arr = craco_F_wH0prior_lines[-1].split("&") + F_lower = str(float(arr[1]) - float(arr[2][5:9])) + F_lower_tex = f"\\newcommand{{\Flower}}{{\\ensuremath{{{F_lower}}}}} \n" + tbfil.write(F_lower_tex) + + tbfil.close() + + print("Wrote {:s}".format(outfile)) + + +def mktab_frbs(outfile="tab_frbs.tex", sub=False): + state = parameters.State() + zDMgrid, zvals, dmvals = misc_functions.get_zdm_grid( + state, new=True, plot=False, method="analytic" + ) + + # Load up the surveys + names = ["CRAFT/ICS892", "CRAFT/ICS", "CRAFT/ICS1632"] + survey_name = ["\icslow", "\icsmid", "\icshigh"] + new_frb_count = [3, 3, 2] + + # Open + tbfil = open(outfile, "w") + + # Header + tbfil.write("\\begin{table*}\n") + tbfil.write("\\centering\n") + tbfil.write("\\begin{minipage}{170mm} \n") + tbfil.write("\\centering\n") + tbfil.write( + "\\caption{New FRB detections detected in 2022 used in addition to the FRB surveys used in \citet{j22b}. The FRB name, SNR-maximizing DM, \dmism\ estimated using the NE2001 model of \citet{CordesLazio01}, central frequency of observation $\\nu$, measured signal-to-noise ratio SNR, redshift $z$, and original reference. Where redshifts are not given, this is because (a): no voltage data were dumped, preventing radio localization; (b) optical follow-up observations are not yet complete; (c) Substantial Galactic extinction has challenged follow-up optical observations; (d) the host galaxy appears too distant to accurately measure a redshift. All FRBs referenced are from Shannon et al. (in prep.) with the exception of FRB20220610A \citep{ryder22}. \label{tab:frbs}}\n" + ) + tbfil.write("\\begin{tabular}{ccccccc}\n") + tbfil.write("\\hline \n") + tbfil.write("Name & Survey & DM & \dmism & $\\nu$ & SNR & $z$ \\\ \n") + tbfil.write("& & (\dmunits) & (\dmunits) & (MHz) & & \n") + tbfil.write("\\\\ \n") + tbfil.write("\\hline \n") + + # Loop on survey + for i, name in enumerate(names): + isurvey = survey.load_survey(name, state, dmvals) + # Loop on FRBs + for frb_idx in range(new_frb_count[i]): + idx = int(-(frb_idx + 1)) + slin = f'{isurvey.frbs["TNS"].iat[idx]}' + slin += f"& {survey_name[i]}" + slin += f'& {isurvey.frbs["DM"].iat[idx]}' + slin += f'& {isurvey.frbs["DMG"].iat[idx]}' + slin += f'& {isurvey.frbs["FBAR"].iat[idx]}' + slin += f'& {isurvey.frbs["SNR"].iat[idx]}' + redshift = isurvey.frbs["Z"].iat[idx] + if redshift != -1: + slin += f"& {redshift}" + else: + slin += f"& --" + + # Write + tbfil.write(slin) + tbfil.write("\\\\ \n") + tbfil.write("\\hline \n") + + # End + tbfil.write("\\hline") + tbfil.write("\\end{tabular} \n") + tbfil.write("\\end{minipage} \n") + tbfil.write("\\end{table*} \n") + + tbfil.close() + + print("Wrote {:s}".format(outfile)) + + +# Command line execution +if __name__ == "__main__": + mktab_model_params() + mktex_measurements() + mktab_frbs() diff --git a/papers/F/speedtest.py b/papers/F/speedtest.py new file mode 100644 index 00000000..33530529 --- /dev/null +++ b/papers/F/speedtest.py @@ -0,0 +1,26 @@ +from zdm.craco import loading +import time +import numpy as np +import os +from pkg_resources import resource_filename + +i = 30 +res_list = [] + +for i in range(i): + st = time.process_time() + + isurvey, igrid = loading.survey_and_grid( + survey_name="CRACO_std_May2022", + NFRB=100, + lum_func=3, + # sdir=os.path.join(resource_filename("zdm", "data"), "Surveys/James2022a"), + ) + + et = time.process_time() + res = et - st + res_list.append(res) + +avg_res = np.mean(res_list) + +print("CPU Execution time average:", avg_res, "seconds") diff --git a/papers/H0_I/Figures/H0_vs_Emax.ipynb b/papers/H0_I/Figures/H0_vs_Emax.ipynb index 0987c14d..2b8f1543 100644 --- a/papers/H0_I/Figures/H0_vs_Emax.ipynb +++ b/papers/H0_I/Figures/H0_vs_Emax.ipynb @@ -245,7 +245,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -259,7 +259,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.6" + "version": "3.9.9" } }, "nbformat": 4, diff --git a/papers/H0_I/Figures/py/figs_zdm_H0_I.py b/papers/H0_I/Figures/py/figs_zdm_H0_I.py index ffbeaf00..af167536 100644 --- a/papers/H0_I/Figures/py/figs_zdm_H0_I.py +++ b/papers/H0_I/Figures/py/figs_zdm_H0_I.py @@ -222,7 +222,7 @@ def fig_craco_varyH0_zDM(outfile, lstyles = ['-', '-', '-', ':'] zticks = [0.5, 1.0, 1.5, 2.] ylim = (0., DMmax) - elif other_param == 'F': + elif other_param == 'logF': H0_values = [60., 70., 80., 60.] other_values = [fiducial_F, fiducial_F, fiducial_F, 0.5] lstyle = '-' @@ -242,8 +242,8 @@ def fig_craco_varyH0_zDM(outfile, vparams['H0'] = H0 if other_param == 'Emax': vparams['lEmax'] = fiducial_Emax + scl - elif other_param == 'F': - vparams['F'] = scl + elif other_param == 'logF': + vparams['logF'] = scl grid.update(vparams) # Unpack @@ -279,8 +279,8 @@ def fig_craco_varyH0_zDM(outfile, # Label if other_param == 'Emax': labels.append(r"$H_0 = $"+f"{H0}, log "+r"$E_{\rm max}$"+f"= {vparams['lEmax']}") - elif other_param == 'F': - labels.append(r"$H_0 = $"+f"{H0}, F = {vparams['F']}") + elif other_param == 'logF': + labels.append(r"$H_0 = $"+f"{H0}, F = {vparams['logF']}") ###### gets decent axis labels, down to 1 decimal place ####### ax=plt.gca() @@ -327,7 +327,7 @@ def fig_craco_varyH0_other(outfile, params, H0_values = [60., 70., 80., 80.] other_values = [41.4, 41.4, 41.4, 41.3] lstyles = ['-', '-', '-', ':'] - elif other_param == 'F': + elif other_param == 'logF': H0_values = [60., 70., 80., 60.] other_values = [fiducial_F, fiducial_F, fiducial_F, 0.5] lstyle = '-' @@ -381,8 +381,11 @@ def fig_craco_varyH0_other(outfile, params, if first: if debug: - im=plt.imshow(cut_pgrid,cmap='jet',origin='lower', - interpolation='None', + im = plt.imshow( + cut_pgrid, + cmap="jet", + origin="lower", + interpolation="None", # extent=[0., 2, 0, 2000.], vmin=-30., aspect='auto') @@ -406,28 +409,28 @@ def fig_craco_varyH0_other(outfile, params, legend_lines.append(leg[0]) # Label - if other_param == 'Emax': - labels.append(r"$H_0 = $"+f"{H0}, log "+r"$E_{\rm max}$"+f"= {lEmax}") - elif other_param == 'F': - labels.append(r"$H_0 = $"+f"{H0}, F = {vparams['F']}") + if other_param == "Emax": + labels.append(r"$H_0 = $" + f"{H0}, log " + r"$E_{\rm max}$" + f"= {lEmax}") + elif other_param == "F": + labels.append(r"$H_0 = $" + f"{H0}, F = {vparams['logF']}") ###### gets decent axis labels, down to 1 decimal place ####### - ax=plt.gca() - ax.legend(legend_lines, labels, loc='upper right') + ax = plt.gca() + ax.legend(legend_lines, labels, loc="upper right") # Ticks labels = [item.get_text() for item in ax.get_xticklabels()] for i in np.arange(len(labels)): - labels[i]=labels[i][0:4] + labels[i] = labels[i][0:4] ax.set_xticklabels(labels) labels = [item.get_text() for item in ax.get_yticklabels()] for i in np.arange(len(labels)): - if '.' in labels[i]: - labels[i]=labels[i].split('.')[0] + if "." in labels[i]: + labels[i] = labels[i].split(".")[0] ax.set_yticklabels(labels) ax.yaxis.labelpad = 0 - - fig_utils.set_fontsize(ax, 15.) + + fig_utils.set_fontsize(ax, 15.0) # Finish plt.tight_layout() @@ -435,18 +438,19 @@ def fig_craco_varyH0_other(outfile, params, plt.close() print(f"Wrote: {outfile}") -def fig_craco_H0vsEmax(outfile='fig_craco_H0vsEmax.png'): + +def fig_craco_H0vsEmax(outfile="fig_craco_H0vsEmax.png"): # Load the cube - cube_out = np.load('../Analysis/Cubes/craco_H0_Emax_cube.npz') - ll = cube_out['ll'] # log10 + cube_out = np.load("../Analysis/Cubes/craco_H0_Emax_cube.npz") + ll = cube_out["ll"] # log10 # Slurp - lEmax = cube_out['lEmax'] - H0 = cube_out['H0'] + lEmax = cube_out["lEmax"] + H0 = cube_out["H0"] # - dE = lEmax[1]-lEmax[0] + dE = lEmax[1] - lEmax[0] dH = H0[1] - H0[0] - + # Normalize ll -= ll.max() @@ -454,33 +458,37 @@ def fig_craco_H0vsEmax(outfile='fig_craco_H0vsEmax.png'): plt.clf() ax = plt.gca() - im=plt.imshow(ll.T,cmap='jet',origin='lower', - interpolation='None', extent=[40.4-dE/2, 43.4+dE/2, - 60.-dH/2, 80+dH/2], - aspect='auto', vmin=-4. - )#aspect=aspect) + im = plt.imshow( + ll.T, + cmap="jet", + origin="lower", + interpolation="None", + extent=[40.4 - dE / 2, 43.4 + dE / 2, 60.0 - dH / 2, 80 + dH / 2], + aspect="auto", + vmin=-4.0, + ) # aspect=aspect) # Color bar - cbar=plt.colorbar(im,fraction=0.046, shrink=1.2,aspect=15,pad=0.05) - cbar.set_label(r'$\Delta$ Log10 Likelihood') + cbar = plt.colorbar(im, fraction=0.046, shrink=1.2, aspect=15, pad=0.05) + cbar.set_label(r"$\Delta$ Log10 Likelihood") # - ax.set_xlabel('log Emax') - ax.set_ylabel('H0 (km/s/Mpc)') + ax.set_xlabel("log Emax") + ax.set_ylabel("H0 (km/s/Mpc)") plt.savefig(outfile, dpi=200) print(f"Wrote: {outfile}") -def fig_craco_H0vsF(outfile='fig_craco_H0vsF.png'): +def fig_craco_H0vsF(outfile="fig_craco_H0vsF.png"): # Load the cube - cube_out = np.load('../Analysis/Cubes/craco_H0_F_cube.npz') - ll = cube_out['ll'] # log10 + cube_out = np.load("../Analysis/Cubes/craco_H0_F_cube.npz") + ll = cube_out["ll"] # log10 # Slurp - F = cube_out['F'] - H0 = cube_out['H0'] + F = cube_out["F"] + H0 = cube_out["H0"] # - dF = F[1]-F[0] + dF = F[1] - F[0] dH = H0[1] - H0[0] - + # Normalize ll -= ll.max() @@ -488,17 +496,21 @@ def fig_craco_H0vsF(outfile='fig_craco_H0vsF.png'): plt.clf() ax = plt.gca() - im=plt.imshow(ll.T,cmap='jet',origin='lower', - interpolation='None', extent=[0.1-dF/2, 0.5+dF/2, - 60.-dH/2, 80+dH/2], - aspect='auto', vmin=-4. - )#aspect=aspect) + im = plt.imshow( + ll.T, + cmap="jet", + origin="lower", + interpolation="None", + extent=[0.1 - dF / 2, 0.5 + dF / 2, 60.0 - dH / 2, 80 + dH / 2], + aspect="auto", + vmin=-4.0, + ) # aspect=aspect) # Color bar - cbar=plt.colorbar(im,fraction=0.046, shrink=1.2,aspect=15,pad=0.05) - cbar.set_label(r'$\Delta$ Log10 Likelihood') + cbar = plt.colorbar(im, fraction=0.046, shrink=1.2, aspect=15, pad=0.05) + cbar.set_label(r"$\Delta$ Log10 Likelihood") # - ax.set_xlabel('F') - ax.set_ylabel('H0 (km/s/Mpc)') + ax.set_xlabel("F") + ax.set_ylabel("H0 (km/s/Mpc)") plt.savefig(outfile, dpi=200) print(f"Wrote: {outfile}") @@ -619,10 +631,8 @@ def main(pargs): # Vary H0, F - if pargs.figure == 'varyH0F': - fig_craco_varyH0_zDM(outfile='fig_craco_varyH0F.png', - other_param='F') - + if pargs.figure == "varyH0F": + fig_craco_varyH0_zDM(outfile="fig_craco_varyH0F.png", other_param="F") # H0 vs. Emax if pargs.figure == 'H0vsEmax': @@ -649,17 +659,21 @@ def parse_option(): args: (dict) dictionary of the arguments. """ parser = argparse.ArgumentParser("zdm H0 I Figures") - parser.add_argument("figure", type=str, - help="function to execute: ('fiducial, 'varyH0', 'H0vsEmax')") - #parser.add_argument('--cmap', type=str, help="Color map") - #parser.add_argument('--distr', type=str, default='normal', + parser.add_argument( + "figure", + type=str, + help="function to execute: ('fiducial, 'varyH0', 'H0vsEmax')", + ) + # parser.add_argument('--cmap', type=str, help="Color map") + # parser.add_argument('--distr', type=str, default='normal', # help='Distribution to fit [normal, lognorm]') args = parser.parse_args() - + return args + # Command line execution -if __name__ == '__main__': +if __name__ == "__main__": pargs = parse_option() main(pargs) diff --git a/setup.cfg b/setup.cfg index 5f524440..747e60da 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,7 +32,7 @@ setup_requires = setuptools_scm include_package_data = True install_requires = numpy>=1.18 - astropy>=4.0 + astropy>=5.2.1 scipy>=1.4 matplotlib>=3.3 PyYAML>=5.1 diff --git a/zdm/analyze_cube.py b/zdm/analyze_cube.py index 28c431d6..b4adcc58 100644 --- a/zdm/analyze_cube.py +++ b/zdm/analyze_cube.py @@ -31,18 +31,18 @@ def slurp_cube(input_file:str, prefix:str, outfile:str, suffix (str, optional): File ending. Allows for old .out files """ # Grab em. The order doesn't matter - files = glob.glob(prefix+'*'+suffix) + files = glob.glob(prefix + "*" + suffix) # Init - input_dict=io.process_jfile(input_file) + input_dict = io.process_jfile(input_file) _, cube_dict, vparam_dict = iteration.parse_input_dict(input_dict) PARAMS = list(vparam_dict.keys()) # Prep - order, iorder = iteration.set_orders(cube_dict['parameter_order'], PARAMS) + order, iorder = iteration.set_orders(cube_dict["parameter_order"], PARAMS) cube_shape = iteration.set_cube_shape(vparam_dict, order) - param_shape = np.array([0]+cube_shape)[iorder].tolist()[:-1] + param_shape = np.array([0] + cube_shape)[iorder].tolist()[:-1] # Outputs ll_cube = np.zeros(param_shape, dtype=np.float32) @@ -54,12 +54,12 @@ def slurp_cube(input_file:str, prefix:str, outfile:str, pDMz_cube = np.zeros(param_shape, dtype=np.float32) pz_cube = np.zeros(param_shape, dtype=np.float32) - survey_items = ['lls', 'P_zDM', 'P_n', 'P_s', 'N'] - names = ['icube'] + PARAMS - for ss in range (nsurveys): - names += [item+f'_{ss}' for item in survey_items] - names += ['ll'] - + survey_items = ["lls", "P_zDM", "P_n", "P_s", "N"] + names = ["icube"] + PARAMS + for ss in range(nsurveys): + names += [item + f"_{ss}" for item in survey_items] + names += ["ll"] + # Loop on cube output files survey_arrays = {} nsurvey = 0 @@ -72,10 +72,10 @@ def slurp_cube(input_file:str, prefix:str, outfile:str, if ss == 0: # Count the surveys for key in df.keys(): - if 'P_zDM' in key and len(key) > len('P_zDM'): + if "P_zDM" in key and len(key) > len("P_zDM"): # Generate them for item in survey_items: - survey_arrays[item+key[-1]] = np.zeros(param_shape) + survey_arrays[item + key[-1]] = np.zeros(param_shape) nsurvey += 1 # Get indices @@ -83,10 +83,12 @@ def slurp_cube(input_file:str, prefix:str, outfile:str, ns = df.n for n in ns: - r_current = np.array([0]+list(np.unravel_index( - int(n), cube_shape, order='F'))) - current = r_current[iorder][:-1] # Truncate lC + r_current = np.array( + [0] + list(np.unravel_index(int(n), cube_shape, order="F")) + ) + current = r_current[iorder][:-1] # Truncate lC # Ravel me back + idx = np.ravel_multi_index(current, ll_cube.shape) indices.append(idx) @@ -105,21 +107,25 @@ def slurp_cube(input_file:str, prefix:str, outfile:str, # Check if debug: - embed(header='69 of analyze') - + embed(header="69 of analyze") + # Grids - out_dict = dict(ll=ll_cube, - lC=lC_cube, - params=PARAMS[:-1], - pzDM=pzDM_cube, - pDM=pDM_cube, - pDMz=pDMz_cube, - pz=pz_cube) + out_dict = dict( + ll=ll_cube, + lC=lC_cube, + params=PARAMS[:-1], + pzDM=pzDM_cube, + pDM=pDM_cube, + pDMz=pDMz_cube, + pz=pz_cube, + ) + # Save the parameter values too for name in PARAMS[:-1]: - out_dict[name] = np.linspace(vparam_dict[name]['min'], - vparam_dict[name]['max'], - vparam_dict[name]['n']) + + out_dict[name] = np.linspace( + vparam_dict[name]["min"], vparam_dict[name]["max"], vparam_dict[name]["n"] + ) # Survey items for key in survey_arrays.keys(): out_dict[key] = survey_arrays[key] @@ -129,22 +135,6 @@ def slurp_cube(input_file:str, prefix:str, outfile:str, print(f"Wrote: {outfile}") -def get_param_values(data,params): - """ - Gets the unique values of the data from a cube output - Currently the parameter order is hard-coded - - """ - # gets unique values for each axis - param_vals=[] - #param_list=[data["lEmax"],data["H0"],data["alpha"],data["gamma"],data["sfr_n"],data["lmean"],data["lsigma"]] - #for col in param_list: - for param in params: - col=data[param] - unique=np.unique(col) - param_vals.append(unique) - return param_vals - def apply_gaussian_prior(lls:np.ndarray, iparam:int, values:np.ndarray, @@ -157,31 +147,41 @@ def apply_gaussian_prior(lls:np.ndarray, Returns a vector of length lls modified by that prior. """ - NDIMS= len(lls.shape) + NDIMS = len(lls.shape) if iparam < 0 or iparam >= NDIMS: - raise ValueError("Data only has ",NDIMS," dimensions.", - "Please select iparam between 0 and ",NDIMS-1," not ",iparam) - + raise ValueError( + "Data only has ", + NDIMS, + " dimensions.", + "Please select iparam between 0 and ", + NDIMS - 1, + " not ", + iparam, + ) + wlls = np.copy(lls) - - for iv,val in enumerate(values): + + for iv, val in enumerate(values): # select ivth value from iparam dimension - big_slice = [slice(None,None,None)]*NDIMS + big_slice = [slice(None, None, None)] * NDIMS big_slice[iparam] = iv - - #calculate weights. Yes I know this is silly. - weight = np.exp(-0.5*((val-mean)/sigma)**2) + + # calculate weights. Yes I know this is silly. + weight = np.exp(-0.5 * ((val - mean) / sigma) ** 2) weight = np.log10(weight) wlls[tuple(big_slice)] += weight return wlls -def apply_H0_prior(lls:np.ndarray, - H0dim:int, - H0values:np.ndarray, - cmbH0:float, - cmb_sigma:float, - sn1aH0:float, - sn1a_sigma:float): + +def apply_H0_prior( + lls: np.ndarray, + H0dim: int, + H0values: np.ndarray, + cmbH0: float, + cmb_sigma: float, + sn1aH0: float, + sn1a_sigma: float, +): """ Applies a prior as a function of H0 @@ -206,44 +206,103 @@ def apply_H0_prior(lls:np.ndarray, Returns a vector of length lls modified by that prior. """ - + # orders limits appropriately if cmbH0 < sn1aH0: - lowH0=cmbH0 - lowsigma=cmb_sigma - highH0=sn1aH0 - highsigma=sn1a_sigma + lowH0 = cmbH0 + lowsigma = cmb_sigma + highH0 = sn1aH0 + highsigma = sn1a_sigma else: - lowH0=sn1aH0 - lowsigma=sn1a_sigma - highH0=cmbH0 - highsigma=cmb_sigma - - NDIMS= len(lls.shape) + lowH0 = sn1aH0 + lowsigma = sn1a_sigma + highH0 = cmbH0 + highsigma = cmb_sigma + + NDIMS = len(lls.shape) if H0dim < 0 or H0dim >= NDIMS: - raise ValueError("Data only has ",NDIMS," dimensions.", - "Please select H0dim between 0 and ",NDIMS-1," not ",H0dim) - + raise ValueError( + "Data only has ", + NDIMS, + " dimensions.", + "Please select H0dim between 0 and ", + NDIMS - 1, + " not ", + H0dim, + ) + wlls = np.copy(lls) - - for iv,val in enumerate(H0values): + + for iv, val in enumerate(H0values): # select ivth value from iparam dimension - big_slice = [slice(None,None,None)]*NDIMS + big_slice = [slice(None, None, None)] * NDIMS big_slice[H0dim] = iv - - #calculate weights. + + # calculate weights. if val < lowH0: - weight = -0.5*((val-lowH0)/lowsigma)**2 * np.log10(np.exp(1)) + weight = -0.5 * ((val - lowH0) / lowsigma) ** 2 * np.log10(np.exp(1)) elif val > highH0: - weight = -0.5*((val-highH0)/highsigma)**2 * np.log10(np.exp(1)) + weight = -0.5 * ((val - highH0) / highsigma) ** 2 * np.log10(np.exp(1)) else: - weight=0. - + weight = 0.0 + wlls[tuple(big_slice)] += weight - + return wlls -def get_slice_from_parameters(data,plist,mcvals,verbose=False,wanted="ll"): + +def apply_F_prior( + lls: np.ndarray, + Fdim: int, + Fvalues: np.ndarray, + F_0: float, + F_sigma: float, +): + """ + Applies a prior as a function of F + + This is a Gaussian prior. + + Args: + lls (np.ndarray): values of likelihoods + + Fdim (int): dimension of F0 in the data + + Fvalues (float): vector specifying values of H0 + + F_0 (float): value of F + + F_sigma (float): 1 sigma uncertainty on F + + Returns a vector of length lls modified + by that prior. + """ + + NDIMS = len(lls.shape) + if Fdim < 0 or Fdim >= NDIMS: + raise ValueError( + "Data only has ", + NDIMS, + " dimensions.", + "Please select F dim between 0 and ", + NDIMS - 1, + " not ", + Fdim, + ) + + wlls = np.copy(lls) + + for iv, val in enumerate(Fvalues): + # select ivth value from iparam dimension + big_slice = [slice(None, None, None)] * NDIMS + big_slice[Fdim] = iv + weight = -0.5 * ((val - F_0) / F_sigma) ** 2 * np.log10(np.exp(1)) + wlls[tuple(big_slice)] += weight + + return wlls + + +def get_slice_from_parameters(data, plist, mcvals, verbose=False, wanted="ll"): """ Selects from data according to parameters which are as close to those in the mcvals as possible. @@ -258,50 +317,57 @@ def get_slice_from_parameters(data,plist,mcvals,verbose=False,wanted="ll"): Returns: Array of NDIM=dim(data)-dim(plist) likelihood values """ - NDIMS=len(data["params"]) + NDIMS = len(data["params"]) if verbose: - print("We have ",NDIMS," dimensions to this cube") - + print("We have ", NDIMS, " dimensions to this cube") + # sets up array of which values to keep - which=np.full([NDIMS],-1) - + which = np.full([NDIMS], -1) + # finds the order of these parameters in the multidimensional cube - iplist=[] + iplist = [] for param in plist: iplist.append(np.where(data["params"] == param)[0][0]) - + # identifies the closest parameter values - iclosest=[] - for i,param in enumerate(plist): - vals=data[param] - vals=np.array(vals) - diffs=(mcvals[i]-vals)**2 - imindiff=np.argmin(diffs) + iclosest = [] + for i, param in enumerate(plist): + vals = data[param] + vals = np.array(vals) + diffs = (mcvals[i] - vals) ** 2 + imindiff = np.argmin(diffs) iclosest.append(imindiff) if verbose: - print('For ',param,' MC truth ',mcvals[i]," closest cube value is the ", - imindiff,"th, with value ",vals[imindiff]) - which[iplist[i]]=imindiff - + print( + "For ", + param, + " MC truth ", + mcvals[i], + " closest cube value is the ", + imindiff, + "th, with value ", + vals[imindiff], + ) + which[iplist[i]] = imindiff + # selects the slice while keeping all MC parameters constant - big_slice = [slice(None,None,None)]*NDIMS + big_slice = [slice(None, None, None)] * NDIMS for i in np.arange(NDIMS): - if which[i] >= 0: #insert code of -1 for "leave free" + if which[i] >= 0: # insert code of -1 for "leave free" big_slice[i] = which[i] if isinstance(wanted, list): - for i,item in enumerate(wanted): - if i==0: - selection=data[item][tuple(big_slice)] + for i, item in enumerate(wanted): + if i == 0: + selection = data[item][tuple(big_slice)] else: selection += data[item][tuple(big_slice)] else: - selection=data[wanted][tuple(big_slice)] + selection = data[wanted][tuple(big_slice)] selection = np.array(selection) return selection -def get_bayesian_data(lls:np.ndarray, - plls:np.ndarray=None, - pklfile=None): + +def get_bayesian_data(lls: np.ndarray, plls: np.ndarray = None, pklfile=None): """ Method to perform simple Bayesian analysis on the Log-likelihood cube @@ -316,102 +382,102 @@ def get_bayesian_data(lls:np.ndarray, lists of np.ndarray's of LL analysis One item per parameter in the cube """ - NDIMS= len(lls.shape) - + NDIMS = len(lls.shape) + # multiplies all log-likelihoods by the maximum value # ensures no floating point problems global_max = np.nanmax(lls) lls -= global_max - - #eventually remove this line + + # eventually remove this line if plls is None: plls = lls - - origlls=lls - + + origlls = lls + if plls is not None: w_global_max = np.nanmax(plls) plls = plls - w_global_max - - uvals=[] - + + uvals = [] + for i in np.arange(NDIMS): unique = np.arange(lls.shape[i]) uvals.append(unique) # we now have a list of unique values for each dimension - vectors=[] # this will contain the best values for 1d plots - wvectors=[] # holds same as above, but including spectral penalty factor from ASKAP obs - + vectors = [] # this will contain the best values for 1d plots + wvectors = ( + [] + ) # holds same as above, but including spectral penalty factor from ASKAP obs + # loop over the DIMS for i in np.arange(NDIMS): - + # does 1D values - vector=np.zeros([len(uvals[i])]) - wvector=np.zeros([len(uvals[i])]) + vector = np.zeros([len(uvals[i])]) + wvector = np.zeros([len(uvals[i])]) # selects for lls a subset corresponding only to that particular value of a variables for iv, ivv in enumerate(uvals[i]): - big_slice = [slice(None,None,None)]*NDIMS + big_slice = [slice(None, None, None)] * NDIMS # Construct the slice big_slice[i] = ivv - #set1=np.where(data[:,idim]==ivv) #selects for a set of values - #lls=data[set1,llindex] - lls=origlls[tuple(big_slice)].flatten() - + # set1=np.where(data[:,idim]==ivv) #selects for a set of values + # lls=data[set1,llindex] + lls = origlls[tuple(big_slice)].flatten() + # ignores all values of 0, which is what missing data is - ignore=np.where(lls == 0.)[0] - lls[ignore]=-99999 - + # ignore = np.where(lls == 0.0)[0] + # lls[ignore] = -99999 + lls[np.isnan(lls)] = -99999 + # selects all fits that are close to the peak (i.e. percentage within 0.1%) try: - themax=np.nanmax(lls) + themax = np.nanmax(lls) except: # all nans, probability =0. Easy! - vector[iv]=0. - wvector[iv]=0. + vector[iv] = 0.0 + wvector[iv] = 0.0 continue - - OKlls=np.isfinite(lls) & (lls > themax-3) - vector[iv]=np.sum(10**lls[OKlls]) - + + OKlls = np.isfinite(lls) & (lls > themax - 3) + vector[iv] = np.sum(10 ** lls[OKlls]) + if plls is not None: - wlls=plls[tuple(big_slice)].flatten() - wthemax=np.nanmax(wlls) - OKwlls=np.isfinite(wlls) & (wlls > wthemax-3) - wvector[iv]=np.sum(10**wlls[OKwlls]) - - #import pdb; pdb.set_trace() + wlls = plls[tuple(big_slice)].flatten() + wthemax = np.nanmax(wlls) + OKwlls = np.isfinite(wlls) & (wlls > wthemax - 3) + wvector[iv] = np.sum(10 ** wlls[OKwlls]) + + # import pdb; pdb.set_trace() # Check - vector *= 1./np.sum(vector) - vector *= 1./np.abs(uvals[i][1]-uvals[i][0]) + vector *= 1.0 / np.sum(vector) + vector *= 1.0 / np.abs(uvals[i][1] - uvals[i][0]) vectors.append(vector) if plls is not None: - wvector *= 1./np.sum(wvector) - wvector *= 1./np.abs(uvals[i][1]-uvals[i][0]) - wvectors.append(wvector) - - + wvector *= 1.0 / np.sum(wvector) + wvector *= 1.0 / np.abs(uvals[i][1] - uvals[i][0]) + wvectors.append(wvector) + # now makes correction lls += global_max if plls is not None: plls += w_global_max - + # Pickle? if pklfile is not None: - with open(pklfile, 'wb') as output: + with open(pklfile, "wb") as output: pickle.dump(uvals, output, pickle.HIGHEST_PROTOCOL) pickle.dump(vectors, output, pickle.HIGHEST_PROTOCOL) pickle.dump(wvectors, output, pickle.HIGHEST_PROTOCOL) - + # result is just the total probability, normalised to unity, when summed over the parameter space # technically needs to be divided by the x-increment in bins. - return uvals,vectors,wvectors + return uvals, vectors, wvectors -def get_2D_bayesian_data(lls:np.ndarray, - plls:np.ndarray=None, - pklfile=None): +def get_2D_bayesian_data(lls: np.ndarray, plls: np.ndarray = None, pklfile=None): """ Method to perform simple Bayesian analysis on the Log-likelihood cube @@ -430,98 +496,99 @@ def get_2D_bayesian_data(lls:np.ndarray, ijs, arrays, and warrays have Nitems = Nparams*(Nparams-1)/2 """ - NDIMS= len(lls.shape) - + NDIMS = len(lls.shape) + # multiplies all log-likelihoods by the maximum value global_max = np.nanmax(lls) lls -= global_max - - #eventually remove this line + + # eventually remove this line if plls is None: plls = lls - + if plls is not None: w_global_max = np.nanmax(plls) plls = plls - w_global_max - - origlls=lls - uvals=[] - + + origlls = lls + uvals = [] + for i in np.arange(NDIMS): unique = np.arange(lls.shape[i]) uvals.append(unique) # we now have a list of unique values for each dimension - arrays=[] # this will contain the best values for 1d plots - warrays=[] # holds same as above, but including spectral penalty factor from ASKAP obs - ijs=[] - + arrays = [] # this will contain the best values for 1d plots + warrays = ( + [] + ) # holds same as above, but including spectral penalty factor from ASKAP obs + ijs = [] + # loop over the first dimensional combination for i in np.arange(NDIMS): - + # loops over the second dimension - for j in (np.arange(NDIMS-i-1)+i+1): - + for j in np.arange(NDIMS - i - 1) + i + 1: + # does 1D values - array=np.zeros([len(uvals[i]),len(uvals[j])]) - warray=np.zeros([len(uvals[i]),len(uvals[j])]) - + array = np.zeros([len(uvals[i]), len(uvals[j])]) + warray = np.zeros([len(uvals[i]), len(uvals[j])]) + # selects for lls a subset corresponding only to that particular value of a variables for iv, ivv in enumerate(uvals[i]): - big_slice = [slice(None,None,None)]*NDIMS + big_slice = [slice(None, None, None)] * NDIMS # Construct the slice big_slice[i] = ivv - + for jv, jvv in enumerate(uvals[j]): # Construct the slice big_slice[j] = jvv - - - #lls=data[set1,llindex] - lls=origlls[tuple(big_slice)].flatten() - + + # lls=data[set1,llindex] + lls = origlls[tuple(big_slice)].flatten() + # ignores all values of 0, which is what missing data is - ignore=np.where(lls == 0.)[0] - lls[ignore]=-99999 - + # ignore = np.where(lls == 0.0)[0] + # lls[ignore] = -99999 + lls[np.isnan(lls)] = -99999 + try: - themax=np.nanmax(lls) + themax = np.nanmax(lls) except: # all nans, probability =0. Easy! - arrays[iv,jv]=0. - warrays[iv,jv]=0. + arrays[iv, jv] = 0.0 + warrays[iv, jv] = 0.0 continue - - OKlls=np.isfinite(lls) & (lls > themax-3) - array[iv,jv]=np.sum(10**lls[OKlls]) - + + OKlls = np.isfinite(lls) & (lls > themax - 3) + array[iv, jv] = np.sum(10 ** lls[OKlls]) + if plls is not None: - wlls=plls[tuple(big_slice)].flatten() - wthemax=np.nanmax(wlls) - OKwlls=np.isfinite(wlls) & (wlls > wthemax-3) - warray[iv,jv]=np.sum(10**wlls[OKwlls]) - - - #normalisation over the parameter space to unity - array *= 1./np.sum(array) + wlls = plls[tuple(big_slice)].flatten() + wthemax = np.nanmax(wlls) + OKwlls = np.isfinite(wlls) & (wlls > wthemax - 3) + warray[iv, jv] = np.sum(10 ** wlls[OKwlls]) + + # normalisation over the parameter space to unity + array *= 1.0 / np.sum(array) arrays.append(array) if plls is not None: - warray *= 1./np.sum(warray) + warray *= 1.0 / np.sum(warray) warrays.append(warray) - - ijs.append([i,j]) - + + ijs.append([i, j]) + lls += global_max if plls is not None: plls += w_global_max - + # Pickle? if pklfile is not None: - with open(pklfile, 'wb') as output: + with open(pklfile, "wb") as output: pickle.dump(uvals, output, pickle.HIGHEST_PROTOCOL) pickle.dump(vectors, output, pickle.HIGHEST_PROTOCOL) pickle.dump(wvectors, output, pickle.HIGHEST_PROTOCOL) - + # result is just the total probability, normalised to unity, when summed over the parameter space # technically needs to be divided by the x-increment in bins. return uvals,ijs,arrays,warrays @@ -543,99 +610,95 @@ def get_maxl_data(lls:np.ndarray, lists of np.ndarray's of LL analysis One item per parameter in the cube """ - NDIMS= len(lls.shape) - + NDIMS = len(lls.shape) + # multiplies all log-likelihoods by the maximum value # ensures no floating point problems global_max = np.nanmax(lls) lls -= global_max - - #eventually remove this line + + # eventually remove this line if plls is None: plls = lls - - origlls=lls - + + origlls = lls + if plls is not None: w_global_max = np.nanmax(plls) plls = plls - w_global_max - - - - - uvals=[] - + + uvals = [] + for i in np.arange(NDIMS): unique = np.arange(lls.shape[i]) uvals.append(unique) # we now have a list of unique values for each dimension - vectors=[] # this will contain the best values for 1d plots - wvectors=[] # holds same as above, but including spectral penalty factor from ASKAP obs - + vectors = [] # this will contain the best values for 1d plots + wvectors = ( + [] + ) # holds same as above, but including spectral penalty factor from ASKAP obs + # loop over the DIMS for i in np.arange(NDIMS): - + # does 1D values - vector=np.zeros([len(uvals[i])]) - wvector=np.zeros([len(uvals[i])]) + vector = np.zeros([len(uvals[i])]) + wvector = np.zeros([len(uvals[i])]) # selects for lls a subset corresponding only to that particular value of a variables for iv, ivv in enumerate(uvals[i]): - big_slice = [slice(None,None,None)]*NDIMS + big_slice = [slice(None, None, None)] * NDIMS # Construct the slice big_slice[i] = ivv - #set1=np.where(data[:,idim]==ivv) #selects for a set of values - #lls=data[set1,llindex] - lls=origlls[tuple(big_slice)].flatten() - + # set1=np.where(data[:,idim]==ivv) #selects for a set of values + # lls=data[set1,llindex] + lls = origlls[tuple(big_slice)].flatten() + # ignores all values of 0, which is what missing data is - ignore=np.where(lls == 0.)[0] - lls[ignore]=-99999 - + ignore = np.where(lls == 0.0)[0] + lls[ignore] = -99999 + # selects all fits that are close to the peak (i.e. percentage within 0.1%) try: - themax=np.nanmax(lls) + themax = np.nanmax(lls) except: # all nans, probability =0. Easy! - vector[iv]=0. - wvector[iv]=0. + vector[iv] = 0.0 + wvector[iv] = 0.0 continue - - vector[iv]=themax - + + vector[iv] = themax + if plls is not None: - wlls=plls[tuple(big_slice)].flatten() - wthemax=np.nanmax(wlls) - wvector[iv]=wthemax - - #import pdb; pdb.set_trace() + wlls = plls[tuple(big_slice)].flatten() + wthemax = np.nanmax(wlls) + wvector[iv] = wthemax + + # import pdb; pdb.set_trace() # Check vectors.append(vector) if plls is not None: - wvectors.append(wvector) - - + wvectors.append(wvector) + # now makes correction lls += global_max if plls is not None: plls += w_global_max - + # Pickle? if pklfile is not None: - with open(pklfile, 'wb') as output: + with open(pklfile, "wb") as output: pickle.dump(uvals, output, pickle.HIGHEST_PROTOCOL) pickle.dump(vectors, output, pickle.HIGHEST_PROTOCOL) pickle.dump(wvectors, output, pickle.HIGHEST_PROTOCOL) - + # result is just the total probability, normalised to unit, when summed over the parameter space # technically needs to be divided by the x-increment in bins. - return uvals,vectors,wvectors + return uvals, vectors, wvectors -def get_2D_maxl_data(lls:np.ndarray, - plls:np.ndarray=None, - pklfile=None): +def get_2D_maxl_data(lls: np.ndarray, plls: np.ndarray = None, pklfile=None): """ Method to perform simple Bayesian analysis on the Log-likelihood cube @@ -654,98 +717,99 @@ def get_2D_maxl_data(lls:np.ndarray, ijs, arrays, and warrays have Nitems = Nparams*(Nparams-1)/2 """ - NDIMS= len(lls.shape) - + NDIMS = len(lls.shape) + # multiplies all log-likelihoods by the maximum value global_max = np.nanmax(lls) lls -= global_max - - #eventually remove this line + + # eventually remove this line if plls is None: plls = lls - + if plls is not None: w_global_max = np.nanmax(plls) plls = plls - w_global_max - - origlls=lls - uvals=[] - + + origlls = lls + uvals = [] + for i in np.arange(NDIMS): unique = np.arange(lls.shape[i]) uvals.append(unique) # we now have a list of unique values for each dimension - arrays=[] # this will contain the best values for 1d plots - warrays=[] # holds same as above, but including spectral penalty factor from ASKAP obs - ijs=[] - + arrays = [] # this will contain the best values for 1d plots + warrays = ( + [] + ) # holds same as above, but including spectral penalty factor from ASKAP obs + ijs = [] + # loop over the first dimensional combination for i in np.arange(NDIMS): - + # loops over the second dimension - for j in (np.arange(NDIMS-i-1)+i+1): - + for j in np.arange(NDIMS - i - 1) + i + 1: + # does 1D values - array=np.zeros([len(uvals[i]),len(uvals[j])]) - warray=np.zeros([len(uvals[i]),len(uvals[j])]) - + array = np.zeros([len(uvals[i]), len(uvals[j])]) + warray = np.zeros([len(uvals[i]), len(uvals[j])]) + # selects for lls a subset corresponding only to that particular value of a variables for iv, ivv in enumerate(uvals[i]): - big_slice = [slice(None,None,None)]*NDIMS + big_slice = [slice(None, None, None)] * NDIMS # Construct the slice big_slice[i] = ivv - + for jv, jvv in enumerate(uvals[j]): # Construct the slice big_slice[j] = jvv - lls=origlls[tuple(big_slice)].flatten() - + lls = origlls[tuple(big_slice)].flatten() + # ignores all values of 0, which is what missing data is - ignore=np.where(lls == 0.)[0] - lls[ignore]=-99999 - + ignore = np.where(lls == 0.0)[0] + lls[ignore] = -99999 + try: - themax=np.nanmax(lls) + themax = np.nanmax(lls) except: # all nans, probability =0. Easy! - arrays[iv,jv]=0. - warrays[iv,jv]=0. + arrays[iv, jv] = 0.0 + warrays[iv, jv] = 0.0 continue - - array[iv,jv]=themax - + + array[iv, jv] = themax + if plls is not None: - wlls=plls[tuple(big_slice)].flatten() - wthemax=np.nanmax(wlls) - warray[iv,jv]=wthemax - - - #normalisation over the parameter space to unity + wlls = plls[tuple(big_slice)].flatten() + wthemax = np.nanmax(wlls) + warray[iv, jv] = wthemax + + # normalisation over the parameter space to unity arrays.append(array) if plls is not None: - warray *= 1./np.sum(warray) + warray *= 1.0 / np.sum(warray) warrays.append(warray) - - ijs.append([i,j]) - + + ijs.append([i, j]) + lls += global_max if plls is not None: plls += w_global_max - + # Pickle? if pklfile is not None: - with open(pklfile, 'wb') as output: + with open(pklfile, "wb") as output: pickle.dump(uvals, output, pickle.HIGHEST_PROTOCOL) pickle.dump(vectors, output, pickle.HIGHEST_PROTOCOL) pickle.dump(wvectors, output, pickle.HIGHEST_PROTOCOL) - + # result is just the total probability, normalised to unity, when summed over the parameter space # technically needs to be divided by the x-increment in bins. - return uvals,ijs,arrays,warrays + return uvals, ijs, arrays, warrays -def interpolate_points(oldx,oldy,logspline=False, kind='cubic'): +def interpolate_points(oldx, oldy, logspline=False, kind="cubic"): """ performs simle spline interpolation of the data args: @@ -756,24 +820,24 @@ def interpolate_points(oldx,oldy,logspline=False, kind='cubic'): returns: x,y: interpolated points """ - + #### does unweighted plotting #### - x=np.linspace(oldx[0],oldx[-1],400) - + x = np.linspace(oldx[0], oldx[-1], 400) + if logspline: # does interpolation in log-space - f=scipy.interpolate.interp1d(oldx,np.log(oldy), kind=kind) - y=np.exp(f(x)) + f = scipy.interpolate.interp1d(oldx, np.log(oldy), kind=kind) + y = np.exp(f(x)) else: - f=scipy.interpolate.interp1d(oldx,oldy, kind=kind) - y=f(x) + f = scipy.interpolate.interp1d(oldx, oldy, kind=kind) + y = f(x) # check to ensure the splines have not done anything too dumb - - f2=scipy.interpolate.interp1d(oldx,np.log(oldy), kind=kind) - y2=np.exp(f2(x)) - + + f2 = scipy.interpolate.interp1d(oldx, np.log(oldy), kind=kind) + y2 = np.exp(f2(x)) + # replaces linear interpolation in small-value regime where splines can be dumb - if np.min(y2) < 1.e-2: + if np.min(y2) < 1.0e-2: very_small = np.where(y2 < 1e-2)[0] y[very_small]=y2[very_small] @@ -791,17 +855,17 @@ def extract_limits(x,y,p,method=1): returns: v0,v1: lower and upper bounds of range """ - + # sets intervals according to highest likelihood - if method==1: + if method == 1: # this sorts from lowest to highest - sy=np.sort(y) + sy = np.sort(y) # highest to lowest - sy=sy[::-1] + sy = sy[::-1] # now 0 to 1 - csy=np.cumsum(sy) + csy = np.cumsum(sy) csy /= csy[-1] - + # this is the likelihood we cut on cut=np.where(csy < 1.-2.*p)[0] # allowed values in interval cut=cut[-1] # last allowed value @@ -811,55 +875,24 @@ def extract_limits(x,y,p,method=1): ik2=OK[-1] v0=x[ik1] v1=x[ik2] - if v1 < v0: - temp=v0 - v0=v1 - v1=temp elif method==2: cy=np.cumsum(y) cy /= cy[-1] # ignores normalisation in dx direction # gets lower value - inside=np.where(cy > p)[0] - ik1=inside[0] - v0=x[ik1] + inside = np.where(cy > p)[0] + ik1 = inside[0] + v0 = x[ik1] # gets upper value inside=np.where(cy > 1.-p)[0] ik2=inside[0] v1=x[ik2] return v0,v1,ik1,ik2 -def interpolate_and_limits(x0,y0,limits,logspline=True,aslatex=True): - """ - Fits a spline to y0(x0) (both np arrays of equal length) - Extracts values of x corresponding to the limits in limits, - and 1-limits - Returns: limits (list) - - Logspline: interpolate y in logspace - """ - xlims=[] - - x,y=interpolate_points(x0,y0,logspline) - for limit in limits: - l1,l2,ik1,ik2=extract_limits(x,y,limit,method=1) - xlims.append([l1,l2]) - - if aslatex: - xmax=x[np.argmax(y)] - string="${0:4.2f}$".format(xmax) - for pair in xlims: - minus=pair[0]-xmax - plus=pair[1]-xmax - latex="& $_{{{0:3.2f}}}^{{+{1:3.2f}}}$ ".format(minus,plus) - string += latex - return string - return xlims - def do_single_plots(uvals,vectors,wvectors,names,tag=None, fig_exten='.png', dolevels=False,log=True,outdir='SingleFigs/', vparams_dict=None, prefix='',truth=None,latexnames=None, - units=None,logspline=True, others=None): + units=None,logspline=True, others=None, compact=False, others_labels=None): """ Generate a series of 1D plots of the cube parameters Args: @@ -886,233 +919,402 @@ def do_single_plots(uvals,vectors,wvectors,names,tag=None, fig_exten='.png', others(list of arrays): list of other plots to add to data """ - + if tag is not None: - outdir=tag+outdir + outdir = tag + outdir if not os.path.isdir(outdir): - os.makedirs(outdir) - + os.makedirs(outdir) + if log: - logfile=outdir+'limits.dat' - logfile=open(logfile,'w') - + logfile = outdir + "limits.dat" + logfile = open(logfile, "w") + if dolevels: - results=np.zeros([len(uvals),9]) # holds mean and error info for each parameter - prior_results=np.zeros([len(uvals),9]) # does the same with alpha priors - - for i,vals in enumerate(uvals): - if len(vals) == 1: - continue - if len(vals) < 4: - kind = 'linear' - else: - kind = 'cubic' - # does the for alpha - plt.figure() - lw=3 - + results = np.zeros( + [len(uvals), 9] + ) # holds mean and error info for each parameter + prior_results = np.zeros([len(uvals), 9]) # does the same with alpha priors + + for i, vals in enumerate(uvals): # Convert vals? if vparams_dict is not None: # Check - assert vparams_dict[names[i]]['n'] == len(vals) - vals = np.linspace(vparams_dict[names[i]]['min'], - vparams_dict[names[i]]['max'], - len(vals)) + assert vparams_dict[names[i]]["n"] == len(vals) + vals = np.linspace( + vparams_dict[names[i]]["min"], vparams_dict[names[i]]["max"], len(vals) + ) + + plt.figure(dpi=300) + lw = 3 + + if compact: + plt.gcf().set_figheight(3) + plt.gcf().set_figwidth(3.5) # get raw ylimits # removes zeroes, could lead to strange behaviour in theory - ymax=np.max(vectors[i]) - temp=np.where((vectors[i] > 0.) & (np.isfinite(vectors[i])) ) - + ymax = np.max(vectors[i]) + temp = np.where((vectors[i] > 0.0) & (np.isfinite(vectors[i]))) + # set to integers and get range - ymax=math.ceil(ymax) - ymin=0. - - x,y=interpolate_points(vals[temp],vectors[i][temp],logspline) + ymax = math.ceil(ymax) + ymin = 0.0 + + kind = None + + if len(vals[temp]) == 1: + continue + if len(vals[temp]) < 4: + kind = "linear" + else: + kind = "cubic" + # does the for alpha - norm=np.sum(y)*(x[1]-x[0]) # integral y dx ~ sum y delta x - norm=np.abs(norm) + + x, y = interpolate_points(vals[temp], vectors[i][temp], logspline, kind=kind) + + norm = np.sum(y) * (x[1] - x[0]) # integral y dx ~ sum y delta x + norm = np.abs(norm) y /= norm vectors[i][temp] /= norm - plt.plot(x,y,label='Uniform',color='blue',linewidth=lw,linestyle='-') - plt.plot(vals[temp],vectors[i][temp],color='blue',linestyle='',marker='s') - - + plt.plot(x, y, label="Uniform", color="blue", linewidth=lw, linestyle="-") + if compact: + plt.plot(vals[temp], vectors[i][temp], color="blue", linestyle="", marker="s", ms=5) + else: + plt.plot(vals[temp], vectors[i][temp], color="blue", linestyle="", marker="s") + # weighted plotting if wvectors is not None: - wx,wy=interpolate_points(vals[temp],wvectors[i][temp],logspline) - wnorm=np.sum(wy)*(x[1]-x[0]) + wx, wy = interpolate_points( + vals[temp], wvectors[i][temp], logspline, kind=kind + ) + wnorm = np.sum(wy) * (x[1] - x[0]) wnorm = np.abs(wnorm) - + wvectors[i][temp] /= wnorm wy /= wnorm - plt.plot(x,wy,label='Gauss',color='orange',linewidth=lw,linestyle='--') - - ax=plt.gca() - ax.xaxis.set_ticks_position('both') - #ax.Xaxis.set_ticks_position('both') + plt.plot(x, wy, label="Gauss", color="orange", linewidth=lw, linestyle="--") + + ax = plt.gca() + ax.xaxis.set_ticks_position("both") + # ax.Xaxis.set_ticks_position('both') if wvectors is not None: - ymax=np.max([np.max(wy),np.max(y)]) + ymax = np.max([np.max(wy), np.max(y)]) else: - ymax=np.max(y) - - #ymax=(np.ceil(ymax*5.))/5. - - - if dolevels==True:# and i != 1: - limvals=np.array([0.00135,0.0228,0.05,0.15866]) - labels=['99.7%','95%','90%','68%'] - styles=['--',':','-.','-'] - upper=np.max(vectors[i]) - - besty=np.max(y) - imax=np.argmax(y) - xmax=x[imax] - results[i,0]=xmax - string=names[i]+" & {0:4.2f}".format(xmax) - for iav,av in enumerate(limvals): + ymax = np.max(y) + + # ymax=(np.ceil(ymax*5.))/5. + + if dolevels == True: # and i != 1: + limvals = np.array([0.00135, 0.0228, 0.05, 0.15866]) + labels = ["99.7%", "95%", "90%", "68%"] + styles = ["--", ":", "-.", "-"] + upper = np.max(vectors[i]) + + besty = np.max(y) + imax = np.argmax(y) + xmax = x[imax] + results[i, 0] = xmax + string = names[i] + " & {0:4.2f}".format(xmax) + for iav, av in enumerate(limvals): # need to integrate from min to some point # gets cumulative distribution # sets intervals according to highest likelihood - - v0,v1,ik1,ik2=extract_limits(x,y,av,method=1) - + + v0, v1, ik1, ik2 = extract_limits(x, y, av, method=1) + string += " & $_{" - string += "{0:4.2f}".format(v0-xmax) + string += "{0:4.2f}".format(v0 - xmax) string += "}^{+" - string += "{0:4.2f}".format(v1-xmax) + string += "{0:4.2f}".format(v1 - xmax) string += "}$ " - results[i,2*iav+1]=v0-xmax - results[i,2*iav+2]=v1-xmax - - hl=0.03 - doff=(x[-1]-x[0])/100. - ybar=(av+ymax)/2. - xbar=(v0+v1)/2. - + results[i, 2 * iav + 1] = v0 - xmax + results[i, 2 * iav + 2] = v1 - xmax + + hl = 0.03 + doff = (x[-1] - x[0]) / 100.0 + ybar = (av + ymax) / 2.0 + xbar = (v0 + v1) / 2.0 + # need to separate the plots if wvectors is not None: if ik1 != 0: - #if iav==3 and i==4: + # if iav==3 and i==4: # ybar -= 0.8 - plt.plot([x[ik1],x[ik1]],[ymax,y[ik1]],color='blue',linestyle=styles[iav],alpha=0.5) - if i==1: - t=plt.text(x[ik1]+doff*0.5,(ymax)+(-3.6+iav)*0.2*ymax,labels[iav],rotation=90,fontsize=12) - t.set_bbox(dict(facecolor='white', alpha=0.7, edgecolor='white',pad=-1)) - if ik2 != wy.size-1: - plt.plot([x[ik2],x[ik2]],[ymax,y[ik2]],color='blue',linestyle=styles[iav],alpha=0.5) + plt.plot( + [x[ik1], x[ik1]], + [ymax, y[ik1]], + color="blue", + linestyle=styles[iav], + alpha=0.5, + ) + if i == 1: + t = plt.text( + x[ik1] + doff * 0.5, + (ymax) + (-3.6 + iav) * 0.2 * ymax, + labels[iav], + rotation=90, + fontsize=12, + ) + t.set_bbox( + dict( + facecolor="white", + alpha=0.7, + edgecolor="white", + pad=-1, + ) + ) + if ik2 != wy.size - 1: + plt.plot( + [x[ik2], x[ik2]], + [ymax, y[ik2]], + color="blue", + linestyle=styles[iav], + alpha=0.5, + ) if i != 1: - t=plt.text(x[ik2]-doff*3,(ymax)+(-3.6+iav)*0.2*ymax,labels[iav],rotation=90,fontsize=12) - t.set_bbox(dict(facecolor='white', alpha=0.7, edgecolor='white',pad=-1)) + t = plt.text( + x[ik2] - doff * 3, + (ymax) + (-3.6 + iav) * 0.2 * ymax, + labels[iav], + rotation=90, + fontsize=12, + ) + t.set_bbox( + dict( + facecolor="white", + alpha=0.7, + edgecolor="white", + pad=-1, + ) + ) else: - plt.plot([x[ik1],x[ik1]],[0,y[ik1]],color='red',linestyle=styles[iav]) - plt.plot([x[ik2],x[ik2]],[0,y[ik2]],color='red',linestyle=styles[iav]) - Dx=x[-1]-x[0] - if Dx < 0.: - plt.text(x[ik1],y[ik1]+ymax*0.03,labels[iav],color='red',rotation=90) - plt.text(x[ik2]+0.02*Dx,y[ik2]+ymax*0.03,labels[iav],color='red',rotation=90) + plt.plot( + [x[ik1], x[ik1]], + [0, y[ik1]], + color="red", + linestyle=styles[iav], + ) + plt.plot( + [x[ik2], x[ik2]], + [0, y[ik2]], + color="red", + linestyle=styles[iav], + ) + Dx = x[-1] - x[0] + if Dx < 0.0: + plt.text( + x[ik1], + y[ik1] + ymax * 0.03, + labels[iav], + color="red", + rotation=90, + ) + plt.text( + x[ik2] + 0.02 * Dx, + y[ik2] + ymax * 0.03, + labels[iav], + color="red", + rotation=90, + ) else: - plt.text(x[ik1]-0.02*Dx,y[ik1]+ymax*0.03,labels[iav],color='red',rotation=90) - plt.text(x[ik2],y[ik2]+ymax*0.03,labels[iav],color='red',rotation=90) - #print("For parameter ",i," CI ",iav, " is ",x[ik1]," to ",x[ik2]) + plt.text( + x[ik1] - 0.02 * Dx, + y[ik1] + ymax * 0.03, + labels[iav], + color="red", + rotation=90, + ) + plt.text( + x[ik2], + y[ik2] + ymax * 0.03, + labels[iav], + color="red", + rotation=90, + ) + # print("For parameter ",i," CI ",iav, " is ",x[ik1]," to ",x[ik2]) string += " & " - - #could just ignore the weightings + + # could just ignore the weightings if wvectors is not None: - plt.plot(vals[temp],wvectors[i][temp],color='orange',linestyle='',marker='o') - if dolevels==True: - limvals=np.array([0.0015,0.025,0.05,0.16]) - labels=['99.7%','95%','90%','68%'] - styles=['--',':','-.','-'] - upper=np.max(wvectors[i]) - - besty=np.max(wy) - imax=np.argmax(wy) - xmax=x[imax] - prior_results[i,0]=xmax - string+=" {0:4.2f}".format(xmax) - for iav,av in enumerate(limvals): - + plt.plot( + vals[temp], wvectors[i][temp], color="orange", linestyle="", marker="o" + ) + if dolevels == True: + limvals = np.array([0.0015, 0.025, 0.05, 0.16]) + labels = ["99.7%", "95%", "90%", "68%"] + styles = ["--", ":", "-.", "-"] + upper = np.max(wvectors[i]) + + besty = np.max(wy) + imax = np.argmax(wy) + xmax = x[imax] + prior_results[i, 0] = xmax + string += " {0:4.2f}".format(xmax) + for iav, av in enumerate(limvals): + # sets intervals according to highest likelihood - v0,v1,ik1,ik2=extract_limits(x,wy,av,method=1) - + v0, v1, ik1, ik2 = extract_limits(x, wy, av, method=1) + string += " & $_{" - string += "{0:4.2f}".format(v0-xmax) + string += "{0:4.2f}".format(v0 - xmax) string += "}^{+" - string += "{0:4.2f}".format(v1-xmax) + string += "{0:4.2f}".format(v1 - xmax) string += "}$ " - prior_results[i,2*iav+1]=v0-xmax - prior_results[i,2*iav+2]=v1-xmax - + prior_results[i, 2 * iav + 1] = v0 - xmax + prior_results[i, 2 * iav + 2] = v1 - xmax + # version 2 - hl=0.03 - - doff=(x[-1]-x[0])/100. - if i==1: - doff=0.001 - ybar=(av+ymin)/2. - xbar=(v0+v1)/2. + hl = 0.03 + + doff = (x[-1] - x[0]) / 100.0 + if i == 1: + doff = 0.001 + ybar = (av + ymin) / 2.0 + xbar = (v0 + v1) / 2.0 if ik1 != 0: - plt.plot([x[ik1],x[ik1]],[ymin,wy[ik1]],color='orange',linestyle=styles[iav]) - if i ==1: - t=plt.text(x[ik1]+doff*0.5,wy[ik1]/2.2,labels[iav],rotation=90,fontsize=12) - t.set_bbox(dict(facecolor='white', alpha=0.7, edgecolor='white',pad=-1)) - - if ik2 != wy.size-1: - - plt.plot([x[ik2],x[ik2]],[ymin,wy[ik2]],color='orange',linestyle=styles[iav]) + plt.plot( + [x[ik1], x[ik1]], + [ymin, wy[ik1]], + color="orange", + linestyle=styles[iav], + ) + if i == 1: + t = plt.text( + x[ik1] + doff * 0.5, + wy[ik1] / 2.2, + labels[iav], + rotation=90, + fontsize=12, + ) + t.set_bbox( + dict( + facecolor="white", + alpha=0.7, + edgecolor="white", + pad=-1, + ) + ) + + if ik2 != wy.size - 1: + + plt.plot( + [x[ik2], x[ik2]], + [ymin, wy[ik2]], + color="orange", + linestyle=styles[iav], + ) if i != 1: - t=plt.text(x[ik2]-doff*3,wy[ik2]/2.2,labels[iav],rotation=90,fontsize=12) - t.set_bbox(dict(facecolor='white', alpha=0.7, edgecolor='white',pad=-1)) - other_styles=[":","--","-."] + t = plt.text( + x[ik2] - doff * 3, + wy[ik2] / 2.2, + labels[iav], + rotation=90, + fontsize=12, + ) + t.set_bbox( + dict( + facecolor="white", + alpha=0.7, + edgecolor="white", + pad=-1, + ) + ) + other_styles = [":", "--", "-."] + + # other_colors = ["orange", "green", "red"] # plot any other plots if others is not None: if others[i] is not None: - for io,data in enumerate(others[i]): - x,y=interpolate_points(vals,data,logspline) - norm=np.sum(y)*(x[1]-x[0]) # integral y dx ~ sum y delta x - norm=np.abs(norm) + for io, data in enumerate(others[i]): + x, y = interpolate_points(vals, data, logspline, kind=kind) + norm = np.sum(y) * (x[1] - x[0]) # integral y dx ~ sum y delta x + norm = np.abs(norm) y /= norm - plt.plot(x,y,color='grey',linewidth=1,linestyle=other_styles[io % 3]) + + imax = np.argmax(y) + xmax = x[imax] + + if dolevels: + + logfile_others = outdir + f"limits_others_{others_labels[io]}.dat" + logfile_others = open(logfile_others, "w") + others_string = "" + # print(f"Confidence intervals for alternative distribution {names[i]}, {others_labels[io]}") + # limvals = np.array([0.00135, 0.0228, 0.05, 0.15866]) + # labels = ["99.7%", "95%", "90%", "68%"] + + limvals = np.array([0.15866]) + labels = ["68%"] + + for iav, av in enumerate(limvals): + v0, v1, ik1, ik2 = extract_limits(x, y, av, method=1) + others_string += "{} : ${}_{{{}}}^{{+{}}}$".format(labels[iav], format(xmax, '.2f'), format(v0 - xmax, '.2f'), format(v1 - xmax, '.2f')) + + logfile_others.write(string + "\n") + logfile_others.close() + + # data_norm = np.sum(data) * (vals[1] - vals[0]) + # data_norm = np.abs(norm) + + # plt.plot(vals, data/data_norm, color=other_colors[io % 3], marker="s") + plt.plot( + x, y, color="grey", linewidth=1, linestyle=other_styles[io % 3], label=others_labels[io % 3] + ) + + plt.legend() if dolevels: string += "\\\\" if log: - logfile.write(string+'\n') + logfile.write(string + "\n") else: print(string) - #plt.ylim(0.,ymax) + # plt.ylim(0.,ymax) plt.gca().set_ylim(bottom=0) if truth is not None: - plt.plot([truth[i],truth[i]],plt.gca().get_ylim(),color='black',linestyle=':') - Dx=x[-1]-x[0] - plt.text(truth[i]+0.01*Dx,ymax*0.4,'simulated truth',rotation=90) - + plt.plot( + [truth[i], truth[i]], plt.gca().get_ylim(), color="black", linestyle=":" + ) + Dx = x[-1] - x[0] + plt.text(truth[i] + 0.01 * Dx, ymax * 0.4, "simulated truth", rotation=90) + if latexnames is not None: if units is not None: - plt.xlabel(latexnames[i]+" "+units[i]) + plt.xlabel(latexnames[i] + " " + units[i]) else: plt.xlabel(latexnames[i]) - plt.ylabel('$p($'+latexnames[i]+'$)$') + plt.ylabel("$p($" + latexnames[i] + "$)$") else: plt.xlabel(names[i]) - plt.ylabel('p('+names[i]+')') - if i==4 and wvectors is not None: - plt.legend(loc='upper left',title='Prior on $\\alpha$') - + plt.ylabel("p(" + names[i] + ")") + if i == 4 and wvectors is not None: + plt.legend(loc="upper left", title="Prior on $\\alpha$") + plt.tight_layout() - plt.savefig(os.path.join(outdir, prefix+names[i]+fig_exten), dpi=200) + plt.savefig(os.path.join(outdir, prefix + names[i] + fig_exten), dpi=300) plt.close() if log: logfile.close() if dolevels: - return results,prior_results + return results, prior_results else: return -def make_1d_plots_by_contribution(data,contributions,labels,prefix="", - fig_exten='.png',log=False,splines=True,latexnames=None,units=None, - linestyles=None,colors=None): + +def make_1d_plots_by_contribution( + data, + contributions, + labels, + prefix="", + fig_exten=".png", + log=False, + splines=True, + latexnames=None, + units=None, + linestyles=None, + colors=None, +): """ contributions: list of vectors giving various likelihood terms args: @@ -1122,79 +1324,116 @@ def make_1d_plots_by_contribution(data,contributions,labels,prefix="", units: appends units to x axis but not p(X) """ ######################### 1D plots, split by terms ################ - all_uvals=[] - all_vectors=[] - all_wvectors=[] - combined=data["pzDM"]+data["pDM"] - + all_uvals = [] + all_vectors = [] + all_wvectors = [] + combined = data["pzDM"] + data["pDM"] + # gets 1D Bayesian curves for each contribution for datatype in contributions: - uvals,vectors,wvectors=get_bayesian_data(datatype) + uvals, vectors, wvectors = get_bayesian_data(datatype) all_uvals.append(uvals) all_vectors.append(vectors) all_wvectors.append(wvectors) - params=data["params"] - + params = data["params"] + # gets unique values for each axis - param_vals=[] - param_list=[data["lEmax"],data["H0"],data["alpha"],data["gamma"],data["sfr_n"],data["lmean"],data["lsigma"]] - xlatexnames=['\\log_{10} E_{\\rm max} {\\rm [erg]}','H_0 {\\rm [km\,s^{-1}\,Mpc^{-1}]}','\\alpha','\\gamma','n_{\\rm sfr}','\\mu_{\\rm host} {\\rm [pc\,cm^{-3}]}','\\sigma_{\\rm host}'] - ylatexnames=['\\log_{10} E_{\\rm max}','H_0','\\alpha','\\gamma','n_{\\rm sfr}','\\mu_{\\rm host}','\\sigma_{\\rm host}'] - + param_vals = [] + param_list = [ + data["lEmax"], + data["H0"], + data["alpha"], + data["gamma"], + data["sfr_n"], + data["lmean"], + data["lsigma"], + ] + xlatexnames = [ + "\\log_{10} E_{\\rm max} {\\rm [erg]}", + "H_0 {\\rm [km\,s^{-1}\,Mpc^{-1}]}", + "\\alpha", + "\\gamma", + "n_{\\rm sfr}", + "\\mu_{\\rm host} {\\rm [pc\,cm^{-3}]}", + "\\sigma_{\\rm host}", + ] + ylatexnames = [ + "\\log_{10} E_{\\rm max}", + "H_0", + "\\alpha", + "\\gamma", + "n_{\\rm sfr}", + "\\mu_{\\rm host}", + "\\sigma_{\\rm host}", + ] + for col in param_list: - unique=np.unique(col) + unique = np.unique(col) param_vals.append(unique) # assigns different plotting styles to help distinguish curves if linestyles is None: - linestyles=['-','--','-.',':','-','--','-.',':','-','--','-.',':'] + linestyles = ["-", "--", "-.", ":", "-", "--", "-.", ":", "-", "--", "-.", ":"] if colors is None: - colors=plt.rcParams['axes.prop_cycle'].by_key()['color'] + colors = plt.rcParams["axes.prop_cycle"].by_key()["color"] for which in np.arange(len(param_list)): plt.figure() - plt.xlabel('$'+xlatexnames[which]+'$') - plt.ylabel('$p('+ylatexnames[which]+')$') - xvals=param_vals[which] - - for idata,vectors in enumerate(all_vectors): + plt.xlabel("$" + xlatexnames[which] + "$") + plt.ylabel("$p(" + ylatexnames[which] + ")$") + xvals = param_vals[which] + + for idata, vectors in enumerate(all_vectors): if splines: - xdata=np.linspace(xvals[0],xvals[-1],100) - f=scipy.interpolate.interp1d(xvals,np.log(vectors[which]), - kind='cubic') - ydata=np.exp(f(xdata)) - plt.plot(xdata,ydata,label=labels[idata], - linestyle=linestyles[idata], color=colors[idata]) - plt.scatter(xvals,vectors[which],color=plt.gca().lines[-1].get_color()) + xdata = np.linspace(xvals[0], xvals[-1], 100) + f = scipy.interpolate.interp1d( + xvals, np.log(vectors[which]), kind="cubic" + ) + ydata = np.exp(f(xdata)) + plt.plot( + xdata, + ydata, + label=labels[idata], + linestyle=linestyles[idata], + color=colors[idata], + ) + plt.scatter( + xvals, vectors[which], color=plt.gca().lines[-1].get_color() + ) else: - ydata=vectors[which] - xdata=xvals - #print(labels[idata]," has values ",vector) - plt.plot(xdata,ydata,label=labels[idata],linestyle=linestyles[idata], - color=colors[idata]) - + ydata = vectors[which] + xdata = xvals + # print(labels[idata]," has values ",vector) + plt.plot( + xdata, + ydata, + label=labels[idata], + linestyle=linestyles[idata], + color=colors[idata], + ) + if log: - plt.yscale('log') - #plt.ylim(np.max(vector)*1e-3,np.max(vector)) #improve this + plt.yscale("log") + # plt.ylim(np.max(vector)*1e-3,np.max(vector)) #improve this plt.legend() - plt.savefig(prefix+params[which]+fig_exten) + plt.savefig(prefix + params[which] + fig_exten) plt.close() - -def gen_vparams(indices:tuple, vparam_dict:dict): + + +def gen_vparams(indices: tuple, vparam_dict: dict): new_dict = {} for ss, key in enumerate(vparam_dict.keys()): - if vparam_dict[key]['n'] <= 0: + if vparam_dict[key]["n"] <= 0: continue - # - vals = np.linspace(vparam_dict[key]['min'], - vparam_dict[key]['max'], - vparam_dict[key]['n']) - # + # + vals = np.linspace( + vparam_dict[key]["min"], vparam_dict[key]["max"], vparam_dict[key]["n"] + ) + # new_dict[key] = vals[indices[ss]] # Return return new_dict - -def make_2d_plot(array,xlabel,ylabel,xvals,yvals,savename=None,norm=None): +def make_2d_plot(array, xlabel, ylabel, xvals, yvals, savename=None, norm=None): """ Makes 2D plot given an array of probabilities @@ -1208,43 +1447,48 @@ def make_2d_plot(array,xlabel,ylabel,xvals,yvals,savename=None,norm=None): savename (optional): string to save data under """ - plt.figure() + plt.figure(dpi=300) plt.xlabel(xlabel) plt.ylabel(ylabel) - + # calculates increment in values - Dx=xvals[-1]-xvals[0] - Dy=yvals[-1]-yvals[0] - - nx=xvals.size - ny=yvals.size - - dx=np.abs(Dx/nx) - dy=np.abs(Dy/ny) - - aspect=np.abs(dx/dy * nx/ny) - + Dx = xvals[-1] - xvals[0] + Dy = yvals[-1] - yvals[0] + + nx = xvals.size + ny = yvals.size + + dx = np.abs(Dx / nx) + dy = np.abs(Dy / ny) + + aspect = np.abs(dx / dy * nx / ny) + # the dx/2 etc is so that parameter values line up with the centres of each pixel - extent=[np.min(xvals)-dx/2.,np.max(xvals)+dx/2.,np.min(yvals)-dy/2.,np.max(yvals)+dy/2.] - - if norm==0: - array=array/np.max(array,axis=0) - clabel='$p($'+ylabel+'|'+xlabel+'$)$' - elif norm==1: - array=array.T/np.max(array,axis=1) - array=array.T - clabel='$p($'+xlabel+'|'+ylabel+'$)$' + extent = [ + np.min(xvals) - dx / 2.0, + np.max(xvals) + dx / 2.0, + np.min(yvals) - dy / 2.0, + np.max(yvals) + dy / 2.0, + ] + + if norm == 0: + array = array / np.max(array, axis=0) + clabel = "$p($" + ylabel + "|" + xlabel + "$)$" + elif norm == 1: + array = array.T / np.max(array, axis=1) + array = array.T + clabel = "$p($" + xlabel + "|" + ylabel + "$)$" else: - clabel='$p($'+xlabel+','+ylabel+'$)$' - - plt.imshow(array.T,origin='lower',extent=extent,aspect=aspect) - plt.xlabel(xlabel) - plt.ylabel(ylabel) + clabel = "$p($" + xlabel + "," + ylabel + "$)$" + + plt.imshow(array.T, origin="lower", extent=extent, aspect=aspect) + plt.xlabel(xlabel, fontsize=18) + plt.ylabel(ylabel, fontsize=18) plt.xticks(rotation=90) - cbar=plt.colorbar() - cbar.set_label(clabel) + cbar = plt.colorbar() + cbar.set_label(clabel, fontsize=18) if savename is None: - savename=xlabel+"_"+ylabel+".pdf" + savename = xlabel + "_" + ylabel + ".pdf" plt.tight_layout() plt.savefig(savename) plt.close() diff --git a/zdm/craco/MC_F/Surveys/F_0.01_dmhost_suppressed_survey_state.json b/zdm/craco/MC_F/Surveys/F_0.01_dmhost_suppressed_survey_state.json new file mode 100644 index 00000000..1a2786ba --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_0.01_dmhost_suppressed_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.01 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 0.001, + "lsigma": 0.1 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/MC_F/Surveys/F_0.01_survey_state.json b/zdm/craco/MC_F/Surveys/F_0.01_survey_state.json new file mode 100644 index 00000000..d1394e1c --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_0.01_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.01 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/MC_F/Surveys/F_0.32_survey.dat b/zdm/craco/MC_F/Surveys/F_0.32_survey.dat new file mode 100644 index 00000000..aad8c47e --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_0.32_survey.dat @@ -0,0 +1,1015 @@ +BW 288 #MHz +FRES 1 #MHz +DIAM 12 +NBEAMS 36 +BEAM lat50_log #prefix of beam file +NBINS 5 +FBAR 1320 +TRES 1.7 #ms +SNRTHRESH 9.5 +NFRB 1000 +NORM_FRB 1000 +TOBS 96.65 # days of 100% efficient operation +THRESH 0.99 #Jy ms to 1 ms burst [ 22 Jy ms / 24 antennas *sqrt{336/288} bandwidth factor] +KEY ID DM DMG DMEG Z SNR WIDTH +# fake data from MC simulations +FRB 0 550.1 35 465.1 0.313 25.5 2.0 +FRB 1 273.7 35 188.7 0.020 22.8 2.0 +FRB 2 680.2 35 595.2 0.645 10.2 1.0 +FRB 3 515.1 35 430.1 0.179 36.1 3.0 +FRB 4 572.3 35 487.3 0.207 44.0 5.0 +FRB 5 330.9 35 245.9 0.299 17.6 4.0 +FRB 6 888.9 35 803.9 0.737 22.3 3.0 +FRB 7 378.2 35 293.2 0.358 25.7 2.0 +FRB 8 458.5 35 373.5 0.047 104.3 1.0 +FRB 9 1047.4 35 962.4 1.259 19.8 2.0 +FRB 10 349.8 35 264.8 0.300 39.3 4.0 +FRB 11 376.2 35 291.2 0.476 15.3 2.0 +FRB 12 240.3 35 155.3 0.254 33.6 1.0 +FRB 13 495.1 35 410.1 0.486 13.1 3.0 +FRB 14 302.0 35 217.0 0.061 16.2 3.0 +FRB 15 465.4 35 380.4 0.222 46.8 3.0 +FRB 16 298.9 35 213.9 0.173 12.0 3.0 +FRB 17 362.7 35 277.7 0.074 12.0 4.0 +FRB 18 1707.5 35 1622.5 0.842 16.8 3.0 +FRB 19 122.8 35 37.8 0.003 53.0 2.0 +FRB 20 405.5 35 320.5 0.538 58.0 3.0 +FRB 21 896.8 35 811.8 0.754 13.1 3.0 +FRB 22 300.8 35 215.8 0.163 19.6 2.0 +FRB 23 913.3 35 828.3 0.768 10.6 2.0 +FRB 24 763.0 35 678.0 0.716 31.8 3.0 +FRB 25 1107.1 35 1022.1 1.020 13.2 2.0 +FRB 26 417.6 35 332.6 0.352 138.9 1.0 +FRB 27 355.0 35 270.0 0.283 14.8 2.0 +FRB 28 240.7 35 155.7 0.038 18.7 3.0 +FRB 29 618.0 35 533.0 0.318 37.9 4.0 +FRB 30 975.5 35 890.5 0.407 17.5 2.0 +FRB 31 403.9 35 318.9 0.124 10.0 3.0 +FRB 32 975.2 35 890.2 1.093 11.3 2.0 +FRB 33 142.8 35 57.8 0.001 20.2 4.0 +FRB 34 299.6 35 214.6 0.208 16.5 1.0 +FRB 35 243.5 35 158.5 0.050 10.1 0.0 +FRB 36 1455.2 35 1370.2 1.873 10.6 2.0 +FRB 37 178.4 35 93.4 0.082 68.0 2.0 +FRB 38 719.1 35 634.1 0.927 10.1 4.0 +FRB 39 795.7 35 710.7 0.495 11.8 1.0 +FRB 40 397.4 35 312.4 0.347 10.4 2.0 +FRB 41 350.3 35 265.3 0.111 18.2 2.0 +FRB 42 218.6 35 133.6 0.092 12.9 1.0 +FRB 43 332.3 35 247.3 0.179 29.6 3.0 +FRB 44 435.0 35 350.0 0.256 16.5 3.0 +FRB 45 568.2 35 483.2 0.463 11.9 1.0 +FRB 46 1062.3 35 977.3 1.071 18.1 1.0 +FRB 47 401.7 35 316.7 0.293 30.1 2.0 +FRB 48 589.2 35 504.2 0.503 13.1 1.0 +FRB 49 244.4 35 159.4 0.014 36.6 3.0 +FRB 50 223.5 35 138.5 0.224 193.2 3.0 +FRB 51 1308.0 35 1223.0 0.453 10.3 2.0 +FRB 52 384.5 35 299.5 0.286 23.9 1.0 +FRB 53 678.3 35 593.3 0.588 10.5 3.0 +FRB 54 488.8 35 403.8 0.333 9.8 1.0 +FRB 55 418.4 35 333.4 0.382 12.0 2.0 +FRB 56 388.3 35 303.3 0.354 55.5 4.0 +FRB 57 479.7 35 394.7 0.135 55.6 2.0 +FRB 58 176.3 35 91.3 0.078 40.5 2.0 +FRB 59 328.3 35 243.3 0.277 16.8 1.0 +FRB 60 577.7 35 492.7 0.683 38.5 2.0 +FRB 61 509.6 35 424.6 0.359 11.7 0.0 +FRB 62 398.7 35 313.7 0.483 18.9 2.0 +FRB 63 691.3 35 606.3 0.197 20.8 2.0 +FRB 64 493.2 35 408.2 0.374 15.2 3.0 +FRB 65 350.9 35 265.9 0.028 93.5 3.0 +FRB 66 428.1 35 343.1 0.435 16.8 4.0 +FRB 67 801.0 35 716.0 1.053 16.2 4.0 +FRB 68 412.7 35 327.7 0.172 15.2 2.0 +FRB 69 907.4 35 822.4 0.497 26.8 1.0 +FRB 70 461.0 35 376.0 0.272 125.7 3.0 +FRB 71 943.3 35 858.3 0.638 16.8 3.0 +FRB 72 419.5 35 334.5 0.234 59.2 1.0 +FRB 73 187.7 35 102.7 0.064 168.5 2.0 +FRB 74 551.6 35 466.6 0.459 26.4 3.0 +FRB 75 276.6 35 191.6 0.288 25.6 0.0 +FRB 76 275.7 35 190.7 0.141 28.0 3.0 +FRB 77 421.4 35 336.4 0.097 13.7 1.0 +FRB 78 345.1 35 260.1 0.222 11.3 1.0 +FRB 79 476.7 35 391.7 0.191 15.6 3.0 +FRB 80 277.7 35 192.7 0.055 645.9 1.0 +FRB 81 411.0 35 326.0 0.333 12.3 2.0 +FRB 82 654.8 35 569.8 0.060 16.8 4.0 +FRB 83 440.5 35 355.5 0.101 20.4 0.0 +FRB 84 355.8 35 270.8 0.184 89.8 3.0 +FRB 85 627.5 35 542.5 0.428 13.5 5.0 +FRB 86 1497.3 35 1412.3 1.597 10.1 3.0 +FRB 87 220.6 35 135.6 0.127 16.7 3.0 +FRB 88 219.8 35 134.8 0.104 10.2 1.0 +FRB 89 193.1 35 108.1 0.127 15.0 3.0 +FRB 90 532.5 35 447.5 0.490 13.4 2.0 +FRB 91 1473.7 35 1388.7 0.689 12.6 3.0 +FRB 92 528.4 35 443.4 0.256 9.6 2.0 +FRB 93 886.6 35 801.6 0.942 10.3 1.0 +FRB 94 558.4 35 473.4 0.827 39.2 2.0 +FRB 95 751.5 35 666.5 0.788 19.6 2.0 +FRB 96 365.8 35 280.8 0.071 48.4 3.0 +FRB 97 442.8 35 357.8 0.290 10.4 2.0 +FRB 98 808.5 35 723.5 0.421 11.3 2.0 +FRB 99 1026.1 35 941.1 1.304 14.3 4.0 +FRB 100 186.7 35 101.7 0.150 15.9 2.0 +FRB 101 1179.5 35 1094.5 1.321 26.0 1.0 +FRB 102 438.5 35 353.5 0.062 20.2 4.0 +FRB 103 315.3 35 230.3 0.089 17.9 1.0 +FRB 104 833.1 35 748.1 0.949 10.5 2.0 +FRB 105 595.3 35 510.3 0.250 32.8 2.0 +FRB 106 313.4 35 228.4 0.370 16.8 4.0 +FRB 107 568.5 35 483.5 0.629 13.1 2.0 +FRB 108 143.5 35 58.5 0.026 11.0 4.0 +FRB 109 743.4 35 658.4 0.812 12.6 3.0 +FRB 110 941.9 35 856.9 0.755 10.0 2.0 +FRB 111 460.5 35 375.5 0.355 10.7 2.0 +FRB 112 1271.8 35 1186.8 0.432 12.1 2.0 +FRB 113 1308.6 35 1223.6 1.273 15.7 2.0 +FRB 114 567.9 35 482.9 0.608 12.4 3.0 +FRB 115 410.5 35 325.5 0.057 84.7 2.0 +FRB 116 391.1 35 306.1 0.251 117.3 1.0 +FRB 117 1287.8 35 1202.8 1.592 9.7 2.0 +FRB 118 634.8 35 549.8 0.378 15.9 2.0 +FRB 119 383.0 35 298.0 0.176 15.6 2.0 +FRB 120 372.7 35 287.7 0.167 16.2 2.0 +FRB 121 237.3 35 152.3 0.041 13.3 2.0 +FRB 122 478.8 35 393.8 0.354 27.0 2.0 +FRB 123 835.0 35 750.0 0.735 51.2 2.0 +FRB 124 282.6 35 197.6 0.263 10.6 3.0 +FRB 125 151.4 35 66.4 0.046 223.4 3.0 +FRB 126 819.9 35 734.9 0.750 13.1 4.0 +FRB 127 162.3 35 77.3 0.138 17.3 3.0 +FRB 128 371.1 35 286.1 0.282 25.0 1.0 +FRB 129 357.4 35 272.4 0.262 16.3 1.0 +FRB 130 331.8 35 246.8 0.085 40.2 3.0 +FRB 131 557.5 35 472.5 0.289 88.5 3.0 +FRB 132 818.5 35 733.5 0.660 9.8 3.0 +FRB 133 1257.6 35 1172.6 0.699 22.4 3.0 +FRB 134 1116.3 35 1031.3 1.367 11.6 2.0 +FRB 135 2259.2 35 2174.2 1.338 12.3 3.0 +FRB 136 307.9 35 222.9 0.243 22.6 4.0 +FRB 137 1311.1 35 1226.1 1.712 24.4 3.0 +FRB 138 848.2 35 763.2 1.006 11.6 2.0 +FRB 139 1060.6 35 975.6 1.108 10.6 3.0 +FRB 140 785.5 35 700.5 0.164 10.0 3.0 +FRB 141 484.9 35 399.9 0.520 11.7 0.0 +FRB 142 481.2 35 396.2 0.424 9.6 3.0 +FRB 143 484.7 35 399.7 0.610 14.9 3.0 +FRB 144 260.6 35 175.6 0.054 12.9 3.0 +FRB 145 393.8 35 308.8 0.291 12.7 4.0 +FRB 146 273.7 35 188.7 0.182 22.7 3.0 +FRB 147 534.4 35 449.4 0.556 21.0 3.0 +FRB 148 703.6 35 618.6 0.195 10.8 1.0 +FRB 149 335.9 35 250.9 0.329 18.5 3.0 +FRB 150 898.1 35 813.1 0.718 32.2 2.0 +FRB 151 582.2 35 497.2 0.571 13.8 3.0 +FRB 152 636.2 35 551.2 0.441 23.1 2.0 +FRB 153 735.7 35 650.7 0.482 27.7 2.0 +FRB 154 1405.0 35 1320.0 1.318 11.4 4.0 +FRB 155 1083.0 35 998.0 1.101 19.3 3.0 +FRB 156 709.4 35 624.4 0.580 12.4 2.0 +FRB 157 1794.1 35 1709.1 1.849 14.9 3.0 +FRB 158 736.2 35 651.2 0.546 11.0 2.0 +FRB 159 808.6 35 723.6 0.472 33.4 2.0 +FRB 160 352.0 35 267.0 0.126 16.0 3.0 +FRB 161 447.5 35 362.5 0.543 38.3 1.0 +FRB 162 1346.2 35 1261.2 1.567 12.3 2.0 +FRB 163 428.3 35 343.3 0.537 12.3 2.0 +FRB 164 421.8 35 336.8 0.018 28.0 4.0 +FRB 165 602.3 35 517.3 0.093 16.3 2.0 +FRB 166 1110.1 35 1025.1 0.439 94.0 3.0 +FRB 167 303.5 35 218.5 0.137 10.8 1.0 +FRB 168 799.7 35 714.7 0.465 18.8 3.0 +FRB 169 309.6 35 224.6 0.159 30.0 2.0 +FRB 170 3446.6 35 3361.6 0.080 25.6 5.0 +FRB 171 721.5 35 636.5 0.306 25.8 2.0 +FRB 172 296.3 35 211.3 0.134 21.4 5.0 +FRB 173 573.2 35 488.2 0.464 19.6 2.0 +FRB 174 184.5 35 99.5 0.063 11.4 1.0 +FRB 175 580.0 35 495.0 0.632 15.6 0.0 +FRB 176 754.0 35 669.0 0.103 9.6 1.0 +FRB 177 391.9 35 306.9 0.430 11.2 1.0 +FRB 178 282.0 35 197.0 0.073 21.7 3.0 +FRB 179 548.7 35 463.7 0.350 25.8 4.0 +FRB 180 449.7 35 364.7 0.019 12.6 3.0 +FRB 181 187.9 35 102.9 0.052 40.8 2.0 +FRB 182 522.1 35 437.1 0.353 11.8 2.0 +FRB 183 233.3 35 148.3 0.081 85.5 2.0 +FRB 184 923.9 35 838.9 0.961 9.9 2.0 +FRB 185 568.1 35 483.1 0.295 15.9 5.0 +FRB 186 1327.1 35 1242.1 0.437 18.6 2.0 +FRB 187 901.0 35 816.0 0.744 39.8 2.0 +FRB 188 776.9 35 691.9 0.786 14.5 2.0 +FRB 189 359.8 35 274.8 0.372 46.4 1.0 +FRB 190 733.7 35 648.7 0.633 18.7 2.0 +FRB 191 685.6 35 600.6 0.765 9.8 3.0 +FRB 192 568.9 35 483.9 0.644 14.8 3.0 +FRB 193 398.7 35 313.7 0.239 23.3 3.0 +FRB 194 664.2 35 579.2 0.495 15.8 3.0 +FRB 195 326.6 35 241.6 0.251 14.2 1.0 +FRB 196 726.0 35 641.0 0.089 23.7 5.0 +FRB 197 342.1 35 257.1 0.029 48.2 2.0 +FRB 198 376.5 35 291.5 0.279 47.9 1.0 +FRB 199 271.9 35 186.9 0.237 18.9 2.0 +FRB 200 226.2 35 141.2 0.036 25.8 2.0 +FRB 201 636.8 35 551.8 0.069 18.9 1.0 +FRB 202 1305.4 35 1220.4 1.562 13.6 1.0 +FRB 203 1160.6 35 1075.6 0.743 11.9 3.0 +FRB 204 393.9 35 308.9 0.118 67.2 2.0 +FRB 205 208.4 35 123.4 0.200 9.9 2.0 +FRB 206 747.5 35 662.5 0.232 28.0 2.0 +FRB 207 544.7 35 459.7 0.397 14.1 2.0 +FRB 208 208.3 35 123.3 0.125 25.2 2.0 +FRB 209 647.3 35 562.3 0.658 10.2 2.0 +FRB 210 942.2 35 857.2 0.343 10.9 2.0 +FRB 211 512.8 35 427.8 0.053 24.3 2.0 +FRB 212 407.9 35 322.9 0.102 23.2 1.0 +FRB 213 519.0 35 434.0 0.377 13.9 2.0 +FRB 214 1342.6 35 1257.6 0.707 10.9 2.0 +FRB 215 424.8 35 339.8 0.230 18.1 4.0 +FRB 216 621.2 35 536.2 0.790 16.0 3.0 +FRB 217 655.3 35 570.3 0.588 16.5 2.0 +FRB 218 2215.0 35 2130.0 0.080 19.1 3.0 +FRB 219 716.7 35 631.7 0.683 41.8 2.0 +FRB 220 294.3 35 209.3 0.197 22.7 4.0 +FRB 221 690.7 35 605.7 0.703 20.4 2.0 +FRB 222 794.9 35 709.9 0.048 33.2 2.0 +FRB 223 704.5 35 619.5 0.802 10.0 3.0 +FRB 224 676.6 35 591.6 0.153 11.3 2.0 +FRB 225 458.6 35 373.6 0.467 92.5 3.0 +FRB 226 508.2 35 423.2 0.432 15.3 3.0 +FRB 227 1294.8 35 1209.8 1.343 10.6 2.0 +FRB 228 666.7 35 581.7 0.579 22.5 0.0 +FRB 229 178.7 35 93.7 0.054 22.7 3.0 +FRB 230 154.3 35 69.3 0.039 31.8 3.0 +FRB 231 790.1 35 705.1 1.095 9.8 2.0 +FRB 232 625.4 35 540.4 0.622 11.2 3.0 +FRB 233 448.6 35 363.6 0.272 14.1 1.0 +FRB 234 351.6 35 266.6 0.212 28.0 1.0 +FRB 235 532.9 35 447.9 0.502 14.2 2.0 +FRB 236 146.4 35 61.4 0.026 25.9 2.0 +FRB 237 363.8 35 278.8 0.317 12.5 1.0 +FRB 238 235.7 35 150.7 0.182 47.5 3.0 +FRB 239 394.0 35 309.0 0.356 15.3 4.0 +FRB 240 1055.4 35 970.4 0.935 27.4 1.0 +FRB 241 212.1 35 127.1 0.148 10.6 2.0 +FRB 242 2097.3 35 2012.3 2.036 9.9 1.0 +FRB 243 440.9 35 355.9 0.405 13.3 2.0 +FRB 244 677.6 35 592.6 0.310 16.1 3.0 +FRB 245 339.0 35 254.0 0.042 10.6 1.0 +FRB 246 270.0 35 185.0 0.033 12.0 4.0 +FRB 247 430.7 35 345.7 0.464 15.2 2.0 +FRB 248 2151.2 35 2066.2 0.622 25.4 1.0 +FRB 249 445.0 35 360.0 0.301 14.0 4.0 +FRB 250 326.7 35 241.7 0.229 16.6 3.0 +FRB 251 756.5 35 671.5 0.619 12.1 4.0 +FRB 252 474.3 35 389.3 0.136 11.6 4.0 +FRB 253 301.1 35 216.1 0.080 24.9 3.0 +FRB 254 251.3 35 166.3 0.190 34.5 3.0 +FRB 255 215.4 35 130.4 0.152 66.6 2.0 +FRB 256 688.1 35 603.1 0.562 11.4 2.0 +FRB 257 395.1 35 310.1 0.234 19.7 4.0 +FRB 258 1602.7 35 1517.7 1.216 20.4 2.0 +FRB 259 409.3 35 324.3 0.196 14.4 3.0 +FRB 260 785.5 35 700.5 0.821 25.5 2.0 +FRB 261 1411.5 35 1326.5 0.908 10.5 2.0 +FRB 262 365.7 35 280.7 0.208 29.0 1.0 +FRB 263 809.8 35 724.8 0.106 10.1 3.0 +FRB 264 377.8 35 292.8 0.139 13.8 2.0 +FRB 265 422.9 35 337.9 0.423 12.2 1.0 +FRB 266 295.9 35 210.9 0.215 21.9 2.0 +FRB 267 199.7 35 114.7 0.161 39.4 2.0 +FRB 268 456.5 35 371.5 0.210 12.2 2.0 +FRB 269 587.6 35 502.6 0.055 10.8 3.0 +FRB 270 275.5 35 190.5 0.096 10.2 2.0 +FRB 271 386.9 35 301.9 0.053 18.2 1.0 +FRB 272 1319.3 35 1234.3 1.418 10.1 2.0 +FRB 273 629.7 35 544.7 0.741 26.0 2.0 +FRB 274 157.7 35 72.7 0.024 21.4 2.0 +FRB 275 722.1 35 637.1 0.616 27.7 4.0 +FRB 276 775.6 35 690.6 0.609 22.5 3.0 +FRB 277 476.8 35 391.8 0.393 9.8 3.0 +FRB 278 823.4 35 738.4 0.801 12.4 2.0 +FRB 279 709.3 35 624.3 0.796 17.7 3.0 +FRB 280 765.4 35 680.4 1.032 9.9 1.0 +FRB 281 1306.7 35 1221.7 0.336 28.2 3.0 +FRB 282 253.7 35 168.7 0.066 36.1 3.0 +FRB 283 762.3 35 677.3 0.667 10.5 4.0 +FRB 284 618.1 35 533.1 0.586 12.9 2.0 +FRB 285 1062.3 35 977.3 0.792 71.5 0.0 +FRB 286 578.1 35 493.1 0.532 17.7 2.0 +FRB 287 679.1 35 594.1 0.338 12.4 2.0 +FRB 288 330.7 35 245.7 0.363 75.1 3.0 +FRB 289 312.7 35 227.7 0.059 13.9 4.0 +FRB 290 165.8 35 80.8 0.022 16.7 1.0 +FRB 291 1139.2 35 1054.2 1.241 18.3 2.0 +FRB 292 320.1 35 235.1 0.290 88.2 2.0 +FRB 293 700.6 35 615.6 0.921 13.4 2.0 +FRB 294 246.4 35 161.4 0.123 23.4 3.0 +FRB 295 283.5 35 198.5 0.085 16.0 0.0 +FRB 296 406.3 35 321.3 0.275 12.0 0.0 +FRB 297 1543.3 35 1458.3 1.742 9.7 3.0 +FRB 298 511.2 35 426.2 0.268 18.6 2.0 +FRB 299 271.5 35 186.5 0.079 9.9 1.0 +FRB 300 449.7 35 364.7 0.622 10.7 1.0 +FRB 301 900.2 35 815.2 0.150 9.9 3.0 +FRB 302 863.7 35 778.7 0.837 37.9 2.0 +FRB 303 275.3 35 190.3 0.104 18.8 3.0 +FRB 304 179.1 35 94.1 0.000 109.1 3.0 +FRB 305 814.0 35 729.0 0.420 11.6 3.0 +FRB 306 201.2 35 116.2 0.010 13.7 1.0 +FRB 307 517.9 35 432.9 0.633 11.2 4.0 +FRB 308 548.6 35 463.6 0.470 11.9 2.0 +FRB 309 385.2 35 300.2 0.227 55.9 2.0 +FRB 310 347.6 35 262.6 0.170 12.2 3.0 +FRB 311 266.5 35 181.5 0.068 15.9 4.0 +FRB 312 359.8 35 274.8 0.362 13.7 2.0 +FRB 313 1062.6 35 977.6 0.864 11.0 2.0 +FRB 314 602.4 35 517.4 0.390 27.8 1.0 +FRB 315 615.3 35 530.3 0.815 13.1 2.0 +FRB 316 930.0 35 845.0 0.490 19.8 4.0 +FRB 317 652.9 35 567.9 0.633 12.2 5.0 +FRB 318 634.4 35 549.4 0.407 20.7 2.0 +FRB 319 747.8 35 662.8 0.086 9.6 4.0 +FRB 320 596.2 35 511.2 0.603 21.3 2.0 +FRB 321 469.1 35 384.1 0.387 52.5 3.0 +FRB 322 1028.2 35 943.2 0.645 11.3 2.0 +FRB 323 430.6 35 345.6 0.345 12.5 0.0 +FRB 324 1121.6 35 1036.6 1.146 11.2 3.0 +FRB 325 403.1 35 318.1 0.284 26.6 3.0 +FRB 326 563.6 35 478.6 0.689 22.1 1.0 +FRB 327 1644.2 35 1559.2 2.063 13.4 3.0 +FRB 328 389.5 35 304.5 0.307 23.9 3.0 +FRB 329 624.6 35 539.6 0.159 62.3 2.0 +FRB 330 490.1 35 405.1 0.532 14.0 2.0 +FRB 331 912.3 35 827.3 0.645 15.9 3.0 +FRB 332 692.6 35 607.6 0.798 27.3 2.0 +FRB 333 179.2 35 94.2 0.103 18.5 3.0 +FRB 334 780.0 35 695.0 0.408 17.7 4.0 +FRB 335 964.2 35 879.2 1.173 11.6 1.0 +FRB 336 203.2 35 118.2 0.092 14.0 3.0 +FRB 337 698.1 35 613.1 0.460 38.8 3.0 +FRB 338 338.5 35 253.5 0.318 15.2 3.0 +FRB 339 520.4 35 435.4 0.439 12.8 2.0 +FRB 340 958.2 35 873.2 0.289 12.3 2.0 +FRB 341 576.5 35 491.5 0.514 24.2 3.0 +FRB 342 418.5 35 333.5 0.370 22.6 3.0 +FRB 343 296.4 35 211.4 0.053 18.3 3.0 +FRB 344 666.2 35 581.2 0.846 12.6 1.0 +FRB 345 315.6 35 230.6 0.285 20.5 3.0 +FRB 346 140.5 35 55.5 0.036 12.0 0.0 +FRB 347 764.2 35 679.2 0.951 9.5 1.0 +FRB 348 841.2 35 756.2 0.603 14.6 0.0 +FRB 349 938.2 35 853.2 0.192 20.4 3.0 +FRB 350 489.1 35 404.1 0.241 13.3 1.0 +FRB 351 655.5 35 570.5 0.442 12.3 2.0 +FRB 352 552.8 35 467.8 0.194 71.4 1.0 +FRB 353 2749.7 35 2664.7 2.304 9.9 0.0 +FRB 354 3004.1 35 2919.1 0.315 14.3 3.0 +FRB 355 668.2 35 583.2 0.132 33.2 3.0 +FRB 356 663.6 35 578.6 0.575 19.0 2.0 +FRB 357 564.6 35 479.6 0.333 86.8 4.0 +FRB 358 485.8 35 400.8 0.378 19.0 1.0 +FRB 359 639.6 35 554.6 0.238 131.0 2.0 +FRB 360 94.2 35 9.2 0.003 23.9 2.0 +FRB 361 1468.8 35 1383.8 0.241 29.3 3.0 +FRB 362 215.7 35 130.7 0.081 20.8 2.0 +FRB 363 969.2 35 884.2 0.571 16.2 2.0 +FRB 364 1324.9 35 1239.9 1.313 12.0 5.0 +FRB 365 426.8 35 341.8 0.429 20.7 4.0 +FRB 366 524.1 35 439.1 0.060 28.2 3.0 +FRB 367 686.1 35 601.1 0.764 24.5 2.0 +FRB 368 1243.9 35 1158.9 1.332 14.0 2.0 +FRB 369 875.0 35 790.0 0.899 23.3 2.0 +FRB 370 1351.9 35 1266.9 1.325 24.4 4.0 +FRB 371 402.8 35 317.8 0.171 40.1 2.0 +FRB 372 884.3 35 799.3 0.408 9.6 3.0 +FRB 373 411.0 35 326.0 0.022 11.8 4.0 +FRB 374 494.9 35 409.9 0.516 9.8 3.0 +FRB 375 645.2 35 560.2 0.607 12.5 2.0 +FRB 376 504.0 35 419.0 0.452 12.2 1.0 +FRB 377 593.8 35 508.8 0.620 12.0 3.0 +FRB 378 491.2 35 406.2 0.141 21.8 3.0 +FRB 379 395.1 35 310.1 0.429 16.3 3.0 +FRB 380 566.1 35 481.1 0.515 10.0 3.0 +FRB 381 181.1 35 96.1 0.065 22.5 2.0 +FRB 382 532.3 35 447.3 0.590 11.1 2.0 +FRB 383 991.9 35 906.9 1.222 15.6 2.0 +FRB 384 1035.4 35 950.4 1.114 27.8 3.0 +FRB 385 715.9 35 630.9 0.090 19.1 4.0 +FRB 386 691.9 35 606.9 0.696 9.9 4.0 +FRB 387 1031.6 35 946.6 1.312 10.3 4.0 +FRB 388 181.0 35 96.0 0.136 26.0 2.0 +FRB 389 362.4 35 277.4 0.287 10.0 2.0 +FRB 390 503.6 35 418.6 0.639 29.2 3.0 +FRB 391 667.5 35 582.5 0.128 13.7 4.0 +FRB 392 765.5 35 680.5 0.742 19.0 3.0 +FRB 393 135.7 35 50.7 0.039 27.9 4.0 +FRB 394 599.2 35 514.2 0.240 24.3 4.0 +FRB 395 1321.2 35 1236.2 0.407 12.3 2.0 +FRB 396 388.5 35 303.5 0.135 10.1 2.0 +FRB 397 269.0 35 184.0 0.123 30.0 4.0 +FRB 398 944.6 35 859.6 0.874 23.0 2.0 +FRB 399 259.8 35 174.8 0.019 29.0 2.0 +FRB 400 916.6 35 831.6 0.997 14.4 3.0 +FRB 401 266.6 35 181.6 0.241 10.5 2.0 +FRB 402 451.4 35 366.4 0.454 17.4 3.0 +FRB 403 724.2 35 639.2 0.793 32.0 2.0 +FRB 404 187.5 35 102.5 0.046 16.4 3.0 +FRB 405 485.5 35 400.5 0.162 20.3 4.0 +FRB 406 236.1 35 151.1 0.142 18.3 3.0 +FRB 407 730.6 35 645.6 0.720 41.2 3.0 +FRB 408 272.6 35 187.6 0.141 39.8 3.0 +FRB 409 524.5 35 439.5 0.623 11.7 0.0 +FRB 410 489.3 35 404.3 0.446 15.3 1.0 +FRB 411 448.1 35 363.1 0.467 12.7 2.0 +FRB 412 1045.2 35 960.2 1.060 27.5 4.0 +FRB 413 958.7 35 873.7 1.035 23.9 3.0 +FRB 414 233.6 35 148.6 0.075 9.6 3.0 +FRB 415 659.9 35 574.9 0.318 10.5 2.0 +FRB 416 635.2 35 550.2 0.418 22.9 3.0 +FRB 417 2488.2 35 2403.2 2.001 22.0 3.0 +FRB 418 416.8 35 331.8 0.462 9.6 4.0 +FRB 419 460.9 35 375.9 0.164 76.9 2.0 +FRB 420 559.6 35 474.6 0.720 14.7 4.0 +FRB 421 878.5 35 793.5 0.631 12.7 3.0 +FRB 422 836.2 35 751.2 0.306 10.6 1.0 +FRB 423 717.2 35 632.2 0.901 10.3 2.0 +FRB 424 203.8 35 118.8 0.008 50.4 4.0 +FRB 425 332.5 35 247.5 0.255 10.0 2.0 +FRB 426 513.5 35 428.5 0.412 11.9 3.0 +FRB 427 890.1 35 805.1 1.106 17.0 2.0 +FRB 428 1119.1 35 1034.1 1.247 11.6 1.0 +FRB 429 692.3 35 607.3 0.665 17.5 3.0 +FRB 430 794.0 35 709.0 0.265 56.4 4.0 +FRB 431 692.8 35 607.8 0.926 11.1 3.0 +FRB 432 529.2 35 444.2 0.226 111.0 2.0 +FRB 433 476.0 35 391.0 0.458 12.5 4.0 +FRB 434 439.2 35 354.2 0.270 10.9 1.0 +FRB 435 842.2 35 757.2 0.772 19.2 1.0 +FRB 436 644.8 35 559.8 0.709 26.2 1.0 +FRB 437 389.8 35 304.8 0.112 13.5 1.0 +FRB 438 363.0 35 278.0 0.166 62.7 0.0 +FRB 439 1050.3 35 965.3 0.544 26.1 2.0 +FRB 440 182.9 35 97.9 0.002 19.0 1.0 +FRB 441 686.3 35 601.3 0.151 13.3 2.0 +FRB 442 335.0 35 250.0 0.104 13.5 4.0 +FRB 443 613.8 35 528.8 0.791 14.1 3.0 +FRB 444 317.5 35 232.5 0.274 11.4 2.0 +FRB 445 427.7 35 342.7 0.551 25.2 4.0 +FRB 446 155.8 35 70.8 0.075 20.2 4.0 +FRB 447 988.1 35 903.1 1.024 13.3 3.0 +FRB 448 256.9 35 171.9 0.065 11.8 3.0 +FRB 449 412.3 35 327.3 0.343 48.7 2.0 +FRB 450 595.9 35 510.9 0.255 69.4 4.0 +FRB 451 210.9 35 125.9 0.012 113.3 3.0 +FRB 452 463.7 35 378.7 0.245 14.9 2.0 +FRB 453 831.0 35 746.0 0.714 9.8 3.0 +FRB 454 3302.9 35 3217.9 1.408 10.4 4.0 +FRB 455 924.3 35 839.3 0.244 16.5 3.0 +FRB 456 625.2 35 540.2 0.519 15.8 3.0 +FRB 457 836.0 35 751.0 0.497 28.4 2.0 +FRB 458 1100.8 35 1015.8 1.079 12.2 2.0 +FRB 459 380.1 35 295.1 0.149 16.6 3.0 +FRB 460 615.4 35 530.4 0.215 15.5 2.0 +FRB 461 786.4 35 701.4 0.364 77.7 2.0 +FRB 462 460.6 35 375.6 0.153 12.4 2.0 +FRB 463 734.3 35 649.3 0.393 14.9 2.0 +FRB 464 1370.5 35 1285.5 0.292 16.2 2.0 +FRB 465 463.3 35 378.3 0.344 13.3 4.0 +FRB 466 250.4 35 165.4 0.001 11.0 2.0 +FRB 467 478.9 35 393.9 0.471 10.8 4.0 +FRB 468 164.9 35 79.9 0.020 48.7 1.0 +FRB 469 331.3 35 246.3 0.336 36.3 3.0 +FRB 470 940.2 35 855.2 0.651 18.3 4.0 +FRB 471 740.2 35 655.2 0.844 9.7 2.0 +FRB 472 677.1 35 592.1 0.575 12.0 2.0 +FRB 473 910.6 35 825.6 0.963 10.3 2.0 +FRB 474 552.9 35 467.9 0.287 13.9 2.0 +FRB 475 342.1 35 257.1 0.315 201.4 1.0 +FRB 476 323.7 35 238.7 0.180 31.2 2.0 +FRB 477 553.2 35 468.2 0.354 29.9 1.0 +FRB 478 541.8 35 456.8 0.428 10.2 3.0 +FRB 479 330.2 35 245.2 0.326 46.8 2.0 +FRB 480 518.4 35 433.4 0.364 18.8 4.0 +FRB 481 381.3 35 296.3 0.297 36.2 4.0 +FRB 482 1405.2 35 1320.2 1.059 15.4 2.0 +FRB 483 282.5 35 197.5 0.209 14.5 3.0 +FRB 484 610.2 35 525.2 0.515 35.2 3.0 +FRB 485 270.6 35 185.6 0.323 14.5 3.0 +FRB 486 375.0 35 290.0 0.249 30.8 2.0 +FRB 487 982.7 35 897.7 0.836 10.0 2.0 +FRB 488 248.4 35 163.4 0.076 11.2 1.0 +FRB 489 2137.1 35 2052.1 0.049 15.4 5.0 +FRB 490 423.0 35 338.0 0.311 11.5 3.0 +FRB 491 494.6 35 409.6 0.116 12.8 3.0 +FRB 492 211.5 35 126.5 0.145 12.8 2.0 +FRB 493 871.3 35 786.3 0.917 25.3 5.0 +FRB 494 864.6 35 779.6 0.557 10.3 3.0 +FRB 495 960.7 35 875.7 0.209 9.9 2.0 +FRB 496 377.2 35 292.2 0.223 136.5 2.0 +FRB 497 420.1 35 335.1 0.275 14.1 2.0 +FRB 498 212.0 35 127.0 0.022 11.5 4.0 +FRB 499 301.6 35 216.6 0.172 9.6 0.0 +FRB 500 892.1 35 807.1 1.031 17.3 3.0 +FRB 501 491.5 35 406.5 0.193 10.1 2.0 +FRB 502 391.7 35 306.7 0.071 23.1 2.0 +FRB 503 435.7 35 350.7 0.336 11.9 2.0 +FRB 504 232.4 35 147.4 0.003 9.7 4.0 +FRB 505 148.3 35 63.3 0.051 410.7 3.0 +FRB 506 604.8 35 519.8 0.845 10.9 1.0 +FRB 507 367.8 35 282.8 0.316 15.0 3.0 +FRB 508 491.2 35 406.2 0.590 24.1 0.0 +FRB 509 1014.1 35 929.1 0.332 16.1 4.0 +FRB 510 1117.8 35 1032.8 0.924 11.4 3.0 +FRB 511 472.8 35 387.8 0.554 16.1 4.0 +FRB 512 642.9 35 557.9 0.430 11.8 2.0 +FRB 513 208.0 35 123.0 0.152 17.9 2.0 +FRB 514 783.0 35 698.0 0.930 12.7 3.0 +FRB 515 869.7 35 784.7 0.328 23.6 2.0 +FRB 516 274.3 35 189.3 0.250 13.0 4.0 +FRB 517 458.5 35 373.5 0.546 12.5 4.0 +FRB 518 1750.0 35 1665.0 0.991 10.2 1.0 +FRB 519 1113.0 35 1028.0 1.267 14.2 2.0 +FRB 520 257.2 35 172.2 0.002 13.4 2.0 +FRB 521 1075.0 35 990.0 0.055 10.8 3.0 +FRB 522 313.5 35 228.5 0.077 13.5 4.0 +FRB 523 527.0 35 442.0 0.442 10.9 3.0 +FRB 524 549.7 35 464.7 0.250 11.6 1.0 +FRB 525 990.7 35 905.7 0.987 60.2 2.0 +FRB 526 446.0 35 361.0 0.548 32.2 1.0 +FRB 527 398.9 35 313.9 0.420 11.3 3.0 +FRB 528 257.7 35 172.7 0.206 42.6 1.0 +FRB 529 413.9 35 328.9 0.428 88.2 2.0 +FRB 530 455.6 35 370.6 0.043 15.1 4.0 +FRB 531 346.0 35 261.0 0.136 268.1 3.0 +FRB 532 587.8 35 502.8 0.440 45.8 2.0 +FRB 533 343.5 35 258.5 0.357 56.1 3.0 +FRB 534 1243.0 35 1158.0 1.553 13.7 1.0 +FRB 535 483.7 35 398.7 0.426 9.9 3.0 +FRB 536 471.1 35 386.1 0.429 17.0 3.0 +FRB 537 269.3 35 184.3 0.267 20.6 1.0 +FRB 538 242.4 35 157.4 0.066 12.8 3.0 +FRB 539 1627.4 35 1542.4 1.156 13.3 2.0 +FRB 540 562.4 35 477.4 0.595 24.3 2.0 +FRB 541 125.9 35 40.9 0.025 11.6 1.0 +FRB 542 1062.3 35 977.3 1.306 31.0 3.0 +FRB 543 366.7 35 281.7 0.433 13.0 2.0 +FRB 544 814.9 35 729.9 0.752 13.7 3.0 +FRB 545 124.3 35 39.3 0.046 14.8 4.0 +FRB 546 431.5 35 346.5 0.041 12.5 2.0 +FRB 547 312.5 35 227.5 0.170 18.6 1.0 +FRB 548 720.7 35 635.7 0.329 26.7 2.0 +FRB 549 537.4 35 452.4 0.321 23.5 2.0 +FRB 550 437.0 35 352.0 0.403 11.9 3.0 +FRB 551 443.4 35 358.4 0.390 28.3 2.0 +FRB 552 585.0 35 500.0 0.368 19.9 1.0 +FRB 553 811.8 35 726.8 0.789 16.2 3.0 +FRB 554 608.4 35 523.4 0.389 21.8 2.0 +FRB 555 281.2 35 196.2 0.099 17.0 3.0 +FRB 556 594.1 35 509.1 0.145 13.5 4.0 +FRB 557 329.8 35 244.8 0.282 33.1 3.0 +FRB 558 593.5 35 508.5 0.700 61.8 1.0 +FRB 559 1161.1 35 1076.1 0.899 12.8 2.0 +FRB 560 290.6 35 205.6 0.026 29.3 2.0 +FRB 561 416.8 35 331.8 0.419 25.7 3.0 +FRB 562 1513.6 35 1428.6 0.275 16.6 3.0 +FRB 563 408.6 35 323.6 0.386 41.7 2.0 +FRB 564 1315.3 35 1230.3 1.159 36.9 3.0 +FRB 565 446.2 35 361.2 0.158 13.4 1.0 +FRB 566 298.4 35 213.4 0.207 9.7 2.0 +FRB 567 721.1 35 636.1 0.351 67.3 2.0 +FRB 568 184.3 35 99.3 0.036 171.1 2.0 +FRB 569 129.6 35 44.6 0.097 10.8 1.0 +FRB 570 624.8 35 539.8 0.150 132.1 2.0 +FRB 571 1829.0 35 1744.0 1.818 22.9 3.0 +FRB 572 438.5 35 353.5 0.205 183.6 3.0 +FRB 573 1390.3 35 1305.3 1.050 16.4 1.0 +FRB 574 829.0 35 744.0 0.253 20.2 4.0 +FRB 575 771.9 35 686.9 0.675 11.6 1.0 +FRB 576 575.5 35 490.5 0.693 40.1 3.0 +FRB 577 282.4 35 197.4 0.140 17.0 2.0 +FRB 578 166.3 35 81.3 0.180 11.0 3.0 +FRB 579 390.1 35 305.1 0.124 9.7 1.0 +FRB 580 518.5 35 433.5 0.476 67.6 2.0 +FRB 581 485.0 35 400.0 0.047 14.9 5.0 +FRB 582 1440.3 35 1355.3 1.788 18.3 2.0 +FRB 583 648.5 35 563.5 0.519 21.9 2.0 +FRB 584 732.4 35 647.4 0.514 14.0 3.0 +FRB 585 498.6 35 413.6 0.257 15.4 2.0 +FRB 586 1418.2 35 1333.2 0.020 11.6 4.0 +FRB 587 510.3 35 425.3 0.508 12.5 1.0 +FRB 588 641.0 35 556.0 0.536 58.8 4.0 +FRB 589 176.0 35 91.0 0.032 9.8 3.0 +FRB 590 515.8 35 430.8 0.441 13.9 1.0 +FRB 591 131.3 35 46.3 0.040 151.3 1.0 +FRB 592 437.2 35 352.2 0.449 62.6 2.0 +FRB 593 175.1 35 90.1 0.151 289.1 2.0 +FRB 594 702.0 35 617.0 0.526 12.5 3.0 +FRB 595 1701.6 35 1616.6 1.675 12.3 2.0 +FRB 596 459.8 35 374.8 0.572 13.7 2.0 +FRB 597 2375.3 35 2290.3 2.793 9.7 3.0 +FRB 598 445.5 35 360.5 0.209 17.7 2.0 +FRB 599 199.4 35 114.4 0.122 20.1 2.0 +FRB 600 1155.0 35 1070.0 0.493 16.3 2.0 +FRB 601 292.6 35 207.6 0.101 27.7 3.0 +FRB 602 410.7 35 325.7 0.242 10.8 2.0 +FRB 603 192.1 35 107.1 0.126 18.4 4.0 +FRB 604 373.7 35 288.7 0.031 9.9 3.0 +FRB 605 722.7 35 637.7 0.574 13.5 5.0 +FRB 606 915.4 35 830.4 0.870 12.4 3.0 +FRB 607 343.0 35 258.0 0.287 13.8 3.0 +FRB 608 127.5 35 42.5 0.055 15.8 2.0 +FRB 609 771.3 35 686.3 0.987 23.1 3.0 +FRB 610 506.2 35 421.2 0.501 18.4 3.0 +FRB 611 607.9 35 522.9 0.242 27.8 2.0 +FRB 612 975.2 35 890.2 0.981 34.8 1.0 +FRB 613 592.0 35 507.0 0.018 10.5 2.0 +FRB 614 653.4 35 568.4 0.476 25.1 2.0 +FRB 615 843.6 35 758.6 1.086 10.4 3.0 +FRB 616 348.3 35 263.3 0.181 10.1 3.0 +FRB 617 185.9 35 100.9 0.118 24.8 3.0 +FRB 618 1906.7 35 1821.7 1.795 13.0 2.0 +FRB 619 237.6 35 152.6 0.184 27.8 1.0 +FRB 620 267.9 35 182.9 0.116 58.0 3.0 +FRB 621 406.6 35 321.6 0.415 15.0 3.0 +FRB 622 430.5 35 345.5 0.455 12.6 3.0 +FRB 623 1150.5 35 1065.5 0.369 16.7 3.0 +FRB 624 383.2 35 298.2 0.175 15.8 3.0 +FRB 625 671.0 35 586.0 0.894 20.1 3.0 +FRB 626 372.8 35 287.8 0.102 14.0 2.0 +FRB 627 888.9 35 803.9 0.032 12.9 3.0 +FRB 628 1052.2 35 967.2 1.371 26.5 2.0 +FRB 629 1023.3 35 938.3 1.418 21.5 1.0 +FRB 630 281.3 35 196.3 0.041 25.2 4.0 +FRB 631 238.1 35 153.1 0.251 12.6 2.0 +FRB 632 552.2 35 467.2 0.562 11.6 3.0 +FRB 633 558.2 35 473.2 0.484 9.8 3.0 +FRB 634 337.6 35 252.6 0.080 22.0 1.0 +FRB 635 295.2 35 210.2 0.209 11.4 3.0 +FRB 636 575.8 35 490.8 0.189 10.4 2.0 +FRB 637 375.9 35 290.9 0.064 14.7 1.0 +FRB 638 129.2 35 44.2 0.073 24.3 2.0 +FRB 639 198.3 35 113.3 0.058 10.5 0.0 +FRB 640 445.5 35 360.5 0.330 87.9 1.0 +FRB 641 215.9 35 130.9 0.114 35.2 1.0 +FRB 642 212.4 35 127.4 0.084 16.9 3.0 +FRB 643 1228.4 35 1143.4 1.305 13.0 3.0 +FRB 644 578.5 35 493.5 0.149 11.5 1.0 +FRB 645 706.3 35 621.3 0.794 39.2 1.0 +FRB 646 597.8 35 512.8 0.536 38.6 3.0 +FRB 647 283.6 35 198.6 0.195 14.3 2.0 +FRB 648 2236.7 35 2151.7 1.327 20.4 2.0 +FRB 649 694.4 35 609.4 0.099 15.4 4.0 +FRB 650 213.5 35 128.5 0.136 11.9 3.0 +FRB 651 961.6 35 876.6 0.475 28.1 2.0 +FRB 652 801.4 35 716.4 0.818 12.3 2.0 +FRB 653 396.1 35 311.1 0.233 22.6 4.0 +FRB 654 1093.6 35 1008.6 0.806 10.9 3.0 +FRB 655 493.6 35 408.6 0.322 9.9 1.0 +FRB 656 518.1 35 433.1 0.520 14.7 3.0 +FRB 657 478.0 35 393.0 0.094 16.7 4.0 +FRB 658 242.1 35 157.1 0.098 139.7 3.0 +FRB 659 261.7 35 176.7 0.142 43.3 3.0 +FRB 660 443.3 35 358.3 0.042 11.6 2.0 +FRB 661 1386.8 35 1301.8 0.544 26.7 3.0 +FRB 662 475.0 35 390.0 0.228 22.0 1.0 +FRB 663 545.5 35 460.5 0.709 9.7 3.0 +FRB 664 220.1 35 135.1 0.093 21.6 2.0 +FRB 665 809.9 35 724.9 0.829 12.2 2.0 +FRB 666 358.1 35 273.1 0.122 14.5 1.0 +FRB 667 842.0 35 757.0 0.323 12.4 3.0 +FRB 668 1395.1 35 1310.1 0.441 11.5 4.0 +FRB 669 732.5 35 647.5 0.612 42.3 3.0 +FRB 670 423.2 35 338.2 0.322 15.5 2.0 +FRB 671 1328.1 35 1243.1 0.927 10.8 1.0 +FRB 672 530.2 35 445.2 0.490 13.2 2.0 +FRB 673 1584.2 35 1499.2 1.705 15.0 3.0 +FRB 674 147.1 35 62.1 0.047 15.8 2.0 +FRB 675 726.1 35 641.1 0.903 16.9 3.0 +FRB 676 346.6 35 261.6 0.028 10.1 4.0 +FRB 677 1399.0 35 1314.0 1.447 15.0 3.0 +FRB 678 884.5 35 799.5 1.112 9.8 3.0 +FRB 679 1032.9 35 947.9 1.183 23.1 2.0 +FRB 680 182.6 35 97.6 0.056 12.3 1.0 +FRB 681 1051.2 35 966.2 1.131 10.4 2.0 +FRB 682 1485.1 35 1400.1 1.608 13.5 3.0 +FRB 683 299.7 35 214.7 0.150 17.1 5.0 +FRB 684 395.2 35 310.2 0.229 13.2 3.0 +FRB 685 517.8 35 432.8 0.276 23.0 1.0 +FRB 686 356.1 35 271.1 0.325 18.7 3.0 +FRB 687 368.5 35 283.5 0.250 54.5 1.0 +FRB 688 277.4 35 192.4 0.303 18.4 2.0 +FRB 689 644.6 35 559.6 0.764 10.1 2.0 +FRB 690 1221.8 35 1136.8 0.005 10.1 4.0 +FRB 691 422.4 35 337.4 0.321 14.3 3.0 +FRB 692 374.0 35 289.0 0.400 53.2 1.0 +FRB 693 422.3 35 337.3 0.245 42.6 3.0 +FRB 694 283.2 35 198.2 0.327 15.3 2.0 +FRB 695 1116.8 35 1031.8 0.638 39.6 4.0 +FRB 696 408.3 35 323.3 0.353 10.9 2.0 +FRB 697 296.8 35 211.8 0.026 30.9 4.0 +FRB 698 294.1 35 209.1 0.119 22.3 2.0 +FRB 699 385.7 35 300.7 0.272 68.5 2.0 +FRB 700 351.1 35 266.1 0.216 15.3 1.0 +FRB 701 189.6 35 104.6 0.042 13.8 2.0 +FRB 702 180.7 35 95.7 0.136 11.0 2.0 +FRB 703 653.5 35 568.5 0.285 11.2 4.0 +FRB 704 779.7 35 694.7 1.103 11.9 2.0 +FRB 705 217.9 35 132.9 0.018 15.9 1.0 +FRB 706 185.0 35 100.0 0.092 34.9 2.0 +FRB 707 439.6 35 354.6 0.427 41.0 3.0 +FRB 708 623.7 35 538.7 0.238 9.7 3.0 +FRB 709 450.0 35 365.0 0.267 11.7 3.0 +FRB 710 893.3 35 808.3 1.138 10.0 3.0 +FRB 711 414.6 35 329.6 0.323 37.3 3.0 +FRB 712 851.4 35 766.4 0.832 12.6 3.0 +FRB 713 214.4 35 129.4 0.069 12.4 2.0 +FRB 714 611.7 35 526.7 0.485 10.6 2.0 +FRB 715 301.7 35 216.7 0.112 21.8 2.0 +FRB 716 761.3 35 676.3 0.537 11.8 1.0 +FRB 717 309.8 35 224.8 0.138 14.8 2.0 +FRB 718 697.6 35 612.6 0.334 35.4 1.0 +FRB 719 185.1 35 100.1 0.131 11.1 3.0 +FRB 720 1456.7 35 1371.7 1.606 11.3 1.0 +FRB 721 138.2 35 53.2 0.032 9.5 1.0 +FRB 722 163.7 35 78.7 0.034 50.7 1.0 +FRB 723 308.7 35 223.7 0.345 29.4 2.0 +FRB 724 582.7 35 497.7 0.376 9.5 3.0 +FRB 725 771.6 35 686.6 0.037 16.4 1.0 +FRB 726 483.9 35 398.9 0.387 21.6 3.0 +FRB 727 951.5 35 866.5 0.402 11.3 4.0 +FRB 728 225.3 35 140.3 0.049 12.7 1.0 +FRB 729 561.8 35 476.8 0.320 10.1 3.0 +FRB 730 603.7 35 518.7 0.743 10.6 2.0 +FRB 731 1044.5 35 959.5 0.675 15.8 3.0 +FRB 732 409.1 35 324.1 0.256 13.4 2.0 +FRB 733 341.3 35 256.3 0.098 9.9 3.0 +FRB 734 1638.5 35 1553.5 0.205 88.3 2.0 +FRB 735 443.9 35 358.9 0.132 49.0 4.0 +FRB 736 490.6 35 405.6 0.501 18.0 2.0 +FRB 737 420.7 35 335.7 0.119 18.0 3.0 +FRB 738 686.3 35 601.3 0.417 15.7 3.0 +FRB 739 767.1 35 682.1 0.480 10.6 1.0 +FRB 740 475.7 35 390.7 0.527 9.8 3.0 +FRB 741 1537.6 35 1452.6 0.862 11.3 3.0 +FRB 742 195.3 35 110.3 0.168 9.9 2.0 +FRB 743 619.2 35 534.2 0.673 39.1 3.0 +FRB 744 162.7 35 77.7 0.040 62.5 3.0 +FRB 745 1006.0 35 921.0 0.137 16.0 4.0 +FRB 746 358.5 35 273.5 0.096 112.9 2.0 +FRB 747 560.2 35 475.2 0.201 10.7 4.0 +FRB 748 690.6 35 605.6 0.668 25.1 4.0 +FRB 749 654.1 35 569.1 0.565 9.9 2.0 +FRB 750 692.5 35 607.5 0.083 16.8 1.0 +FRB 751 396.5 35 311.5 0.229 29.3 4.0 +FRB 752 223.3 35 138.3 0.120 78.2 2.0 +FRB 753 483.5 35 398.5 0.427 10.1 3.0 +FRB 754 937.4 35 852.4 1.326 29.9 2.0 +FRB 755 188.5 35 103.5 0.138 18.9 2.0 +FRB 756 529.8 35 444.8 0.512 12.6 1.0 +FRB 757 196.3 35 111.3 0.177 12.2 3.0 +FRB 758 489.6 35 404.6 0.501 159.3 1.0 +FRB 759 527.5 35 442.5 0.202 25.6 4.0 +FRB 760 544.7 35 459.7 0.613 22.5 3.0 +FRB 761 306.1 35 221.1 0.292 13.8 1.0 +FRB 762 650.9 35 565.9 0.731 50.7 3.0 +FRB 763 478.2 35 393.2 0.052 10.7 5.0 +FRB 764 190.9 35 105.9 0.113 9.8 4.0 +FRB 765 1307.3 35 1222.3 1.913 20.9 2.0 +FRB 766 1313.0 35 1228.0 0.787 23.7 3.0 +FRB 767 408.8 35 323.8 0.145 78.2 5.0 +FRB 768 831.6 35 746.6 0.165 9.9 3.0 +FRB 769 664.2 35 579.2 0.595 11.4 1.0 +FRB 770 259.1 35 174.1 0.093 120.2 4.0 +FRB 771 310.4 35 225.4 0.199 9.7 4.0 +FRB 772 962.8 35 877.8 0.919 11.5 4.0 +FRB 773 830.4 35 745.4 1.007 9.9 3.0 +FRB 774 855.0 35 770.0 0.619 27.6 4.0 +FRB 775 324.6 35 239.6 0.248 127.6 3.0 +FRB 776 596.0 35 511.0 0.500 20.0 3.0 +FRB 777 533.7 35 448.7 0.304 18.4 2.0 +FRB 778 1653.2 35 1568.2 0.729 10.7 1.0 +FRB 779 662.3 35 577.3 0.807 11.8 3.0 +FRB 780 410.8 35 325.8 0.014 72.7 3.0 +FRB 781 856.2 35 771.2 0.959 18.5 2.0 +FRB 782 364.5 35 279.5 0.222 34.6 1.0 +FRB 783 486.6 35 401.6 0.508 10.2 3.0 +FRB 784 362.0 35 277.0 0.193 27.8 3.0 +FRB 785 1218.0 35 1133.0 1.560 19.0 2.0 +FRB 786 1109.0 35 1024.0 1.042 24.5 4.0 +FRB 787 1330.3 35 1245.3 1.535 11.2 2.0 +FRB 788 834.8 35 749.8 0.782 13.6 4.0 +FRB 789 181.3 35 96.3 0.073 34.9 4.0 +FRB 790 538.9 35 453.9 0.439 24.6 2.0 +FRB 791 492.1 35 407.1 0.527 14.2 2.0 +FRB 792 176.4 35 91.4 0.106 16.5 4.0 +FRB 793 427.2 35 342.2 0.020 13.3 3.0 +FRB 794 307.4 35 222.4 0.060 31.0 2.0 +FRB 795 210.7 35 125.7 0.015 12.4 2.0 +FRB 796 1031.6 35 946.6 0.079 12.8 3.0 +FRB 797 1439.8 35 1354.8 0.276 390.0 2.0 +FRB 798 205.5 35 120.5 0.044 424.9 2.0 +FRB 799 335.2 35 250.2 0.224 81.3 3.0 +FRB 800 737.1 35 652.1 0.738 11.7 1.0 +FRB 801 657.5 35 572.5 0.689 10.5 4.0 +FRB 802 325.0 35 240.0 0.197 17.6 1.0 +FRB 803 360.9 35 275.9 0.406 18.9 3.0 +FRB 804 1518.7 35 1433.7 0.719 10.4 2.0 +FRB 805 650.4 35 565.4 0.628 11.0 3.0 +FRB 806 310.7 35 225.7 0.286 12.4 3.0 +FRB 807 318.1 35 233.1 0.159 43.1 2.0 +FRB 808 422.6 35 337.6 0.476 11.2 2.0 +FRB 809 243.3 35 158.3 0.160 13.8 4.0 +FRB 810 1414.7 35 1329.7 0.566 21.0 3.0 +FRB 811 672.1 35 587.1 0.831 12.7 3.0 +FRB 812 743.0 35 658.0 0.912 19.6 2.0 +FRB 813 906.6 35 821.6 0.057 10.3 3.0 +FRB 814 539.5 35 454.5 0.549 68.4 2.0 +FRB 815 497.4 35 412.4 0.248 66.2 4.0 +FRB 816 861.2 35 776.2 0.986 10.9 2.0 +FRB 817 184.9 35 99.9 0.001 12.0 3.0 +FRB 818 1703.6 35 1618.6 0.953 15.6 2.0 +FRB 819 1362.6 35 1277.6 0.661 11.1 3.0 +FRB 820 434.7 35 349.7 0.075 12.2 1.0 +FRB 821 1323.7 35 1238.7 1.049 13.9 4.0 +FRB 822 171.3 35 86.3 0.130 9.5 3.0 +FRB 823 329.5 35 244.5 0.369 9.7 2.0 +FRB 824 563.8 35 478.8 0.498 57.3 0.0 +FRB 825 513.6 35 428.6 0.049 10.2 2.0 +FRB 826 833.9 35 748.9 1.049 16.9 2.0 +FRB 827 734.8 35 649.8 0.743 10.5 2.0 +FRB 828 214.4 35 129.4 0.196 12.2 5.0 +FRB 829 639.2 35 554.2 0.320 12.6 3.0 +FRB 830 393.9 35 308.9 0.321 36.9 2.0 +FRB 831 554.7 35 469.7 0.716 18.4 3.0 +FRB 832 475.1 35 390.1 0.149 18.5 1.0 +FRB 833 441.1 35 356.1 0.391 19.2 2.0 +FRB 834 239.7 35 154.7 0.038 63.9 2.0 +FRB 835 733.9 35 648.9 0.785 18.4 1.0 +FRB 836 706.7 35 621.7 0.781 17.0 1.0 +FRB 837 388.2 35 303.2 0.385 30.8 3.0 +FRB 838 1225.9 35 1140.9 0.971 16.8 1.0 +FRB 839 391.6 35 306.6 0.369 23.3 3.0 +FRB 840 611.5 35 526.5 0.205 16.4 2.0 +FRB 841 1052.3 35 967.3 0.026 14.7 3.0 +FRB 842 503.5 35 418.5 0.376 13.0 4.0 +FRB 843 809.9 35 724.9 0.826 15.8 2.0 +FRB 844 236.2 35 151.2 0.157 74.9 2.0 +FRB 845 223.2 35 138.2 0.079 24.2 3.0 +FRB 846 343.7 35 258.7 0.178 23.3 2.0 +FRB 847 367.6 35 282.6 0.234 24.0 0.0 +FRB 848 1253.0 35 1168.0 0.789 10.5 3.0 +FRB 849 194.5 35 109.5 0.161 10.8 2.0 +FRB 850 477.9 35 392.9 0.519 14.0 3.0 +FRB 851 362.2 35 277.2 0.048 20.1 3.0 +FRB 852 530.0 35 445.0 0.275 16.5 0.0 +FRB 853 268.6 35 183.6 0.001 13.2 1.0 +FRB 854 899.1 35 814.1 0.322 20.0 1.0 +FRB 855 727.1 35 642.1 0.513 11.9 3.0 +FRB 856 352.4 35 267.4 0.014 36.7 1.0 +FRB 857 395.1 35 310.1 0.167 15.9 3.0 +FRB 858 848.2 35 763.2 0.870 32.7 3.0 +FRB 859 847.8 35 762.8 0.909 15.4 3.0 +FRB 860 526.7 35 441.7 0.546 33.0 3.0 +FRB 861 448.5 35 363.5 0.177 11.8 3.0 +FRB 862 345.2 35 260.2 0.249 12.3 1.0 +FRB 863 799.2 35 714.2 0.143 14.5 1.0 +FRB 864 1080.7 35 995.7 0.122 12.2 5.0 +FRB 865 892.1 35 807.1 0.914 34.4 3.0 +FRB 866 1352.0 35 1267.0 0.982 15.1 2.0 +FRB 867 674.1 35 589.1 0.356 184.9 3.0 +FRB 868 725.3 35 640.3 0.706 59.8 1.0 +FRB 869 325.9 35 240.9 0.300 12.6 3.0 +FRB 870 1809.5 35 1724.5 0.151 13.7 2.0 +FRB 871 408.5 35 323.5 0.342 69.6 4.0 +FRB 872 533.4 35 448.4 0.302 11.3 2.0 +FRB 873 1394.9 35 1309.9 0.888 10.6 2.0 +FRB 874 466.9 35 381.9 0.007 39.7 2.0 +FRB 875 152.1 35 67.1 0.018 43.9 1.0 +FRB 876 434.7 35 349.7 0.232 15.3 3.0 +FRB 877 676.8 35 591.8 0.553 17.4 1.0 +FRB 878 455.1 35 370.1 0.127 13.0 0.0 +FRB 879 485.5 35 400.5 0.142 30.9 1.0 +FRB 880 1341.2 35 1256.2 0.165 82.8 0.0 +FRB 881 292.7 35 207.7 0.248 124.8 2.0 +FRB 882 256.1 35 171.1 0.198 11.5 1.0 +FRB 883 234.8 35 149.8 0.220 11.3 3.0 +FRB 884 395.9 35 310.9 0.173 9.5 2.0 +FRB 885 384.6 35 299.6 0.230 449.6 2.0 +FRB 886 1467.8 35 1382.8 0.810 14.9 4.0 +FRB 887 167.8 35 82.8 0.062 22.8 2.0 +FRB 888 287.6 35 202.6 0.266 25.0 3.0 +FRB 889 116.9 35 31.9 0.033 89.5 1.0 +FRB 890 211.2 35 126.2 0.103 29.9 3.0 +FRB 891 807.2 35 722.2 0.785 10.5 2.0 +FRB 892 438.7 35 353.7 0.478 14.2 4.0 +FRB 893 175.2 35 90.2 0.023 17.4 1.0 +FRB 894 350.0 35 265.0 0.313 12.3 3.0 +FRB 895 1865.2 35 1780.2 1.939 10.4 2.0 +FRB 896 560.0 35 475.0 0.468 18.4 2.0 +FRB 897 198.2 35 113.2 0.039 233.6 2.0 +FRB 898 585.4 35 500.4 0.667 11.1 2.0 +FRB 899 347.7 35 262.7 0.258 13.7 2.0 +FRB 900 756.3 35 671.3 0.889 10.6 1.0 +FRB 901 210.4 35 125.4 0.010 11.4 0.0 +FRB 902 656.0 35 571.0 0.508 10.1 4.0 +FRB 903 1539.0 35 1454.0 2.030 15.9 2.0 +FRB 904 137.6 35 52.6 0.016 14.6 2.0 +FRB 905 480.9 35 395.9 0.081 45.1 2.0 +FRB 906 506.7 35 421.7 0.425 42.2 2.0 +FRB 907 479.0 35 394.0 0.264 13.5 4.0 +FRB 908 910.5 35 825.5 1.062 12.0 1.0 +FRB 909 764.0 35 679.0 1.017 25.4 1.0 +FRB 910 358.5 35 273.5 0.041 43.9 4.0 +FRB 911 100.5 35 15.5 0.007 92.1 3.0 +FRB 912 403.5 35 318.5 0.327 13.4 2.0 +FRB 913 349.2 35 264.2 0.161 32.6 4.0 +FRB 914 1399.6 35 1314.6 0.970 9.7 0.0 +FRB 915 130.8 35 45.8 0.049 27.4 2.0 +FRB 916 184.5 35 99.5 0.092 10.6 4.0 +FRB 917 553.7 35 468.7 0.241 10.1 3.0 +FRB 918 465.2 35 380.2 0.547 25.5 2.0 +FRB 919 627.3 35 542.3 0.410 31.8 2.0 +FRB 920 629.9 35 544.9 0.010 77.8 4.0 +FRB 921 779.1 35 694.1 0.449 60.8 2.0 +FRB 922 511.7 35 426.7 0.154 12.0 2.0 +FRB 923 224.6 35 139.6 0.012 51.8 3.0 +FRB 924 389.8 35 304.8 0.122 42.0 3.0 +FRB 925 661.0 35 576.0 0.818 15.7 2.0 +FRB 926 993.1 35 908.1 0.237 11.5 3.0 +FRB 927 1479.7 35 1394.7 1.498 9.7 3.0 +FRB 928 476.2 35 391.2 0.517 22.0 3.0 +FRB 929 414.2 35 329.2 0.170 37.4 3.0 +FRB 930 319.1 35 234.1 0.201 15.1 2.0 +FRB 931 1336.7 35 1251.7 1.526 10.8 3.0 +FRB 932 1027.7 35 942.7 1.055 13.1 3.0 +FRB 933 545.3 35 460.3 0.388 26.9 3.0 +FRB 934 369.4 35 284.4 0.010 10.7 1.0 +FRB 935 168.6 35 83.6 0.003 29.4 2.0 +FRB 936 1013.5 35 928.5 1.012 13.2 2.0 +FRB 937 254.8 35 169.8 0.184 14.9 3.0 +FRB 938 1715.0 35 1630.0 2.012 12.1 2.0 +FRB 939 2046.3 35 1961.3 1.186 13.0 0.0 +FRB 940 194.4 35 109.4 0.031 35.6 2.0 +FRB 941 235.0 35 150.0 0.218 149.4 3.0 +FRB 942 636.0 35 551.0 0.467 12.9 3.0 +FRB 943 260.7 35 175.7 0.118 15.2 3.0 +FRB 944 923.6 35 838.6 0.803 18.1 3.0 +FRB 945 913.5 35 828.5 1.208 24.7 1.0 +FRB 946 200.0 35 115.0 0.155 11.0 3.0 +FRB 947 363.2 35 278.2 0.386 12.0 3.0 +FRB 948 324.1 35 239.1 0.178 22.7 1.0 +FRB 949 497.9 35 412.9 0.549 24.1 3.0 +FRB 950 464.8 35 379.8 0.503 10.6 4.0 +FRB 951 897.2 35 812.2 0.893 19.2 3.0 +FRB 952 243.3 35 158.3 0.111 12.5 2.0 +FRB 953 340.6 35 255.6 0.173 9.9 2.0 +FRB 954 239.4 35 154.4 0.240 11.0 3.0 +FRB 955 672.0 35 587.0 0.618 12.1 3.0 +FRB 956 918.3 35 833.3 0.450 19.9 3.0 +FRB 957 351.4 35 266.4 0.394 27.7 3.0 +FRB 958 865.6 35 780.6 1.064 10.3 0.0 +FRB 959 1634.9 35 1549.9 1.946 15.9 3.0 +FRB 960 375.6 35 290.6 0.255 9.6 1.0 +FRB 961 1282.2 35 1197.2 1.503 12.7 3.0 +FRB 962 810.4 35 725.4 0.109 22.6 3.0 +FRB 963 1615.8 35 1530.8 0.363 14.0 4.0 +FRB 964 410.2 35 325.2 0.229 14.9 2.0 +FRB 965 322.5 35 237.5 0.171 37.2 4.0 +FRB 966 807.4 35 722.4 0.926 20.6 3.0 +FRB 967 809.0 35 724.0 0.973 15.2 3.0 +FRB 968 200.8 35 115.8 0.017 40.9 1.0 +FRB 969 624.5 35 539.5 0.608 29.0 3.0 +FRB 970 765.5 35 680.5 0.903 27.9 3.0 +FRB 971 723.4 35 638.4 0.748 18.6 2.0 +FRB 972 1077.4 35 992.4 0.677 17.1 2.0 +FRB 973 817.6 35 732.6 0.672 11.1 4.0 +FRB 974 1497.4 35 1412.4 1.515 10.0 4.0 +FRB 975 569.8 35 484.8 0.124 57.6 3.0 +FRB 976 510.3 35 425.3 0.480 33.4 2.0 +FRB 977 452.5 35 367.5 0.265 10.3 4.0 +FRB 978 975.6 35 890.6 1.173 11.2 3.0 +FRB 979 496.8 35 411.8 0.375 55.7 1.0 +FRB 980 199.7 35 114.7 0.038 9.9 3.0 +FRB 981 806.6 35 721.6 0.794 14.6 2.0 +FRB 982 642.3 35 557.3 0.439 13.4 3.0 +FRB 983 959.5 35 874.5 0.787 16.6 0.0 +FRB 984 396.7 35 311.7 0.330 21.8 3.0 +FRB 985 142.1 35 57.1 0.043 21.8 3.0 +FRB 986 376.1 35 291.1 0.219 19.0 1.0 +FRB 987 1077.2 35 992.2 1.389 35.2 1.0 +FRB 988 632.7 35 547.7 0.475 11.9 0.0 +FRB 989 330.1 35 245.1 0.163 11.7 3.0 +FRB 990 247.1 35 162.1 0.152 18.0 3.0 +FRB 991 140.6 35 55.6 0.019 20.3 3.0 +FRB 992 578.6 35 493.6 0.301 53.0 1.0 +FRB 993 230.2 35 145.2 0.125 10.1 2.0 +FRB 994 420.1 35 335.1 0.135 18.6 3.0 +FRB 995 579.4 35 494.4 0.360 14.9 1.0 +FRB 996 1031.4 35 946.4 1.190 14.7 2.0 +FRB 997 391.9 35 306.9 0.147 20.3 5.0 +FRB 998 341.4 35 256.4 0.267 79.0 1.0 +FRB 999 442.7 35 357.7 0.433 14.0 3.0 diff --git a/zdm/craco/MC_F/Surveys/F_0.32_survey.ecsv b/zdm/craco/MC_F/Surveys/F_0.32_survey.ecsv new file mode 100644 index 00000000..0a7b80c4 --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_0.32_survey.ecsv @@ -0,0 +1,1024 @@ +# %ECSV 0.9 +# --- +# datatype: +# - {name: TNS, datatype: string} +# - {name: BW, datatype: float64} +# - {name: DM, datatype: float64} +# - {name: DMG, datatype: float64} +# - {name: FBAR, datatype: float64} +# - {name: FRES, datatype: float64} +# - {name: Gb, datatype: object} +# - {name: Gl, datatype: object} +# - {name: SNR, datatype: float64} +# - {name: SNRTHRESH, datatype: float64} +# - {name: THRESH, datatype: float64} +# - {name: TRES, datatype: float64} +# - {name: WIDTH, datatype: float64} +# - {name: XDec, datatype: object} +# - {name: XRA, datatype: object} +# - {name: Z, datatype: float64} +# meta: !!omap +# - {survey_data: "{\n \"observing\": {\n \"NORM_FRB\": 1000,\n \"TOBS\": 96.65\n },\n \"telescope\": {\n \ +# \ \"BEAM\": \"lat50_log\",\n \"DIAM\": 12.0,\n \"NBEAMS\": 36,\n \"NBINS\": 5\n }\n}"} +# schema: astropy-2.0 +TNS BW DM DMG FBAR FRES Gb Gl SNR SNRTHRESH THRESH TRES WIDTH XDec XRA Z +0 288.0 550.1 35.0 1320.0 1.0 "" "" 25.5 9.5 0.99 1.7 2.0 "" "" 0.313 +1 288.0 273.7 35.0 1320.0 1.0 "" "" 22.8 9.5 0.99 1.7 2.0 "" "" 0.02 +2 288.0 680.2 35.0 1320.0 1.0 "" "" 10.2 9.5 0.99 1.7 1.0 "" "" 0.645 +3 288.0 515.1 35.0 1320.0 1.0 "" "" 36.1 9.5 0.99 1.7 3.0 "" "" 0.179 +4 288.0 572.3 35.0 1320.0 1.0 "" "" 44.0 9.5 0.99 1.7 5.0 "" "" 0.207 +5 288.0 330.9 35.0 1320.0 1.0 "" "" 17.6 9.5 0.99 1.7 4.0 "" "" 0.299 +6 288.0 888.9 35.0 1320.0 1.0 "" "" 22.3 9.5 0.99 1.7 3.0 "" "" 0.737 +7 288.0 378.2 35.0 1320.0 1.0 "" "" 25.7 9.5 0.99 1.7 2.0 "" "" 0.358 +8 288.0 458.5 35.0 1320.0 1.0 "" "" 104.3 9.5 0.99 1.7 1.0 "" "" 0.047 +9 288.0 1047.4 35.0 1320.0 1.0 "" "" 19.8 9.5 0.99 1.7 2.0 "" "" 1.259 +10 288.0 349.8 35.0 1320.0 1.0 "" "" 39.3 9.5 0.99 1.7 4.0 "" "" 0.3 +11 288.0 376.2 35.0 1320.0 1.0 "" "" 15.3 9.5 0.99 1.7 2.0 "" "" 0.476 +12 288.0 240.3 35.0 1320.0 1.0 "" "" 33.6 9.5 0.99 1.7 1.0 "" "" 0.254 +13 288.0 495.1 35.0 1320.0 1.0 "" "" 13.1 9.5 0.99 1.7 3.0 "" "" 0.486 +14 288.0 302.0 35.0 1320.0 1.0 "" "" 16.2 9.5 0.99 1.7 3.0 "" "" 0.061 +15 288.0 465.4 35.0 1320.0 1.0 "" "" 46.8 9.5 0.99 1.7 3.0 "" "" 0.222 +16 288.0 298.9 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 3.0 "" "" 0.173 +17 288.0 362.7 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 4.0 "" "" 0.074 +18 288.0 1707.5 35.0 1320.0 1.0 "" "" 16.8 9.5 0.99 1.7 3.0 "" "" 0.842 +19 288.0 122.8 35.0 1320.0 1.0 "" "" 53.0 9.5 0.99 1.7 2.0 "" "" 0.003 +20 288.0 405.5 35.0 1320.0 1.0 "" "" 58.0 9.5 0.99 1.7 3.0 "" "" 0.538 +21 288.0 896.8 35.0 1320.0 1.0 "" "" 13.1 9.5 0.99 1.7 3.0 "" "" 0.754 +22 288.0 300.8 35.0 1320.0 1.0 "" "" 19.6 9.5 0.99 1.7 2.0 "" "" 0.163 +23 288.0 913.3 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 2.0 "" "" 0.768 +24 288.0 763.0 35.0 1320.0 1.0 "" "" 31.8 9.5 0.99 1.7 3.0 "" "" 0.716 +25 288.0 1107.1 35.0 1320.0 1.0 "" "" 13.2 9.5 0.99 1.7 2.0 "" "" 1.02 +26 288.0 417.6 35.0 1320.0 1.0 "" "" 138.9 9.5 0.99 1.7 1.0 "" "" 0.352 +27 288.0 355.0 35.0 1320.0 1.0 "" "" 14.8 9.5 0.99 1.7 2.0 "" "" 0.283 +28 288.0 240.7 35.0 1320.0 1.0 "" "" 18.7 9.5 0.99 1.7 3.0 "" "" 0.038 +29 288.0 618.0 35.0 1320.0 1.0 "" "" 37.9 9.5 0.99 1.7 4.0 "" "" 0.318 +30 288.0 975.5 35.0 1320.0 1.0 "" "" 17.5 9.5 0.99 1.7 2.0 "" "" 0.407 +31 288.0 403.9 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 3.0 "" "" 0.124 +32 288.0 975.2 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 2.0 "" "" 1.093 +33 288.0 142.8 35.0 1320.0 1.0 "" "" 20.2 9.5 0.99 1.7 4.0 "" "" 0.001 +34 288.0 299.6 35.0 1320.0 1.0 "" "" 16.5 9.5 0.99 1.7 1.0 "" "" 0.208 +35 288.0 243.5 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 0.0 "" "" 0.05 +36 288.0 1455.2 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 2.0 "" "" 1.873 +37 288.0 178.4 35.0 1320.0 1.0 "" "" 68.0 9.5 0.99 1.7 2.0 "" "" 0.082 +38 288.0 719.1 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 4.0 "" "" 0.927 +39 288.0 795.7 35.0 1320.0 1.0 "" "" 11.8 9.5 0.99 1.7 1.0 "" "" 0.495 +40 288.0 397.4 35.0 1320.0 1.0 "" "" 10.4 9.5 0.99 1.7 2.0 "" "" 0.347 +41 288.0 350.3 35.0 1320.0 1.0 "" "" 18.2 9.5 0.99 1.7 2.0 "" "" 0.111 +42 288.0 218.6 35.0 1320.0 1.0 "" "" 12.9 9.5 0.99 1.7 1.0 "" "" 0.092 +43 288.0 332.3 35.0 1320.0 1.0 "" "" 29.6 9.5 0.99 1.7 3.0 "" "" 0.179 +44 288.0 435.0 35.0 1320.0 1.0 "" "" 16.5 9.5 0.99 1.7 3.0 "" "" 0.256 +45 288.0 568.2 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 1.0 "" "" 0.463 +46 288.0 1062.3 35.0 1320.0 1.0 "" "" 18.1 9.5 0.99 1.7 1.0 "" "" 1.071 +47 288.0 401.7 35.0 1320.0 1.0 "" "" 30.1 9.5 0.99 1.7 2.0 "" "" 0.293 +48 288.0 589.2 35.0 1320.0 1.0 "" "" 13.1 9.5 0.99 1.7 1.0 "" "" 0.503 +49 288.0 244.4 35.0 1320.0 1.0 "" "" 36.6 9.5 0.99 1.7 3.0 "" "" 0.014 +50 288.0 223.5 35.0 1320.0 1.0 "" "" 193.2 9.5 0.99 1.7 3.0 "" "" 0.224 +51 288.0 1308.0 35.0 1320.0 1.0 "" "" 10.3 9.5 0.99 1.7 2.0 "" "" 0.453 +52 288.0 384.5 35.0 1320.0 1.0 "" "" 23.9 9.5 0.99 1.7 1.0 "" "" 0.286 +53 288.0 678.3 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 3.0 "" "" 0.588 +54 288.0 488.8 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 1.0 "" "" 0.333 +55 288.0 418.4 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 2.0 "" "" 0.382 +56 288.0 388.3 35.0 1320.0 1.0 "" "" 55.5 9.5 0.99 1.7 4.0 "" "" 0.354 +57 288.0 479.7 35.0 1320.0 1.0 "" "" 55.6 9.5 0.99 1.7 2.0 "" "" 0.135 +58 288.0 176.3 35.0 1320.0 1.0 "" "" 40.5 9.5 0.99 1.7 2.0 "" "" 0.078 +59 288.0 328.3 35.0 1320.0 1.0 "" "" 16.8 9.5 0.99 1.7 1.0 "" "" 0.277 +60 288.0 577.7 35.0 1320.0 1.0 "" "" 38.5 9.5 0.99 1.7 2.0 "" "" 0.683 +61 288.0 509.6 35.0 1320.0 1.0 "" "" 11.7 9.5 0.99 1.7 0.0 "" "" 0.359 +62 288.0 398.7 35.0 1320.0 1.0 "" "" 18.9 9.5 0.99 1.7 2.0 "" "" 0.483 +63 288.0 691.3 35.0 1320.0 1.0 "" "" 20.8 9.5 0.99 1.7 2.0 "" "" 0.197 +64 288.0 493.2 35.0 1320.0 1.0 "" "" 15.2 9.5 0.99 1.7 3.0 "" "" 0.374 +65 288.0 350.9 35.0 1320.0 1.0 "" "" 93.5 9.5 0.99 1.7 3.0 "" "" 0.028 +66 288.0 428.1 35.0 1320.0 1.0 "" "" 16.8 9.5 0.99 1.7 4.0 "" "" 0.435 +67 288.0 801.0 35.0 1320.0 1.0 "" "" 16.2 9.5 0.99 1.7 4.0 "" "" 1.053 +68 288.0 412.7 35.0 1320.0 1.0 "" "" 15.2 9.5 0.99 1.7 2.0 "" "" 0.172 +69 288.0 907.4 35.0 1320.0 1.0 "" "" 26.8 9.5 0.99 1.7 1.0 "" "" 0.497 +70 288.0 461.0 35.0 1320.0 1.0 "" "" 125.7 9.5 0.99 1.7 3.0 "" "" 0.272 +71 288.0 943.3 35.0 1320.0 1.0 "" "" 16.8 9.5 0.99 1.7 3.0 "" "" 0.638 +72 288.0 419.5 35.0 1320.0 1.0 "" "" 59.2 9.5 0.99 1.7 1.0 "" "" 0.234 +73 288.0 187.7 35.0 1320.0 1.0 "" "" 168.5 9.5 0.99 1.7 2.0 "" "" 0.064 +74 288.0 551.6 35.0 1320.0 1.0 "" "" 26.4 9.5 0.99 1.7 3.0 "" "" 0.459 +75 288.0 276.6 35.0 1320.0 1.0 "" "" 25.6 9.5 0.99 1.7 0.0 "" "" 0.288 +76 288.0 275.7 35.0 1320.0 1.0 "" "" 28.0 9.5 0.99 1.7 3.0 "" "" 0.141 +77 288.0 421.4 35.0 1320.0 1.0 "" "" 13.7 9.5 0.99 1.7 1.0 "" "" 0.097 +78 288.0 345.1 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 1.0 "" "" 0.222 +79 288.0 476.7 35.0 1320.0 1.0 "" "" 15.6 9.5 0.99 1.7 3.0 "" "" 0.191 +80 288.0 277.7 35.0 1320.0 1.0 "" "" 645.9 9.5 0.99 1.7 1.0 "" "" 0.055 +81 288.0 411.0 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 2.0 "" "" 0.333 +82 288.0 654.8 35.0 1320.0 1.0 "" "" 16.8 9.5 0.99 1.7 4.0 "" "" 0.06 +83 288.0 440.5 35.0 1320.0 1.0 "" "" 20.4 9.5 0.99 1.7 0.0 "" "" 0.101 +84 288.0 355.8 35.0 1320.0 1.0 "" "" 89.8 9.5 0.99 1.7 3.0 "" "" 0.184 +85 288.0 627.5 35.0 1320.0 1.0 "" "" 13.5 9.5 0.99 1.7 5.0 "" "" 0.428 +86 288.0 1497.3 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 3.0 "" "" 1.597 +87 288.0 220.6 35.0 1320.0 1.0 "" "" 16.7 9.5 0.99 1.7 3.0 "" "" 0.127 +88 288.0 219.8 35.0 1320.0 1.0 "" "" 10.2 9.5 0.99 1.7 1.0 "" "" 0.104 +89 288.0 193.1 35.0 1320.0 1.0 "" "" 15.0 9.5 0.99 1.7 3.0 "" "" 0.127 +90 288.0 532.5 35.0 1320.0 1.0 "" "" 13.4 9.5 0.99 1.7 2.0 "" "" 0.49 +91 288.0 1473.7 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 3.0 "" "" 0.689 +92 288.0 528.4 35.0 1320.0 1.0 "" "" 9.6 9.5 0.99 1.7 2.0 "" "" 0.256 +93 288.0 886.6 35.0 1320.0 1.0 "" "" 10.3 9.5 0.99 1.7 1.0 "" "" 0.942 +94 288.0 558.4 35.0 1320.0 1.0 "" "" 39.2 9.5 0.99 1.7 2.0 "" "" 0.827 +95 288.0 751.5 35.0 1320.0 1.0 "" "" 19.6 9.5 0.99 1.7 2.0 "" "" 0.788 +96 288.0 365.8 35.0 1320.0 1.0 "" "" 48.4 9.5 0.99 1.7 3.0 "" "" 0.071 +97 288.0 442.8 35.0 1320.0 1.0 "" "" 10.4 9.5 0.99 1.7 2.0 "" "" 0.29 +98 288.0 808.5 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 2.0 "" "" 0.421 +99 288.0 1026.1 35.0 1320.0 1.0 "" "" 14.3 9.5 0.99 1.7 4.0 "" "" 1.304 +100 288.0 186.7 35.0 1320.0 1.0 "" "" 15.9 9.5 0.99 1.7 2.0 "" "" 0.15 +101 288.0 1179.5 35.0 1320.0 1.0 "" "" 26.0 9.5 0.99 1.7 1.0 "" "" 1.321 +102 288.0 438.5 35.0 1320.0 1.0 "" "" 20.2 9.5 0.99 1.7 4.0 "" "" 0.062 +103 288.0 315.3 35.0 1320.0 1.0 "" "" 17.9 9.5 0.99 1.7 1.0 "" "" 0.089 +104 288.0 833.1 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 2.0 "" "" 0.949 +105 288.0 595.3 35.0 1320.0 1.0 "" "" 32.8 9.5 0.99 1.7 2.0 "" "" 0.25 +106 288.0 313.4 35.0 1320.0 1.0 "" "" 16.8 9.5 0.99 1.7 4.0 "" "" 0.37 +107 288.0 568.5 35.0 1320.0 1.0 "" "" 13.1 9.5 0.99 1.7 2.0 "" "" 0.629 +108 288.0 143.5 35.0 1320.0 1.0 "" "" 11.0 9.5 0.99 1.7 4.0 "" "" 0.026 +109 288.0 743.4 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 3.0 "" "" 0.812 +110 288.0 941.9 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 2.0 "" "" 0.755 +111 288.0 460.5 35.0 1320.0 1.0 "" "" 10.7 9.5 0.99 1.7 2.0 "" "" 0.355 +112 288.0 1271.8 35.0 1320.0 1.0 "" "" 12.1 9.5 0.99 1.7 2.0 "" "" 0.432 +113 288.0 1308.6 35.0 1320.0 1.0 "" "" 15.7 9.5 0.99 1.7 2.0 "" "" 1.273 +114 288.0 567.9 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 3.0 "" "" 0.608 +115 288.0 410.5 35.0 1320.0 1.0 "" "" 84.7 9.5 0.99 1.7 2.0 "" "" 0.057 +116 288.0 391.1 35.0 1320.0 1.0 "" "" 117.3 9.5 0.99 1.7 1.0 "" "" 0.251 +117 288.0 1287.8 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 2.0 "" "" 1.592 +118 288.0 634.8 35.0 1320.0 1.0 "" "" 15.9 9.5 0.99 1.7 2.0 "" "" 0.378 +119 288.0 383.0 35.0 1320.0 1.0 "" "" 15.6 9.5 0.99 1.7 2.0 "" "" 0.176 +120 288.0 372.7 35.0 1320.0 1.0 "" "" 16.2 9.5 0.99 1.7 2.0 "" "" 0.167 +121 288.0 237.3 35.0 1320.0 1.0 "" "" 13.3 9.5 0.99 1.7 2.0 "" "" 0.041 +122 288.0 478.8 35.0 1320.0 1.0 "" "" 27.0 9.5 0.99 1.7 2.0 "" "" 0.354 +123 288.0 835.0 35.0 1320.0 1.0 "" "" 51.2 9.5 0.99 1.7 2.0 "" "" 0.735 +124 288.0 282.6 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 3.0 "" "" 0.263 +125 288.0 151.4 35.0 1320.0 1.0 "" "" 223.4 9.5 0.99 1.7 3.0 "" "" 0.046 +126 288.0 819.9 35.0 1320.0 1.0 "" "" 13.1 9.5 0.99 1.7 4.0 "" "" 0.75 +127 288.0 162.3 35.0 1320.0 1.0 "" "" 17.3 9.5 0.99 1.7 3.0 "" "" 0.138 +128 288.0 371.1 35.0 1320.0 1.0 "" "" 25.0 9.5 0.99 1.7 1.0 "" "" 0.282 +129 288.0 357.4 35.0 1320.0 1.0 "" "" 16.3 9.5 0.99 1.7 1.0 "" "" 0.262 +130 288.0 331.8 35.0 1320.0 1.0 "" "" 40.2 9.5 0.99 1.7 3.0 "" "" 0.085 +131 288.0 557.5 35.0 1320.0 1.0 "" "" 88.5 9.5 0.99 1.7 3.0 "" "" 0.289 +132 288.0 818.5 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 3.0 "" "" 0.66 +133 288.0 1257.6 35.0 1320.0 1.0 "" "" 22.4 9.5 0.99 1.7 3.0 "" "" 0.699 +134 288.0 1116.3 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 2.0 "" "" 1.367 +135 288.0 2259.2 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 3.0 "" "" 1.338 +136 288.0 307.9 35.0 1320.0 1.0 "" "" 22.6 9.5 0.99 1.7 4.0 "" "" 0.243 +137 288.0 1311.1 35.0 1320.0 1.0 "" "" 24.4 9.5 0.99 1.7 3.0 "" "" 1.712 +138 288.0 848.2 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 2.0 "" "" 1.006 +139 288.0 1060.6 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 3.0 "" "" 1.108 +140 288.0 785.5 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 3.0 "" "" 0.164 +141 288.0 484.9 35.0 1320.0 1.0 "" "" 11.7 9.5 0.99 1.7 0.0 "" "" 0.52 +142 288.0 481.2 35.0 1320.0 1.0 "" "" 9.6 9.5 0.99 1.7 3.0 "" "" 0.424 +143 288.0 484.7 35.0 1320.0 1.0 "" "" 14.9 9.5 0.99 1.7 3.0 "" "" 0.61 +144 288.0 260.6 35.0 1320.0 1.0 "" "" 12.9 9.5 0.99 1.7 3.0 "" "" 0.054 +145 288.0 393.8 35.0 1320.0 1.0 "" "" 12.7 9.5 0.99 1.7 4.0 "" "" 0.291 +146 288.0 273.7 35.0 1320.0 1.0 "" "" 22.7 9.5 0.99 1.7 3.0 "" "" 0.182 +147 288.0 534.4 35.0 1320.0 1.0 "" "" 21.0 9.5 0.99 1.7 3.0 "" "" 0.556 +148 288.0 703.6 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 1.0 "" "" 0.195 +149 288.0 335.9 35.0 1320.0 1.0 "" "" 18.5 9.5 0.99 1.7 3.0 "" "" 0.329 +150 288.0 898.1 35.0 1320.0 1.0 "" "" 32.2 9.5 0.99 1.7 2.0 "" "" 0.718 +151 288.0 582.2 35.0 1320.0 1.0 "" "" 13.8 9.5 0.99 1.7 3.0 "" "" 0.571 +152 288.0 636.2 35.0 1320.0 1.0 "" "" 23.1 9.5 0.99 1.7 2.0 "" "" 0.441 +153 288.0 735.7 35.0 1320.0 1.0 "" "" 27.7 9.5 0.99 1.7 2.0 "" "" 0.482 +154 288.0 1405.0 35.0 1320.0 1.0 "" "" 11.4 9.5 0.99 1.7 4.0 "" "" 1.318 +155 288.0 1083.0 35.0 1320.0 1.0 "" "" 19.3 9.5 0.99 1.7 3.0 "" "" 1.101 +156 288.0 709.4 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 2.0 "" "" 0.58 +157 288.0 1794.1 35.0 1320.0 1.0 "" "" 14.9 9.5 0.99 1.7 3.0 "" "" 1.849 +158 288.0 736.2 35.0 1320.0 1.0 "" "" 11.0 9.5 0.99 1.7 2.0 "" "" 0.546 +159 288.0 808.6 35.0 1320.0 1.0 "" "" 33.4 9.5 0.99 1.7 2.0 "" "" 0.472 +160 288.0 352.0 35.0 1320.0 1.0 "" "" 16.0 9.5 0.99 1.7 3.0 "" "" 0.126 +161 288.0 447.5 35.0 1320.0 1.0 "" "" 38.3 9.5 0.99 1.7 1.0 "" "" 0.543 +162 288.0 1346.2 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 2.0 "" "" 1.567 +163 288.0 428.3 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 2.0 "" "" 0.537 +164 288.0 421.8 35.0 1320.0 1.0 "" "" 28.0 9.5 0.99 1.7 4.0 "" "" 0.018 +165 288.0 602.3 35.0 1320.0 1.0 "" "" 16.3 9.5 0.99 1.7 2.0 "" "" 0.093 +166 288.0 1110.1 35.0 1320.0 1.0 "" "" 94.0 9.5 0.99 1.7 3.0 "" "" 0.439 +167 288.0 303.5 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 1.0 "" "" 0.137 +168 288.0 799.7 35.0 1320.0 1.0 "" "" 18.8 9.5 0.99 1.7 3.0 "" "" 0.465 +169 288.0 309.6 35.0 1320.0 1.0 "" "" 30.0 9.5 0.99 1.7 2.0 "" "" 0.159 +170 288.0 3446.6 35.0 1320.0 1.0 "" "" 25.6 9.5 0.99 1.7 5.0 "" "" 0.08 +171 288.0 721.5 35.0 1320.0 1.0 "" "" 25.8 9.5 0.99 1.7 2.0 "" "" 0.306 +172 288.0 296.3 35.0 1320.0 1.0 "" "" 21.4 9.5 0.99 1.7 5.0 "" "" 0.134 +173 288.0 573.2 35.0 1320.0 1.0 "" "" 19.6 9.5 0.99 1.7 2.0 "" "" 0.464 +174 288.0 184.5 35.0 1320.0 1.0 "" "" 11.4 9.5 0.99 1.7 1.0 "" "" 0.063 +175 288.0 580.0 35.0 1320.0 1.0 "" "" 15.6 9.5 0.99 1.7 0.0 "" "" 0.632 +176 288.0 754.0 35.0 1320.0 1.0 "" "" 9.6 9.5 0.99 1.7 1.0 "" "" 0.103 +177 288.0 391.9 35.0 1320.0 1.0 "" "" 11.2 9.5 0.99 1.7 1.0 "" "" 0.43 +178 288.0 282.0 35.0 1320.0 1.0 "" "" 21.7 9.5 0.99 1.7 3.0 "" "" 0.073 +179 288.0 548.7 35.0 1320.0 1.0 "" "" 25.8 9.5 0.99 1.7 4.0 "" "" 0.35 +180 288.0 449.7 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 3.0 "" "" 0.019 +181 288.0 187.9 35.0 1320.0 1.0 "" "" 40.8 9.5 0.99 1.7 2.0 "" "" 0.052 +182 288.0 522.1 35.0 1320.0 1.0 "" "" 11.8 9.5 0.99 1.7 2.0 "" "" 0.353 +183 288.0 233.3 35.0 1320.0 1.0 "" "" 85.5 9.5 0.99 1.7 2.0 "" "" 0.081 +184 288.0 923.9 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 2.0 "" "" 0.961 +185 288.0 568.1 35.0 1320.0 1.0 "" "" 15.9 9.5 0.99 1.7 5.0 "" "" 0.295 +186 288.0 1327.1 35.0 1320.0 1.0 "" "" 18.6 9.5 0.99 1.7 2.0 "" "" 0.437 +187 288.0 901.0 35.0 1320.0 1.0 "" "" 39.8 9.5 0.99 1.7 2.0 "" "" 0.744 +188 288.0 776.9 35.0 1320.0 1.0 "" "" 14.5 9.5 0.99 1.7 2.0 "" "" 0.786 +189 288.0 359.8 35.0 1320.0 1.0 "" "" 46.4 9.5 0.99 1.7 1.0 "" "" 0.372 +190 288.0 733.7 35.0 1320.0 1.0 "" "" 18.7 9.5 0.99 1.7 2.0 "" "" 0.633 +191 288.0 685.6 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 3.0 "" "" 0.765 +192 288.0 568.9 35.0 1320.0 1.0 "" "" 14.8 9.5 0.99 1.7 3.0 "" "" 0.644 +193 288.0 398.7 35.0 1320.0 1.0 "" "" 23.3 9.5 0.99 1.7 3.0 "" "" 0.239 +194 288.0 664.2 35.0 1320.0 1.0 "" "" 15.8 9.5 0.99 1.7 3.0 "" "" 0.495 +195 288.0 326.6 35.0 1320.0 1.0 "" "" 14.2 9.5 0.99 1.7 1.0 "" "" 0.251 +196 288.0 726.0 35.0 1320.0 1.0 "" "" 23.7 9.5 0.99 1.7 5.0 "" "" 0.089 +197 288.0 342.1 35.0 1320.0 1.0 "" "" 48.2 9.5 0.99 1.7 2.0 "" "" 0.029 +198 288.0 376.5 35.0 1320.0 1.0 "" "" 47.9 9.5 0.99 1.7 1.0 "" "" 0.279 +199 288.0 271.9 35.0 1320.0 1.0 "" "" 18.9 9.5 0.99 1.7 2.0 "" "" 0.237 +200 288.0 226.2 35.0 1320.0 1.0 "" "" 25.8 9.5 0.99 1.7 2.0 "" "" 0.036 +201 288.0 636.8 35.0 1320.0 1.0 "" "" 18.9 9.5 0.99 1.7 1.0 "" "" 0.069 +202 288.0 1305.4 35.0 1320.0 1.0 "" "" 13.6 9.5 0.99 1.7 1.0 "" "" 1.562 +203 288.0 1160.6 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 3.0 "" "" 0.743 +204 288.0 393.9 35.0 1320.0 1.0 "" "" 67.2 9.5 0.99 1.7 2.0 "" "" 0.118 +205 288.0 208.4 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 2.0 "" "" 0.2 +206 288.0 747.5 35.0 1320.0 1.0 "" "" 28.0 9.5 0.99 1.7 2.0 "" "" 0.232 +207 288.0 544.7 35.0 1320.0 1.0 "" "" 14.1 9.5 0.99 1.7 2.0 "" "" 0.397 +208 288.0 208.3 35.0 1320.0 1.0 "" "" 25.2 9.5 0.99 1.7 2.0 "" "" 0.125 +209 288.0 647.3 35.0 1320.0 1.0 "" "" 10.2 9.5 0.99 1.7 2.0 "" "" 0.658 +210 288.0 942.2 35.0 1320.0 1.0 "" "" 10.9 9.5 0.99 1.7 2.0 "" "" 0.343 +211 288.0 512.8 35.0 1320.0 1.0 "" "" 24.3 9.5 0.99 1.7 2.0 "" "" 0.053 +212 288.0 407.9 35.0 1320.0 1.0 "" "" 23.2 9.5 0.99 1.7 1.0 "" "" 0.102 +213 288.0 519.0 35.0 1320.0 1.0 "" "" 13.9 9.5 0.99 1.7 2.0 "" "" 0.377 +214 288.0 1342.6 35.0 1320.0 1.0 "" "" 10.9 9.5 0.99 1.7 2.0 "" "" 0.707 +215 288.0 424.8 35.0 1320.0 1.0 "" "" 18.1 9.5 0.99 1.7 4.0 "" "" 0.23 +216 288.0 621.2 35.0 1320.0 1.0 "" "" 16.0 9.5 0.99 1.7 3.0 "" "" 0.79 +217 288.0 655.3 35.0 1320.0 1.0 "" "" 16.5 9.5 0.99 1.7 2.0 "" "" 0.588 +218 288.0 2215.0 35.0 1320.0 1.0 "" "" 19.1 9.5 0.99 1.7 3.0 "" "" 0.08 +219 288.0 716.7 35.0 1320.0 1.0 "" "" 41.8 9.5 0.99 1.7 2.0 "" "" 0.683 +220 288.0 294.3 35.0 1320.0 1.0 "" "" 22.7 9.5 0.99 1.7 4.0 "" "" 0.197 +221 288.0 690.7 35.0 1320.0 1.0 "" "" 20.4 9.5 0.99 1.7 2.0 "" "" 0.703 +222 288.0 794.9 35.0 1320.0 1.0 "" "" 33.2 9.5 0.99 1.7 2.0 "" "" 0.048 +223 288.0 704.5 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 3.0 "" "" 0.802 +224 288.0 676.6 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 2.0 "" "" 0.153 +225 288.0 458.6 35.0 1320.0 1.0 "" "" 92.5 9.5 0.99 1.7 3.0 "" "" 0.467 +226 288.0 508.2 35.0 1320.0 1.0 "" "" 15.3 9.5 0.99 1.7 3.0 "" "" 0.432 +227 288.0 1294.8 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 2.0 "" "" 1.343 +228 288.0 666.7 35.0 1320.0 1.0 "" "" 22.5 9.5 0.99 1.7 0.0 "" "" 0.579 +229 288.0 178.7 35.0 1320.0 1.0 "" "" 22.7 9.5 0.99 1.7 3.0 "" "" 0.054 +230 288.0 154.3 35.0 1320.0 1.0 "" "" 31.8 9.5 0.99 1.7 3.0 "" "" 0.039 +231 288.0 790.1 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 2.0 "" "" 1.095 +232 288.0 625.4 35.0 1320.0 1.0 "" "" 11.2 9.5 0.99 1.7 3.0 "" "" 0.622 +233 288.0 448.6 35.0 1320.0 1.0 "" "" 14.1 9.5 0.99 1.7 1.0 "" "" 0.272 +234 288.0 351.6 35.0 1320.0 1.0 "" "" 28.0 9.5 0.99 1.7 1.0 "" "" 0.212 +235 288.0 532.9 35.0 1320.0 1.0 "" "" 14.2 9.5 0.99 1.7 2.0 "" "" 0.502 +236 288.0 146.4 35.0 1320.0 1.0 "" "" 25.9 9.5 0.99 1.7 2.0 "" "" 0.026 +237 288.0 363.8 35.0 1320.0 1.0 "" "" 12.5 9.5 0.99 1.7 1.0 "" "" 0.317 +238 288.0 235.7 35.0 1320.0 1.0 "" "" 47.5 9.5 0.99 1.7 3.0 "" "" 0.182 +239 288.0 394.0 35.0 1320.0 1.0 "" "" 15.3 9.5 0.99 1.7 4.0 "" "" 0.356 +240 288.0 1055.4 35.0 1320.0 1.0 "" "" 27.4 9.5 0.99 1.7 1.0 "" "" 0.935 +241 288.0 212.1 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 2.0 "" "" 0.148 +242 288.0 2097.3 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 1.0 "" "" 2.036 +243 288.0 440.9 35.0 1320.0 1.0 "" "" 13.3 9.5 0.99 1.7 2.0 "" "" 0.405 +244 288.0 677.6 35.0 1320.0 1.0 "" "" 16.1 9.5 0.99 1.7 3.0 "" "" 0.31 +245 288.0 339.0 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 1.0 "" "" 0.042 +246 288.0 270.0 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 4.0 "" "" 0.033 +247 288.0 430.7 35.0 1320.0 1.0 "" "" 15.2 9.5 0.99 1.7 2.0 "" "" 0.464 +248 288.0 2151.2 35.0 1320.0 1.0 "" "" 25.4 9.5 0.99 1.7 1.0 "" "" 0.622 +249 288.0 445.0 35.0 1320.0 1.0 "" "" 14.0 9.5 0.99 1.7 4.0 "" "" 0.301 +250 288.0 326.7 35.0 1320.0 1.0 "" "" 16.6 9.5 0.99 1.7 3.0 "" "" 0.229 +251 288.0 756.5 35.0 1320.0 1.0 "" "" 12.1 9.5 0.99 1.7 4.0 "" "" 0.619 +252 288.0 474.3 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 4.0 "" "" 0.136 +253 288.0 301.1 35.0 1320.0 1.0 "" "" 24.9 9.5 0.99 1.7 3.0 "" "" 0.08 +254 288.0 251.3 35.0 1320.0 1.0 "" "" 34.5 9.5 0.99 1.7 3.0 "" "" 0.19 +255 288.0 215.4 35.0 1320.0 1.0 "" "" 66.6 9.5 0.99 1.7 2.0 "" "" 0.152 +256 288.0 688.1 35.0 1320.0 1.0 "" "" 11.4 9.5 0.99 1.7 2.0 "" "" 0.562 +257 288.0 395.1 35.0 1320.0 1.0 "" "" 19.7 9.5 0.99 1.7 4.0 "" "" 0.234 +258 288.0 1602.7 35.0 1320.0 1.0 "" "" 20.4 9.5 0.99 1.7 2.0 "" "" 1.216 +259 288.0 409.3 35.0 1320.0 1.0 "" "" 14.4 9.5 0.99 1.7 3.0 "" "" 0.196 +260 288.0 785.5 35.0 1320.0 1.0 "" "" 25.5 9.5 0.99 1.7 2.0 "" "" 0.821 +261 288.0 1411.5 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 2.0 "" "" 0.908 +262 288.0 365.7 35.0 1320.0 1.0 "" "" 29.0 9.5 0.99 1.7 1.0 "" "" 0.208 +263 288.0 809.8 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 3.0 "" "" 0.106 +264 288.0 377.8 35.0 1320.0 1.0 "" "" 13.8 9.5 0.99 1.7 2.0 "" "" 0.139 +265 288.0 422.9 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 1.0 "" "" 0.423 +266 288.0 295.9 35.0 1320.0 1.0 "" "" 21.9 9.5 0.99 1.7 2.0 "" "" 0.215 +267 288.0 199.7 35.0 1320.0 1.0 "" "" 39.4 9.5 0.99 1.7 2.0 "" "" 0.161 +268 288.0 456.5 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 2.0 "" "" 0.21 +269 288.0 587.6 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 3.0 "" "" 0.055 +270 288.0 275.5 35.0 1320.0 1.0 "" "" 10.2 9.5 0.99 1.7 2.0 "" "" 0.096 +271 288.0 386.9 35.0 1320.0 1.0 "" "" 18.2 9.5 0.99 1.7 1.0 "" "" 0.053 +272 288.0 1319.3 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 2.0 "" "" 1.418 +273 288.0 629.7 35.0 1320.0 1.0 "" "" 26.0 9.5 0.99 1.7 2.0 "" "" 0.741 +274 288.0 157.7 35.0 1320.0 1.0 "" "" 21.4 9.5 0.99 1.7 2.0 "" "" 0.024 +275 288.0 722.1 35.0 1320.0 1.0 "" "" 27.7 9.5 0.99 1.7 4.0 "" "" 0.616 +276 288.0 775.6 35.0 1320.0 1.0 "" "" 22.5 9.5 0.99 1.7 3.0 "" "" 0.609 +277 288.0 476.8 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 3.0 "" "" 0.393 +278 288.0 823.4 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 2.0 "" "" 0.801 +279 288.0 709.3 35.0 1320.0 1.0 "" "" 17.7 9.5 0.99 1.7 3.0 "" "" 0.796 +280 288.0 765.4 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 1.0 "" "" 1.032 +281 288.0 1306.7 35.0 1320.0 1.0 "" "" 28.2 9.5 0.99 1.7 3.0 "" "" 0.336 +282 288.0 253.7 35.0 1320.0 1.0 "" "" 36.1 9.5 0.99 1.7 3.0 "" "" 0.066 +283 288.0 762.3 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 4.0 "" "" 0.667 +284 288.0 618.1 35.0 1320.0 1.0 "" "" 12.9 9.5 0.99 1.7 2.0 "" "" 0.586 +285 288.0 1062.3 35.0 1320.0 1.0 "" "" 71.5 9.5 0.99 1.7 0.0 "" "" 0.792 +286 288.0 578.1 35.0 1320.0 1.0 "" "" 17.7 9.5 0.99 1.7 2.0 "" "" 0.532 +287 288.0 679.1 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 2.0 "" "" 0.338 +288 288.0 330.7 35.0 1320.0 1.0 "" "" 75.1 9.5 0.99 1.7 3.0 "" "" 0.363 +289 288.0 312.7 35.0 1320.0 1.0 "" "" 13.9 9.5 0.99 1.7 4.0 "" "" 0.059 +290 288.0 165.8 35.0 1320.0 1.0 "" "" 16.7 9.5 0.99 1.7 1.0 "" "" 0.022 +291 288.0 1139.2 35.0 1320.0 1.0 "" "" 18.3 9.5 0.99 1.7 2.0 "" "" 1.241 +292 288.0 320.1 35.0 1320.0 1.0 "" "" 88.2 9.5 0.99 1.7 2.0 "" "" 0.29 +293 288.0 700.6 35.0 1320.0 1.0 "" "" 13.4 9.5 0.99 1.7 2.0 "" "" 0.921 +294 288.0 246.4 35.0 1320.0 1.0 "" "" 23.4 9.5 0.99 1.7 3.0 "" "" 0.123 +295 288.0 283.5 35.0 1320.0 1.0 "" "" 16.0 9.5 0.99 1.7 0.0 "" "" 0.085 +296 288.0 406.3 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 0.0 "" "" 0.275 +297 288.0 1543.3 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 3.0 "" "" 1.742 +298 288.0 511.2 35.0 1320.0 1.0 "" "" 18.6 9.5 0.99 1.7 2.0 "" "" 0.268 +299 288.0 271.5 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 1.0 "" "" 0.079 +300 288.0 449.7 35.0 1320.0 1.0 "" "" 10.7 9.5 0.99 1.7 1.0 "" "" 0.622 +301 288.0 900.2 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 3.0 "" "" 0.15 +302 288.0 863.7 35.0 1320.0 1.0 "" "" 37.9 9.5 0.99 1.7 2.0 "" "" 0.837 +303 288.0 275.3 35.0 1320.0 1.0 "" "" 18.8 9.5 0.99 1.7 3.0 "" "" 0.104 +304 288.0 179.1 35.0 1320.0 1.0 "" "" 109.1 9.5 0.99 1.7 3.0 "" "" 0.001 +305 288.0 814.0 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 3.0 "" "" 0.42 +306 288.0 201.2 35.0 1320.0 1.0 "" "" 13.7 9.5 0.99 1.7 1.0 "" "" 0.01 +307 288.0 517.9 35.0 1320.0 1.0 "" "" 11.2 9.5 0.99 1.7 4.0 "" "" 0.633 +308 288.0 548.6 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 2.0 "" "" 0.47 +309 288.0 385.2 35.0 1320.0 1.0 "" "" 55.9 9.5 0.99 1.7 2.0 "" "" 0.227 +310 288.0 347.6 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 3.0 "" "" 0.17 +311 288.0 266.5 35.0 1320.0 1.0 "" "" 15.9 9.5 0.99 1.7 4.0 "" "" 0.068 +312 288.0 359.8 35.0 1320.0 1.0 "" "" 13.7 9.5 0.99 1.7 2.0 "" "" 0.362 +313 288.0 1062.6 35.0 1320.0 1.0 "" "" 11.0 9.5 0.99 1.7 2.0 "" "" 0.864 +314 288.0 602.4 35.0 1320.0 1.0 "" "" 27.8 9.5 0.99 1.7 1.0 "" "" 0.39 +315 288.0 615.3 35.0 1320.0 1.0 "" "" 13.1 9.5 0.99 1.7 2.0 "" "" 0.815 +316 288.0 930.0 35.0 1320.0 1.0 "" "" 19.8 9.5 0.99 1.7 4.0 "" "" 0.49 +317 288.0 652.9 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 5.0 "" "" 0.633 +318 288.0 634.4 35.0 1320.0 1.0 "" "" 20.7 9.5 0.99 1.7 2.0 "" "" 0.407 +319 288.0 747.8 35.0 1320.0 1.0 "" "" 9.6 9.5 0.99 1.7 4.0 "" "" 0.086 +320 288.0 596.2 35.0 1320.0 1.0 "" "" 21.3 9.5 0.99 1.7 2.0 "" "" 0.603 +321 288.0 469.1 35.0 1320.0 1.0 "" "" 52.5 9.5 0.99 1.7 3.0 "" "" 0.387 +322 288.0 1028.2 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 2.0 "" "" 0.645 +323 288.0 430.6 35.0 1320.0 1.0 "" "" 12.5 9.5 0.99 1.7 0.0 "" "" 0.345 +324 288.0 1121.6 35.0 1320.0 1.0 "" "" 11.2 9.5 0.99 1.7 3.0 "" "" 1.146 +325 288.0 403.1 35.0 1320.0 1.0 "" "" 26.6 9.5 0.99 1.7 3.0 "" "" 0.284 +326 288.0 563.6 35.0 1320.0 1.0 "" "" 22.1 9.5 0.99 1.7 1.0 "" "" 0.689 +327 288.0 1644.2 35.0 1320.0 1.0 "" "" 13.4 9.5 0.99 1.7 3.0 "" "" 2.063 +328 288.0 389.5 35.0 1320.0 1.0 "" "" 23.9 9.5 0.99 1.7 3.0 "" "" 0.307 +329 288.0 624.6 35.0 1320.0 1.0 "" "" 62.3 9.5 0.99 1.7 2.0 "" "" 0.159 +330 288.0 490.1 35.0 1320.0 1.0 "" "" 14.0 9.5 0.99 1.7 2.0 "" "" 0.532 +331 288.0 912.3 35.0 1320.0 1.0 "" "" 15.9 9.5 0.99 1.7 3.0 "" "" 0.645 +332 288.0 692.6 35.0 1320.0 1.0 "" "" 27.3 9.5 0.99 1.7 2.0 "" "" 0.798 +333 288.0 179.2 35.0 1320.0 1.0 "" "" 18.5 9.5 0.99 1.7 3.0 "" "" 0.103 +334 288.0 780.0 35.0 1320.0 1.0 "" "" 17.7 9.5 0.99 1.7 4.0 "" "" 0.408 +335 288.0 964.2 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 1.0 "" "" 1.173 +336 288.0 203.2 35.0 1320.0 1.0 "" "" 14.0 9.5 0.99 1.7 3.0 "" "" 0.092 +337 288.0 698.1 35.0 1320.0 1.0 "" "" 38.8 9.5 0.99 1.7 3.0 "" "" 0.46 +338 288.0 338.5 35.0 1320.0 1.0 "" "" 15.2 9.5 0.99 1.7 3.0 "" "" 0.318 +339 288.0 520.4 35.0 1320.0 1.0 "" "" 12.8 9.5 0.99 1.7 2.0 "" "" 0.439 +340 288.0 958.2 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 2.0 "" "" 0.289 +341 288.0 576.5 35.0 1320.0 1.0 "" "" 24.2 9.5 0.99 1.7 3.0 "" "" 0.514 +342 288.0 418.5 35.0 1320.0 1.0 "" "" 22.6 9.5 0.99 1.7 3.0 "" "" 0.37 +343 288.0 296.4 35.0 1320.0 1.0 "" "" 18.3 9.5 0.99 1.7 3.0 "" "" 0.053 +344 288.0 666.2 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 1.0 "" "" 0.846 +345 288.0 315.6 35.0 1320.0 1.0 "" "" 20.5 9.5 0.99 1.7 3.0 "" "" 0.285 +346 288.0 140.5 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 0.0 "" "" 0.036 +347 288.0 764.2 35.0 1320.0 1.0 "" "" 9.5 9.5 0.99 1.7 1.0 "" "" 0.951 +348 288.0 841.2 35.0 1320.0 1.0 "" "" 14.6 9.5 0.99 1.7 0.0 "" "" 0.603 +349 288.0 938.2 35.0 1320.0 1.0 "" "" 20.4 9.5 0.99 1.7 3.0 "" "" 0.192 +350 288.0 489.1 35.0 1320.0 1.0 "" "" 13.3 9.5 0.99 1.7 1.0 "" "" 0.241 +351 288.0 655.5 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 2.0 "" "" 0.442 +352 288.0 552.8 35.0 1320.0 1.0 "" "" 71.4 9.5 0.99 1.7 1.0 "" "" 0.194 +353 288.0 2749.7 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 0.0 "" "" 2.304 +354 288.0 3004.1 35.0 1320.0 1.0 "" "" 14.3 9.5 0.99 1.7 3.0 "" "" 0.315 +355 288.0 668.2 35.0 1320.0 1.0 "" "" 33.2 9.5 0.99 1.7 3.0 "" "" 0.132 +356 288.0 663.6 35.0 1320.0 1.0 "" "" 19.0 9.5 0.99 1.7 2.0 "" "" 0.575 +357 288.0 564.6 35.0 1320.0 1.0 "" "" 86.8 9.5 0.99 1.7 4.0 "" "" 0.333 +358 288.0 485.8 35.0 1320.0 1.0 "" "" 19.0 9.5 0.99 1.7 1.0 "" "" 0.378 +359 288.0 639.6 35.0 1320.0 1.0 "" "" 131.0 9.5 0.99 1.7 2.0 "" "" 0.238 +360 288.0 94.2 35.0 1320.0 1.0 "" "" 23.9 9.5 0.99 1.7 2.0 "" "" 0.003 +361 288.0 1468.8 35.0 1320.0 1.0 "" "" 29.3 9.5 0.99 1.7 3.0 "" "" 0.241 +362 288.0 215.7 35.0 1320.0 1.0 "" "" 20.8 9.5 0.99 1.7 2.0 "" "" 0.081 +363 288.0 969.2 35.0 1320.0 1.0 "" "" 16.2 9.5 0.99 1.7 2.0 "" "" 0.571 +364 288.0 1324.9 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 5.0 "" "" 1.313 +365 288.0 426.8 35.0 1320.0 1.0 "" "" 20.7 9.5 0.99 1.7 4.0 "" "" 0.429 +366 288.0 524.1 35.0 1320.0 1.0 "" "" 28.2 9.5 0.99 1.7 3.0 "" "" 0.06 +367 288.0 686.1 35.0 1320.0 1.0 "" "" 24.5 9.5 0.99 1.7 2.0 "" "" 0.764 +368 288.0 1243.9 35.0 1320.0 1.0 "" "" 14.0 9.5 0.99 1.7 2.0 "" "" 1.332 +369 288.0 875.0 35.0 1320.0 1.0 "" "" 23.3 9.5 0.99 1.7 2.0 "" "" 0.899 +370 288.0 1351.9 35.0 1320.0 1.0 "" "" 24.4 9.5 0.99 1.7 4.0 "" "" 1.325 +371 288.0 402.8 35.0 1320.0 1.0 "" "" 40.1 9.5 0.99 1.7 2.0 "" "" 0.171 +372 288.0 884.3 35.0 1320.0 1.0 "" "" 9.6 9.5 0.99 1.7 3.0 "" "" 0.408 +373 288.0 411.0 35.0 1320.0 1.0 "" "" 11.8 9.5 0.99 1.7 4.0 "" "" 0.022 +374 288.0 494.9 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 3.0 "" "" 0.516 +375 288.0 645.2 35.0 1320.0 1.0 "" "" 12.5 9.5 0.99 1.7 2.0 "" "" 0.607 +376 288.0 504.0 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 1.0 "" "" 0.452 +377 288.0 593.8 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 3.0 "" "" 0.62 +378 288.0 491.2 35.0 1320.0 1.0 "" "" 21.8 9.5 0.99 1.7 3.0 "" "" 0.141 +379 288.0 395.1 35.0 1320.0 1.0 "" "" 16.3 9.5 0.99 1.7 3.0 "" "" 0.429 +380 288.0 566.1 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 3.0 "" "" 0.515 +381 288.0 181.1 35.0 1320.0 1.0 "" "" 22.5 9.5 0.99 1.7 2.0 "" "" 0.065 +382 288.0 532.3 35.0 1320.0 1.0 "" "" 11.1 9.5 0.99 1.7 2.0 "" "" 0.59 +383 288.0 991.9 35.0 1320.0 1.0 "" "" 15.6 9.5 0.99 1.7 2.0 "" "" 1.222 +384 288.0 1035.4 35.0 1320.0 1.0 "" "" 27.8 9.5 0.99 1.7 3.0 "" "" 1.114 +385 288.0 715.9 35.0 1320.0 1.0 "" "" 19.1 9.5 0.99 1.7 4.0 "" "" 0.09 +386 288.0 691.9 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 4.0 "" "" 0.696 +387 288.0 1031.6 35.0 1320.0 1.0 "" "" 10.3 9.5 0.99 1.7 4.0 "" "" 1.312 +388 288.0 181.0 35.0 1320.0 1.0 "" "" 26.0 9.5 0.99 1.7 2.0 "" "" 0.136 +389 288.0 362.4 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 2.0 "" "" 0.287 +390 288.0 503.6 35.0 1320.0 1.0 "" "" 29.2 9.5 0.99 1.7 3.0 "" "" 0.639 +391 288.0 667.5 35.0 1320.0 1.0 "" "" 13.7 9.5 0.99 1.7 4.0 "" "" 0.128 +392 288.0 765.5 35.0 1320.0 1.0 "" "" 19.0 9.5 0.99 1.7 3.0 "" "" 0.742 +393 288.0 135.7 35.0 1320.0 1.0 "" "" 27.9 9.5 0.99 1.7 4.0 "" "" 0.039 +394 288.0 599.2 35.0 1320.0 1.0 "" "" 24.3 9.5 0.99 1.7 4.0 "" "" 0.24 +395 288.0 1321.2 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 2.0 "" "" 0.407 +396 288.0 388.5 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 2.0 "" "" 0.135 +397 288.0 269.0 35.0 1320.0 1.0 "" "" 30.0 9.5 0.99 1.7 4.0 "" "" 0.123 +398 288.0 944.6 35.0 1320.0 1.0 "" "" 23.0 9.5 0.99 1.7 2.0 "" "" 0.874 +399 288.0 259.8 35.0 1320.0 1.0 "" "" 29.0 9.5 0.99 1.7 2.0 "" "" 0.019 +400 288.0 916.6 35.0 1320.0 1.0 "" "" 14.4 9.5 0.99 1.7 3.0 "" "" 0.997 +401 288.0 266.6 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 2.0 "" "" 0.241 +402 288.0 451.4 35.0 1320.0 1.0 "" "" 17.4 9.5 0.99 1.7 3.0 "" "" 0.454 +403 288.0 724.2 35.0 1320.0 1.0 "" "" 32.0 9.5 0.99 1.7 2.0 "" "" 0.793 +404 288.0 187.5 35.0 1320.0 1.0 "" "" 16.4 9.5 0.99 1.7 3.0 "" "" 0.046 +405 288.0 485.5 35.0 1320.0 1.0 "" "" 20.3 9.5 0.99 1.7 4.0 "" "" 0.162 +406 288.0 236.1 35.0 1320.0 1.0 "" "" 18.3 9.5 0.99 1.7 3.0 "" "" 0.142 +407 288.0 730.6 35.0 1320.0 1.0 "" "" 41.2 9.5 0.99 1.7 3.0 "" "" 0.72 +408 288.0 272.6 35.0 1320.0 1.0 "" "" 39.8 9.5 0.99 1.7 3.0 "" "" 0.141 +409 288.0 524.5 35.0 1320.0 1.0 "" "" 11.7 9.5 0.99 1.7 0.0 "" "" 0.623 +410 288.0 489.3 35.0 1320.0 1.0 "" "" 15.3 9.5 0.99 1.7 1.0 "" "" 0.446 +411 288.0 448.1 35.0 1320.0 1.0 "" "" 12.7 9.5 0.99 1.7 2.0 "" "" 0.467 +412 288.0 1045.2 35.0 1320.0 1.0 "" "" 27.5 9.5 0.99 1.7 4.0 "" "" 1.06 +413 288.0 958.7 35.0 1320.0 1.0 "" "" 23.9 9.5 0.99 1.7 3.0 "" "" 1.035 +414 288.0 233.6 35.0 1320.0 1.0 "" "" 9.6 9.5 0.99 1.7 3.0 "" "" 0.075 +415 288.0 659.9 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 2.0 "" "" 0.318 +416 288.0 635.2 35.0 1320.0 1.0 "" "" 22.9 9.5 0.99 1.7 3.0 "" "" 0.418 +417 288.0 2488.2 35.0 1320.0 1.0 "" "" 22.0 9.5 0.99 1.7 3.0 "" "" 2.001 +418 288.0 416.8 35.0 1320.0 1.0 "" "" 9.6 9.5 0.99 1.7 4.0 "" "" 0.462 +419 288.0 460.9 35.0 1320.0 1.0 "" "" 76.9 9.5 0.99 1.7 2.0 "" "" 0.164 +420 288.0 559.6 35.0 1320.0 1.0 "" "" 14.7 9.5 0.99 1.7 4.0 "" "" 0.72 +421 288.0 878.5 35.0 1320.0 1.0 "" "" 12.7 9.5 0.99 1.7 3.0 "" "" 0.631 +422 288.0 836.2 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 1.0 "" "" 0.306 +423 288.0 717.2 35.0 1320.0 1.0 "" "" 10.3 9.5 0.99 1.7 2.0 "" "" 0.901 +424 288.0 203.8 35.0 1320.0 1.0 "" "" 50.4 9.5 0.99 1.7 4.0 "" "" 0.008 +425 288.0 332.5 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 2.0 "" "" 0.255 +426 288.0 513.5 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 3.0 "" "" 0.412 +427 288.0 890.1 35.0 1320.0 1.0 "" "" 17.0 9.5 0.99 1.7 2.0 "" "" 1.106 +428 288.0 1119.1 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 1.0 "" "" 1.247 +429 288.0 692.3 35.0 1320.0 1.0 "" "" 17.5 9.5 0.99 1.7 3.0 "" "" 0.665 +430 288.0 794.0 35.0 1320.0 1.0 "" "" 56.4 9.5 0.99 1.7 4.0 "" "" 0.265 +431 288.0 692.8 35.0 1320.0 1.0 "" "" 11.1 9.5 0.99 1.7 3.0 "" "" 0.926 +432 288.0 529.2 35.0 1320.0 1.0 "" "" 111.0 9.5 0.99 1.7 2.0 "" "" 0.226 +433 288.0 476.0 35.0 1320.0 1.0 "" "" 12.5 9.5 0.99 1.7 4.0 "" "" 0.458 +434 288.0 439.2 35.0 1320.0 1.0 "" "" 10.9 9.5 0.99 1.7 1.0 "" "" 0.27 +435 288.0 842.2 35.0 1320.0 1.0 "" "" 19.2 9.5 0.99 1.7 1.0 "" "" 0.772 +436 288.0 644.8 35.0 1320.0 1.0 "" "" 26.2 9.5 0.99 1.7 1.0 "" "" 0.709 +437 288.0 389.8 35.0 1320.0 1.0 "" "" 13.5 9.5 0.99 1.7 1.0 "" "" 0.112 +438 288.0 363.0 35.0 1320.0 1.0 "" "" 62.7 9.5 0.99 1.7 0.0 "" "" 0.166 +439 288.0 1050.3 35.0 1320.0 1.0 "" "" 26.1 9.5 0.99 1.7 2.0 "" "" 0.544 +440 288.0 182.9 35.0 1320.0 1.0 "" "" 19.0 9.5 0.99 1.7 1.0 "" "" 0.002 +441 288.0 686.3 35.0 1320.0 1.0 "" "" 13.3 9.5 0.99 1.7 2.0 "" "" 0.151 +442 288.0 335.0 35.0 1320.0 1.0 "" "" 13.5 9.5 0.99 1.7 4.0 "" "" 0.104 +443 288.0 613.8 35.0 1320.0 1.0 "" "" 14.1 9.5 0.99 1.7 3.0 "" "" 0.791 +444 288.0 317.5 35.0 1320.0 1.0 "" "" 11.4 9.5 0.99 1.7 2.0 "" "" 0.274 +445 288.0 427.7 35.0 1320.0 1.0 "" "" 25.2 9.5 0.99 1.7 4.0 "" "" 0.551 +446 288.0 155.8 35.0 1320.0 1.0 "" "" 20.2 9.5 0.99 1.7 4.0 "" "" 0.075 +447 288.0 988.1 35.0 1320.0 1.0 "" "" 13.3 9.5 0.99 1.7 3.0 "" "" 1.024 +448 288.0 256.9 35.0 1320.0 1.0 "" "" 11.8 9.5 0.99 1.7 3.0 "" "" 0.065 +449 288.0 412.3 35.0 1320.0 1.0 "" "" 48.7 9.5 0.99 1.7 2.0 "" "" 0.343 +450 288.0 595.9 35.0 1320.0 1.0 "" "" 69.4 9.5 0.99 1.7 4.0 "" "" 0.255 +451 288.0 210.9 35.0 1320.0 1.0 "" "" 113.3 9.5 0.99 1.7 3.0 "" "" 0.012 +452 288.0 463.7 35.0 1320.0 1.0 "" "" 14.9 9.5 0.99 1.7 2.0 "" "" 0.245 +453 288.0 831.0 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 3.0 "" "" 0.714 +454 288.0 3302.9 35.0 1320.0 1.0 "" "" 10.4 9.5 0.99 1.7 4.0 "" "" 1.408 +455 288.0 924.3 35.0 1320.0 1.0 "" "" 16.5 9.5 0.99 1.7 3.0 "" "" 0.244 +456 288.0 625.2 35.0 1320.0 1.0 "" "" 15.8 9.5 0.99 1.7 3.0 "" "" 0.519 +457 288.0 836.0 35.0 1320.0 1.0 "" "" 28.4 9.5 0.99 1.7 2.0 "" "" 0.497 +458 288.0 1100.8 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 2.0 "" "" 1.079 +459 288.0 380.1 35.0 1320.0 1.0 "" "" 16.6 9.5 0.99 1.7 3.0 "" "" 0.149 +460 288.0 615.4 35.0 1320.0 1.0 "" "" 15.5 9.5 0.99 1.7 2.0 "" "" 0.215 +461 288.0 786.4 35.0 1320.0 1.0 "" "" 77.7 9.5 0.99 1.7 2.0 "" "" 0.364 +462 288.0 460.6 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 2.0 "" "" 0.153 +463 288.0 734.3 35.0 1320.0 1.0 "" "" 14.9 9.5 0.99 1.7 2.0 "" "" 0.393 +464 288.0 1370.5 35.0 1320.0 1.0 "" "" 16.2 9.5 0.99 1.7 2.0 "" "" 0.292 +465 288.0 463.3 35.0 1320.0 1.0 "" "" 13.3 9.5 0.99 1.7 4.0 "" "" 0.344 +466 288.0 250.4 35.0 1320.0 1.0 "" "" 11.0 9.5 0.99 1.7 2.0 "" "" 0.001 +467 288.0 478.9 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 4.0 "" "" 0.471 +468 288.0 164.9 35.0 1320.0 1.0 "" "" 48.7 9.5 0.99 1.7 1.0 "" "" 0.02 +469 288.0 331.3 35.0 1320.0 1.0 "" "" 36.3 9.5 0.99 1.7 3.0 "" "" 0.336 +470 288.0 940.2 35.0 1320.0 1.0 "" "" 18.3 9.5 0.99 1.7 4.0 "" "" 0.651 +471 288.0 740.2 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 2.0 "" "" 0.844 +472 288.0 677.1 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 2.0 "" "" 0.575 +473 288.0 910.6 35.0 1320.0 1.0 "" "" 10.3 9.5 0.99 1.7 2.0 "" "" 0.963 +474 288.0 552.9 35.0 1320.0 1.0 "" "" 13.9 9.5 0.99 1.7 2.0 "" "" 0.287 +475 288.0 342.1 35.0 1320.0 1.0 "" "" 201.4 9.5 0.99 1.7 1.0 "" "" 0.315 +476 288.0 323.7 35.0 1320.0 1.0 "" "" 31.2 9.5 0.99 1.7 2.0 "" "" 0.18 +477 288.0 553.2 35.0 1320.0 1.0 "" "" 29.9 9.5 0.99 1.7 1.0 "" "" 0.354 +478 288.0 541.8 35.0 1320.0 1.0 "" "" 10.2 9.5 0.99 1.7 3.0 "" "" 0.428 +479 288.0 330.2 35.0 1320.0 1.0 "" "" 46.8 9.5 0.99 1.7 2.0 "" "" 0.326 +480 288.0 518.4 35.0 1320.0 1.0 "" "" 18.8 9.5 0.99 1.7 4.0 "" "" 0.364 +481 288.0 381.3 35.0 1320.0 1.0 "" "" 36.2 9.5 0.99 1.7 4.0 "" "" 0.297 +482 288.0 1405.2 35.0 1320.0 1.0 "" "" 15.4 9.5 0.99 1.7 2.0 "" "" 1.059 +483 288.0 282.5 35.0 1320.0 1.0 "" "" 14.5 9.5 0.99 1.7 3.0 "" "" 0.209 +484 288.0 610.2 35.0 1320.0 1.0 "" "" 35.2 9.5 0.99 1.7 3.0 "" "" 0.515 +485 288.0 270.6 35.0 1320.0 1.0 "" "" 14.5 9.5 0.99 1.7 3.0 "" "" 0.323 +486 288.0 375.0 35.0 1320.0 1.0 "" "" 30.8 9.5 0.99 1.7 2.0 "" "" 0.249 +487 288.0 982.7 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 2.0 "" "" 0.836 +488 288.0 248.4 35.0 1320.0 1.0 "" "" 11.2 9.5 0.99 1.7 1.0 "" "" 0.076 +489 288.0 2137.1 35.0 1320.0 1.0 "" "" 15.4 9.5 0.99 1.7 5.0 "" "" 0.049 +490 288.0 423.0 35.0 1320.0 1.0 "" "" 11.5 9.5 0.99 1.7 3.0 "" "" 0.311 +491 288.0 494.6 35.0 1320.0 1.0 "" "" 12.8 9.5 0.99 1.7 3.0 "" "" 0.116 +492 288.0 211.5 35.0 1320.0 1.0 "" "" 12.8 9.5 0.99 1.7 2.0 "" "" 0.145 +493 288.0 871.3 35.0 1320.0 1.0 "" "" 25.3 9.5 0.99 1.7 5.0 "" "" 0.917 +494 288.0 864.6 35.0 1320.0 1.0 "" "" 10.3 9.5 0.99 1.7 3.0 "" "" 0.557 +495 288.0 960.7 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 2.0 "" "" 0.209 +496 288.0 377.2 35.0 1320.0 1.0 "" "" 136.5 9.5 0.99 1.7 2.0 "" "" 0.223 +497 288.0 420.1 35.0 1320.0 1.0 "" "" 14.1 9.5 0.99 1.7 2.0 "" "" 0.275 +498 288.0 212.0 35.0 1320.0 1.0 "" "" 11.5 9.5 0.99 1.7 4.0 "" "" 0.022 +499 288.0 301.6 35.0 1320.0 1.0 "" "" 9.6 9.5 0.99 1.7 0.0 "" "" 0.172 +500 288.0 892.1 35.0 1320.0 1.0 "" "" 17.3 9.5 0.99 1.7 3.0 "" "" 1.031 +501 288.0 491.5 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 2.0 "" "" 0.193 +502 288.0 391.7 35.0 1320.0 1.0 "" "" 23.1 9.5 0.99 1.7 2.0 "" "" 0.071 +503 288.0 435.7 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 2.0 "" "" 0.336 +504 288.0 232.4 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 4.0 "" "" 0.003 +505 288.0 148.3 35.0 1320.0 1.0 "" "" 410.7 9.5 0.99 1.7 3.0 "" "" 0.051 +506 288.0 604.8 35.0 1320.0 1.0 "" "" 10.9 9.5 0.99 1.7 1.0 "" "" 0.845 +507 288.0 367.8 35.0 1320.0 1.0 "" "" 15.0 9.5 0.99 1.7 3.0 "" "" 0.316 +508 288.0 491.2 35.0 1320.0 1.0 "" "" 24.1 9.5 0.99 1.7 0.0 "" "" 0.59 +509 288.0 1014.1 35.0 1320.0 1.0 "" "" 16.1 9.5 0.99 1.7 4.0 "" "" 0.332 +510 288.0 1117.8 35.0 1320.0 1.0 "" "" 11.4 9.5 0.99 1.7 3.0 "" "" 0.924 +511 288.0 472.8 35.0 1320.0 1.0 "" "" 16.1 9.5 0.99 1.7 4.0 "" "" 0.554 +512 288.0 642.9 35.0 1320.0 1.0 "" "" 11.8 9.5 0.99 1.7 2.0 "" "" 0.43 +513 288.0 208.0 35.0 1320.0 1.0 "" "" 17.9 9.5 0.99 1.7 2.0 "" "" 0.152 +514 288.0 783.0 35.0 1320.0 1.0 "" "" 12.7 9.5 0.99 1.7 3.0 "" "" 0.93 +515 288.0 869.7 35.0 1320.0 1.0 "" "" 23.6 9.5 0.99 1.7 2.0 "" "" 0.328 +516 288.0 274.3 35.0 1320.0 1.0 "" "" 13.0 9.5 0.99 1.7 4.0 "" "" 0.25 +517 288.0 458.5 35.0 1320.0 1.0 "" "" 12.5 9.5 0.99 1.7 4.0 "" "" 0.546 +518 288.0 1750.0 35.0 1320.0 1.0 "" "" 10.2 9.5 0.99 1.7 1.0 "" "" 0.991 +519 288.0 1113.0 35.0 1320.0 1.0 "" "" 14.2 9.5 0.99 1.7 2.0 "" "" 1.267 +520 288.0 257.2 35.0 1320.0 1.0 "" "" 13.4 9.5 0.99 1.7 2.0 "" "" 0.002 +521 288.0 1075.0 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 3.0 "" "" 0.055 +522 288.0 313.5 35.0 1320.0 1.0 "" "" 13.5 9.5 0.99 1.7 4.0 "" "" 0.077 +523 288.0 527.0 35.0 1320.0 1.0 "" "" 10.9 9.5 0.99 1.7 3.0 "" "" 0.442 +524 288.0 549.7 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 1.0 "" "" 0.25 +525 288.0 990.7 35.0 1320.0 1.0 "" "" 60.2 9.5 0.99 1.7 2.0 "" "" 0.987 +526 288.0 446.0 35.0 1320.0 1.0 "" "" 32.2 9.5 0.99 1.7 1.0 "" "" 0.548 +527 288.0 398.9 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 3.0 "" "" 0.42 +528 288.0 257.7 35.0 1320.0 1.0 "" "" 42.6 9.5 0.99 1.7 1.0 "" "" 0.206 +529 288.0 413.9 35.0 1320.0 1.0 "" "" 88.2 9.5 0.99 1.7 2.0 "" "" 0.428 +530 288.0 455.6 35.0 1320.0 1.0 "" "" 15.1 9.5 0.99 1.7 4.0 "" "" 0.043 +531 288.0 346.0 35.0 1320.0 1.0 "" "" 268.1 9.5 0.99 1.7 3.0 "" "" 0.136 +532 288.0 587.8 35.0 1320.0 1.0 "" "" 45.8 9.5 0.99 1.7 2.0 "" "" 0.44 +533 288.0 343.5 35.0 1320.0 1.0 "" "" 56.1 9.5 0.99 1.7 3.0 "" "" 0.357 +534 288.0 1243.0 35.0 1320.0 1.0 "" "" 13.7 9.5 0.99 1.7 1.0 "" "" 1.553 +535 288.0 483.7 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 3.0 "" "" 0.426 +536 288.0 471.1 35.0 1320.0 1.0 "" "" 17.0 9.5 0.99 1.7 3.0 "" "" 0.429 +537 288.0 269.3 35.0 1320.0 1.0 "" "" 20.6 9.5 0.99 1.7 1.0 "" "" 0.267 +538 288.0 242.4 35.0 1320.0 1.0 "" "" 12.8 9.5 0.99 1.7 3.0 "" "" 0.066 +539 288.0 1627.4 35.0 1320.0 1.0 "" "" 13.3 9.5 0.99 1.7 2.0 "" "" 1.156 +540 288.0 562.4 35.0 1320.0 1.0 "" "" 24.3 9.5 0.99 1.7 2.0 "" "" 0.595 +541 288.0 125.9 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 1.0 "" "" 0.025 +542 288.0 1062.3 35.0 1320.0 1.0 "" "" 31.0 9.5 0.99 1.7 3.0 "" "" 1.306 +543 288.0 366.7 35.0 1320.0 1.0 "" "" 13.0 9.5 0.99 1.7 2.0 "" "" 0.433 +544 288.0 814.9 35.0 1320.0 1.0 "" "" 13.7 9.5 0.99 1.7 3.0 "" "" 0.752 +545 288.0 124.3 35.0 1320.0 1.0 "" "" 14.8 9.5 0.99 1.7 4.0 "" "" 0.046 +546 288.0 431.5 35.0 1320.0 1.0 "" "" 12.5 9.5 0.99 1.7 2.0 "" "" 0.041 +547 288.0 312.5 35.0 1320.0 1.0 "" "" 18.6 9.5 0.99 1.7 1.0 "" "" 0.17 +548 288.0 720.7 35.0 1320.0 1.0 "" "" 26.7 9.5 0.99 1.7 2.0 "" "" 0.329 +549 288.0 537.4 35.0 1320.0 1.0 "" "" 23.5 9.5 0.99 1.7 2.0 "" "" 0.321 +550 288.0 437.0 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 3.0 "" "" 0.403 +551 288.0 443.4 35.0 1320.0 1.0 "" "" 28.3 9.5 0.99 1.7 2.0 "" "" 0.39 +552 288.0 585.0 35.0 1320.0 1.0 "" "" 19.9 9.5 0.99 1.7 1.0 "" "" 0.368 +553 288.0 811.8 35.0 1320.0 1.0 "" "" 16.2 9.5 0.99 1.7 3.0 "" "" 0.789 +554 288.0 608.4 35.0 1320.0 1.0 "" "" 21.8 9.5 0.99 1.7 2.0 "" "" 0.389 +555 288.0 281.2 35.0 1320.0 1.0 "" "" 17.0 9.5 0.99 1.7 3.0 "" "" 0.099 +556 288.0 594.1 35.0 1320.0 1.0 "" "" 13.5 9.5 0.99 1.7 4.0 "" "" 0.145 +557 288.0 329.8 35.0 1320.0 1.0 "" "" 33.1 9.5 0.99 1.7 3.0 "" "" 0.282 +558 288.0 593.5 35.0 1320.0 1.0 "" "" 61.8 9.5 0.99 1.7 1.0 "" "" 0.7 +559 288.0 1161.1 35.0 1320.0 1.0 "" "" 12.8 9.5 0.99 1.7 2.0 "" "" 0.899 +560 288.0 290.6 35.0 1320.0 1.0 "" "" 29.3 9.5 0.99 1.7 2.0 "" "" 0.026 +561 288.0 416.8 35.0 1320.0 1.0 "" "" 25.7 9.5 0.99 1.7 3.0 "" "" 0.419 +562 288.0 1513.6 35.0 1320.0 1.0 "" "" 16.6 9.5 0.99 1.7 3.0 "" "" 0.275 +563 288.0 408.6 35.0 1320.0 1.0 "" "" 41.7 9.5 0.99 1.7 2.0 "" "" 0.386 +564 288.0 1315.3 35.0 1320.0 1.0 "" "" 36.9 9.5 0.99 1.7 3.0 "" "" 1.159 +565 288.0 446.2 35.0 1320.0 1.0 "" "" 13.4 9.5 0.99 1.7 1.0 "" "" 0.158 +566 288.0 298.4 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 2.0 "" "" 0.207 +567 288.0 721.1 35.0 1320.0 1.0 "" "" 67.3 9.5 0.99 1.7 2.0 "" "" 0.351 +568 288.0 184.3 35.0 1320.0 1.0 "" "" 171.1 9.5 0.99 1.7 2.0 "" "" 0.036 +569 288.0 129.6 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 1.0 "" "" 0.097 +570 288.0 624.8 35.0 1320.0 1.0 "" "" 132.1 9.5 0.99 1.7 2.0 "" "" 0.15 +571 288.0 1829.0 35.0 1320.0 1.0 "" "" 22.9 9.5 0.99 1.7 3.0 "" "" 1.818 +572 288.0 438.5 35.0 1320.0 1.0 "" "" 183.6 9.5 0.99 1.7 3.0 "" "" 0.205 +573 288.0 1390.3 35.0 1320.0 1.0 "" "" 16.4 9.5 0.99 1.7 1.0 "" "" 1.05 +574 288.0 829.0 35.0 1320.0 1.0 "" "" 20.2 9.5 0.99 1.7 4.0 "" "" 0.253 +575 288.0 771.9 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 1.0 "" "" 0.675 +576 288.0 575.5 35.0 1320.0 1.0 "" "" 40.1 9.5 0.99 1.7 3.0 "" "" 0.693 +577 288.0 282.4 35.0 1320.0 1.0 "" "" 17.0 9.5 0.99 1.7 2.0 "" "" 0.14 +578 288.0 166.3 35.0 1320.0 1.0 "" "" 11.0 9.5 0.99 1.7 3.0 "" "" 0.18 +579 288.0 390.1 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 1.0 "" "" 0.124 +580 288.0 518.5 35.0 1320.0 1.0 "" "" 67.6 9.5 0.99 1.7 2.0 "" "" 0.476 +581 288.0 485.0 35.0 1320.0 1.0 "" "" 14.9 9.5 0.99 1.7 5.0 "" "" 0.047 +582 288.0 1440.3 35.0 1320.0 1.0 "" "" 18.3 9.5 0.99 1.7 2.0 "" "" 1.788 +583 288.0 648.5 35.0 1320.0 1.0 "" "" 21.9 9.5 0.99 1.7 2.0 "" "" 0.519 +584 288.0 732.4 35.0 1320.0 1.0 "" "" 14.0 9.5 0.99 1.7 3.0 "" "" 0.514 +585 288.0 498.6 35.0 1320.0 1.0 "" "" 15.4 9.5 0.99 1.7 2.0 "" "" 0.257 +586 288.0 1418.2 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 4.0 "" "" 0.02 +587 288.0 510.3 35.0 1320.0 1.0 "" "" 12.5 9.5 0.99 1.7 1.0 "" "" 0.508 +588 288.0 641.0 35.0 1320.0 1.0 "" "" 58.8 9.5 0.99 1.7 4.0 "" "" 0.536 +589 288.0 176.0 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 3.0 "" "" 0.032 +590 288.0 515.8 35.0 1320.0 1.0 "" "" 13.9 9.5 0.99 1.7 1.0 "" "" 0.441 +591 288.0 131.3 35.0 1320.0 1.0 "" "" 151.3 9.5 0.99 1.7 1.0 "" "" 0.04 +592 288.0 437.2 35.0 1320.0 1.0 "" "" 62.6 9.5 0.99 1.7 2.0 "" "" 0.449 +593 288.0 175.1 35.0 1320.0 1.0 "" "" 289.1 9.5 0.99 1.7 2.0 "" "" 0.151 +594 288.0 702.0 35.0 1320.0 1.0 "" "" 12.5 9.5 0.99 1.7 3.0 "" "" 0.526 +595 288.0 1701.6 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 2.0 "" "" 1.675 +596 288.0 459.8 35.0 1320.0 1.0 "" "" 13.7 9.5 0.99 1.7 2.0 "" "" 0.572 +597 288.0 2375.3 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 3.0 "" "" 2.793 +598 288.0 445.5 35.0 1320.0 1.0 "" "" 17.7 9.5 0.99 1.7 2.0 "" "" 0.209 +599 288.0 199.4 35.0 1320.0 1.0 "" "" 20.1 9.5 0.99 1.7 2.0 "" "" 0.122 +600 288.0 1155.0 35.0 1320.0 1.0 "" "" 16.3 9.5 0.99 1.7 2.0 "" "" 0.493 +601 288.0 292.6 35.0 1320.0 1.0 "" "" 27.7 9.5 0.99 1.7 3.0 "" "" 0.101 +602 288.0 410.7 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 2.0 "" "" 0.242 +603 288.0 192.1 35.0 1320.0 1.0 "" "" 18.4 9.5 0.99 1.7 4.0 "" "" 0.126 +604 288.0 373.7 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 3.0 "" "" 0.031 +605 288.0 722.7 35.0 1320.0 1.0 "" "" 13.5 9.5 0.99 1.7 5.0 "" "" 0.574 +606 288.0 915.4 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 3.0 "" "" 0.87 +607 288.0 343.0 35.0 1320.0 1.0 "" "" 13.8 9.5 0.99 1.7 3.0 "" "" 0.287 +608 288.0 127.5 35.0 1320.0 1.0 "" "" 15.8 9.5 0.99 1.7 2.0 "" "" 0.055 +609 288.0 771.3 35.0 1320.0 1.0 "" "" 23.1 9.5 0.99 1.7 3.0 "" "" 0.987 +610 288.0 506.2 35.0 1320.0 1.0 "" "" 18.4 9.5 0.99 1.7 3.0 "" "" 0.501 +611 288.0 607.9 35.0 1320.0 1.0 "" "" 27.8 9.5 0.99 1.7 2.0 "" "" 0.242 +612 288.0 975.2 35.0 1320.0 1.0 "" "" 34.8 9.5 0.99 1.7 1.0 "" "" 0.981 +613 288.0 592.0 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 2.0 "" "" 0.018 +614 288.0 653.4 35.0 1320.0 1.0 "" "" 25.1 9.5 0.99 1.7 2.0 "" "" 0.476 +615 288.0 843.6 35.0 1320.0 1.0 "" "" 10.4 9.5 0.99 1.7 3.0 "" "" 1.086 +616 288.0 348.3 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 3.0 "" "" 0.181 +617 288.0 185.9 35.0 1320.0 1.0 "" "" 24.8 9.5 0.99 1.7 3.0 "" "" 0.118 +618 288.0 1906.7 35.0 1320.0 1.0 "" "" 13.0 9.5 0.99 1.7 2.0 "" "" 1.795 +619 288.0 237.6 35.0 1320.0 1.0 "" "" 27.8 9.5 0.99 1.7 1.0 "" "" 0.184 +620 288.0 267.9 35.0 1320.0 1.0 "" "" 58.0 9.5 0.99 1.7 3.0 "" "" 0.116 +621 288.0 406.6 35.0 1320.0 1.0 "" "" 15.0 9.5 0.99 1.7 3.0 "" "" 0.415 +622 288.0 430.5 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 3.0 "" "" 0.455 +623 288.0 1150.5 35.0 1320.0 1.0 "" "" 16.7 9.5 0.99 1.7 3.0 "" "" 0.369 +624 288.0 383.2 35.0 1320.0 1.0 "" "" 15.8 9.5 0.99 1.7 3.0 "" "" 0.175 +625 288.0 671.0 35.0 1320.0 1.0 "" "" 20.1 9.5 0.99 1.7 3.0 "" "" 0.894 +626 288.0 372.8 35.0 1320.0 1.0 "" "" 14.0 9.5 0.99 1.7 2.0 "" "" 0.102 +627 288.0 888.9 35.0 1320.0 1.0 "" "" 12.9 9.5 0.99 1.7 3.0 "" "" 0.032 +628 288.0 1052.2 35.0 1320.0 1.0 "" "" 26.5 9.5 0.99 1.7 2.0 "" "" 1.371 +629 288.0 1023.3 35.0 1320.0 1.0 "" "" 21.5 9.5 0.99 1.7 1.0 "" "" 1.418 +630 288.0 281.3 35.0 1320.0 1.0 "" "" 25.2 9.5 0.99 1.7 4.0 "" "" 0.041 +631 288.0 238.1 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 2.0 "" "" 0.251 +632 288.0 552.2 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 3.0 "" "" 0.562 +633 288.0 558.2 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 3.0 "" "" 0.484 +634 288.0 337.6 35.0 1320.0 1.0 "" "" 22.0 9.5 0.99 1.7 1.0 "" "" 0.08 +635 288.0 295.2 35.0 1320.0 1.0 "" "" 11.4 9.5 0.99 1.7 3.0 "" "" 0.209 +636 288.0 575.8 35.0 1320.0 1.0 "" "" 10.4 9.5 0.99 1.7 2.0 "" "" 0.189 +637 288.0 375.9 35.0 1320.0 1.0 "" "" 14.7 9.5 0.99 1.7 1.0 "" "" 0.064 +638 288.0 129.2 35.0 1320.0 1.0 "" "" 24.3 9.5 0.99 1.7 2.0 "" "" 0.073 +639 288.0 198.3 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 0.0 "" "" 0.058 +640 288.0 445.5 35.0 1320.0 1.0 "" "" 87.9 9.5 0.99 1.7 1.0 "" "" 0.33 +641 288.0 215.9 35.0 1320.0 1.0 "" "" 35.2 9.5 0.99 1.7 1.0 "" "" 0.114 +642 288.0 212.4 35.0 1320.0 1.0 "" "" 16.9 9.5 0.99 1.7 3.0 "" "" 0.084 +643 288.0 1228.4 35.0 1320.0 1.0 "" "" 13.0 9.5 0.99 1.7 3.0 "" "" 1.305 +644 288.0 578.5 35.0 1320.0 1.0 "" "" 11.5 9.5 0.99 1.7 1.0 "" "" 0.149 +645 288.0 706.3 35.0 1320.0 1.0 "" "" 39.2 9.5 0.99 1.7 1.0 "" "" 0.794 +646 288.0 597.8 35.0 1320.0 1.0 "" "" 38.6 9.5 0.99 1.7 3.0 "" "" 0.536 +647 288.0 283.6 35.0 1320.0 1.0 "" "" 14.3 9.5 0.99 1.7 2.0 "" "" 0.195 +648 288.0 2236.7 35.0 1320.0 1.0 "" "" 20.4 9.5 0.99 1.7 2.0 "" "" 1.327 +649 288.0 694.4 35.0 1320.0 1.0 "" "" 15.4 9.5 0.99 1.7 4.0 "" "" 0.099 +650 288.0 213.5 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 3.0 "" "" 0.136 +651 288.0 961.6 35.0 1320.0 1.0 "" "" 28.1 9.5 0.99 1.7 2.0 "" "" 0.475 +652 288.0 801.4 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 2.0 "" "" 0.818 +653 288.0 396.1 35.0 1320.0 1.0 "" "" 22.6 9.5 0.99 1.7 4.0 "" "" 0.233 +654 288.0 1093.6 35.0 1320.0 1.0 "" "" 10.9 9.5 0.99 1.7 3.0 "" "" 0.806 +655 288.0 493.6 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 1.0 "" "" 0.322 +656 288.0 518.1 35.0 1320.0 1.0 "" "" 14.7 9.5 0.99 1.7 3.0 "" "" 0.52 +657 288.0 478.0 35.0 1320.0 1.0 "" "" 16.7 9.5 0.99 1.7 4.0 "" "" 0.094 +658 288.0 242.1 35.0 1320.0 1.0 "" "" 139.7 9.5 0.99 1.7 3.0 "" "" 0.098 +659 288.0 261.7 35.0 1320.0 1.0 "" "" 43.3 9.5 0.99 1.7 3.0 "" "" 0.142 +660 288.0 443.3 35.0 1320.0 1.0 "" "" 11.6 9.5 0.99 1.7 2.0 "" "" 0.042 +661 288.0 1386.8 35.0 1320.0 1.0 "" "" 26.7 9.5 0.99 1.7 3.0 "" "" 0.544 +662 288.0 475.0 35.0 1320.0 1.0 "" "" 22.0 9.5 0.99 1.7 1.0 "" "" 0.228 +663 288.0 545.5 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 3.0 "" "" 0.709 +664 288.0 220.1 35.0 1320.0 1.0 "" "" 21.6 9.5 0.99 1.7 2.0 "" "" 0.093 +665 288.0 809.9 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 2.0 "" "" 0.829 +666 288.0 358.1 35.0 1320.0 1.0 "" "" 14.5 9.5 0.99 1.7 1.0 "" "" 0.122 +667 288.0 842.0 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 3.0 "" "" 0.323 +668 288.0 1395.1 35.0 1320.0 1.0 "" "" 11.5 9.5 0.99 1.7 4.0 "" "" 0.441 +669 288.0 732.5 35.0 1320.0 1.0 "" "" 42.3 9.5 0.99 1.7 3.0 "" "" 0.612 +670 288.0 423.2 35.0 1320.0 1.0 "" "" 15.5 9.5 0.99 1.7 2.0 "" "" 0.322 +671 288.0 1328.1 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 1.0 "" "" 0.927 +672 288.0 530.2 35.0 1320.0 1.0 "" "" 13.2 9.5 0.99 1.7 2.0 "" "" 0.49 +673 288.0 1584.2 35.0 1320.0 1.0 "" "" 15.0 9.5 0.99 1.7 3.0 "" "" 1.705 +674 288.0 147.1 35.0 1320.0 1.0 "" "" 15.8 9.5 0.99 1.7 2.0 "" "" 0.047 +675 288.0 726.1 35.0 1320.0 1.0 "" "" 16.9 9.5 0.99 1.7 3.0 "" "" 0.903 +676 288.0 346.6 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 4.0 "" "" 0.028 +677 288.0 1399.0 35.0 1320.0 1.0 "" "" 15.0 9.5 0.99 1.7 3.0 "" "" 1.447 +678 288.0 884.5 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 3.0 "" "" 1.112 +679 288.0 1032.9 35.0 1320.0 1.0 "" "" 23.1 9.5 0.99 1.7 2.0 "" "" 1.183 +680 288.0 182.6 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 1.0 "" "" 0.056 +681 288.0 1051.2 35.0 1320.0 1.0 "" "" 10.4 9.5 0.99 1.7 2.0 "" "" 1.131 +682 288.0 1485.1 35.0 1320.0 1.0 "" "" 13.5 9.5 0.99 1.7 3.0 "" "" 1.608 +683 288.0 299.7 35.0 1320.0 1.0 "" "" 17.1 9.5 0.99 1.7 5.0 "" "" 0.15 +684 288.0 395.2 35.0 1320.0 1.0 "" "" 13.2 9.5 0.99 1.7 3.0 "" "" 0.229 +685 288.0 517.8 35.0 1320.0 1.0 "" "" 23.0 9.5 0.99 1.7 1.0 "" "" 0.276 +686 288.0 356.1 35.0 1320.0 1.0 "" "" 18.7 9.5 0.99 1.7 3.0 "" "" 0.325 +687 288.0 368.5 35.0 1320.0 1.0 "" "" 54.5 9.5 0.99 1.7 1.0 "" "" 0.25 +688 288.0 277.4 35.0 1320.0 1.0 "" "" 18.4 9.5 0.99 1.7 2.0 "" "" 0.303 +689 288.0 644.6 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 2.0 "" "" 0.764 +690 288.0 1221.8 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 4.0 "" "" 0.005 +691 288.0 422.4 35.0 1320.0 1.0 "" "" 14.3 9.5 0.99 1.7 3.0 "" "" 0.321 +692 288.0 374.0 35.0 1320.0 1.0 "" "" 53.2 9.5 0.99 1.7 1.0 "" "" 0.4 +693 288.0 422.3 35.0 1320.0 1.0 "" "" 42.6 9.5 0.99 1.7 3.0 "" "" 0.245 +694 288.0 283.2 35.0 1320.0 1.0 "" "" 15.3 9.5 0.99 1.7 2.0 "" "" 0.327 +695 288.0 1116.8 35.0 1320.0 1.0 "" "" 39.6 9.5 0.99 1.7 4.0 "" "" 0.638 +696 288.0 408.3 35.0 1320.0 1.0 "" "" 10.9 9.5 0.99 1.7 2.0 "" "" 0.353 +697 288.0 296.8 35.0 1320.0 1.0 "" "" 30.9 9.5 0.99 1.7 4.0 "" "" 0.026 +698 288.0 294.1 35.0 1320.0 1.0 "" "" 22.3 9.5 0.99 1.7 2.0 "" "" 0.119 +699 288.0 385.7 35.0 1320.0 1.0 "" "" 68.5 9.5 0.99 1.7 2.0 "" "" 0.272 +700 288.0 351.1 35.0 1320.0 1.0 "" "" 15.3 9.5 0.99 1.7 1.0 "" "" 0.216 +701 288.0 189.6 35.0 1320.0 1.0 "" "" 13.8 9.5 0.99 1.7 2.0 "" "" 0.042 +702 288.0 180.7 35.0 1320.0 1.0 "" "" 11.0 9.5 0.99 1.7 2.0 "" "" 0.136 +703 288.0 653.5 35.0 1320.0 1.0 "" "" 11.2 9.5 0.99 1.7 4.0 "" "" 0.285 +704 288.0 779.7 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 2.0 "" "" 1.103 +705 288.0 217.9 35.0 1320.0 1.0 "" "" 15.9 9.5 0.99 1.7 1.0 "" "" 0.018 +706 288.0 185.0 35.0 1320.0 1.0 "" "" 34.9 9.5 0.99 1.7 2.0 "" "" 0.092 +707 288.0 439.6 35.0 1320.0 1.0 "" "" 41.0 9.5 0.99 1.7 3.0 "" "" 0.427 +708 288.0 623.7 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 3.0 "" "" 0.238 +709 288.0 450.0 35.0 1320.0 1.0 "" "" 11.7 9.5 0.99 1.7 3.0 "" "" 0.267 +710 288.0 893.3 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 3.0 "" "" 1.138 +711 288.0 414.6 35.0 1320.0 1.0 "" "" 37.3 9.5 0.99 1.7 3.0 "" "" 0.323 +712 288.0 851.4 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 3.0 "" "" 0.832 +713 288.0 214.4 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 2.0 "" "" 0.069 +714 288.0 611.7 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 2.0 "" "" 0.485 +715 288.0 301.7 35.0 1320.0 1.0 "" "" 21.8 9.5 0.99 1.7 2.0 "" "" 0.112 +716 288.0 761.3 35.0 1320.0 1.0 "" "" 11.8 9.5 0.99 1.7 1.0 "" "" 0.537 +717 288.0 309.8 35.0 1320.0 1.0 "" "" 14.8 9.5 0.99 1.7 2.0 "" "" 0.138 +718 288.0 697.6 35.0 1320.0 1.0 "" "" 35.4 9.5 0.99 1.7 1.0 "" "" 0.334 +719 288.0 185.1 35.0 1320.0 1.0 "" "" 11.1 9.5 0.99 1.7 3.0 "" "" 0.131 +720 288.0 1456.7 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 1.0 "" "" 1.606 +721 288.0 138.2 35.0 1320.0 1.0 "" "" 9.5 9.5 0.99 1.7 1.0 "" "" 0.032 +722 288.0 163.7 35.0 1320.0 1.0 "" "" 50.7 9.5 0.99 1.7 1.0 "" "" 0.034 +723 288.0 308.7 35.0 1320.0 1.0 "" "" 29.4 9.5 0.99 1.7 2.0 "" "" 0.345 +724 288.0 582.7 35.0 1320.0 1.0 "" "" 9.5 9.5 0.99 1.7 3.0 "" "" 0.376 +725 288.0 771.6 35.0 1320.0 1.0 "" "" 16.4 9.5 0.99 1.7 1.0 "" "" 0.037 +726 288.0 483.9 35.0 1320.0 1.0 "" "" 21.6 9.5 0.99 1.7 3.0 "" "" 0.387 +727 288.0 951.5 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 4.0 "" "" 0.402 +728 288.0 225.3 35.0 1320.0 1.0 "" "" 12.7 9.5 0.99 1.7 1.0 "" "" 0.049 +729 288.0 561.8 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 3.0 "" "" 0.32 +730 288.0 603.7 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 2.0 "" "" 0.743 +731 288.0 1044.5 35.0 1320.0 1.0 "" "" 15.8 9.5 0.99 1.7 3.0 "" "" 0.675 +732 288.0 409.1 35.0 1320.0 1.0 "" "" 13.4 9.5 0.99 1.7 2.0 "" "" 0.256 +733 288.0 341.3 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 3.0 "" "" 0.098 +734 288.0 1638.5 35.0 1320.0 1.0 "" "" 88.3 9.5 0.99 1.7 2.0 "" "" 0.205 +735 288.0 443.9 35.0 1320.0 1.0 "" "" 49.0 9.5 0.99 1.7 4.0 "" "" 0.132 +736 288.0 490.6 35.0 1320.0 1.0 "" "" 18.0 9.5 0.99 1.7 2.0 "" "" 0.501 +737 288.0 420.7 35.0 1320.0 1.0 "" "" 18.0 9.5 0.99 1.7 3.0 "" "" 0.119 +738 288.0 686.3 35.0 1320.0 1.0 "" "" 15.7 9.5 0.99 1.7 3.0 "" "" 0.417 +739 288.0 767.1 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 1.0 "" "" 0.48 +740 288.0 475.7 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 3.0 "" "" 0.527 +741 288.0 1537.6 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 3.0 "" "" 0.862 +742 288.0 195.3 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 2.0 "" "" 0.168 +743 288.0 619.2 35.0 1320.0 1.0 "" "" 39.1 9.5 0.99 1.7 3.0 "" "" 0.673 +744 288.0 162.7 35.0 1320.0 1.0 "" "" 62.5 9.5 0.99 1.7 3.0 "" "" 0.04 +745 288.0 1006.0 35.0 1320.0 1.0 "" "" 16.0 9.5 0.99 1.7 4.0 "" "" 0.137 +746 288.0 358.5 35.0 1320.0 1.0 "" "" 112.9 9.5 0.99 1.7 2.0 "" "" 0.096 +747 288.0 560.2 35.0 1320.0 1.0 "" "" 10.7 9.5 0.99 1.7 4.0 "" "" 0.201 +748 288.0 690.6 35.0 1320.0 1.0 "" "" 25.1 9.5 0.99 1.7 4.0 "" "" 0.668 +749 288.0 654.1 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 2.0 "" "" 0.565 +750 288.0 692.5 35.0 1320.0 1.0 "" "" 16.8 9.5 0.99 1.7 1.0 "" "" 0.083 +751 288.0 396.5 35.0 1320.0 1.0 "" "" 29.3 9.5 0.99 1.7 4.0 "" "" 0.229 +752 288.0 223.3 35.0 1320.0 1.0 "" "" 78.2 9.5 0.99 1.7 2.0 "" "" 0.12 +753 288.0 483.5 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 3.0 "" "" 0.427 +754 288.0 937.4 35.0 1320.0 1.0 "" "" 29.9 9.5 0.99 1.7 2.0 "" "" 1.326 +755 288.0 188.5 35.0 1320.0 1.0 "" "" 18.9 9.5 0.99 1.7 2.0 "" "" 0.138 +756 288.0 529.8 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 1.0 "" "" 0.512 +757 288.0 196.3 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 3.0 "" "" 0.177 +758 288.0 489.6 35.0 1320.0 1.0 "" "" 159.3 9.5 0.99 1.7 1.0 "" "" 0.501 +759 288.0 527.5 35.0 1320.0 1.0 "" "" 25.6 9.5 0.99 1.7 4.0 "" "" 0.202 +760 288.0 544.7 35.0 1320.0 1.0 "" "" 22.5 9.5 0.99 1.7 3.0 "" "" 0.613 +761 288.0 306.1 35.0 1320.0 1.0 "" "" 13.8 9.5 0.99 1.7 1.0 "" "" 0.292 +762 288.0 650.9 35.0 1320.0 1.0 "" "" 50.7 9.5 0.99 1.7 3.0 "" "" 0.731 +763 288.0 478.2 35.0 1320.0 1.0 "" "" 10.7 9.5 0.99 1.7 5.0 "" "" 0.052 +764 288.0 190.9 35.0 1320.0 1.0 "" "" 9.8 9.5 0.99 1.7 4.0 "" "" 0.113 +765 288.0 1307.3 35.0 1320.0 1.0 "" "" 20.9 9.5 0.99 1.7 2.0 "" "" 1.913 +766 288.0 1313.0 35.0 1320.0 1.0 "" "" 23.7 9.5 0.99 1.7 3.0 "" "" 0.787 +767 288.0 408.8 35.0 1320.0 1.0 "" "" 78.2 9.5 0.99 1.7 5.0 "" "" 0.145 +768 288.0 831.6 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 3.0 "" "" 0.165 +769 288.0 664.2 35.0 1320.0 1.0 "" "" 11.4 9.5 0.99 1.7 1.0 "" "" 0.595 +770 288.0 259.1 35.0 1320.0 1.0 "" "" 120.2 9.5 0.99 1.7 4.0 "" "" 0.093 +771 288.0 310.4 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 4.0 "" "" 0.199 +772 288.0 962.8 35.0 1320.0 1.0 "" "" 11.5 9.5 0.99 1.7 4.0 "" "" 0.919 +773 288.0 830.4 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 3.0 "" "" 1.007 +774 288.0 855.0 35.0 1320.0 1.0 "" "" 27.6 9.5 0.99 1.7 4.0 "" "" 0.619 +775 288.0 324.6 35.0 1320.0 1.0 "" "" 127.6 9.5 0.99 1.7 3.0 "" "" 0.248 +776 288.0 596.0 35.0 1320.0 1.0 "" "" 20.0 9.5 0.99 1.7 3.0 "" "" 0.5 +777 288.0 533.7 35.0 1320.0 1.0 "" "" 18.4 9.5 0.99 1.7 2.0 "" "" 0.304 +778 288.0 1653.2 35.0 1320.0 1.0 "" "" 10.7 9.5 0.99 1.7 1.0 "" "" 0.729 +779 288.0 662.3 35.0 1320.0 1.0 "" "" 11.8 9.5 0.99 1.7 3.0 "" "" 0.807 +780 288.0 410.8 35.0 1320.0 1.0 "" "" 72.7 9.5 0.99 1.7 3.0 "" "" 0.014 +781 288.0 856.2 35.0 1320.0 1.0 "" "" 18.5 9.5 0.99 1.7 2.0 "" "" 0.959 +782 288.0 364.5 35.0 1320.0 1.0 "" "" 34.6 9.5 0.99 1.7 1.0 "" "" 0.222 +783 288.0 486.6 35.0 1320.0 1.0 "" "" 10.2 9.5 0.99 1.7 3.0 "" "" 0.508 +784 288.0 362.0 35.0 1320.0 1.0 "" "" 27.8 9.5 0.99 1.7 3.0 "" "" 0.193 +785 288.0 1218.0 35.0 1320.0 1.0 "" "" 19.0 9.5 0.99 1.7 2.0 "" "" 1.56 +786 288.0 1109.0 35.0 1320.0 1.0 "" "" 24.5 9.5 0.99 1.7 4.0 "" "" 1.042 +787 288.0 1330.3 35.0 1320.0 1.0 "" "" 11.2 9.5 0.99 1.7 2.0 "" "" 1.535 +788 288.0 834.8 35.0 1320.0 1.0 "" "" 13.6 9.5 0.99 1.7 4.0 "" "" 0.782 +789 288.0 181.3 35.0 1320.0 1.0 "" "" 34.9 9.5 0.99 1.7 4.0 "" "" 0.073 +790 288.0 538.9 35.0 1320.0 1.0 "" "" 24.6 9.5 0.99 1.7 2.0 "" "" 0.439 +791 288.0 492.1 35.0 1320.0 1.0 "" "" 14.2 9.5 0.99 1.7 2.0 "" "" 0.527 +792 288.0 176.4 35.0 1320.0 1.0 "" "" 16.5 9.5 0.99 1.7 4.0 "" "" 0.106 +793 288.0 427.2 35.0 1320.0 1.0 "" "" 13.3 9.5 0.99 1.7 3.0 "" "" 0.02 +794 288.0 307.4 35.0 1320.0 1.0 "" "" 31.0 9.5 0.99 1.7 2.0 "" "" 0.06 +795 288.0 210.7 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 2.0 "" "" 0.015 +796 288.0 1031.6 35.0 1320.0 1.0 "" "" 12.8 9.5 0.99 1.7 3.0 "" "" 0.079 +797 288.0 1439.8 35.0 1320.0 1.0 "" "" 390.0 9.5 0.99 1.7 2.0 "" "" 0.276 +798 288.0 205.5 35.0 1320.0 1.0 "" "" 424.9 9.5 0.99 1.7 2.0 "" "" 0.044 +799 288.0 335.2 35.0 1320.0 1.0 "" "" 81.3 9.5 0.99 1.7 3.0 "" "" 0.224 +800 288.0 737.1 35.0 1320.0 1.0 "" "" 11.7 9.5 0.99 1.7 1.0 "" "" 0.738 +801 288.0 657.5 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 4.0 "" "" 0.689 +802 288.0 325.0 35.0 1320.0 1.0 "" "" 17.6 9.5 0.99 1.7 1.0 "" "" 0.197 +803 288.0 360.9 35.0 1320.0 1.0 "" "" 18.9 9.5 0.99 1.7 3.0 "" "" 0.406 +804 288.0 1518.7 35.0 1320.0 1.0 "" "" 10.4 9.5 0.99 1.7 2.0 "" "" 0.719 +805 288.0 650.4 35.0 1320.0 1.0 "" "" 11.0 9.5 0.99 1.7 3.0 "" "" 0.628 +806 288.0 310.7 35.0 1320.0 1.0 "" "" 12.4 9.5 0.99 1.7 3.0 "" "" 0.286 +807 288.0 318.1 35.0 1320.0 1.0 "" "" 43.1 9.5 0.99 1.7 2.0 "" "" 0.159 +808 288.0 422.6 35.0 1320.0 1.0 "" "" 11.2 9.5 0.99 1.7 2.0 "" "" 0.476 +809 288.0 243.3 35.0 1320.0 1.0 "" "" 13.8 9.5 0.99 1.7 4.0 "" "" 0.16 +810 288.0 1414.7 35.0 1320.0 1.0 "" "" 21.0 9.5 0.99 1.7 3.0 "" "" 0.566 +811 288.0 672.1 35.0 1320.0 1.0 "" "" 12.7 9.5 0.99 1.7 3.0 "" "" 0.831 +812 288.0 743.0 35.0 1320.0 1.0 "" "" 19.6 9.5 0.99 1.7 2.0 "" "" 0.912 +813 288.0 906.6 35.0 1320.0 1.0 "" "" 10.3 9.5 0.99 1.7 3.0 "" "" 0.057 +814 288.0 539.5 35.0 1320.0 1.0 "" "" 68.4 9.5 0.99 1.7 2.0 "" "" 0.549 +815 288.0 497.4 35.0 1320.0 1.0 "" "" 66.2 9.5 0.99 1.7 4.0 "" "" 0.248 +816 288.0 861.2 35.0 1320.0 1.0 "" "" 10.9 9.5 0.99 1.7 2.0 "" "" 0.986 +817 288.0 184.9 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 3.0 "" "" 0.001 +818 288.0 1703.6 35.0 1320.0 1.0 "" "" 15.6 9.5 0.99 1.7 2.0 "" "" 0.953 +819 288.0 1362.6 35.0 1320.0 1.0 "" "" 11.1 9.5 0.99 1.7 3.0 "" "" 0.661 +820 288.0 434.7 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 1.0 "" "" 0.075 +821 288.0 1323.7 35.0 1320.0 1.0 "" "" 13.9 9.5 0.99 1.7 4.0 "" "" 1.049 +822 288.0 171.3 35.0 1320.0 1.0 "" "" 9.5 9.5 0.99 1.7 3.0 "" "" 0.13 +823 288.0 329.5 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 2.0 "" "" 0.369 +824 288.0 563.8 35.0 1320.0 1.0 "" "" 57.3 9.5 0.99 1.7 0.0 "" "" 0.498 +825 288.0 513.6 35.0 1320.0 1.0 "" "" 10.2 9.5 0.99 1.7 2.0 "" "" 0.049 +826 288.0 833.9 35.0 1320.0 1.0 "" "" 16.9 9.5 0.99 1.7 2.0 "" "" 1.049 +827 288.0 734.8 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 2.0 "" "" 0.743 +828 288.0 214.4 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 5.0 "" "" 0.196 +829 288.0 639.2 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 3.0 "" "" 0.32 +830 288.0 393.9 35.0 1320.0 1.0 "" "" 36.9 9.5 0.99 1.7 2.0 "" "" 0.321 +831 288.0 554.7 35.0 1320.0 1.0 "" "" 18.4 9.5 0.99 1.7 3.0 "" "" 0.716 +832 288.0 475.1 35.0 1320.0 1.0 "" "" 18.5 9.5 0.99 1.7 1.0 "" "" 0.149 +833 288.0 441.1 35.0 1320.0 1.0 "" "" 19.2 9.5 0.99 1.7 2.0 "" "" 0.391 +834 288.0 239.7 35.0 1320.0 1.0 "" "" 63.9 9.5 0.99 1.7 2.0 "" "" 0.038 +835 288.0 733.9 35.0 1320.0 1.0 "" "" 18.4 9.5 0.99 1.7 1.0 "" "" 0.785 +836 288.0 706.7 35.0 1320.0 1.0 "" "" 17.0 9.5 0.99 1.7 1.0 "" "" 0.781 +837 288.0 388.2 35.0 1320.0 1.0 "" "" 30.8 9.5 0.99 1.7 3.0 "" "" 0.385 +838 288.0 1225.9 35.0 1320.0 1.0 "" "" 16.8 9.5 0.99 1.7 1.0 "" "" 0.971 +839 288.0 391.6 35.0 1320.0 1.0 "" "" 23.3 9.5 0.99 1.7 3.0 "" "" 0.369 +840 288.0 611.5 35.0 1320.0 1.0 "" "" 16.4 9.5 0.99 1.7 2.0 "" "" 0.205 +841 288.0 1052.3 35.0 1320.0 1.0 "" "" 14.7 9.5 0.99 1.7 3.0 "" "" 0.026 +842 288.0 503.5 35.0 1320.0 1.0 "" "" 13.0 9.5 0.99 1.7 4.0 "" "" 0.376 +843 288.0 809.9 35.0 1320.0 1.0 "" "" 15.8 9.5 0.99 1.7 2.0 "" "" 0.826 +844 288.0 236.2 35.0 1320.0 1.0 "" "" 74.9 9.5 0.99 1.7 2.0 "" "" 0.157 +845 288.0 223.2 35.0 1320.0 1.0 "" "" 24.2 9.5 0.99 1.7 3.0 "" "" 0.079 +846 288.0 343.7 35.0 1320.0 1.0 "" "" 23.3 9.5 0.99 1.7 2.0 "" "" 0.178 +847 288.0 367.6 35.0 1320.0 1.0 "" "" 24.0 9.5 0.99 1.7 0.0 "" "" 0.234 +848 288.0 1253.0 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 3.0 "" "" 0.789 +849 288.0 194.5 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 2.0 "" "" 0.161 +850 288.0 477.9 35.0 1320.0 1.0 "" "" 14.0 9.5 0.99 1.7 3.0 "" "" 0.519 +851 288.0 362.2 35.0 1320.0 1.0 "" "" 20.1 9.5 0.99 1.7 3.0 "" "" 0.048 +852 288.0 530.0 35.0 1320.0 1.0 "" "" 16.5 9.5 0.99 1.7 0.0 "" "" 0.275 +853 288.0 268.6 35.0 1320.0 1.0 "" "" 13.2 9.5 0.99 1.7 1.0 "" "" 0.001 +854 288.0 899.1 35.0 1320.0 1.0 "" "" 20.0 9.5 0.99 1.7 1.0 "" "" 0.322 +855 288.0 727.1 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 3.0 "" "" 0.513 +856 288.0 352.4 35.0 1320.0 1.0 "" "" 36.7 9.5 0.99 1.7 1.0 "" "" 0.014 +857 288.0 395.1 35.0 1320.0 1.0 "" "" 15.9 9.5 0.99 1.7 3.0 "" "" 0.167 +858 288.0 848.2 35.0 1320.0 1.0 "" "" 32.7 9.5 0.99 1.7 3.0 "" "" 0.87 +859 288.0 847.8 35.0 1320.0 1.0 "" "" 15.4 9.5 0.99 1.7 3.0 "" "" 0.909 +860 288.0 526.7 35.0 1320.0 1.0 "" "" 33.0 9.5 0.99 1.7 3.0 "" "" 0.546 +861 288.0 448.5 35.0 1320.0 1.0 "" "" 11.8 9.5 0.99 1.7 3.0 "" "" 0.177 +862 288.0 345.2 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 1.0 "" "" 0.249 +863 288.0 799.2 35.0 1320.0 1.0 "" "" 14.5 9.5 0.99 1.7 1.0 "" "" 0.143 +864 288.0 1080.7 35.0 1320.0 1.0 "" "" 12.2 9.5 0.99 1.7 5.0 "" "" 0.122 +865 288.0 892.1 35.0 1320.0 1.0 "" "" 34.4 9.5 0.99 1.7 3.0 "" "" 0.914 +866 288.0 1352.0 35.0 1320.0 1.0 "" "" 15.1 9.5 0.99 1.7 2.0 "" "" 0.982 +867 288.0 674.1 35.0 1320.0 1.0 "" "" 184.9 9.5 0.99 1.7 3.0 "" "" 0.356 +868 288.0 725.3 35.0 1320.0 1.0 "" "" 59.8 9.5 0.99 1.7 1.0 "" "" 0.706 +869 288.0 325.9 35.0 1320.0 1.0 "" "" 12.6 9.5 0.99 1.7 3.0 "" "" 0.3 +870 288.0 1809.5 35.0 1320.0 1.0 "" "" 13.7 9.5 0.99 1.7 2.0 "" "" 0.151 +871 288.0 408.5 35.0 1320.0 1.0 "" "" 69.6 9.5 0.99 1.7 4.0 "" "" 0.342 +872 288.0 533.4 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 2.0 "" "" 0.302 +873 288.0 1394.9 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 2.0 "" "" 0.888 +874 288.0 466.9 35.0 1320.0 1.0 "" "" 39.7 9.5 0.99 1.7 2.0 "" "" 0.007 +875 288.0 152.1 35.0 1320.0 1.0 "" "" 43.9 9.5 0.99 1.7 1.0 "" "" 0.018 +876 288.0 434.7 35.0 1320.0 1.0 "" "" 15.3 9.5 0.99 1.7 3.0 "" "" 0.232 +877 288.0 676.8 35.0 1320.0 1.0 "" "" 17.4 9.5 0.99 1.7 1.0 "" "" 0.553 +878 288.0 455.1 35.0 1320.0 1.0 "" "" 13.0 9.5 0.99 1.7 0.0 "" "" 0.127 +879 288.0 485.5 35.0 1320.0 1.0 "" "" 30.9 9.5 0.99 1.7 1.0 "" "" 0.142 +880 288.0 1341.2 35.0 1320.0 1.0 "" "" 82.8 9.5 0.99 1.7 0.0 "" "" 0.165 +881 288.0 292.7 35.0 1320.0 1.0 "" "" 124.8 9.5 0.99 1.7 2.0 "" "" 0.248 +882 288.0 256.1 35.0 1320.0 1.0 "" "" 11.5 9.5 0.99 1.7 1.0 "" "" 0.198 +883 288.0 234.8 35.0 1320.0 1.0 "" "" 11.3 9.5 0.99 1.7 3.0 "" "" 0.22 +884 288.0 395.9 35.0 1320.0 1.0 "" "" 9.5 9.5 0.99 1.7 2.0 "" "" 0.173 +885 288.0 384.6 35.0 1320.0 1.0 "" "" 449.6 9.5 0.99 1.7 2.0 "" "" 0.23 +886 288.0 1467.8 35.0 1320.0 1.0 "" "" 14.9 9.5 0.99 1.7 4.0 "" "" 0.81 +887 288.0 167.8 35.0 1320.0 1.0 "" "" 22.8 9.5 0.99 1.7 2.0 "" "" 0.062 +888 288.0 287.6 35.0 1320.0 1.0 "" "" 25.0 9.5 0.99 1.7 3.0 "" "" 0.266 +889 288.0 116.9 35.0 1320.0 1.0 "" "" 89.5 9.5 0.99 1.7 1.0 "" "" 0.033 +890 288.0 211.2 35.0 1320.0 1.0 "" "" 29.9 9.5 0.99 1.7 3.0 "" "" 0.103 +891 288.0 807.2 35.0 1320.0 1.0 "" "" 10.5 9.5 0.99 1.7 2.0 "" "" 0.785 +892 288.0 438.7 35.0 1320.0 1.0 "" "" 14.2 9.5 0.99 1.7 4.0 "" "" 0.478 +893 288.0 175.2 35.0 1320.0 1.0 "" "" 17.4 9.5 0.99 1.7 1.0 "" "" 0.023 +894 288.0 350.0 35.0 1320.0 1.0 "" "" 12.3 9.5 0.99 1.7 3.0 "" "" 0.313 +895 288.0 1865.2 35.0 1320.0 1.0 "" "" 10.4 9.5 0.99 1.7 2.0 "" "" 1.939 +896 288.0 560.0 35.0 1320.0 1.0 "" "" 18.4 9.5 0.99 1.7 2.0 "" "" 0.468 +897 288.0 198.2 35.0 1320.0 1.0 "" "" 233.6 9.5 0.99 1.7 2.0 "" "" 0.039 +898 288.0 585.4 35.0 1320.0 1.0 "" "" 11.1 9.5 0.99 1.7 2.0 "" "" 0.667 +899 288.0 347.7 35.0 1320.0 1.0 "" "" 13.7 9.5 0.99 1.7 2.0 "" "" 0.258 +900 288.0 756.3 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 1.0 "" "" 0.889 +901 288.0 210.4 35.0 1320.0 1.0 "" "" 11.4 9.5 0.99 1.7 0.0 "" "" 0.01 +902 288.0 656.0 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 4.0 "" "" 0.508 +903 288.0 1539.0 35.0 1320.0 1.0 "" "" 15.9 9.5 0.99 1.7 2.0 "" "" 2.03 +904 288.0 137.6 35.0 1320.0 1.0 "" "" 14.6 9.5 0.99 1.7 2.0 "" "" 0.016 +905 288.0 480.9 35.0 1320.0 1.0 "" "" 45.1 9.5 0.99 1.7 2.0 "" "" 0.081 +906 288.0 506.7 35.0 1320.0 1.0 "" "" 42.2 9.5 0.99 1.7 2.0 "" "" 0.425 +907 288.0 479.0 35.0 1320.0 1.0 "" "" 13.5 9.5 0.99 1.7 4.0 "" "" 0.264 +908 288.0 910.5 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 1.0 "" "" 1.062 +909 288.0 764.0 35.0 1320.0 1.0 "" "" 25.4 9.5 0.99 1.7 1.0 "" "" 1.017 +910 288.0 358.5 35.0 1320.0 1.0 "" "" 43.9 9.5 0.99 1.7 4.0 "" "" 0.041 +911 288.0 100.5 35.0 1320.0 1.0 "" "" 92.1 9.5 0.99 1.7 3.0 "" "" 0.007 +912 288.0 403.5 35.0 1320.0 1.0 "" "" 13.4 9.5 0.99 1.7 2.0 "" "" 0.327 +913 288.0 349.2 35.0 1320.0 1.0 "" "" 32.6 9.5 0.99 1.7 4.0 "" "" 0.161 +914 288.0 1399.6 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 0.0 "" "" 0.97 +915 288.0 130.8 35.0 1320.0 1.0 "" "" 27.4 9.5 0.99 1.7 2.0 "" "" 0.049 +916 288.0 184.5 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 4.0 "" "" 0.092 +917 288.0 553.7 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 3.0 "" "" 0.241 +918 288.0 465.2 35.0 1320.0 1.0 "" "" 25.5 9.5 0.99 1.7 2.0 "" "" 0.547 +919 288.0 627.3 35.0 1320.0 1.0 "" "" 31.8 9.5 0.99 1.7 2.0 "" "" 0.41 +920 288.0 629.9 35.0 1320.0 1.0 "" "" 77.8 9.5 0.99 1.7 4.0 "" "" 0.01 +921 288.0 779.1 35.0 1320.0 1.0 "" "" 60.8 9.5 0.99 1.7 2.0 "" "" 0.449 +922 288.0 511.7 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 2.0 "" "" 0.154 +923 288.0 224.6 35.0 1320.0 1.0 "" "" 51.8 9.5 0.99 1.7 3.0 "" "" 0.012 +924 288.0 389.8 35.0 1320.0 1.0 "" "" 42.0 9.5 0.99 1.7 3.0 "" "" 0.122 +925 288.0 661.0 35.0 1320.0 1.0 "" "" 15.7 9.5 0.99 1.7 2.0 "" "" 0.818 +926 288.0 993.1 35.0 1320.0 1.0 "" "" 11.5 9.5 0.99 1.7 3.0 "" "" 0.237 +927 288.0 1479.7 35.0 1320.0 1.0 "" "" 9.7 9.5 0.99 1.7 3.0 "" "" 1.498 +928 288.0 476.2 35.0 1320.0 1.0 "" "" 22.0 9.5 0.99 1.7 3.0 "" "" 0.517 +929 288.0 414.2 35.0 1320.0 1.0 "" "" 37.4 9.5 0.99 1.7 3.0 "" "" 0.17 +930 288.0 319.1 35.0 1320.0 1.0 "" "" 15.1 9.5 0.99 1.7 2.0 "" "" 0.201 +931 288.0 1336.7 35.0 1320.0 1.0 "" "" 10.8 9.5 0.99 1.7 3.0 "" "" 1.526 +932 288.0 1027.7 35.0 1320.0 1.0 "" "" 13.1 9.5 0.99 1.7 3.0 "" "" 1.055 +933 288.0 545.3 35.0 1320.0 1.0 "" "" 26.9 9.5 0.99 1.7 3.0 "" "" 0.388 +934 288.0 369.4 35.0 1320.0 1.0 "" "" 10.7 9.5 0.99 1.7 1.0 "" "" 0.01 +935 288.0 168.6 35.0 1320.0 1.0 "" "" 29.4 9.5 0.99 1.7 2.0 "" "" 0.003 +936 288.0 1013.5 35.0 1320.0 1.0 "" "" 13.2 9.5 0.99 1.7 2.0 "" "" 1.012 +937 288.0 254.8 35.0 1320.0 1.0 "" "" 14.9 9.5 0.99 1.7 3.0 "" "" 0.184 +938 288.0 1715.0 35.0 1320.0 1.0 "" "" 12.1 9.5 0.99 1.7 2.0 "" "" 2.012 +939 288.0 2046.3 35.0 1320.0 1.0 "" "" 13.0 9.5 0.99 1.7 0.0 "" "" 1.186 +940 288.0 194.4 35.0 1320.0 1.0 "" "" 35.6 9.5 0.99 1.7 2.0 "" "" 0.031 +941 288.0 235.0 35.0 1320.0 1.0 "" "" 149.4 9.5 0.99 1.7 3.0 "" "" 0.218 +942 288.0 636.0 35.0 1320.0 1.0 "" "" 12.9 9.5 0.99 1.7 3.0 "" "" 0.467 +943 288.0 260.7 35.0 1320.0 1.0 "" "" 15.2 9.5 0.99 1.7 3.0 "" "" 0.118 +944 288.0 923.6 35.0 1320.0 1.0 "" "" 18.1 9.5 0.99 1.7 3.0 "" "" 0.803 +945 288.0 913.5 35.0 1320.0 1.0 "" "" 24.7 9.5 0.99 1.7 1.0 "" "" 1.208 +946 288.0 200.0 35.0 1320.0 1.0 "" "" 11.0 9.5 0.99 1.7 3.0 "" "" 0.155 +947 288.0 363.2 35.0 1320.0 1.0 "" "" 12.0 9.5 0.99 1.7 3.0 "" "" 0.386 +948 288.0 324.1 35.0 1320.0 1.0 "" "" 22.7 9.5 0.99 1.7 1.0 "" "" 0.178 +949 288.0 497.9 35.0 1320.0 1.0 "" "" 24.1 9.5 0.99 1.7 3.0 "" "" 0.549 +950 288.0 464.8 35.0 1320.0 1.0 "" "" 10.6 9.5 0.99 1.7 4.0 "" "" 0.503 +951 288.0 897.2 35.0 1320.0 1.0 "" "" 19.2 9.5 0.99 1.7 3.0 "" "" 0.893 +952 288.0 243.3 35.0 1320.0 1.0 "" "" 12.5 9.5 0.99 1.7 2.0 "" "" 0.111 +953 288.0 340.6 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 2.0 "" "" 0.173 +954 288.0 239.4 35.0 1320.0 1.0 "" "" 11.0 9.5 0.99 1.7 3.0 "" "" 0.24 +955 288.0 672.0 35.0 1320.0 1.0 "" "" 12.1 9.5 0.99 1.7 3.0 "" "" 0.618 +956 288.0 918.3 35.0 1320.0 1.0 "" "" 19.9 9.5 0.99 1.7 3.0 "" "" 0.45 +957 288.0 351.4 35.0 1320.0 1.0 "" "" 27.7 9.5 0.99 1.7 3.0 "" "" 0.394 +958 288.0 865.6 35.0 1320.0 1.0 "" "" 10.3 9.5 0.99 1.7 0.0 "" "" 1.064 +959 288.0 1634.9 35.0 1320.0 1.0 "" "" 15.9 9.5 0.99 1.7 3.0 "" "" 1.946 +960 288.0 375.6 35.0 1320.0 1.0 "" "" 9.6 9.5 0.99 1.7 1.0 "" "" 0.255 +961 288.0 1282.2 35.0 1320.0 1.0 "" "" 12.7 9.5 0.99 1.7 3.0 "" "" 1.503 +962 288.0 810.4 35.0 1320.0 1.0 "" "" 22.6 9.5 0.99 1.7 3.0 "" "" 0.109 +963 288.0 1615.8 35.0 1320.0 1.0 "" "" 14.0 9.5 0.99 1.7 4.0 "" "" 0.363 +964 288.0 410.2 35.0 1320.0 1.0 "" "" 14.9 9.5 0.99 1.7 2.0 "" "" 0.229 +965 288.0 322.5 35.0 1320.0 1.0 "" "" 37.2 9.5 0.99 1.7 4.0 "" "" 0.171 +966 288.0 807.4 35.0 1320.0 1.0 "" "" 20.6 9.5 0.99 1.7 3.0 "" "" 0.926 +967 288.0 809.0 35.0 1320.0 1.0 "" "" 15.2 9.5 0.99 1.7 3.0 "" "" 0.973 +968 288.0 200.8 35.0 1320.0 1.0 "" "" 40.9 9.5 0.99 1.7 1.0 "" "" 0.017 +969 288.0 624.5 35.0 1320.0 1.0 "" "" 29.0 9.5 0.99 1.7 3.0 "" "" 0.608 +970 288.0 765.5 35.0 1320.0 1.0 "" "" 27.9 9.5 0.99 1.7 3.0 "" "" 0.903 +971 288.0 723.4 35.0 1320.0 1.0 "" "" 18.6 9.5 0.99 1.7 2.0 "" "" 0.748 +972 288.0 1077.4 35.0 1320.0 1.0 "" "" 17.1 9.5 0.99 1.7 2.0 "" "" 0.677 +973 288.0 817.6 35.0 1320.0 1.0 "" "" 11.1 9.5 0.99 1.7 4.0 "" "" 0.672 +974 288.0 1497.4 35.0 1320.0 1.0 "" "" 10.0 9.5 0.99 1.7 4.0 "" "" 1.515 +975 288.0 569.8 35.0 1320.0 1.0 "" "" 57.6 9.5 0.99 1.7 3.0 "" "" 0.124 +976 288.0 510.3 35.0 1320.0 1.0 "" "" 33.4 9.5 0.99 1.7 2.0 "" "" 0.48 +977 288.0 452.5 35.0 1320.0 1.0 "" "" 10.3 9.5 0.99 1.7 4.0 "" "" 0.265 +978 288.0 975.6 35.0 1320.0 1.0 "" "" 11.2 9.5 0.99 1.7 3.0 "" "" 1.173 +979 288.0 496.8 35.0 1320.0 1.0 "" "" 55.7 9.5 0.99 1.7 1.0 "" "" 0.375 +980 288.0 199.7 35.0 1320.0 1.0 "" "" 9.9 9.5 0.99 1.7 3.0 "" "" 0.038 +981 288.0 806.6 35.0 1320.0 1.0 "" "" 14.6 9.5 0.99 1.7 2.0 "" "" 0.794 +982 288.0 642.3 35.0 1320.0 1.0 "" "" 13.4 9.5 0.99 1.7 3.0 "" "" 0.439 +983 288.0 959.5 35.0 1320.0 1.0 "" "" 16.6 9.5 0.99 1.7 0.0 "" "" 0.787 +984 288.0 396.7 35.0 1320.0 1.0 "" "" 21.8 9.5 0.99 1.7 3.0 "" "" 0.33 +985 288.0 142.1 35.0 1320.0 1.0 "" "" 21.8 9.5 0.99 1.7 3.0 "" "" 0.043 +986 288.0 376.1 35.0 1320.0 1.0 "" "" 19.0 9.5 0.99 1.7 1.0 "" "" 0.219 +987 288.0 1077.2 35.0 1320.0 1.0 "" "" 35.2 9.5 0.99 1.7 1.0 "" "" 1.389 +988 288.0 632.7 35.0 1320.0 1.0 "" "" 11.9 9.5 0.99 1.7 0.0 "" "" 0.475 +989 288.0 330.1 35.0 1320.0 1.0 "" "" 11.7 9.5 0.99 1.7 3.0 "" "" 0.163 +990 288.0 247.1 35.0 1320.0 1.0 "" "" 18.0 9.5 0.99 1.7 3.0 "" "" 0.152 +991 288.0 140.6 35.0 1320.0 1.0 "" "" 20.3 9.5 0.99 1.7 3.0 "" "" 0.019 +992 288.0 578.6 35.0 1320.0 1.0 "" "" 53.0 9.5 0.99 1.7 1.0 "" "" 0.301 +993 288.0 230.2 35.0 1320.0 1.0 "" "" 10.1 9.5 0.99 1.7 2.0 "" "" 0.125 +994 288.0 420.1 35.0 1320.0 1.0 "" "" 18.6 9.5 0.99 1.7 3.0 "" "" 0.135 +995 288.0 579.4 35.0 1320.0 1.0 "" "" 14.9 9.5 0.99 1.7 1.0 "" "" 0.36 +996 288.0 1031.4 35.0 1320.0 1.0 "" "" 14.7 9.5 0.99 1.7 2.0 "" "" 1.19 +997 288.0 391.9 35.0 1320.0 1.0 "" "" 20.3 9.5 0.99 1.7 5.0 "" "" 0.147 +998 288.0 341.4 35.0 1320.0 1.0 "" "" 79.0 9.5 0.99 1.7 1.0 "" "" 0.267 +999 288.0 442.7 35.0 1320.0 1.0 "" "" 14.0 9.5 0.99 1.7 3.0 "" "" 0.433 diff --git a/zdm/craco/MC_F/Surveys/F_0.32_survey_state.json b/zdm/craco/MC_F/Surveys/F_0.32_survey_state.json new file mode 100644 index 00000000..38ba399e --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_0.32_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.32 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/MC_F/Surveys/F_0.7_dmhost_suppressed_survey_state.json b/zdm/craco/MC_F/Surveys/F_0.7_dmhost_suppressed_survey_state.json new file mode 100644 index 00000000..85364587 --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_0.7_dmhost_suppressed_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.7 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 0.001, + "lsigma": 0.1 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/MC_F/Surveys/F_0.7_survey_state.json b/zdm/craco/MC_F/Surveys/F_0.7_survey_state.json new file mode 100644 index 00000000..9b158036 --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_0.7_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.7 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/MC_F/Surveys/F_0.9_dmhost_suppressed_survey_state.json b/zdm/craco/MC_F/Surveys/F_0.9_dmhost_suppressed_survey_state.json new file mode 100644 index 00000000..22a1f8b1 --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_0.9_dmhost_suppressed_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.9 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 0.001, + "lsigma": 0.1 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/MC_F/Surveys/F_0.9_survey_state.json b/zdm/craco/MC_F/Surveys/F_0.9_survey_state.json new file mode 100644 index 00000000..80d4aa07 --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_0.9_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.9 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/MC_F/Surveys/F_vanilla_dmhost_suppressed_survey_state.json b/zdm/craco/MC_F/Surveys/F_vanilla_dmhost_suppressed_survey_state.json new file mode 100644 index 00000000..dca5c55f --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_vanilla_dmhost_suppressed_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.32 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 0.001, + "lsigma": 0.1 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/MC_F/Surveys/F_vanilla_survey_state.json b/zdm/craco/MC_F/Surveys/F_vanilla_survey_state.json new file mode 100644 index 00000000..38ba399e --- /dev/null +++ b/zdm/craco/MC_F/Surveys/F_vanilla_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.32 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/MC_Surveys/CRACO_F_0.32_survey.dat b/zdm/craco/MC_Surveys/CRACO_F_0.32_survey.dat new file mode 100644 index 00000000..a9ab2b88 --- /dev/null +++ b/zdm/craco/MC_Surveys/CRACO_F_0.32_survey.dat @@ -0,0 +1,1014 @@ +BW 288 #MHz +FRES 1 #MHz +DIAM 12 +NBEAMS 36 +BEAM lat50_log #prefix of beam file +FBAR 1320 +TRES 1.7 #ms +SNRTHRESH 9.5 +NFRB 1000 +NORM_FRB 1000 +TOBS 96.65 # days of 100% efficient operation +THRESH 0.99 #Jy ms to 1 ms burst [ 22 Jy ms / 24 antennas *sqrt{336/288} bandwidth factor] +KEY ID DM DMG DMEG Z SNR WIDTH +# fake data from MC simulations +FRB 0 550.1 35 465.1 0.313 25.5 2.0 +FRB 1 273.7 35 188.7 0.020 22.8 2.0 +FRB 2 680.2 35 595.2 0.645 10.2 1.0 +FRB 3 515.1 35 430.1 0.179 36.1 3.0 +FRB 4 572.3 35 487.3 0.207 44.0 5.0 +FRB 5 330.9 35 245.9 0.299 17.6 4.0 +FRB 6 888.9 35 803.9 0.737 22.3 3.0 +FRB 7 378.2 35 293.2 0.358 25.7 2.0 +FRB 8 458.5 35 373.5 0.047 104.3 1.0 +FRB 9 1047.4 35 962.4 1.259 19.8 2.0 +FRB 10 349.8 35 264.8 0.300 39.3 4.0 +FRB 11 376.2 35 291.2 0.476 15.3 2.0 +FRB 12 240.3 35 155.3 0.254 33.6 1.0 +FRB 13 495.1 35 410.1 0.486 13.1 3.0 +FRB 14 302.0 35 217.0 0.061 16.2 3.0 +FRB 15 465.4 35 380.4 0.222 46.8 3.0 +FRB 16 298.9 35 213.9 0.173 12.0 3.0 +FRB 17 362.7 35 277.7 0.074 12.0 4.0 +FRB 18 1707.5 35 1622.5 0.842 16.8 3.0 +FRB 19 122.8 35 37.8 0.003 53.0 2.0 +FRB 20 405.5 35 320.5 0.538 58.0 3.0 +FRB 21 896.8 35 811.8 0.754 13.1 3.0 +FRB 22 300.8 35 215.8 0.163 19.6 2.0 +FRB 23 913.3 35 828.3 0.768 10.6 2.0 +FRB 24 763.0 35 678.0 0.716 31.8 3.0 +FRB 25 1107.1 35 1022.1 1.020 13.2 2.0 +FRB 26 417.6 35 332.6 0.352 138.9 1.0 +FRB 27 355.0 35 270.0 0.283 14.8 2.0 +FRB 28 240.7 35 155.7 0.038 18.7 3.0 +FRB 29 618.0 35 533.0 0.318 37.9 4.0 +FRB 30 975.5 35 890.5 0.407 17.5 2.0 +FRB 31 403.9 35 318.9 0.124 10.0 3.0 +FRB 32 975.2 35 890.2 1.093 11.3 2.0 +FRB 33 142.8 35 57.8 0.001 20.2 4.0 +FRB 34 299.6 35 214.6 0.208 16.5 1.0 +FRB 35 243.5 35 158.5 0.050 10.1 0.0 +FRB 36 1455.2 35 1370.2 1.873 10.6 2.0 +FRB 37 178.4 35 93.4 0.082 68.0 2.0 +FRB 38 719.1 35 634.1 0.927 10.1 4.0 +FRB 39 795.7 35 710.7 0.495 11.8 1.0 +FRB 40 397.4 35 312.4 0.347 10.4 2.0 +FRB 41 350.3 35 265.3 0.111 18.2 2.0 +FRB 42 218.6 35 133.6 0.092 12.9 1.0 +FRB 43 332.3 35 247.3 0.179 29.6 3.0 +FRB 44 435.0 35 350.0 0.256 16.5 3.0 +FRB 45 568.2 35 483.2 0.463 11.9 1.0 +FRB 46 1062.3 35 977.3 1.071 18.1 1.0 +FRB 47 401.7 35 316.7 0.293 30.1 2.0 +FRB 48 589.2 35 504.2 0.503 13.1 1.0 +FRB 49 244.4 35 159.4 0.014 36.6 3.0 +FRB 50 223.5 35 138.5 0.224 193.2 3.0 +FRB 51 1308.0 35 1223.0 0.453 10.3 2.0 +FRB 52 384.5 35 299.5 0.286 23.9 1.0 +FRB 53 678.3 35 593.3 0.588 10.5 3.0 +FRB 54 488.8 35 403.8 0.333 9.8 1.0 +FRB 55 418.4 35 333.4 0.382 12.0 2.0 +FRB 56 388.3 35 303.3 0.354 55.5 4.0 +FRB 57 479.7 35 394.7 0.135 55.6 2.0 +FRB 58 176.3 35 91.3 0.078 40.5 2.0 +FRB 59 328.3 35 243.3 0.277 16.8 1.0 +FRB 60 577.7 35 492.7 0.683 38.5 2.0 +FRB 61 509.6 35 424.6 0.359 11.7 0.0 +FRB 62 398.7 35 313.7 0.483 18.9 2.0 +FRB 63 691.3 35 606.3 0.197 20.8 2.0 +FRB 64 493.2 35 408.2 0.374 15.2 3.0 +FRB 65 350.9 35 265.9 0.028 93.5 3.0 +FRB 66 428.1 35 343.1 0.435 16.8 4.0 +FRB 67 801.0 35 716.0 1.053 16.2 4.0 +FRB 68 412.7 35 327.7 0.172 15.2 2.0 +FRB 69 907.4 35 822.4 0.497 26.8 1.0 +FRB 70 461.0 35 376.0 0.272 125.7 3.0 +FRB 71 943.3 35 858.3 0.638 16.8 3.0 +FRB 72 419.5 35 334.5 0.234 59.2 1.0 +FRB 73 187.7 35 102.7 0.064 168.5 2.0 +FRB 74 551.6 35 466.6 0.459 26.4 3.0 +FRB 75 276.6 35 191.6 0.288 25.6 0.0 +FRB 76 275.7 35 190.7 0.141 28.0 3.0 +FRB 77 421.4 35 336.4 0.097 13.7 1.0 +FRB 78 345.1 35 260.1 0.222 11.3 1.0 +FRB 79 476.7 35 391.7 0.191 15.6 3.0 +FRB 80 277.7 35 192.7 0.055 645.9 1.0 +FRB 81 411.0 35 326.0 0.333 12.3 2.0 +FRB 82 654.8 35 569.8 0.060 16.8 4.0 +FRB 83 440.5 35 355.5 0.101 20.4 0.0 +FRB 84 355.8 35 270.8 0.184 89.8 3.0 +FRB 85 627.5 35 542.5 0.428 13.5 5.0 +FRB 86 1497.3 35 1412.3 1.597 10.1 3.0 +FRB 87 220.6 35 135.6 0.127 16.7 3.0 +FRB 88 219.8 35 134.8 0.104 10.2 1.0 +FRB 89 193.1 35 108.1 0.127 15.0 3.0 +FRB 90 532.5 35 447.5 0.490 13.4 2.0 +FRB 91 1473.7 35 1388.7 0.689 12.6 3.0 +FRB 92 528.4 35 443.4 0.256 9.6 2.0 +FRB 93 886.6 35 801.6 0.942 10.3 1.0 +FRB 94 558.4 35 473.4 0.827 39.2 2.0 +FRB 95 751.5 35 666.5 0.788 19.6 2.0 +FRB 96 365.8 35 280.8 0.071 48.4 3.0 +FRB 97 442.8 35 357.8 0.290 10.4 2.0 +FRB 98 808.5 35 723.5 0.421 11.3 2.0 +FRB 99 1026.1 35 941.1 1.304 14.3 4.0 +FRB 100 186.7 35 101.7 0.150 15.9 2.0 +FRB 101 1179.5 35 1094.5 1.321 26.0 1.0 +FRB 102 438.5 35 353.5 0.062 20.2 4.0 +FRB 103 315.3 35 230.3 0.089 17.9 1.0 +FRB 104 833.1 35 748.1 0.949 10.5 2.0 +FRB 105 595.3 35 510.3 0.250 32.8 2.0 +FRB 106 313.4 35 228.4 0.370 16.8 4.0 +FRB 107 568.5 35 483.5 0.629 13.1 2.0 +FRB 108 143.5 35 58.5 0.026 11.0 4.0 +FRB 109 743.4 35 658.4 0.812 12.6 3.0 +FRB 110 941.9 35 856.9 0.755 10.0 2.0 +FRB 111 460.5 35 375.5 0.355 10.7 2.0 +FRB 112 1271.8 35 1186.8 0.432 12.1 2.0 +FRB 113 1308.6 35 1223.6 1.273 15.7 2.0 +FRB 114 567.9 35 482.9 0.608 12.4 3.0 +FRB 115 410.5 35 325.5 0.057 84.7 2.0 +FRB 116 391.1 35 306.1 0.251 117.3 1.0 +FRB 117 1287.8 35 1202.8 1.592 9.7 2.0 +FRB 118 634.8 35 549.8 0.378 15.9 2.0 +FRB 119 383.0 35 298.0 0.176 15.6 2.0 +FRB 120 372.7 35 287.7 0.167 16.2 2.0 +FRB 121 237.3 35 152.3 0.041 13.3 2.0 +FRB 122 478.8 35 393.8 0.354 27.0 2.0 +FRB 123 835.0 35 750.0 0.735 51.2 2.0 +FRB 124 282.6 35 197.6 0.263 10.6 3.0 +FRB 125 151.4 35 66.4 0.046 223.4 3.0 +FRB 126 819.9 35 734.9 0.750 13.1 4.0 +FRB 127 162.3 35 77.3 0.138 17.3 3.0 +FRB 128 371.1 35 286.1 0.282 25.0 1.0 +FRB 129 357.4 35 272.4 0.262 16.3 1.0 +FRB 130 331.8 35 246.8 0.085 40.2 3.0 +FRB 131 557.5 35 472.5 0.289 88.5 3.0 +FRB 132 818.5 35 733.5 0.660 9.8 3.0 +FRB 133 1257.6 35 1172.6 0.699 22.4 3.0 +FRB 134 1116.3 35 1031.3 1.367 11.6 2.0 +FRB 135 2259.2 35 2174.2 1.338 12.3 3.0 +FRB 136 307.9 35 222.9 0.243 22.6 4.0 +FRB 137 1311.1 35 1226.1 1.712 24.4 3.0 +FRB 138 848.2 35 763.2 1.006 11.6 2.0 +FRB 139 1060.6 35 975.6 1.108 10.6 3.0 +FRB 140 785.5 35 700.5 0.164 10.0 3.0 +FRB 141 484.9 35 399.9 0.520 11.7 0.0 +FRB 142 481.2 35 396.2 0.424 9.6 3.0 +FRB 143 484.7 35 399.7 0.610 14.9 3.0 +FRB 144 260.6 35 175.6 0.054 12.9 3.0 +FRB 145 393.8 35 308.8 0.291 12.7 4.0 +FRB 146 273.7 35 188.7 0.182 22.7 3.0 +FRB 147 534.4 35 449.4 0.556 21.0 3.0 +FRB 148 703.6 35 618.6 0.195 10.8 1.0 +FRB 149 335.9 35 250.9 0.329 18.5 3.0 +FRB 150 898.1 35 813.1 0.718 32.2 2.0 +FRB 151 582.2 35 497.2 0.571 13.8 3.0 +FRB 152 636.2 35 551.2 0.441 23.1 2.0 +FRB 153 735.7 35 650.7 0.482 27.7 2.0 +FRB 154 1405.0 35 1320.0 1.318 11.4 4.0 +FRB 155 1083.0 35 998.0 1.101 19.3 3.0 +FRB 156 709.4 35 624.4 0.580 12.4 2.0 +FRB 157 1794.1 35 1709.1 1.849 14.9 3.0 +FRB 158 736.2 35 651.2 0.546 11.0 2.0 +FRB 159 808.6 35 723.6 0.472 33.4 2.0 +FRB 160 352.0 35 267.0 0.126 16.0 3.0 +FRB 161 447.5 35 362.5 0.543 38.3 1.0 +FRB 162 1346.2 35 1261.2 1.567 12.3 2.0 +FRB 163 428.3 35 343.3 0.537 12.3 2.0 +FRB 164 421.8 35 336.8 0.018 28.0 4.0 +FRB 165 602.3 35 517.3 0.093 16.3 2.0 +FRB 166 1110.1 35 1025.1 0.439 94.0 3.0 +FRB 167 303.5 35 218.5 0.137 10.8 1.0 +FRB 168 799.7 35 714.7 0.465 18.8 3.0 +FRB 169 309.6 35 224.6 0.159 30.0 2.0 +FRB 170 3446.6 35 3361.6 0.080 25.6 5.0 +FRB 171 721.5 35 636.5 0.306 25.8 2.0 +FRB 172 296.3 35 211.3 0.134 21.4 5.0 +FRB 173 573.2 35 488.2 0.464 19.6 2.0 +FRB 174 184.5 35 99.5 0.063 11.4 1.0 +FRB 175 580.0 35 495.0 0.632 15.6 0.0 +FRB 176 754.0 35 669.0 0.103 9.6 1.0 +FRB 177 391.9 35 306.9 0.430 11.2 1.0 +FRB 178 282.0 35 197.0 0.073 21.7 3.0 +FRB 179 548.7 35 463.7 0.350 25.8 4.0 +FRB 180 449.7 35 364.7 0.019 12.6 3.0 +FRB 181 187.9 35 102.9 0.052 40.8 2.0 +FRB 182 522.1 35 437.1 0.353 11.8 2.0 +FRB 183 233.3 35 148.3 0.081 85.5 2.0 +FRB 184 923.9 35 838.9 0.961 9.9 2.0 +FRB 185 568.1 35 483.1 0.295 15.9 5.0 +FRB 186 1327.1 35 1242.1 0.437 18.6 2.0 +FRB 187 901.0 35 816.0 0.744 39.8 2.0 +FRB 188 776.9 35 691.9 0.786 14.5 2.0 +FRB 189 359.8 35 274.8 0.372 46.4 1.0 +FRB 190 733.7 35 648.7 0.633 18.7 2.0 +FRB 191 685.6 35 600.6 0.765 9.8 3.0 +FRB 192 568.9 35 483.9 0.644 14.8 3.0 +FRB 193 398.7 35 313.7 0.239 23.3 3.0 +FRB 194 664.2 35 579.2 0.495 15.8 3.0 +FRB 195 326.6 35 241.6 0.251 14.2 1.0 +FRB 196 726.0 35 641.0 0.089 23.7 5.0 +FRB 197 342.1 35 257.1 0.029 48.2 2.0 +FRB 198 376.5 35 291.5 0.279 47.9 1.0 +FRB 199 271.9 35 186.9 0.237 18.9 2.0 +FRB 200 226.2 35 141.2 0.036 25.8 2.0 +FRB 201 636.8 35 551.8 0.069 18.9 1.0 +FRB 202 1305.4 35 1220.4 1.562 13.6 1.0 +FRB 203 1160.6 35 1075.6 0.743 11.9 3.0 +FRB 204 393.9 35 308.9 0.118 67.2 2.0 +FRB 205 208.4 35 123.4 0.200 9.9 2.0 +FRB 206 747.5 35 662.5 0.232 28.0 2.0 +FRB 207 544.7 35 459.7 0.397 14.1 2.0 +FRB 208 208.3 35 123.3 0.125 25.2 2.0 +FRB 209 647.3 35 562.3 0.658 10.2 2.0 +FRB 210 942.2 35 857.2 0.343 10.9 2.0 +FRB 211 512.8 35 427.8 0.053 24.3 2.0 +FRB 212 407.9 35 322.9 0.102 23.2 1.0 +FRB 213 519.0 35 434.0 0.377 13.9 2.0 +FRB 214 1342.6 35 1257.6 0.707 10.9 2.0 +FRB 215 424.8 35 339.8 0.230 18.1 4.0 +FRB 216 621.2 35 536.2 0.790 16.0 3.0 +FRB 217 655.3 35 570.3 0.588 16.5 2.0 +FRB 218 2215.0 35 2130.0 0.080 19.1 3.0 +FRB 219 716.7 35 631.7 0.683 41.8 2.0 +FRB 220 294.3 35 209.3 0.197 22.7 4.0 +FRB 221 690.7 35 605.7 0.703 20.4 2.0 +FRB 222 794.9 35 709.9 0.048 33.2 2.0 +FRB 223 704.5 35 619.5 0.802 10.0 3.0 +FRB 224 676.6 35 591.6 0.153 11.3 2.0 +FRB 225 458.6 35 373.6 0.467 92.5 3.0 +FRB 226 508.2 35 423.2 0.432 15.3 3.0 +FRB 227 1294.8 35 1209.8 1.343 10.6 2.0 +FRB 228 666.7 35 581.7 0.579 22.5 0.0 +FRB 229 178.7 35 93.7 0.054 22.7 3.0 +FRB 230 154.3 35 69.3 0.039 31.8 3.0 +FRB 231 790.1 35 705.1 1.095 9.8 2.0 +FRB 232 625.4 35 540.4 0.622 11.2 3.0 +FRB 233 448.6 35 363.6 0.272 14.1 1.0 +FRB 234 351.6 35 266.6 0.212 28.0 1.0 +FRB 235 532.9 35 447.9 0.502 14.2 2.0 +FRB 236 146.4 35 61.4 0.026 25.9 2.0 +FRB 237 363.8 35 278.8 0.317 12.5 1.0 +FRB 238 235.7 35 150.7 0.182 47.5 3.0 +FRB 239 394.0 35 309.0 0.356 15.3 4.0 +FRB 240 1055.4 35 970.4 0.935 27.4 1.0 +FRB 241 212.1 35 127.1 0.148 10.6 2.0 +FRB 242 2097.3 35 2012.3 2.036 9.9 1.0 +FRB 243 440.9 35 355.9 0.405 13.3 2.0 +FRB 244 677.6 35 592.6 0.310 16.1 3.0 +FRB 245 339.0 35 254.0 0.042 10.6 1.0 +FRB 246 270.0 35 185.0 0.033 12.0 4.0 +FRB 247 430.7 35 345.7 0.464 15.2 2.0 +FRB 248 2151.2 35 2066.2 0.622 25.4 1.0 +FRB 249 445.0 35 360.0 0.301 14.0 4.0 +FRB 250 326.7 35 241.7 0.229 16.6 3.0 +FRB 251 756.5 35 671.5 0.619 12.1 4.0 +FRB 252 474.3 35 389.3 0.136 11.6 4.0 +FRB 253 301.1 35 216.1 0.080 24.9 3.0 +FRB 254 251.3 35 166.3 0.190 34.5 3.0 +FRB 255 215.4 35 130.4 0.152 66.6 2.0 +FRB 256 688.1 35 603.1 0.562 11.4 2.0 +FRB 257 395.1 35 310.1 0.234 19.7 4.0 +FRB 258 1602.7 35 1517.7 1.216 20.4 2.0 +FRB 259 409.3 35 324.3 0.196 14.4 3.0 +FRB 260 785.5 35 700.5 0.821 25.5 2.0 +FRB 261 1411.5 35 1326.5 0.908 10.5 2.0 +FRB 262 365.7 35 280.7 0.208 29.0 1.0 +FRB 263 809.8 35 724.8 0.106 10.1 3.0 +FRB 264 377.8 35 292.8 0.139 13.8 2.0 +FRB 265 422.9 35 337.9 0.423 12.2 1.0 +FRB 266 295.9 35 210.9 0.215 21.9 2.0 +FRB 267 199.7 35 114.7 0.161 39.4 2.0 +FRB 268 456.5 35 371.5 0.210 12.2 2.0 +FRB 269 587.6 35 502.6 0.055 10.8 3.0 +FRB 270 275.5 35 190.5 0.096 10.2 2.0 +FRB 271 386.9 35 301.9 0.053 18.2 1.0 +FRB 272 1319.3 35 1234.3 1.418 10.1 2.0 +FRB 273 629.7 35 544.7 0.741 26.0 2.0 +FRB 274 157.7 35 72.7 0.024 21.4 2.0 +FRB 275 722.1 35 637.1 0.616 27.7 4.0 +FRB 276 775.6 35 690.6 0.609 22.5 3.0 +FRB 277 476.8 35 391.8 0.393 9.8 3.0 +FRB 278 823.4 35 738.4 0.801 12.4 2.0 +FRB 279 709.3 35 624.3 0.796 17.7 3.0 +FRB 280 765.4 35 680.4 1.032 9.9 1.0 +FRB 281 1306.7 35 1221.7 0.336 28.2 3.0 +FRB 282 253.7 35 168.7 0.066 36.1 3.0 +FRB 283 762.3 35 677.3 0.667 10.5 4.0 +FRB 284 618.1 35 533.1 0.586 12.9 2.0 +FRB 285 1062.3 35 977.3 0.792 71.5 0.0 +FRB 286 578.1 35 493.1 0.532 17.7 2.0 +FRB 287 679.1 35 594.1 0.338 12.4 2.0 +FRB 288 330.7 35 245.7 0.363 75.1 3.0 +FRB 289 312.7 35 227.7 0.059 13.9 4.0 +FRB 290 165.8 35 80.8 0.022 16.7 1.0 +FRB 291 1139.2 35 1054.2 1.241 18.3 2.0 +FRB 292 320.1 35 235.1 0.290 88.2 2.0 +FRB 293 700.6 35 615.6 0.921 13.4 2.0 +FRB 294 246.4 35 161.4 0.123 23.4 3.0 +FRB 295 283.5 35 198.5 0.085 16.0 0.0 +FRB 296 406.3 35 321.3 0.275 12.0 0.0 +FRB 297 1543.3 35 1458.3 1.742 9.7 3.0 +FRB 298 511.2 35 426.2 0.268 18.6 2.0 +FRB 299 271.5 35 186.5 0.079 9.9 1.0 +FRB 300 449.7 35 364.7 0.622 10.7 1.0 +FRB 301 900.2 35 815.2 0.150 9.9 3.0 +FRB 302 863.7 35 778.7 0.837 37.9 2.0 +FRB 303 275.3 35 190.3 0.104 18.8 3.0 +FRB 304 179.1 35 94.1 0.000 109.1 3.0 +FRB 305 814.0 35 729.0 0.420 11.6 3.0 +FRB 306 201.2 35 116.2 0.010 13.7 1.0 +FRB 307 517.9 35 432.9 0.633 11.2 4.0 +FRB 308 548.6 35 463.6 0.470 11.9 2.0 +FRB 309 385.2 35 300.2 0.227 55.9 2.0 +FRB 310 347.6 35 262.6 0.170 12.2 3.0 +FRB 311 266.5 35 181.5 0.068 15.9 4.0 +FRB 312 359.8 35 274.8 0.362 13.7 2.0 +FRB 313 1062.6 35 977.6 0.864 11.0 2.0 +FRB 314 602.4 35 517.4 0.390 27.8 1.0 +FRB 315 615.3 35 530.3 0.815 13.1 2.0 +FRB 316 930.0 35 845.0 0.490 19.8 4.0 +FRB 317 652.9 35 567.9 0.633 12.2 5.0 +FRB 318 634.4 35 549.4 0.407 20.7 2.0 +FRB 319 747.8 35 662.8 0.086 9.6 4.0 +FRB 320 596.2 35 511.2 0.603 21.3 2.0 +FRB 321 469.1 35 384.1 0.387 52.5 3.0 +FRB 322 1028.2 35 943.2 0.645 11.3 2.0 +FRB 323 430.6 35 345.6 0.345 12.5 0.0 +FRB 324 1121.6 35 1036.6 1.146 11.2 3.0 +FRB 325 403.1 35 318.1 0.284 26.6 3.0 +FRB 326 563.6 35 478.6 0.689 22.1 1.0 +FRB 327 1644.2 35 1559.2 2.063 13.4 3.0 +FRB 328 389.5 35 304.5 0.307 23.9 3.0 +FRB 329 624.6 35 539.6 0.159 62.3 2.0 +FRB 330 490.1 35 405.1 0.532 14.0 2.0 +FRB 331 912.3 35 827.3 0.645 15.9 3.0 +FRB 332 692.6 35 607.6 0.798 27.3 2.0 +FRB 333 179.2 35 94.2 0.103 18.5 3.0 +FRB 334 780.0 35 695.0 0.408 17.7 4.0 +FRB 335 964.2 35 879.2 1.173 11.6 1.0 +FRB 336 203.2 35 118.2 0.092 14.0 3.0 +FRB 337 698.1 35 613.1 0.460 38.8 3.0 +FRB 338 338.5 35 253.5 0.318 15.2 3.0 +FRB 339 520.4 35 435.4 0.439 12.8 2.0 +FRB 340 958.2 35 873.2 0.289 12.3 2.0 +FRB 341 576.5 35 491.5 0.514 24.2 3.0 +FRB 342 418.5 35 333.5 0.370 22.6 3.0 +FRB 343 296.4 35 211.4 0.053 18.3 3.0 +FRB 344 666.2 35 581.2 0.846 12.6 1.0 +FRB 345 315.6 35 230.6 0.285 20.5 3.0 +FRB 346 140.5 35 55.5 0.036 12.0 0.0 +FRB 347 764.2 35 679.2 0.951 9.5 1.0 +FRB 348 841.2 35 756.2 0.603 14.6 0.0 +FRB 349 938.2 35 853.2 0.192 20.4 3.0 +FRB 350 489.1 35 404.1 0.241 13.3 1.0 +FRB 351 655.5 35 570.5 0.442 12.3 2.0 +FRB 352 552.8 35 467.8 0.194 71.4 1.0 +FRB 353 2749.7 35 2664.7 2.304 9.9 0.0 +FRB 354 3004.1 35 2919.1 0.315 14.3 3.0 +FRB 355 668.2 35 583.2 0.132 33.2 3.0 +FRB 356 663.6 35 578.6 0.575 19.0 2.0 +FRB 357 564.6 35 479.6 0.333 86.8 4.0 +FRB 358 485.8 35 400.8 0.378 19.0 1.0 +FRB 359 639.6 35 554.6 0.238 131.0 2.0 +FRB 360 94.2 35 9.2 0.003 23.9 2.0 +FRB 361 1468.8 35 1383.8 0.241 29.3 3.0 +FRB 362 215.7 35 130.7 0.081 20.8 2.0 +FRB 363 969.2 35 884.2 0.571 16.2 2.0 +FRB 364 1324.9 35 1239.9 1.313 12.0 5.0 +FRB 365 426.8 35 341.8 0.429 20.7 4.0 +FRB 366 524.1 35 439.1 0.060 28.2 3.0 +FRB 367 686.1 35 601.1 0.764 24.5 2.0 +FRB 368 1243.9 35 1158.9 1.332 14.0 2.0 +FRB 369 875.0 35 790.0 0.899 23.3 2.0 +FRB 370 1351.9 35 1266.9 1.325 24.4 4.0 +FRB 371 402.8 35 317.8 0.171 40.1 2.0 +FRB 372 884.3 35 799.3 0.408 9.6 3.0 +FRB 373 411.0 35 326.0 0.022 11.8 4.0 +FRB 374 494.9 35 409.9 0.516 9.8 3.0 +FRB 375 645.2 35 560.2 0.607 12.5 2.0 +FRB 376 504.0 35 419.0 0.452 12.2 1.0 +FRB 377 593.8 35 508.8 0.620 12.0 3.0 +FRB 378 491.2 35 406.2 0.141 21.8 3.0 +FRB 379 395.1 35 310.1 0.429 16.3 3.0 +FRB 380 566.1 35 481.1 0.515 10.0 3.0 +FRB 381 181.1 35 96.1 0.065 22.5 2.0 +FRB 382 532.3 35 447.3 0.590 11.1 2.0 +FRB 383 991.9 35 906.9 1.222 15.6 2.0 +FRB 384 1035.4 35 950.4 1.114 27.8 3.0 +FRB 385 715.9 35 630.9 0.090 19.1 4.0 +FRB 386 691.9 35 606.9 0.696 9.9 4.0 +FRB 387 1031.6 35 946.6 1.312 10.3 4.0 +FRB 388 181.0 35 96.0 0.136 26.0 2.0 +FRB 389 362.4 35 277.4 0.287 10.0 2.0 +FRB 390 503.6 35 418.6 0.639 29.2 3.0 +FRB 391 667.5 35 582.5 0.128 13.7 4.0 +FRB 392 765.5 35 680.5 0.742 19.0 3.0 +FRB 393 135.7 35 50.7 0.039 27.9 4.0 +FRB 394 599.2 35 514.2 0.240 24.3 4.0 +FRB 395 1321.2 35 1236.2 0.407 12.3 2.0 +FRB 396 388.5 35 303.5 0.135 10.1 2.0 +FRB 397 269.0 35 184.0 0.123 30.0 4.0 +FRB 398 944.6 35 859.6 0.874 23.0 2.0 +FRB 399 259.8 35 174.8 0.019 29.0 2.0 +FRB 400 916.6 35 831.6 0.997 14.4 3.0 +FRB 401 266.6 35 181.6 0.241 10.5 2.0 +FRB 402 451.4 35 366.4 0.454 17.4 3.0 +FRB 403 724.2 35 639.2 0.793 32.0 2.0 +FRB 404 187.5 35 102.5 0.046 16.4 3.0 +FRB 405 485.5 35 400.5 0.162 20.3 4.0 +FRB 406 236.1 35 151.1 0.142 18.3 3.0 +FRB 407 730.6 35 645.6 0.720 41.2 3.0 +FRB 408 272.6 35 187.6 0.141 39.8 3.0 +FRB 409 524.5 35 439.5 0.623 11.7 0.0 +FRB 410 489.3 35 404.3 0.446 15.3 1.0 +FRB 411 448.1 35 363.1 0.467 12.7 2.0 +FRB 412 1045.2 35 960.2 1.060 27.5 4.0 +FRB 413 958.7 35 873.7 1.035 23.9 3.0 +FRB 414 233.6 35 148.6 0.075 9.6 3.0 +FRB 415 659.9 35 574.9 0.318 10.5 2.0 +FRB 416 635.2 35 550.2 0.418 22.9 3.0 +FRB 417 2488.2 35 2403.2 2.001 22.0 3.0 +FRB 418 416.8 35 331.8 0.462 9.6 4.0 +FRB 419 460.9 35 375.9 0.164 76.9 2.0 +FRB 420 559.6 35 474.6 0.720 14.7 4.0 +FRB 421 878.5 35 793.5 0.631 12.7 3.0 +FRB 422 836.2 35 751.2 0.306 10.6 1.0 +FRB 423 717.2 35 632.2 0.901 10.3 2.0 +FRB 424 203.8 35 118.8 0.008 50.4 4.0 +FRB 425 332.5 35 247.5 0.255 10.0 2.0 +FRB 426 513.5 35 428.5 0.412 11.9 3.0 +FRB 427 890.1 35 805.1 1.106 17.0 2.0 +FRB 428 1119.1 35 1034.1 1.247 11.6 1.0 +FRB 429 692.3 35 607.3 0.665 17.5 3.0 +FRB 430 794.0 35 709.0 0.265 56.4 4.0 +FRB 431 692.8 35 607.8 0.926 11.1 3.0 +FRB 432 529.2 35 444.2 0.226 111.0 2.0 +FRB 433 476.0 35 391.0 0.458 12.5 4.0 +FRB 434 439.2 35 354.2 0.270 10.9 1.0 +FRB 435 842.2 35 757.2 0.772 19.2 1.0 +FRB 436 644.8 35 559.8 0.709 26.2 1.0 +FRB 437 389.8 35 304.8 0.112 13.5 1.0 +FRB 438 363.0 35 278.0 0.166 62.7 0.0 +FRB 439 1050.3 35 965.3 0.544 26.1 2.0 +FRB 440 182.9 35 97.9 0.002 19.0 1.0 +FRB 441 686.3 35 601.3 0.151 13.3 2.0 +FRB 442 335.0 35 250.0 0.104 13.5 4.0 +FRB 443 613.8 35 528.8 0.791 14.1 3.0 +FRB 444 317.5 35 232.5 0.274 11.4 2.0 +FRB 445 427.7 35 342.7 0.551 25.2 4.0 +FRB 446 155.8 35 70.8 0.075 20.2 4.0 +FRB 447 988.1 35 903.1 1.024 13.3 3.0 +FRB 448 256.9 35 171.9 0.065 11.8 3.0 +FRB 449 412.3 35 327.3 0.343 48.7 2.0 +FRB 450 595.9 35 510.9 0.255 69.4 4.0 +FRB 451 210.9 35 125.9 0.012 113.3 3.0 +FRB 452 463.7 35 378.7 0.245 14.9 2.0 +FRB 453 831.0 35 746.0 0.714 9.8 3.0 +FRB 454 3302.9 35 3217.9 1.408 10.4 4.0 +FRB 455 924.3 35 839.3 0.244 16.5 3.0 +FRB 456 625.2 35 540.2 0.519 15.8 3.0 +FRB 457 836.0 35 751.0 0.497 28.4 2.0 +FRB 458 1100.8 35 1015.8 1.079 12.2 2.0 +FRB 459 380.1 35 295.1 0.149 16.6 3.0 +FRB 460 615.4 35 530.4 0.215 15.5 2.0 +FRB 461 786.4 35 701.4 0.364 77.7 2.0 +FRB 462 460.6 35 375.6 0.153 12.4 2.0 +FRB 463 734.3 35 649.3 0.393 14.9 2.0 +FRB 464 1370.5 35 1285.5 0.292 16.2 2.0 +FRB 465 463.3 35 378.3 0.344 13.3 4.0 +FRB 466 250.4 35 165.4 0.001 11.0 2.0 +FRB 467 478.9 35 393.9 0.471 10.8 4.0 +FRB 468 164.9 35 79.9 0.020 48.7 1.0 +FRB 469 331.3 35 246.3 0.336 36.3 3.0 +FRB 470 940.2 35 855.2 0.651 18.3 4.0 +FRB 471 740.2 35 655.2 0.844 9.7 2.0 +FRB 472 677.1 35 592.1 0.575 12.0 2.0 +FRB 473 910.6 35 825.6 0.963 10.3 2.0 +FRB 474 552.9 35 467.9 0.287 13.9 2.0 +FRB 475 342.1 35 257.1 0.315 201.4 1.0 +FRB 476 323.7 35 238.7 0.180 31.2 2.0 +FRB 477 553.2 35 468.2 0.354 29.9 1.0 +FRB 478 541.8 35 456.8 0.428 10.2 3.0 +FRB 479 330.2 35 245.2 0.326 46.8 2.0 +FRB 480 518.4 35 433.4 0.364 18.8 4.0 +FRB 481 381.3 35 296.3 0.297 36.2 4.0 +FRB 482 1405.2 35 1320.2 1.059 15.4 2.0 +FRB 483 282.5 35 197.5 0.209 14.5 3.0 +FRB 484 610.2 35 525.2 0.515 35.2 3.0 +FRB 485 270.6 35 185.6 0.323 14.5 3.0 +FRB 486 375.0 35 290.0 0.249 30.8 2.0 +FRB 487 982.7 35 897.7 0.836 10.0 2.0 +FRB 488 248.4 35 163.4 0.076 11.2 1.0 +FRB 489 2137.1 35 2052.1 0.049 15.4 5.0 +FRB 490 423.0 35 338.0 0.311 11.5 3.0 +FRB 491 494.6 35 409.6 0.116 12.8 3.0 +FRB 492 211.5 35 126.5 0.145 12.8 2.0 +FRB 493 871.3 35 786.3 0.917 25.3 5.0 +FRB 494 864.6 35 779.6 0.557 10.3 3.0 +FRB 495 960.7 35 875.7 0.209 9.9 2.0 +FRB 496 377.2 35 292.2 0.223 136.5 2.0 +FRB 497 420.1 35 335.1 0.275 14.1 2.0 +FRB 498 212.0 35 127.0 0.022 11.5 4.0 +FRB 499 301.6 35 216.6 0.172 9.6 0.0 +FRB 500 892.1 35 807.1 1.031 17.3 3.0 +FRB 501 491.5 35 406.5 0.193 10.1 2.0 +FRB 502 391.7 35 306.7 0.071 23.1 2.0 +FRB 503 435.7 35 350.7 0.336 11.9 2.0 +FRB 504 232.4 35 147.4 0.003 9.7 4.0 +FRB 505 148.3 35 63.3 0.051 410.7 3.0 +FRB 506 604.8 35 519.8 0.845 10.9 1.0 +FRB 507 367.8 35 282.8 0.316 15.0 3.0 +FRB 508 491.2 35 406.2 0.590 24.1 0.0 +FRB 509 1014.1 35 929.1 0.332 16.1 4.0 +FRB 510 1117.8 35 1032.8 0.924 11.4 3.0 +FRB 511 472.8 35 387.8 0.554 16.1 4.0 +FRB 512 642.9 35 557.9 0.430 11.8 2.0 +FRB 513 208.0 35 123.0 0.152 17.9 2.0 +FRB 514 783.0 35 698.0 0.930 12.7 3.0 +FRB 515 869.7 35 784.7 0.328 23.6 2.0 +FRB 516 274.3 35 189.3 0.250 13.0 4.0 +FRB 517 458.5 35 373.5 0.546 12.5 4.0 +FRB 518 1750.0 35 1665.0 0.991 10.2 1.0 +FRB 519 1113.0 35 1028.0 1.267 14.2 2.0 +FRB 520 257.2 35 172.2 0.002 13.4 2.0 +FRB 521 1075.0 35 990.0 0.055 10.8 3.0 +FRB 522 313.5 35 228.5 0.077 13.5 4.0 +FRB 523 527.0 35 442.0 0.442 10.9 3.0 +FRB 524 549.7 35 464.7 0.250 11.6 1.0 +FRB 525 990.7 35 905.7 0.987 60.2 2.0 +FRB 526 446.0 35 361.0 0.548 32.2 1.0 +FRB 527 398.9 35 313.9 0.420 11.3 3.0 +FRB 528 257.7 35 172.7 0.206 42.6 1.0 +FRB 529 413.9 35 328.9 0.428 88.2 2.0 +FRB 530 455.6 35 370.6 0.043 15.1 4.0 +FRB 531 346.0 35 261.0 0.136 268.1 3.0 +FRB 532 587.8 35 502.8 0.440 45.8 2.0 +FRB 533 343.5 35 258.5 0.357 56.1 3.0 +FRB 534 1243.0 35 1158.0 1.553 13.7 1.0 +FRB 535 483.7 35 398.7 0.426 9.9 3.0 +FRB 536 471.1 35 386.1 0.429 17.0 3.0 +FRB 537 269.3 35 184.3 0.267 20.6 1.0 +FRB 538 242.4 35 157.4 0.066 12.8 3.0 +FRB 539 1627.4 35 1542.4 1.156 13.3 2.0 +FRB 540 562.4 35 477.4 0.595 24.3 2.0 +FRB 541 125.9 35 40.9 0.025 11.6 1.0 +FRB 542 1062.3 35 977.3 1.306 31.0 3.0 +FRB 543 366.7 35 281.7 0.433 13.0 2.0 +FRB 544 814.9 35 729.9 0.752 13.7 3.0 +FRB 545 124.3 35 39.3 0.046 14.8 4.0 +FRB 546 431.5 35 346.5 0.041 12.5 2.0 +FRB 547 312.5 35 227.5 0.170 18.6 1.0 +FRB 548 720.7 35 635.7 0.329 26.7 2.0 +FRB 549 537.4 35 452.4 0.321 23.5 2.0 +FRB 550 437.0 35 352.0 0.403 11.9 3.0 +FRB 551 443.4 35 358.4 0.390 28.3 2.0 +FRB 552 585.0 35 500.0 0.368 19.9 1.0 +FRB 553 811.8 35 726.8 0.789 16.2 3.0 +FRB 554 608.4 35 523.4 0.389 21.8 2.0 +FRB 555 281.2 35 196.2 0.099 17.0 3.0 +FRB 556 594.1 35 509.1 0.145 13.5 4.0 +FRB 557 329.8 35 244.8 0.282 33.1 3.0 +FRB 558 593.5 35 508.5 0.700 61.8 1.0 +FRB 559 1161.1 35 1076.1 0.899 12.8 2.0 +FRB 560 290.6 35 205.6 0.026 29.3 2.0 +FRB 561 416.8 35 331.8 0.419 25.7 3.0 +FRB 562 1513.6 35 1428.6 0.275 16.6 3.0 +FRB 563 408.6 35 323.6 0.386 41.7 2.0 +FRB 564 1315.3 35 1230.3 1.159 36.9 3.0 +FRB 565 446.2 35 361.2 0.158 13.4 1.0 +FRB 566 298.4 35 213.4 0.207 9.7 2.0 +FRB 567 721.1 35 636.1 0.351 67.3 2.0 +FRB 568 184.3 35 99.3 0.036 171.1 2.0 +FRB 569 129.6 35 44.6 0.097 10.8 1.0 +FRB 570 624.8 35 539.8 0.150 132.1 2.0 +FRB 571 1829.0 35 1744.0 1.818 22.9 3.0 +FRB 572 438.5 35 353.5 0.205 183.6 3.0 +FRB 573 1390.3 35 1305.3 1.050 16.4 1.0 +FRB 574 829.0 35 744.0 0.253 20.2 4.0 +FRB 575 771.9 35 686.9 0.675 11.6 1.0 +FRB 576 575.5 35 490.5 0.693 40.1 3.0 +FRB 577 282.4 35 197.4 0.140 17.0 2.0 +FRB 578 166.3 35 81.3 0.180 11.0 3.0 +FRB 579 390.1 35 305.1 0.124 9.7 1.0 +FRB 580 518.5 35 433.5 0.476 67.6 2.0 +FRB 581 485.0 35 400.0 0.047 14.9 5.0 +FRB 582 1440.3 35 1355.3 1.788 18.3 2.0 +FRB 583 648.5 35 563.5 0.519 21.9 2.0 +FRB 584 732.4 35 647.4 0.514 14.0 3.0 +FRB 585 498.6 35 413.6 0.257 15.4 2.0 +FRB 586 1418.2 35 1333.2 0.020 11.6 4.0 +FRB 587 510.3 35 425.3 0.508 12.5 1.0 +FRB 588 641.0 35 556.0 0.536 58.8 4.0 +FRB 589 176.0 35 91.0 0.032 9.8 3.0 +FRB 590 515.8 35 430.8 0.441 13.9 1.0 +FRB 591 131.3 35 46.3 0.040 151.3 1.0 +FRB 592 437.2 35 352.2 0.449 62.6 2.0 +FRB 593 175.1 35 90.1 0.151 289.1 2.0 +FRB 594 702.0 35 617.0 0.526 12.5 3.0 +FRB 595 1701.6 35 1616.6 1.675 12.3 2.0 +FRB 596 459.8 35 374.8 0.572 13.7 2.0 +FRB 597 2375.3 35 2290.3 2.793 9.7 3.0 +FRB 598 445.5 35 360.5 0.209 17.7 2.0 +FRB 599 199.4 35 114.4 0.122 20.1 2.0 +FRB 600 1155.0 35 1070.0 0.493 16.3 2.0 +FRB 601 292.6 35 207.6 0.101 27.7 3.0 +FRB 602 410.7 35 325.7 0.242 10.8 2.0 +FRB 603 192.1 35 107.1 0.126 18.4 4.0 +FRB 604 373.7 35 288.7 0.031 9.9 3.0 +FRB 605 722.7 35 637.7 0.574 13.5 5.0 +FRB 606 915.4 35 830.4 0.870 12.4 3.0 +FRB 607 343.0 35 258.0 0.287 13.8 3.0 +FRB 608 127.5 35 42.5 0.055 15.8 2.0 +FRB 609 771.3 35 686.3 0.987 23.1 3.0 +FRB 610 506.2 35 421.2 0.501 18.4 3.0 +FRB 611 607.9 35 522.9 0.242 27.8 2.0 +FRB 612 975.2 35 890.2 0.981 34.8 1.0 +FRB 613 592.0 35 507.0 0.018 10.5 2.0 +FRB 614 653.4 35 568.4 0.476 25.1 2.0 +FRB 615 843.6 35 758.6 1.086 10.4 3.0 +FRB 616 348.3 35 263.3 0.181 10.1 3.0 +FRB 617 185.9 35 100.9 0.118 24.8 3.0 +FRB 618 1906.7 35 1821.7 1.795 13.0 2.0 +FRB 619 237.6 35 152.6 0.184 27.8 1.0 +FRB 620 267.9 35 182.9 0.116 58.0 3.0 +FRB 621 406.6 35 321.6 0.415 15.0 3.0 +FRB 622 430.5 35 345.5 0.455 12.6 3.0 +FRB 623 1150.5 35 1065.5 0.369 16.7 3.0 +FRB 624 383.2 35 298.2 0.175 15.8 3.0 +FRB 625 671.0 35 586.0 0.894 20.1 3.0 +FRB 626 372.8 35 287.8 0.102 14.0 2.0 +FRB 627 888.9 35 803.9 0.032 12.9 3.0 +FRB 628 1052.2 35 967.2 1.371 26.5 2.0 +FRB 629 1023.3 35 938.3 1.418 21.5 1.0 +FRB 630 281.3 35 196.3 0.041 25.2 4.0 +FRB 631 238.1 35 153.1 0.251 12.6 2.0 +FRB 632 552.2 35 467.2 0.562 11.6 3.0 +FRB 633 558.2 35 473.2 0.484 9.8 3.0 +FRB 634 337.6 35 252.6 0.080 22.0 1.0 +FRB 635 295.2 35 210.2 0.209 11.4 3.0 +FRB 636 575.8 35 490.8 0.189 10.4 2.0 +FRB 637 375.9 35 290.9 0.064 14.7 1.0 +FRB 638 129.2 35 44.2 0.073 24.3 2.0 +FRB 639 198.3 35 113.3 0.058 10.5 0.0 +FRB 640 445.5 35 360.5 0.330 87.9 1.0 +FRB 641 215.9 35 130.9 0.114 35.2 1.0 +FRB 642 212.4 35 127.4 0.084 16.9 3.0 +FRB 643 1228.4 35 1143.4 1.305 13.0 3.0 +FRB 644 578.5 35 493.5 0.149 11.5 1.0 +FRB 645 706.3 35 621.3 0.794 39.2 1.0 +FRB 646 597.8 35 512.8 0.536 38.6 3.0 +FRB 647 283.6 35 198.6 0.195 14.3 2.0 +FRB 648 2236.7 35 2151.7 1.327 20.4 2.0 +FRB 649 694.4 35 609.4 0.099 15.4 4.0 +FRB 650 213.5 35 128.5 0.136 11.9 3.0 +FRB 651 961.6 35 876.6 0.475 28.1 2.0 +FRB 652 801.4 35 716.4 0.818 12.3 2.0 +FRB 653 396.1 35 311.1 0.233 22.6 4.0 +FRB 654 1093.6 35 1008.6 0.806 10.9 3.0 +FRB 655 493.6 35 408.6 0.322 9.9 1.0 +FRB 656 518.1 35 433.1 0.520 14.7 3.0 +FRB 657 478.0 35 393.0 0.094 16.7 4.0 +FRB 658 242.1 35 157.1 0.098 139.7 3.0 +FRB 659 261.7 35 176.7 0.142 43.3 3.0 +FRB 660 443.3 35 358.3 0.042 11.6 2.0 +FRB 661 1386.8 35 1301.8 0.544 26.7 3.0 +FRB 662 475.0 35 390.0 0.228 22.0 1.0 +FRB 663 545.5 35 460.5 0.709 9.7 3.0 +FRB 664 220.1 35 135.1 0.093 21.6 2.0 +FRB 665 809.9 35 724.9 0.829 12.2 2.0 +FRB 666 358.1 35 273.1 0.122 14.5 1.0 +FRB 667 842.0 35 757.0 0.323 12.4 3.0 +FRB 668 1395.1 35 1310.1 0.441 11.5 4.0 +FRB 669 732.5 35 647.5 0.612 42.3 3.0 +FRB 670 423.2 35 338.2 0.322 15.5 2.0 +FRB 671 1328.1 35 1243.1 0.927 10.8 1.0 +FRB 672 530.2 35 445.2 0.490 13.2 2.0 +FRB 673 1584.2 35 1499.2 1.705 15.0 3.0 +FRB 674 147.1 35 62.1 0.047 15.8 2.0 +FRB 675 726.1 35 641.1 0.903 16.9 3.0 +FRB 676 346.6 35 261.6 0.028 10.1 4.0 +FRB 677 1399.0 35 1314.0 1.447 15.0 3.0 +FRB 678 884.5 35 799.5 1.112 9.8 3.0 +FRB 679 1032.9 35 947.9 1.183 23.1 2.0 +FRB 680 182.6 35 97.6 0.056 12.3 1.0 +FRB 681 1051.2 35 966.2 1.131 10.4 2.0 +FRB 682 1485.1 35 1400.1 1.608 13.5 3.0 +FRB 683 299.7 35 214.7 0.150 17.1 5.0 +FRB 684 395.2 35 310.2 0.229 13.2 3.0 +FRB 685 517.8 35 432.8 0.276 23.0 1.0 +FRB 686 356.1 35 271.1 0.325 18.7 3.0 +FRB 687 368.5 35 283.5 0.250 54.5 1.0 +FRB 688 277.4 35 192.4 0.303 18.4 2.0 +FRB 689 644.6 35 559.6 0.764 10.1 2.0 +FRB 690 1221.8 35 1136.8 0.005 10.1 4.0 +FRB 691 422.4 35 337.4 0.321 14.3 3.0 +FRB 692 374.0 35 289.0 0.400 53.2 1.0 +FRB 693 422.3 35 337.3 0.245 42.6 3.0 +FRB 694 283.2 35 198.2 0.327 15.3 2.0 +FRB 695 1116.8 35 1031.8 0.638 39.6 4.0 +FRB 696 408.3 35 323.3 0.353 10.9 2.0 +FRB 697 296.8 35 211.8 0.026 30.9 4.0 +FRB 698 294.1 35 209.1 0.119 22.3 2.0 +FRB 699 385.7 35 300.7 0.272 68.5 2.0 +FRB 700 351.1 35 266.1 0.216 15.3 1.0 +FRB 701 189.6 35 104.6 0.042 13.8 2.0 +FRB 702 180.7 35 95.7 0.136 11.0 2.0 +FRB 703 653.5 35 568.5 0.285 11.2 4.0 +FRB 704 779.7 35 694.7 1.103 11.9 2.0 +FRB 705 217.9 35 132.9 0.018 15.9 1.0 +FRB 706 185.0 35 100.0 0.092 34.9 2.0 +FRB 707 439.6 35 354.6 0.427 41.0 3.0 +FRB 708 623.7 35 538.7 0.238 9.7 3.0 +FRB 709 450.0 35 365.0 0.267 11.7 3.0 +FRB 710 893.3 35 808.3 1.138 10.0 3.0 +FRB 711 414.6 35 329.6 0.323 37.3 3.0 +FRB 712 851.4 35 766.4 0.832 12.6 3.0 +FRB 713 214.4 35 129.4 0.069 12.4 2.0 +FRB 714 611.7 35 526.7 0.485 10.6 2.0 +FRB 715 301.7 35 216.7 0.112 21.8 2.0 +FRB 716 761.3 35 676.3 0.537 11.8 1.0 +FRB 717 309.8 35 224.8 0.138 14.8 2.0 +FRB 718 697.6 35 612.6 0.334 35.4 1.0 +FRB 719 185.1 35 100.1 0.131 11.1 3.0 +FRB 720 1456.7 35 1371.7 1.606 11.3 1.0 +FRB 721 138.2 35 53.2 0.032 9.5 1.0 +FRB 722 163.7 35 78.7 0.034 50.7 1.0 +FRB 723 308.7 35 223.7 0.345 29.4 2.0 +FRB 724 582.7 35 497.7 0.376 9.5 3.0 +FRB 725 771.6 35 686.6 0.037 16.4 1.0 +FRB 726 483.9 35 398.9 0.387 21.6 3.0 +FRB 727 951.5 35 866.5 0.402 11.3 4.0 +FRB 728 225.3 35 140.3 0.049 12.7 1.0 +FRB 729 561.8 35 476.8 0.320 10.1 3.0 +FRB 730 603.7 35 518.7 0.743 10.6 2.0 +FRB 731 1044.5 35 959.5 0.675 15.8 3.0 +FRB 732 409.1 35 324.1 0.256 13.4 2.0 +FRB 733 341.3 35 256.3 0.098 9.9 3.0 +FRB 734 1638.5 35 1553.5 0.205 88.3 2.0 +FRB 735 443.9 35 358.9 0.132 49.0 4.0 +FRB 736 490.6 35 405.6 0.501 18.0 2.0 +FRB 737 420.7 35 335.7 0.119 18.0 3.0 +FRB 738 686.3 35 601.3 0.417 15.7 3.0 +FRB 739 767.1 35 682.1 0.480 10.6 1.0 +FRB 740 475.7 35 390.7 0.527 9.8 3.0 +FRB 741 1537.6 35 1452.6 0.862 11.3 3.0 +FRB 742 195.3 35 110.3 0.168 9.9 2.0 +FRB 743 619.2 35 534.2 0.673 39.1 3.0 +FRB 744 162.7 35 77.7 0.040 62.5 3.0 +FRB 745 1006.0 35 921.0 0.137 16.0 4.0 +FRB 746 358.5 35 273.5 0.096 112.9 2.0 +FRB 747 560.2 35 475.2 0.201 10.7 4.0 +FRB 748 690.6 35 605.6 0.668 25.1 4.0 +FRB 749 654.1 35 569.1 0.565 9.9 2.0 +FRB 750 692.5 35 607.5 0.083 16.8 1.0 +FRB 751 396.5 35 311.5 0.229 29.3 4.0 +FRB 752 223.3 35 138.3 0.120 78.2 2.0 +FRB 753 483.5 35 398.5 0.427 10.1 3.0 +FRB 754 937.4 35 852.4 1.326 29.9 2.0 +FRB 755 188.5 35 103.5 0.138 18.9 2.0 +FRB 756 529.8 35 444.8 0.512 12.6 1.0 +FRB 757 196.3 35 111.3 0.177 12.2 3.0 +FRB 758 489.6 35 404.6 0.501 159.3 1.0 +FRB 759 527.5 35 442.5 0.202 25.6 4.0 +FRB 760 544.7 35 459.7 0.613 22.5 3.0 +FRB 761 306.1 35 221.1 0.292 13.8 1.0 +FRB 762 650.9 35 565.9 0.731 50.7 3.0 +FRB 763 478.2 35 393.2 0.052 10.7 5.0 +FRB 764 190.9 35 105.9 0.113 9.8 4.0 +FRB 765 1307.3 35 1222.3 1.913 20.9 2.0 +FRB 766 1313.0 35 1228.0 0.787 23.7 3.0 +FRB 767 408.8 35 323.8 0.145 78.2 5.0 +FRB 768 831.6 35 746.6 0.165 9.9 3.0 +FRB 769 664.2 35 579.2 0.595 11.4 1.0 +FRB 770 259.1 35 174.1 0.093 120.2 4.0 +FRB 771 310.4 35 225.4 0.199 9.7 4.0 +FRB 772 962.8 35 877.8 0.919 11.5 4.0 +FRB 773 830.4 35 745.4 1.007 9.9 3.0 +FRB 774 855.0 35 770.0 0.619 27.6 4.0 +FRB 775 324.6 35 239.6 0.248 127.6 3.0 +FRB 776 596.0 35 511.0 0.500 20.0 3.0 +FRB 777 533.7 35 448.7 0.304 18.4 2.0 +FRB 778 1653.2 35 1568.2 0.729 10.7 1.0 +FRB 779 662.3 35 577.3 0.807 11.8 3.0 +FRB 780 410.8 35 325.8 0.014 72.7 3.0 +FRB 781 856.2 35 771.2 0.959 18.5 2.0 +FRB 782 364.5 35 279.5 0.222 34.6 1.0 +FRB 783 486.6 35 401.6 0.508 10.2 3.0 +FRB 784 362.0 35 277.0 0.193 27.8 3.0 +FRB 785 1218.0 35 1133.0 1.560 19.0 2.0 +FRB 786 1109.0 35 1024.0 1.042 24.5 4.0 +FRB 787 1330.3 35 1245.3 1.535 11.2 2.0 +FRB 788 834.8 35 749.8 0.782 13.6 4.0 +FRB 789 181.3 35 96.3 0.073 34.9 4.0 +FRB 790 538.9 35 453.9 0.439 24.6 2.0 +FRB 791 492.1 35 407.1 0.527 14.2 2.0 +FRB 792 176.4 35 91.4 0.106 16.5 4.0 +FRB 793 427.2 35 342.2 0.020 13.3 3.0 +FRB 794 307.4 35 222.4 0.060 31.0 2.0 +FRB 795 210.7 35 125.7 0.015 12.4 2.0 +FRB 796 1031.6 35 946.6 0.079 12.8 3.0 +FRB 797 1439.8 35 1354.8 0.276 390.0 2.0 +FRB 798 205.5 35 120.5 0.044 424.9 2.0 +FRB 799 335.2 35 250.2 0.224 81.3 3.0 +FRB 800 737.1 35 652.1 0.738 11.7 1.0 +FRB 801 657.5 35 572.5 0.689 10.5 4.0 +FRB 802 325.0 35 240.0 0.197 17.6 1.0 +FRB 803 360.9 35 275.9 0.406 18.9 3.0 +FRB 804 1518.7 35 1433.7 0.719 10.4 2.0 +FRB 805 650.4 35 565.4 0.628 11.0 3.0 +FRB 806 310.7 35 225.7 0.286 12.4 3.0 +FRB 807 318.1 35 233.1 0.159 43.1 2.0 +FRB 808 422.6 35 337.6 0.476 11.2 2.0 +FRB 809 243.3 35 158.3 0.160 13.8 4.0 +FRB 810 1414.7 35 1329.7 0.566 21.0 3.0 +FRB 811 672.1 35 587.1 0.831 12.7 3.0 +FRB 812 743.0 35 658.0 0.912 19.6 2.0 +FRB 813 906.6 35 821.6 0.057 10.3 3.0 +FRB 814 539.5 35 454.5 0.549 68.4 2.0 +FRB 815 497.4 35 412.4 0.248 66.2 4.0 +FRB 816 861.2 35 776.2 0.986 10.9 2.0 +FRB 817 184.9 35 99.9 0.001 12.0 3.0 +FRB 818 1703.6 35 1618.6 0.953 15.6 2.0 +FRB 819 1362.6 35 1277.6 0.661 11.1 3.0 +FRB 820 434.7 35 349.7 0.075 12.2 1.0 +FRB 821 1323.7 35 1238.7 1.049 13.9 4.0 +FRB 822 171.3 35 86.3 0.130 9.5 3.0 +FRB 823 329.5 35 244.5 0.369 9.7 2.0 +FRB 824 563.8 35 478.8 0.498 57.3 0.0 +FRB 825 513.6 35 428.6 0.049 10.2 2.0 +FRB 826 833.9 35 748.9 1.049 16.9 2.0 +FRB 827 734.8 35 649.8 0.743 10.5 2.0 +FRB 828 214.4 35 129.4 0.196 12.2 5.0 +FRB 829 639.2 35 554.2 0.320 12.6 3.0 +FRB 830 393.9 35 308.9 0.321 36.9 2.0 +FRB 831 554.7 35 469.7 0.716 18.4 3.0 +FRB 832 475.1 35 390.1 0.149 18.5 1.0 +FRB 833 441.1 35 356.1 0.391 19.2 2.0 +FRB 834 239.7 35 154.7 0.038 63.9 2.0 +FRB 835 733.9 35 648.9 0.785 18.4 1.0 +FRB 836 706.7 35 621.7 0.781 17.0 1.0 +FRB 837 388.2 35 303.2 0.385 30.8 3.0 +FRB 838 1225.9 35 1140.9 0.971 16.8 1.0 +FRB 839 391.6 35 306.6 0.369 23.3 3.0 +FRB 840 611.5 35 526.5 0.205 16.4 2.0 +FRB 841 1052.3 35 967.3 0.026 14.7 3.0 +FRB 842 503.5 35 418.5 0.376 13.0 4.0 +FRB 843 809.9 35 724.9 0.826 15.8 2.0 +FRB 844 236.2 35 151.2 0.157 74.9 2.0 +FRB 845 223.2 35 138.2 0.079 24.2 3.0 +FRB 846 343.7 35 258.7 0.178 23.3 2.0 +FRB 847 367.6 35 282.6 0.234 24.0 0.0 +FRB 848 1253.0 35 1168.0 0.789 10.5 3.0 +FRB 849 194.5 35 109.5 0.161 10.8 2.0 +FRB 850 477.9 35 392.9 0.519 14.0 3.0 +FRB 851 362.2 35 277.2 0.048 20.1 3.0 +FRB 852 530.0 35 445.0 0.275 16.5 0.0 +FRB 853 268.6 35 183.6 0.001 13.2 1.0 +FRB 854 899.1 35 814.1 0.322 20.0 1.0 +FRB 855 727.1 35 642.1 0.513 11.9 3.0 +FRB 856 352.4 35 267.4 0.014 36.7 1.0 +FRB 857 395.1 35 310.1 0.167 15.9 3.0 +FRB 858 848.2 35 763.2 0.870 32.7 3.0 +FRB 859 847.8 35 762.8 0.909 15.4 3.0 +FRB 860 526.7 35 441.7 0.546 33.0 3.0 +FRB 861 448.5 35 363.5 0.177 11.8 3.0 +FRB 862 345.2 35 260.2 0.249 12.3 1.0 +FRB 863 799.2 35 714.2 0.143 14.5 1.0 +FRB 864 1080.7 35 995.7 0.122 12.2 5.0 +FRB 865 892.1 35 807.1 0.914 34.4 3.0 +FRB 866 1352.0 35 1267.0 0.982 15.1 2.0 +FRB 867 674.1 35 589.1 0.356 184.9 3.0 +FRB 868 725.3 35 640.3 0.706 59.8 1.0 +FRB 869 325.9 35 240.9 0.300 12.6 3.0 +FRB 870 1809.5 35 1724.5 0.151 13.7 2.0 +FRB 871 408.5 35 323.5 0.342 69.6 4.0 +FRB 872 533.4 35 448.4 0.302 11.3 2.0 +FRB 873 1394.9 35 1309.9 0.888 10.6 2.0 +FRB 874 466.9 35 381.9 0.007 39.7 2.0 +FRB 875 152.1 35 67.1 0.018 43.9 1.0 +FRB 876 434.7 35 349.7 0.232 15.3 3.0 +FRB 877 676.8 35 591.8 0.553 17.4 1.0 +FRB 878 455.1 35 370.1 0.127 13.0 0.0 +FRB 879 485.5 35 400.5 0.142 30.9 1.0 +FRB 880 1341.2 35 1256.2 0.165 82.8 0.0 +FRB 881 292.7 35 207.7 0.248 124.8 2.0 +FRB 882 256.1 35 171.1 0.198 11.5 1.0 +FRB 883 234.8 35 149.8 0.220 11.3 3.0 +FRB 884 395.9 35 310.9 0.173 9.5 2.0 +FRB 885 384.6 35 299.6 0.230 449.6 2.0 +FRB 886 1467.8 35 1382.8 0.810 14.9 4.0 +FRB 887 167.8 35 82.8 0.062 22.8 2.0 +FRB 888 287.6 35 202.6 0.266 25.0 3.0 +FRB 889 116.9 35 31.9 0.033 89.5 1.0 +FRB 890 211.2 35 126.2 0.103 29.9 3.0 +FRB 891 807.2 35 722.2 0.785 10.5 2.0 +FRB 892 438.7 35 353.7 0.478 14.2 4.0 +FRB 893 175.2 35 90.2 0.023 17.4 1.0 +FRB 894 350.0 35 265.0 0.313 12.3 3.0 +FRB 895 1865.2 35 1780.2 1.939 10.4 2.0 +FRB 896 560.0 35 475.0 0.468 18.4 2.0 +FRB 897 198.2 35 113.2 0.039 233.6 2.0 +FRB 898 585.4 35 500.4 0.667 11.1 2.0 +FRB 899 347.7 35 262.7 0.258 13.7 2.0 +FRB 900 756.3 35 671.3 0.889 10.6 1.0 +FRB 901 210.4 35 125.4 0.010 11.4 0.0 +FRB 902 656.0 35 571.0 0.508 10.1 4.0 +FRB 903 1539.0 35 1454.0 2.030 15.9 2.0 +FRB 904 137.6 35 52.6 0.016 14.6 2.0 +FRB 905 480.9 35 395.9 0.081 45.1 2.0 +FRB 906 506.7 35 421.7 0.425 42.2 2.0 +FRB 907 479.0 35 394.0 0.264 13.5 4.0 +FRB 908 910.5 35 825.5 1.062 12.0 1.0 +FRB 909 764.0 35 679.0 1.017 25.4 1.0 +FRB 910 358.5 35 273.5 0.041 43.9 4.0 +FRB 911 100.5 35 15.5 0.007 92.1 3.0 +FRB 912 403.5 35 318.5 0.327 13.4 2.0 +FRB 913 349.2 35 264.2 0.161 32.6 4.0 +FRB 914 1399.6 35 1314.6 0.970 9.7 0.0 +FRB 915 130.8 35 45.8 0.049 27.4 2.0 +FRB 916 184.5 35 99.5 0.092 10.6 4.0 +FRB 917 553.7 35 468.7 0.241 10.1 3.0 +FRB 918 465.2 35 380.2 0.547 25.5 2.0 +FRB 919 627.3 35 542.3 0.410 31.8 2.0 +FRB 920 629.9 35 544.9 0.010 77.8 4.0 +FRB 921 779.1 35 694.1 0.449 60.8 2.0 +FRB 922 511.7 35 426.7 0.154 12.0 2.0 +FRB 923 224.6 35 139.6 0.012 51.8 3.0 +FRB 924 389.8 35 304.8 0.122 42.0 3.0 +FRB 925 661.0 35 576.0 0.818 15.7 2.0 +FRB 926 993.1 35 908.1 0.237 11.5 3.0 +FRB 927 1479.7 35 1394.7 1.498 9.7 3.0 +FRB 928 476.2 35 391.2 0.517 22.0 3.0 +FRB 929 414.2 35 329.2 0.170 37.4 3.0 +FRB 930 319.1 35 234.1 0.201 15.1 2.0 +FRB 931 1336.7 35 1251.7 1.526 10.8 3.0 +FRB 932 1027.7 35 942.7 1.055 13.1 3.0 +FRB 933 545.3 35 460.3 0.388 26.9 3.0 +FRB 934 369.4 35 284.4 0.010 10.7 1.0 +FRB 935 168.6 35 83.6 0.003 29.4 2.0 +FRB 936 1013.5 35 928.5 1.012 13.2 2.0 +FRB 937 254.8 35 169.8 0.184 14.9 3.0 +FRB 938 1715.0 35 1630.0 2.012 12.1 2.0 +FRB 939 2046.3 35 1961.3 1.186 13.0 0.0 +FRB 940 194.4 35 109.4 0.031 35.6 2.0 +FRB 941 235.0 35 150.0 0.218 149.4 3.0 +FRB 942 636.0 35 551.0 0.467 12.9 3.0 +FRB 943 260.7 35 175.7 0.118 15.2 3.0 +FRB 944 923.6 35 838.6 0.803 18.1 3.0 +FRB 945 913.5 35 828.5 1.208 24.7 1.0 +FRB 946 200.0 35 115.0 0.155 11.0 3.0 +FRB 947 363.2 35 278.2 0.386 12.0 3.0 +FRB 948 324.1 35 239.1 0.178 22.7 1.0 +FRB 949 497.9 35 412.9 0.549 24.1 3.0 +FRB 950 464.8 35 379.8 0.503 10.6 4.0 +FRB 951 897.2 35 812.2 0.893 19.2 3.0 +FRB 952 243.3 35 158.3 0.111 12.5 2.0 +FRB 953 340.6 35 255.6 0.173 9.9 2.0 +FRB 954 239.4 35 154.4 0.240 11.0 3.0 +FRB 955 672.0 35 587.0 0.618 12.1 3.0 +FRB 956 918.3 35 833.3 0.450 19.9 3.0 +FRB 957 351.4 35 266.4 0.394 27.7 3.0 +FRB 958 865.6 35 780.6 1.064 10.3 0.0 +FRB 959 1634.9 35 1549.9 1.946 15.9 3.0 +FRB 960 375.6 35 290.6 0.255 9.6 1.0 +FRB 961 1282.2 35 1197.2 1.503 12.7 3.0 +FRB 962 810.4 35 725.4 0.109 22.6 3.0 +FRB 963 1615.8 35 1530.8 0.363 14.0 4.0 +FRB 964 410.2 35 325.2 0.229 14.9 2.0 +FRB 965 322.5 35 237.5 0.171 37.2 4.0 +FRB 966 807.4 35 722.4 0.926 20.6 3.0 +FRB 967 809.0 35 724.0 0.973 15.2 3.0 +FRB 968 200.8 35 115.8 0.017 40.9 1.0 +FRB 969 624.5 35 539.5 0.608 29.0 3.0 +FRB 970 765.5 35 680.5 0.903 27.9 3.0 +FRB 971 723.4 35 638.4 0.748 18.6 2.0 +FRB 972 1077.4 35 992.4 0.677 17.1 2.0 +FRB 973 817.6 35 732.6 0.672 11.1 4.0 +FRB 974 1497.4 35 1412.4 1.515 10.0 4.0 +FRB 975 569.8 35 484.8 0.124 57.6 3.0 +FRB 976 510.3 35 425.3 0.480 33.4 2.0 +FRB 977 452.5 35 367.5 0.265 10.3 4.0 +FRB 978 975.6 35 890.6 1.173 11.2 3.0 +FRB 979 496.8 35 411.8 0.375 55.7 1.0 +FRB 980 199.7 35 114.7 0.038 9.9 3.0 +FRB 981 806.6 35 721.6 0.794 14.6 2.0 +FRB 982 642.3 35 557.3 0.439 13.4 3.0 +FRB 983 959.5 35 874.5 0.787 16.6 0.0 +FRB 984 396.7 35 311.7 0.330 21.8 3.0 +FRB 985 142.1 35 57.1 0.043 21.8 3.0 +FRB 986 376.1 35 291.1 0.219 19.0 1.0 +FRB 987 1077.2 35 992.2 1.389 35.2 1.0 +FRB 988 632.7 35 547.7 0.475 11.9 0.0 +FRB 989 330.1 35 245.1 0.163 11.7 3.0 +FRB 990 247.1 35 162.1 0.152 18.0 3.0 +FRB 991 140.6 35 55.6 0.019 20.3 3.0 +FRB 992 578.6 35 493.6 0.301 53.0 1.0 +FRB 993 230.2 35 145.2 0.125 10.1 2.0 +FRB 994 420.1 35 335.1 0.135 18.6 3.0 +FRB 995 579.4 35 494.4 0.360 14.9 1.0 +FRB 996 1031.4 35 946.4 1.190 14.7 2.0 +FRB 997 391.9 35 306.9 0.147 20.3 5.0 +FRB 998 341.4 35 256.4 0.267 79.0 1.0 +FRB 999 442.7 35 357.7 0.433 14.0 3.0 diff --git a/zdm/craco/MC_Surveys/CRACO_F_0.32_survey_state.json b/zdm/craco/MC_Surveys/CRACO_F_0.32_survey_state.json new file mode 100644 index 00000000..38ba399e --- /dev/null +++ b/zdm/craco/MC_Surveys/CRACO_F_0.32_survey_state.json @@ -0,0 +1,57 @@ +{ + "FRBdemo": { + "alpha_method": 1, + "lC": 1, + "sfr_n": 0.73, + "source_evolution": 0 + }, + "IGM": { + "F": 0.32 + }, + "MW": { + "DMhalo": 50, + "ISM": 35.0 + }, + "analysis": { + "NewGrids": true, + "sprefix": "Std" + }, + "beam": { + "Bmethod": 2, + "Bthresh": 0 + }, + "cosmo": { + "H0": 67.66, + "Omega_b": 0.04897, + "Omega_b_h2": 0.0224178568132, + "Omega_k": 0.0, + "Omega_lambda": 0.6888463055445441, + "Omega_m": 0.30966, + "fix_Omega_b_h2": true + }, + "energy": { + "alpha": 0.65, + "gamma": -1.01, + "lEmax": 41.4, + "lEmin": 30, + "luminosity_function": 2 + }, + "host": { + "lmean": 2.18, + "lsigma": 0.48 + }, + "scat": { + "Sfnorm": 600, + "Sfpower": -4.0, + "Slogmean": 0.7, + "Slogsigma": 1.9 + }, + "width": { + "Wbins": 10, + "Wlogmean": 1.70267, + "Wlogsigma": 0.899148, + "Wmethod": 2, + "Wscale": 2, + "Wthresh": 0.5 + } +} \ No newline at end of file diff --git a/zdm/craco/mc.py b/zdm/craco/mc.py index 4682c846..0ad84bd6 100644 --- a/zdm/craco/mc.py +++ b/zdm/craco/mc.py @@ -1,4 +1,3 @@ - """ This script generates MC samples for CRAFT CRACO. @@ -22,273 +21,403 @@ import matplotlib.pyplot as plt import matplotlib -matplotlib.rcParams['image.interpolation'] = None +matplotlib.rcParams["image.interpolation"] = None + +defaultsize = 14 +ds = 4 +font = {"family": "normal", "weight": "normal", "size": defaultsize} +matplotlib.rc("font", **font) -defaultsize=14 -ds=4 -font = {'family' : 'normal', - 'weight' : 'normal', - 'size' : defaultsize} -matplotlib.rc('font', **font) -def generate(alpha_method=1, Nsamples=10000, do_plots=True, - lum_func=0, base_survey='CRAFT_CRACO_MC_base', - outfile='FRBs.txt', - savefile=None): +def generate( + alpha_method=1, + Nsamples=10000, + do_plots=True, + lum_func=0, + base_survey="CRAFT_CRACO_MC_base", + outfile="FRBs.txt", + savefile=None, + update_params=None, + plotfile="MC_Plots/mc_frbs_best_zdm_grid.pdf", +): craco, grid = loading.survey_and_grid( - alpha_method=alpha_method, - survey_name=base_survey, - lum_func=lum_func) - - print("Generating ",Nsamples," samples from CRACO survey/grid ") - sample=grid.GenMCSample(Nsamples) - sample=np.array(sample) + alpha_method=alpha_method, survey_name=base_survey, lum_func=lum_func + ) + + if update_params is not None: + grid.update(update_params) + + print("Generating ", Nsamples, " samples from CRACO survey/grid ") + sample = grid.GenMCSample(Nsamples) + sample = np.array(sample) if savefile is not None: - np.save(savefile,sample) - + np.save(savefile, sample) + if do_plots: - Zs = sample[:,0] - DMEGs = sample[:,1] + Zs = sample[:, 0] + DMEGs = sample[:, 1] misc_functions.plot_grid_2( - grid.rates,grid.zvals,grid.dmvals, - #FRBZ=craco.frbs["Z"],FRBDM=craco.DMEGs, - FRBZ=Zs, FRBDM=DMEGs, - zmax=1.8,DMmax=2000, - name='MC_Plots/mc_frbs_best_zdm_grid.pdf',norm=2, - log=True,label='$\\log_{10} p({\\rm DM}_{\\rm EG},z)$', - project=False,Aconts=[0.01,0.1,0.5],Macquart=grid.state) - - #sample + grid.rates, + grid.zvals, + grid.dmvals, + # FRBZ=craco.frbs["Z"],FRBDM=craco.DMEGs, + FRBZ=Zs, + FRBDM=DMEGs, + zmax=1.8, + DMmax=2000, + name=plotfile, + norm=2, + log=True, + label="$\\log_{10} p({\\rm DM}_{\\rm EG},z)$", + project=False, + Aconts=[0.01, 0.1, 0.5], + Macquart=grid.state, + ) + + # sample # 0: z # 1: DM # 2: b # 3: w # 4: s # plot some sample plots - do_basic_sample_plots(sample,opdir='MC_Plots') + do_basic_sample_plots(sample, opdir="MC_Plots") # Read base - sdir = os.path.join(resource_filename('zdm', 'craco'), - 'MC_Surveys') - basefile = os.path.join(sdir, base_survey+'.dat') - with open(basefile, 'r') as f: + sdir = os.path.join(resource_filename("zdm", "craco"), "MC_Surveys") + basefile = os.path.join(sdir, base_survey + ".dat") + with open(basefile, "r") as f: base_lines = f.readlines() # Write FRBs to disk add_header = True - with open(outfile, 'w') as f: + with open(outfile, "w") as f: # Header for base_line in base_lines: if add_header: - if 'NFRB' in base_line: - f.write(f'NFRB {Nsamples}\n') - elif 'NORM_FRB' in base_line: - f.write(f'NORM_FRB {Nsamples}\n') + if "NFRB" in base_line: + f.write(f"NFRB {Nsamples}\n") + elif "NORM_FRB" in base_line: + f.write(f"NORM_FRB {Nsamples}\n") else: f.write(base_line) - if 'fake data' in base_line: + if "fake data" in base_line: add_header = False - # + # for i in np.arange(Nsamples): - DMG=35 - DMEG=sample[i,1] - DMtot=DMEG+DMG+grid.state.MW.DMhalo - SNRTHRESH=9.5 - SNR=SNRTHRESH*sample[i,4] - z=sample[i,0] - w=sample[i,3] - - string="FRB "+str(i)+' {:6.1f} 35 {:6.1f} {:5.3f} {:5.1f} {:5.1f} \n'.format(DMtot,DMEG,z,SNR,w) - #print("FRB ",i,DMtot,SNR,DMEG,w) + DMG = 35 + DMEG = sample[i, 1] + DMtot = DMEG + DMG + grid.state.MW.DMhalo + SNRTHRESH = 9.5 + SNR = SNRTHRESH * sample[i, 4] + z = sample[i, 0] + w = sample[i, 3] + + string = ( + "FRB " + + str(i) + + " {:6.1f} 35 {:6.1f} {:5.3f} {:5.1f} {:5.1f} \n".format( + DMtot, DMEG, z, SNR, w + ) + ) + # print("FRB ",i,DMtot,SNR,DMEG,w) f.write(string) print(f"Wrote: {outfile}") # Write state - state_file = outfile.replace('.dat', '_state.json') + state_file = outfile.replace(".dat", "_state.json") grid.state.write(state_file) print(f"Wrote: {state_file}") - #evaluate_mc_sample_v1(g,s,pset,sample) - #evaluate_mc_sample_v2(g,s,pset,sample) - - -def evaluate_mc_sample_v1(grid,survey,pset,sample,opdir='Plots'): + # evaluate_mc_sample_v1(g,s,pset,sample) + # evaluate_mc_sample_v2(g,s,pset,sample) + + +def evaluate_mc_sample_v1(grid, survey, pset, sample, opdir="Plots"): """ Evaluates the likelihoods for an MC sample of events Simply replaces individual sets of z, DM, s with MC sets Will produce a plot of Nsamples/NFRB pseudo datasets. """ - t0=time.process_time() - - nsamples=sample.shape[0] - + t0 = time.process_time() + + nsamples = sample.shape[0] + # get number of FRBs per sample - Npersurvey=survey.NFRB + Npersurvey = survey.NFRB # determines how many false surveys we have stats for - Nsurveys=int(nsamples/Npersurvey) - - print("We can evaluate ",Nsurveys,"MC surveys given a total of ",nsamples," and ",Npersurvey," FRBs in the original data") - + Nsurveys = int(nsamples / Npersurvey) + + print( + "We can evaluate ", + Nsurveys, + "MC surveys given a total of ", + nsamples, + " and ", + Npersurvey, + " FRBs in the original data", + ) + # makes a deep copy of the survey - s=copy.deepcopy(survey) - - lls=[] - #Data order is DM,z,b,w,s + s = copy.deepcopy(survey) + + lls = [] + # Data order is DM,z,b,w,s # we loop through, artificially altering the survey with the composite values. for i in np.arange(Nsurveys): - this_sample=sample[i*Npersurvey:(i+1)*Npersurvey,:] - s.DMEGs=this_sample[:,0] - s.Ss=this_sample[:,4] - if s.nD==1: # DM, snr only - ll=it.calc_likelihoods_1D(grid,s,pset,psnr=True,Pn=True,dolist=0) + this_sample = sample[i * Npersurvey : (i + 1) * Npersurvey, :] + s.DMEGs = this_sample[:, 0] + s.Ss = this_sample[:, 4] + if s.nD == 1: # DM, snr only + ll = it.calc_likelihoods_1D(grid, s, pset, psnr=True, Pn=True, dolist=0) else: - s.Zs=this_sample[:,1] - ll=it.calc_likelihoods_2D(grid,s,pset,psnr=True,Pn=True,dolist=0) + s.Zs = this_sample[:, 1] + ll = it.calc_likelihoods_2D(grid, s, pset, psnr=True, Pn=True, dolist=0) lls.append(ll) - t1=time.process_time() - dt=t1-t0 - print("Finished after ",dt," seconds") - - lls=np.array(lls) - + t1 = time.process_time() + dt = t1 - t0 + print("Finished after ", dt, " seconds") + + lls = np.array(lls) + plt.figure() - plt.hist(lls,bins=20) - plt.xlabel('log likelihoods [log10]') - plt.ylabel('p(ll)') + plt.hist(lls, bins=20) + plt.xlabel("log likelihoods [log10]") + plt.ylabel("p(ll)") plt.xticks(rotation=90) plt.tight_layout() - plt.savefig(opdir+'/ll_histogram.pdf') + plt.savefig(opdir + "/ll_histogram.pdf") plt.close() -def evaluate_mc_sample_v2(grid,survey,pset,sample,opdir='Plots',Nsubsamp=1000): +def evaluate_mc_sample_v2(grid, survey, pset, sample, opdir="Plots", Nsubsamp=1000): """ Evaluates the likelihoods for an MC sample of events First, gets likelihoods for entire set of FRBs Then re-samples as needed, a total of Nsubsamp times """ - t0=time.process_time() - - nsamples=sample.shape[0] - + t0 = time.process_time() + + nsamples = sample.shape[0] + # makes a deep copy of the survey - s=copy.deepcopy(survey) - NFRBs=s.NFRB - - s.NFRB=nsamples # NOTE: does NOT change the assumed normalised FRB total! - s.DMEGs=sample[:,1] - s.Ss=sample[:,4] - if s.nD==1: # DM, snr only - llsum,lllist,expected,longlist=it.calc_likelihoods_1D(grid,s,pset,psnr=True,Pn=True,dolist=2) + s = copy.deepcopy(survey) + NFRBs = s.NFRB + + s.NFRB = nsamples # NOTE: does NOT change the assumed normalised FRB total! + s.DMEGs = sample[:, 1] + s.Ss = sample[:, 4] + if s.nD == 1: # DM, snr only + llsum, lllist, expected, longlist = it.calc_likelihoods_1D( + grid, s, pset, psnr=True, Pn=True, dolist=2 + ) else: - s.Zs=sample[:,0] - llsum,lllist,expected,longlist=it.calc_likelihoods_2D(grid,s,pset,psnr=True,Pn=True,dolist=2) - + s.Zs = sample[:, 0] + llsum, lllist, expected, longlist = it.calc_likelihoods_2D( + grid, s, pset, psnr=True, Pn=True, dolist=2 + ) + # we should preserve the normalisation factor for Tobs from lllist - Pzdm,Pn,Psnr=lllist - + Pzdm, Pn, Psnr = lllist + # plots histogram of individual FRB likelihoods including Psnr and Pzdm plt.figure() - plt.hist(longlist,bins=100) - plt.xlabel('Individual Psnr,Pzdm log likelihoods [log10]') - plt.ylabel('p(ll)') + plt.hist(longlist, bins=100) + plt.xlabel("Individual Psnr,Pzdm log likelihoods [log10]") + plt.ylabel("p(ll)") plt.tight_layout() - plt.savefig(opdir+'/individual_ll_histogram.pdf') + plt.savefig(opdir + "/individual_ll_histogram.pdf") plt.close() - + # generates many sub-samples of the data - lltots=[] + lltots = [] for i in np.arange(Nsubsamp): - thislist=np.random.choice(longlist,NFRBs) # samples with replacement, by default - lltot=Pn+np.sum(thislist) + thislist = np.random.choice( + longlist, NFRBs + ) # samples with replacement, by default + lltot = Pn + np.sum(thislist) lltots.append(lltot) - + plt.figure() - plt.hist(lltots,bins=20) - plt.xlabel('log likelihoods [log10]') - plt.ylabel('p(ll)') + plt.hist(lltots, bins=20) + plt.xlabel("log likelihoods [log10]") + plt.ylabel("p(ll)") plt.xticks(rotation=90) plt.tight_layout() - plt.savefig(opdir+'/sampled_ll_histogram.pdf') + plt.savefig(opdir + "/sampled_ll_histogram.pdf") plt.close() - - t1=time.process_time() - dt=t1-t0 - print("Finished after ",dt," seconds") - - -def do_basic_sample_plots(sample,opdir='Plots'): + + t1 = time.process_time() + dt = t1 - t0 + print("Finished after ", dt, " seconds") + + +def do_basic_sample_plots(sample, opdir="Plots"): """ Data order is DM,z,b,w,s """ if not os.path.exists(opdir): os.mkdir(opdir) - zs=sample[:,0] - DMs=sample[:,1] + zs = sample[:, 0] + DMs = sample[:, 1] plt.figure() - plt.hist(DMs,bins=100) - plt.xlabel('DM') - plt.ylabel('Sampled DMs') + plt.hist(DMs, bins=100) + plt.xlabel("DM") + plt.ylabel("Sampled DMs") plt.tight_layout() - plt.savefig(opdir+'/DM_histogram.pdf') + plt.savefig(opdir + "/DM_histogram.pdf") plt.close() - + plt.figure() - plt.hist(zs,bins=100) - plt.xlabel('z') - plt.ylabel('Sampled redshifts') + plt.hist(zs, bins=100) + plt.xlabel("z") + plt.ylabel("Sampled redshifts") plt.tight_layout() - plt.savefig(opdir+'/z_histogram.pdf') + plt.savefig(opdir + "/z_histogram.pdf") plt.close() - - bs=sample[:,2] + + bs = sample[:, 2] plt.figure() - plt.hist(np.log10(bs),bins=5) - plt.xlabel('log10 beam value') - plt.yscale('log') - plt.ylabel('Sampled beam bin') + plt.hist(np.log10(bs), bins=5) + plt.xlabel("log10 beam value") + plt.yscale("log") + plt.ylabel("Sampled beam bin") plt.tight_layout() - plt.savefig(opdir+'/b_histogram.pdf') + plt.savefig(opdir + "/b_histogram.pdf") plt.close() - - ws=sample[:,3] + + ws = sample[:, 3] plt.figure() - plt.hist(ws,bins=5) - plt.xlabel('width bin (not actual width!)') - plt.ylabel('Sampled width bin') - plt.yscale('log') + plt.hist(ws, bins=5) + plt.xlabel("width bin (not actual width!)") + plt.ylabel("Sampled width bin") + plt.yscale("log") plt.tight_layout() - plt.savefig(opdir+'/w_histogram.pdf') + plt.savefig(opdir + "/w_histogram.pdf") plt.close() - - s=sample[:,4] + + s = sample[:, 4] plt.figure() - plt.hist(np.log10(s),bins=100) - plt.xlabel('$\\log_{10} (s={\\rm SNR}/{\\rm SNR}_{\\rm th})$') - plt.yscale('log') - plt.ylabel('Sampled $s$') + plt.hist(np.log10(s), bins=100) + plt.xlabel("$\\log_{10} (s={\\rm SNR}/{\\rm SNR}_{\\rm th})$") + plt.yscale("log") + plt.ylabel("Sampled $s$") plt.tight_layout() - plt.savefig(opdir+'/s_histogram.pdf') + plt.savefig(opdir + "/s_histogram.pdf") plt.close() - + # Generate em! # Default run with Planck18 -#generate(alpha_method=1, Nsamples=5000, do_plots=True, +# generate(alpha_method=1, Nsamples=5000, do_plots=True, # outfile='MC_Surveys/CRACO_alpha1_Planck18.dat', # savefile=None) -''' Run in February 2022 +""" Run in February 2022 # Gamma function for energies generate(alpha_method=1, lum_func=2, Nsamples=5000, do_plots=True, outfile='MC_Surveys/CRACO_alpha1_Planck18_Gamma.dat', savefile=None) -''' +""" # Made in May 2022 -generate(alpha_method=1, lum_func=2, - Nsamples=5000, do_plots=True, - outfile='MC_Surveys/CRACO_std_May2022.dat', - savefile=None) \ No newline at end of file +# generate( +# alpha_method=1, +# lum_func=2, +# Nsamples=5000, +# do_plots=True, +# outfile="MC_Surveys/CRACO_std_May2022.dat", +# savefile=None, +# ) + +# JB + +# generate( +# alpha_method=1, +# lum_func=2, +# Nsamples=1000, +# do_plots=True, +# outfile="MC_F/Surveys/F_vanilla_survey.dat", +# plotfile="MC_F/Plots/F_vanilla.pdf", +# savefile=None, +# # update_params={"F": 0.01}, +# ) + +# generate( +# alpha_method=1, +# lum_func=2, +# Nsamples=1000, +# do_plots=True, +# outfile="MC_F/Surveys/F_0.01_survey.dat", +# plotfile="MC_F/Plots/F_0.01.pdf", +# savefile=None, +# update_params={"F": 0.01}, +# ) + +generate( + alpha_method=1, + lum_func=2, + Nsamples=1000, + do_plots=True, + outfile="MC_Surveys/CRACO_F_0.32_survey.dat", + plotfile="MC_Plots/CRACO_F_0.32.pdf", + savefile=None, + update_params={"F": 0.32}, +) + +# generate( +# alpha_method=1, +# lum_func=2, +# Nsamples=1000, +# do_plots=True, +# outfile="MC_F/Surveys/F_0.7_survey.dat", +# plotfile="MC_F/Plots/F_0.7.pdf", +# savefile=None, +# update_params={"F": 0.7}, +# ) + +# generate( +# alpha_method=1, +# lum_func=2, +# Nsamples=1000, +# do_plots=True, +# outfile="MC_F/Surveys/F_0.01_dmhost_suppressed_survey.dat", +# plotfile="MC_F/Plots/F_0.01_dmhost_suppressed.pdf", +# savefile=None, +# update_params={"F": 0.01, "lmean": 1e-3, "lsigma": 0.1}, +# ) + +# generate( +# alpha_method=1, +# lum_func=2, +# Nsamples=1000, +# do_plots=True, +# outfile="MC_F/Surveys/F_0.9_dmhost_suppressed_survey.dat", +# plotfile="MC_F/Plots/F_0.9_dmhost_suppressed.pdf", +# savefile=None, +# update_params={"F": 0.9, "lmean": 1e-3, "lsigma": 0.1}, +# ) + +# generate( +# alpha_method=1, +# lum_func=2, +# Nsamples=1000, +# do_plots=True, +# outfile="MC_F/Surveys/F_0.7_dmhost_suppressed_survey.dat", +# plotfile="MC_F/Plots/F_0.7_dmhost_suppressed.pdf", +# savefile=None, +# update_params={"F": 0.7, "lmean": 1e-3, "lsigma": 0.1}, +# ) + +# generate( +# alpha_method=1, +# lum_func=2, +# Nsamples=1000, +# do_plots=True, +# outfile="MC_F/Surveys/F_vanilla_dmhost_suppressed_survey.dat", +# plotfile="MC_F/Plots/F_vanilla_dmhost_suppressed.pdf", +# savefile=None, +# update_params={"lmean": 1e-3, "lsigma": 0.1}, +# ) diff --git a/zdm/craco/testing.py b/zdm/craco/testing.py index 38143c6b..c74c9705 100644 --- a/zdm/craco/testing.py +++ b/zdm/craco/testing.py @@ -1,7 +1,7 @@ """ Run tests with CRACO FRBs """ ###### -# first run this to generate surveys and parameter sets, by +# first run this to generate surveys and parameter sets, by # setting NewSurveys=True NewGrids=True # Then set these to False and run with command line arguments # to generate *many* outputs @@ -14,75 +14,80 @@ import matplotlib from matplotlib import pyplot as plt +import pandas + from zdm import iteration as it from zdm.craco import loading from IPython import embed -matplotlib.rcParams['image.interpolation'] = None +matplotlib.rcParams["image.interpolation"] = None + +defaultsize = 14 +ds = 4 +font = {"family": "normal", "weight": "normal", "size": defaultsize} +matplotlib.rc("font", **font) -defaultsize=14 -ds=4 -font = {'family' : 'normal', - 'weight' : 'normal', - 'size' : defaultsize} -matplotlib.rc('font', **font) +# import igm +defaultsize = 14 +ds = 4 +font = {"family": "normal", "weight": "normal", "size": defaultsize} +matplotlib.rc("font", **font) -#import igm -defaultsize=14 -ds=4 -font = {'family' : 'normal', - 'weight' : 'normal', - 'size' : defaultsize} -matplotlib.rc('font', **font) def main(pargs): - isurvey, igrid = loading.survey_and_grid(survey_name=pargs.survey, - NFRB=pargs.nFRB, - iFRB=pargs.iFRB, - lum_func=pargs.lum_func) - surveys = [isurvey] + isurvey, igrid = loading.survey_and_grid( + survey_name=pargs.survey, + NFRB=pargs.nFRB, + iFRB=pargs.iFRB, + lum_func=pargs.lum_func, + ) + + surveys = [isurvey] grids = [igrid] pvals = np.linspace(pargs.min, pargs.max, pargs.nstep) vparams = {} vparams[pargs.param] = None - vparams['lC'] = -0.9 - - # DEBUGGING - #print("WARNING: REMOVE THE LINE BELOW WHEN DONE DEBUGGING") - #vparams['lEmax'] = 40.6 - + vparams["lC"] = -0.9 + + # JXP Fussing + #vparams["H0"] = 55. + + ''' + tparams = pandas.read_csv('tst_params.csv') + for key in ['lEmax', 'alpha','gamma','sfr_n','lmean','lsigma','F']: + vparams[key] = tparams[key][0] + tmp_dict = { + 'lEmax': 40.5, 'H0': 64.375, 'alpha': 0.2, 'gamma': -0.5, + 'sfr_n': 0.0, 'lmean': 1.7, 'lsigma': 0.3, 'F': 0.11} + vparams.update(tmp_dict) + #embed(header='64 of testing') + ''' + lls = [] nterms = [] # LL term related to norm (i.e. rates) pvterms = [] # LL term related to norm (i.e. rates) - pvvals = [] # - wzvals = [] # + pvvals = [] # + wzvals = [] # for tt, pval in enumerate(pvals): vparams[pargs.param] = pval - C,llC,lltot=it.minimise_const_only( - vparams,grids,surveys, Verbose=False) + C, llC = it.minimise_const_only(vparams, grids, surveys, Verbose=False) # Set lC - vparams['lC']=C + vparams["lC"] = C igrid.state.FRBdemo.lC = C # Grab final LL - # TODO -- bring this back - #lls_final, nterm, pvterm, lpvals, lwz = it.calc_likelihoods_2D( - # igrid, isurvey, - # norm=True,psnr=True,dolist=4) - # TODO -- remove this - items = it.calc_likelihoods_2D( - igrid, isurvey, - norm=True,psnr=True,dolist=5) - embed(header='78 of testing') + lls_final, nterm, pvterm, lpvals, lwz = it.calc_likelihoods_2D( + igrid, isurvey, norm=True, psnr=True, dolist=4 + ) # Hold lls.append(lls_final) nterms.append(nterm) pvterms.append(pvterm) pvvals.append(lpvals) wzvals.append(lwz) - print(f'{pargs.param}: pval={pval}, C={C}, lltot={lls_final}') + print(f"{pargs.param}: pval={pval}, C={C}, lltot={lls_final}") # Max imx = np.nanargmax(lls) @@ -91,16 +96,16 @@ def main(pargs): # Plot plt.clf() ax = plt.gca() - ax.plot(pvals, lls, 'o') + ax.plot(pvals, lls, "o") # Nan bad = np.isnan(lls) nbad = np.sum(bad) if nbad > 0: - ax.plot(pvals[bad], [np.nanmin(lls)]*nbad, 'x', color='r') + ax.plot(pvals[bad], [np.nanmin(lls)] * nbad, "x", color="r") ax.set_xlabel(pargs.param) - ax.set_ylabel('LL') + ax.set_ylabel("LL") # Max - ax.axvline(pvals[imx], color='g', ls='--', label=f'max={pvals[imx]}') + ax.axvline(pvals[imx], color="g", ls="--", label=f"max={pvals[imx]}") ax.legend() # Save? if pargs.opfile is not None: @@ -113,39 +118,63 @@ def main(pargs): # Plot nterm plt.clf() ax = plt.gca() - ax.plot(pvals, nterms, 'o') + ax.plot(pvals, nterms, "o") ax.set_xlabel(pargs.param) - ax.set_ylabel('nterm') - plt.savefig('nterms.png') + ax.set_ylabel("nterm") + plt.savefig("nterms.png") plt.close() # Plot nterm plt.clf() ax = plt.gca() - ax.plot(pvals, pvterms, 'o') + ax.plot(pvals, pvterms, "o") ax.set_xlabel(pargs.param) - ax.set_ylabel('pvterm') - plt.savefig('pvterms.png') + ax.set_ylabel("pvterm") + plt.savefig("pvterms.png") plt.close() + # command-line arguments here parser = argparse.ArgumentParser() -parser.add_argument('param',type=str,help="paramter to test on") -parser.add_argument('min',type=float,help="minimum value") -parser.add_argument('max',type=float,help="maximum value") -parser.add_argument('--nstep',type=int,default=10,required=False,help="number of steps") -parser.add_argument('--nFRB',type=int,default=1000,required=False,help="number of FRBs to analyze") -parser.add_argument('--iFRB',type=int,default=0,required=False,help="starting number of FRBs to analyze") -parser.add_argument('-o','--opfile',type=str,required=False,help="Output file for the data") -parser.add_argument('--survey',type=str,default='CRACO_alpha1_Planck18', - required=False,help="Survey name") -parser.add_argument('--lum_func',type=int,default=0, required=False,help="Luminosity function (0=power-law, 1=gamma)") +parser.add_argument("param", type=str, help="paramter to test on") +parser.add_argument("min", type=float, help="minimum value") +parser.add_argument("max", type=float, help="maximum value") +parser.add_argument( + "--nstep", type=int, default=10, required=False, help="number of steps" +) +parser.add_argument( + "--nFRB", type=int, default=1000, required=False, help="number of FRBs to analyze" +) +parser.add_argument( + "--iFRB", + type=int, + default=0, + required=False, + help="starting number of FRBs to analyze", +) +parser.add_argument( + "-o", "--opfile", type=str, required=False, help="Output file for the data" +) +parser.add_argument( + "--survey", + type=str, + default="CRACO_std_May2022", + required=False, + help="Survey name", +) +parser.add_argument( + "--lum_func", + type=int, + default=0, + required=False, + help="Luminosity function (0=power-law, 1=gamma)", +) pargs = parser.parse_args() main(pargs) -''' +""" # OUT OF DATE TESTS python test_with_craco.py sfr_n 0.2 2. --nstep 100 --nFRB 1000 --cosmo Planck15 -o CRACO_1000_sfr_n.png python test_with_craco.py gamma -1.5 -0.8 --nstep 30 --nFRB 1000 --cosmo Planck15 -o CRACO_1000_gamma.png @@ -163,7 +192,6 @@ def main(pargs): # Newest round python testing.py lEmax 41. 43. --nstep 50 --nFRB 100 -o MC_Plots/CRACO_100_Emax_new.png -python testing.py H0 60. 80. --nstep 50 --nFRB 100 -o MC_Plots/CRACO_100_H0.png # Gamma python testing.py H0 60. 80. --nstep 50 --nFRB 100 --survey CRACO_alpha1_Planck18_Gamma -o MC_Plots/CRACO_100_H0_Gamma.png --lum_func 2 @@ -172,4 +200,35 @@ def main(pargs): python testing.py alpha 0. 2. --nstep 50 --nFRB 100 --survey CRACO_alpha1_Planck18_Gamma -o MC_Plots/CRACO_100_alpha_Gamma.png --lum_func 2 python testing.py sfr_n 0. 5. --nstep 100 --nFRB 100 --iFRB 100 --survey CRACO_alpha1_Planck18_Gamma -o MC_Plots/CRACO_100_sfr_Gamma.png --lum_func 2 # -''' \ No newline at end of file + +python testing.py H0 60. 80. --nstep 50 --nFRB 100 -o MC_Plots/CRACO_100_H0.png --lum_func 2 + +# +python testing.py F .001 .1 --nstep 100 --nFRB 1000 -o MC_F/Plots/synth_100_F_0.01.png --lum_func 2 --survey ../MC_F/Surveys/F_0.01_survey +python testing.py F .1 .999 --nstep 100 --nFRB 1000 -o MC_F/Plots/synth_100_F_0.7.png --lum_func 2 --survey ../MC_F/Surveys/F_0.7_survey +python testing.py F .1 .999 --nstep 100 --nFRB 1000 -o MC_F/Plots/synth_100_F_0.9.png --lum_func 2 --survey ../MC_F/Surveys/F_0.9_survey +python testing.py F .1 .999 --nstep 100 --nFRB 1000 -o MC_F/Plots/synth_100_F_vanilla.png --lum_func 2 --survey ../MC_F/Surveys/F_vanilla_survey + +python testing.py F .001 .1 --nstep 100 --nFRB 1000 -o MC_F/Plots/synth_100_F_dmhost_suppressed_0.01.png --lum_func 2 --survey ../MC_F/Surveys/F_0.01_dmhost_suppressed_survey +python testing.py F .1 .999 --nstep 100 --nFRB 1000 -o MC_F/Plots/synth_100_F_dmhost_suppressed_0.7.png --lum_func 2 --survey ../MC_F/Surveys/F_0.7_dmhost_suppressed_survey +python testing.py F .1 .999 --nstep 100 --nFRB 1000 -o MC_F/Plots/synth_100_F_dmhost_suppressed_0.9.png --lum_func 2 --survey ../MC_F/Surveys/F_0.9_dmhost_suppressed_survey +python testing.py F .1 .999 --nstep 100 --nFRB 1000 -o MC_F/Plots/synth_100_F_dmhost_suppressed_vanilla.png --lum_func 2 --survey ../MC_F/Surveys/F_vanilla_dmhost_suppressed_survey + +python testing.py H0 60. 80. --nstep 50 --nFRB 100 -o MC_Plots/CRACO_100_H0_TEST.png --lum_func 2 --survey CRACO_alpha1_Planck18_Gamma + +python testing.py H0 60. 80. --nstep 50 --nFRB 100 -o MC_Plots/CRACO_100_H0_TEST.png --lum_func 2 --survey CRACO_alpha1_Planck18_Gamma + +python testing.py H0 60. 80. --nstep 50 --nFRB 100 -o MC_Plots/CRACO_100_H0_TEST_F32.png --lum_func 2 --survey ../MC_F/Surveys/F_0.32_survey + +# More fussing about with F and related +python testing.py H0 60. 80. --nstep 50 --nFRB 100 -o MC_Plots/CRACO_100_H0_TEST_F32.png --lum_func 2 --survey ../MC_F/Surveys/F_0.32_survey + +# Square debugging +python testing.py F 0.1 0.99 --nstep 50 --nFRB 100 -o MC_Plots/CRACO_100_F_TEST_F32.png --lum_func 2 --survey ../MC_F/Surveys/F_0.32_survey --iFRB 100 + # Best F: pval=0.2997959183673469, C=3.630489354871595, lltot=-565.4650145414604 +python testing.py F 0.1 0.99 --nstep 50 --nFRB 100 -o MC_Plots/CRACO_100_F_TEST_F32_H055.png --lum_func 2 --survey ../MC_F/Surveys/F_0.32_survey --iFRB 100 + # Best F: pval=0.8265306122448979, C=3.6174093413949553, lltot=-567.7777429522436 + + +""" + diff --git a/zdm/data/Surveys/CRAFT_ICS.ecsv b/zdm/data/Surveys/CRAFT_ICS.ecsv index feebf5da..4c75d5cd 100644 --- a/zdm/data/Surveys/CRAFT_ICS.ecsv +++ b/zdm/data/Surveys/CRAFT_ICS.ecsv @@ -32,6 +32,9 @@ TNS BW DM DMG FBAR FRES Gb Gl SNR SNRTHRESH THRESH TRES WIDTH XDec XRA Z 20191228A 336.0 297.5 32.9 1271.5 1.0 "" "" 22.9 9.0 4.4 1.728 2.3 -29:35:37.85 22:57:43.269 0.243 20210117A 336.0 730.0 34.4 1271.5 1.0 "" "" 27.1 9.0 4.4 1.182 3.4 -16:11:25.2 22:39:36.0 0.214 20210214A 336.0 398.3 31.9 1271.5 1.0 "" "" 11.6 9.0 4.4 1.182 3.5 -05:49:56 00:27:43 -1.0 -20210407 336.0 1785.3 154.0 1271.5 1.0 "" "" 19.1 9.0 4.4 1.182 8.0 27:03:30.24 05:14:36.202 -1.0 -20210912 336.0 1234.5 30.9 1271.5 1.0 "" "" 31.7 9.0 4.4 1.182 5.5 -30:29:33.1 23:24:40.3 -1.0 -20211127 336.0 234.83 42.5 1271.5 1.0 "" "" 37.9 9.0 4.4 1.182 1.41 -18:49:28.4 13:19:09.5 0.046946 +20210407E 336.0 1785.3 154.0 1271.5 1.0 "" "" 19.1 9.0 4.4 1.182 8.0 27:03:30.24 05:14:36.202 -1.0 +20210912A 336.0 1234.5 30.9 1271.5 1.0 "" "" 31.7 9.0 4.4 1.182 5.5 -30:29:33.1 23:24:40.3 -1.0 +20211127I 336.0 234.83 42.5 1271.5 1.0 "" "" 37.9 9.0 4.4 1.182 1.41 -18:49:28.4 13:19:09.5 0.046946 +20220531A 336.0 727.0 70.0 1271.5 1.0 "" "" 9.7 9.0 4.4 1.182 11.0 -60:17:48.2 "" -1.0 +20220610A 336.0 1458.1 31.0 1271.5 1.0 "" "" 29.8 9.0 4.4 1.182 5.6 -33:30:39.02 "" 1.016 +20220918A 336.0 656.8 40.7 1271.5 1.0 "" "" 26.4 9.0 4.4 1.182 7.1 -70:47:05.9 "" -1.0 \ No newline at end of file diff --git a/zdm/data/Surveys/CRAFT_ICS_1632.dat b/zdm/data/Surveys/CRAFT_ICS_1632.dat new file mode 100644 index 00000000..a80f245e --- /dev/null +++ b/zdm/data/Surveys/CRAFT_ICS_1632.dat @@ -0,0 +1,12 @@ +BW 336 #MHz +FRES 1 #MHz +NFRB 1 #Number of FRBs +BEAM lat50_log #prefix of beam file. +TOBS 8.07 +NORMFRB 1 +THRESH 4.4 #Jy ms to a 1 ms burst, averaged over THRESH of below configs (22/sqrt{Nant}). Should be adjusted to higher frequency. +SNRTHRESH 9 # signal-to-noise threshold: scales jy ms to snr +KEY ID DM FBAR SNR XRA XDEC DMG XNant XConfig TRES WIDTH Z +FRB 211212 206 1632.5 12.8 10:30:40.7 01:40:36.8 27.1 24 closepack36/45/0.9 1.182 2.7 0.0715 +#FRB 220105 583 1632.5 9.8 13:54:51.4 22:29:19.7 22 22 closepack36/45/0.9 1.182 2.0 -1 + diff --git a/zdm/data/Surveys/CRAFT_ICS_1632.ecsv b/zdm/data/Surveys/CRAFT_ICS_1632.ecsv index c2174341..1d7574e3 100644 --- a/zdm/data/Surveys/CRAFT_ICS_1632.ecsv +++ b/zdm/data/Surveys/CRAFT_ICS_1632.ecsv @@ -23,4 +23,6 @@ # BEAM\": \"lat50_log\",\n \"DIAM\": 12.0,\n \"NBEAMS\": 1,\n \"NBINS\": 5\n }\n}"} # schema: astropy-2.0 TNS BW DM DMG FBAR FRES Gb Gl SNR SNRTHRESH THRESH TRES WIDTH XC XDec XRA Z -20211212 336.0 206.0 27.1 1632.5 1.0 "" "" 12.8 9.0 4.4 1.182 2.7 closepack36/45/0.9 01:40:36.8 10:30:40.7 0.0715 +20211212A 336.0 206.0 27.1 1632.5 1.0 "" "" 12.8 9.0 4.4 1.182 2.7 closepack36/45/0.9 01:40:36.8 10:30:40.7 0.0715 +20220105A 336.0 583.0 22.0 1632.5 1.0 "" "" 9.8 9.0 4.4 1.182 2.0 "" 22:29:19.7 13:54:51.4 0.2785 +20221106A 336.0 344.0 34.8 1631.5 1.0 "" "" 35.1 9.0 4.4 1.182 5.7 "" -25:39:44.9 03:46:38.1 -1.0 \ No newline at end of file diff --git a/zdm/data/Surveys/CRAFT_ICS_892.ecsv b/zdm/data/Surveys/CRAFT_ICS_892.ecsv index c8b671be..ff8be05a 100644 --- a/zdm/data/Surveys/CRAFT_ICS_892.ecsv +++ b/zdm/data/Surveys/CRAFT_ICS_892.ecsv @@ -25,9 +25,10 @@ TNS BW DM DMG FBAR FRES Gb Gl SNR SNRTHRESH THRESH TRES WIDTH XC XDec XRA Z 20191001A 336.0 506.92 44.2 919.5 1.0 "" "" 62.0 9.0 4.4 1.728 4.2 closepack36/45 -54:44:54 21:33:24 0.23 20200430A 336.0 380.1 27.0 864.5 1.0 "" "" 16.0 9.0 4.4 1.728 6.5 square_6x6 12:22:34.007 15:18:49.581 0.161 -20200627 336.0 294.0 40.0 920.5 1.0 "" "" 11.0 9.0 4.4 1.728 2.9 closepack36 -39:29:05.0 21:46:47.0 -1.0 +20200627A 336.0 294.0 40.0 920.5 1.0 "" "" 11.0 9.0 4.4 1.728 2.9 closepack36 -39:29:05.0 21:46:47.0 -1.0 20200906A 336.0 577.8 35.9 864.5 1.0 "" "" 19.2 9.0 4.4 1.728 6.0 closepack36 -14:04:59.9136 03:33:58.9364 0.36879 -20210320 336.0 384.8 42.2 864.5 1.0 "" "" 15.3 9.0 4.4 1.728 5.4 square_6x6/45/1.05 -16:09:05.1 13:37:50.08605 0.28 -20210807 336.0 251.9 121.2 920.5 1.0 "" "" 47.1 9.0 4.4 1.182 10.0 square6x6/45/0.9 -00:45:44.5 19:56:53.144 0.12969 -20210809 336.0 651.5 190.1 920.5 1.0 "" "" 16.8 9.0 4.4 1.182 14.2 square6x6/45/0.9 01:19:43.5 18:04:37.7 -1.0 -20211203 336.0 636.2 63.4 920.5 1.0 "" "" 14.2 9.0 4.4 1.182 9.6 closepack36/45/0.9 -31:22:04.0 13:37:52.8 0.34386 +20210320C 336.0 384.8 42.2 864.5 1.0 "" "" 15.3 9.0 4.4 1.728 5.4 square_6x6/45/1.05 -16:09:05.1 13:37:50.08605 0.28 +20210807D 336.0 251.9 121.2 920.5 1.0 "" "" 47.1 9.0 4.4 1.182 10.0 square6x6/45/0.9 -00:45:44.5 19:56:53.144 0.12969 +20210809C 336.0 651.5 190.1 920.5 1.0 "" "" 16.8 9.0 4.4 1.182 14.2 square6x6/45/0.9 01:19:43.5 18:04:37.7 -1.0 +20211203C 336.0 636.2 63.4 920.5 1.0 "" "" 14.2 9.0 4.4 1.182 9.6 closepack36/45/0.9 -31:22:04.0 13:37:52.8 0.34386 +20220725A 336.0 290.4 30.7 920.5 1.0 "" "" 12.7 9.0 4.4 1.182 4.1 "" "" 23:33:32.1 0.1926 \ No newline at end of file diff --git a/zdm/data/Surveys/test.ipynb b/zdm/data/Surveys/test.ipynb new file mode 100644 index 00000000..6479698c --- /dev/null +++ b/zdm/data/Surveys/test.ipynb @@ -0,0 +1,199 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "from astropy.table import unique, Table\n", + "import numpy as np\n", + "\n", + "surveys = [\n", + " \"CRAFT_class_I_and_II.ecsv\",\n", + " \"private_CRAFT_ICS_892.ecsv\",\n", + " \"private_CRAFT_ICS_1272.ecsv\",\n", + " \"private_CRAFT_ICS_1632.ecsv\",\n", + " \"parkes_mb_class_I_and_II.ecsv\"\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Z \n", + "---\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + "...\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + "Length = 26 rows\n", + " Z \n", + "-------\n", + " 0.23\n", + " 0.161\n", + " -1.0\n", + "0.36879\n", + " 0.28\n", + "0.12969\n", + " -1.0\n", + "0.34386\n", + " 0.381\n", + " 0.1926\n", + " Z \n", + "--------\n", + " 0.3214\n", + " 0.4755\n", + " 0.291\n", + " 0.1178\n", + " 0.378\n", + " 0.522\n", + " 0.209\n", + " 0.243\n", + " 0.214\n", + " -1.0\n", + " -1.0\n", + " -1.0\n", + "0.046946\n", + " -1.0\n", + " 1.016\n", + " -1.0\n", + " Z \n", + "------\n", + "0.0715\n", + "0.2785\n", + " -1.0\n", + " Z \n", + "---\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n", + " --\n" + ] + } + ], + "source": [ + "survey_lengths = []\n", + "redshifts = []\n", + "for survey in surveys:\n", + " tb = Table.read(survey)\n", + " print(tb[\"Z\"])\n", + " if type(tb[\"Z\"].data) == np.ma.core.MaskedArray:\n", + " redshifts.append(tb['Z'].data.count())\n", + " else:\n", + " redshifts.append(sum(tb['Z'] != -1))\n", + " survey_lengths.append(len(Table.read(survey)))" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 8, 11, 2, 0]" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "78" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(survey_lengths)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/zdm/energetics.py b/zdm/energetics.py index e63456ef..a2499ea1 100644 --- a/zdm/energetics.py +++ b/zdm/energetics.py @@ -39,7 +39,7 @@ def init_igamma_linear(gammas:list, reinit:bool=False, print(f"Initializing igamma_linear for gamma={gamma} with log10") # values - avals = 10**np.linspace(-7.5, 6., 1000) + avals = 10**np.linspace(-8, 6., 1000) numer = np.array([float(mpmath.gammainc( gamma, a=iEE)) for iEE in avals]) diff --git a/zdm/grid.py b/zdm/grid.py index 8b90691f..b3a4cb9c 100644 --- a/zdm/grid.py +++ b/zdm/grid.py @@ -8,6 +8,7 @@ from zdm import pcosmic from zdm import io + class Grid: """A class to hold a grid of z-dm plots @@ -16,10 +17,8 @@ class Grid: It also assumes a linear uniform grid. """ - - def __init__(self, survey, state, - zDMgrid, zvals, dmvals, smear_mask, - wdist): + + def __init__(self, survey, state, zDMgrid, zvals, dmvals, smear_mask, wdist): """ Class constructor. @@ -32,19 +31,19 @@ def __init__(self, survey, state, wdist (bool): If True, allow for a distribution of widths """ - self.grid=None + self.grid = None self.survey = survey - self.verbose=False + self.verbose = False # Beam - self.beam_b=survey.beam_b - self.beam_o=survey.beam_o - self.b_fractions=None + self.beam_b = survey.beam_b + self.beam_o = survey.beam_o + self.b_fractions = None # State self.state = state - - self.source_function=cos.choose_source_evolution_function( - state.FRBdemo.source_evolution) + self.source_function = cos.choose_source_evolution_function( + state.FRBdemo.source_evolution + ) # Energetics if self.state.energy.luminosity_function in [3]: @@ -53,104 +52,105 @@ def __init__(self, survey, state, self.use_log10 = False self.luminosity_function = self.state.energy.luminosity_function self.init_luminosity_functions() - + #self.nuObs=survey.meta['FBAR']*1e6 #from MHz to Hz self.nuObs= np.median(survey.frbs['FBAR'])*1e6 #from MHz to Hz # Init the grid # THESE SHOULD BE THE SAME ORDER AS self.update() - self.parse_grid(zDMgrid.copy(),zvals.copy(),dmvals.copy()) + self.parse_grid(zDMgrid.copy(), zvals.copy(), dmvals.copy()) self.calc_dV() self.smear_dm(smear_mask.copy()) if wdist: - efficiencies=survey.efficiencies # two dimensions - weights=survey.wplist + efficiencies = survey.efficiencies # two dimensions + weights = survey.wplist else: + efficiencies = survey.mean_efficiencies + weights = None + self.calc_thresholds(survey.meta["THRESH"], efficiencies, weights=weights) efficiencies=survey.mean_efficiencies weights=None - self.efficiencies=efficiencies - self.weights=weights # Warning -- THRESH could be different for each FRB, but we don't treat it that way self.calc_thresholds(np.median(survey.frbs['THRESH']), efficiencies, weights=weights) # Calculate self.calc_pdv() - self.set_evolution() # sets star-formation rate scaling with z - here, no evoltion... - self.calc_rates() #includes sfr smearing factors and pdv mult - - + self.set_evolution() # sets star-formation rate scaling with z - here, no evoltion... + self.calc_rates() # includes sfr smearing factors and pdv mult def init_luminosity_functions(self): """ Set the luminsoity function for FRB energetics """ - if self.luminosity_function==0: # Power-law - self.array_cum_lf=energetics.array_cum_power_law - self.vector_cum_lf=energetics.vector_cum_power_law - self.array_diff_lf=energetics.array_diff_power_law - self.vector_diff_lf=energetics.vector_diff_power_law - elif self.luminosity_function==1: # Gamma function - embed(header='79 of grid -- BEST NOT TO USE THIS!!!!') - self.array_cum_lf=energetics.array_cum_gamma - self.vector_cum_lf=energetics.vector_cum_gamma - self.array_diff_lf=energetics.array_diff_gamma - self.vector_diff_lf=energetics.vector_diff_gamma - elif self.luminosity_function==2: # Spline gamma function - self.array_cum_lf=energetics.array_cum_gamma_spline - self.vector_cum_lf=energetics.vector_cum_gamma_spline - self.array_diff_lf=energetics.array_diff_gamma - self.vector_diff_lf=energetics.vector_diff_gamma - elif self.luminosity_function==3: # Linear + log10 - self.array_cum_lf=energetics.array_cum_gamma_linear - self.vector_cum_lf=energetics.vector_cum_gamma_linear - self.array_diff_lf=energetics.array_diff_gamma - self.vector_diff_lf=energetics.vector_diff_gamma + if self.luminosity_function == 0: # Power-law + self.array_cum_lf = energetics.array_cum_power_law + self.vector_cum_lf = energetics.vector_cum_power_law + self.array_diff_lf = energetics.array_diff_power_law + self.vector_diff_lf = energetics.vector_diff_power_law + elif self.luminosity_function == 1: # Gamma function + embed(header="79 of grid -- BEST NOT TO USE THIS!!!!") + self.array_cum_lf = energetics.array_cum_gamma + self.vector_cum_lf = energetics.vector_cum_gamma + self.array_diff_lf = energetics.array_diff_gamma + self.vector_diff_lf = energetics.vector_diff_gamma + elif self.luminosity_function == 2: # Spline gamma function + self.array_cum_lf = energetics.array_cum_gamma_spline + self.vector_cum_lf = energetics.vector_cum_gamma_spline + self.array_diff_lf = energetics.array_diff_gamma + self.vector_diff_lf = energetics.vector_diff_gamma + elif self.luminosity_function == 3: # Linear + log10 + self.array_cum_lf = energetics.array_cum_gamma_linear + self.vector_cum_lf = energetics.vector_cum_gamma_linear + self.array_diff_lf = energetics.array_diff_gamma + self.vector_diff_lf = energetics.vector_diff_gamma else: - raise ValueError("Luminosity function must be 0, not ",self.luminosity_function) - - def parse_grid(self,zDMgrid,zvals,dmvals): - self.grid=zDMgrid - self.zvals=zvals - self.dmvals=dmvals + raise ValueError( + "Luminosity function must be 0, not ", self.luminosity_function + ) + + def parse_grid(self, zDMgrid, zvals, dmvals): + self.grid = zDMgrid + self.zvals = zvals + self.dmvals = dmvals # self.check_grid() - #self.calc_dV() - + # self.calc_dV() + # this contains all the values used to generate grids # these parameters begin at None, and get filled when # ever something is regenerated. They are semi-hierarchical # in that if a low-level value is reset, high-level ones # get put to None. - - - - def load_grid(self,gridfile,zfile,dmfile): - self.grid=io.load_data(gridfile) - self.zvals=io.load_data(zfile) - self.dmvals=io.load_data(dmfile) + + def load_grid(self, gridfile, zfile, dmfile): + self.grid = io.load_data(gridfile) + self.zvals = io.load_data(zfile) + self.dmvals = io.load_data(dmfile) self.check_grid() self.volume_grid() - - + def check_grid(self): - - self.nz=self.zvals.size - self.ndm=self.dmvals.size - + + self.nz = self.zvals.size + self.ndm = self.dmvals.size + # check to see if these are log-spaced - if (self.zvals[-1]-self.zvals[-2])/(self.zvals[1]-self.zvals[0]) > 1.01: - if np.abs(self.zvals[-1]*self.zvals[0] - self.zvals[-2]*self.zvals[1]) > 0.01: + if (self.zvals[-1] - self.zvals[-2]) / (self.zvals[1] - self.zvals[0]) > 1.01: + if ( + np.abs(self.zvals[-1] * self.zvals[0] - self.zvals[-2] * self.zvals[1]) + > 0.01 + ): raise ValueError("Cannot determine scaling of zvals, exiting...") - self.zlog=True - self.dz=np.log(self.zvals[1]/self.zvals[0]) + self.zlog = True + self.dz = np.log(self.zvals[1] / self.zvals[0]) else: - self.zlog=False - self.dz=self.zvals[1]-self.zvals[0] - - self.ddm=self.dmvals[1]-self.dmvals[0] - shape=self.grid.shape + self.zlog = False + self.dz = self.zvals[1] - self.zvals[0] + + self.ddm = self.dmvals[1] - self.dmvals[0] + shape = self.grid.shape if shape[0] != self.nz: if shape[0] == self.ndm and shape[1] == self.nz: print("Transposing grid, looks like first index is DM") - self.grid=self.grid.transpose + self.grid = self.grid.transpose else: raise ValueError("wrong shape of grid for zvals and dm vals") else: @@ -159,66 +159,81 @@ def check_grid(self): print("Grid successfully initialised") else: raise ValueError("wrong shape of grid for zvals and dm vals") - - - #checks that the grid is approximately linear to high precision + + # checks that the grid is approximately linear to high precision if self.zlog: - expectation=np.exp(np.arange(0,self.nz)*self.dz)*self.zvals[0] + expectation = np.exp(np.arange(0, self.nz) * self.dz) * self.zvals[0] else: - expectation=self.dz*np.arange(0,self.nz)+self.zvals[0] - diff=self.zvals-expectation - maxoff=np.max(diff**2) - if maxoff > 1e-6*self.dz: - raise ValueError("Maximum non-linearity in z-grid of ",maxoff**0.5,"detected, aborting") - - expectation=self.ddm*np.arange(0,self.ndm)+self.dmvals[0] - diff=self.dmvals-expectation - maxoff=np.max(diff**2) - if maxoff > 1e-6*self.ddm: - raise ValueError("Maximum non-linearity in dm-grid of ",maxoff**0.5,"detected, aborting") - - + expectation = self.dz * np.arange(0, self.nz) + self.zvals[0] + diff = self.zvals - expectation + maxoff = np.max(diff ** 2) + if maxoff > 1e-6 * self.dz: + raise ValueError( + "Maximum non-linearity in z-grid of ", + maxoff ** 0.5, + "detected, aborting", + ) + + expectation = self.ddm * np.arange(0, self.ndm) + self.dmvals[0] + diff = self.dmvals - expectation + maxoff = np.max(diff ** 2) + if maxoff > 1e-6 * self.ddm: + raise ValueError( + "Maximum non-linearity in dm-grid of ", + maxoff ** 0.5, + "detected, aborting", + ) + def calc_dV(self, reINIT=False): """ Calculates volume per steradian probed by a survey. Does this only in the z-dimension (for obvious reasons!) """ - + if (cos.INIT is False) or reINIT: - #print('WARNING: cosmology not yet initiated, using default parameters.') + # print('WARNING: cosmology not yet initiated, using default parameters.') cos.init_dist_measures() if self.zlog: # if zlog, dz is actually .dlogz. And dlogz/dz=1/z, i.e. dz= z dlogz - self.dV=cos.dvdtau(self.zvals)*self.dz*self.zvals + self.dV = cos.dvdtau(self.zvals) * self.dz * self.zvals else: - self.dV=cos.dvdtau(self.zvals)*self.dz - - - def EF(self,alpha=0,bandwidth=1e9): + self.dV = cos.dvdtau(self.zvals) * self.dz + + def EF(self, alpha=0, bandwidth=1e9): """Calculates the fluence--energy conversion factors as a function of redshift This does NOT account for the central frequency """ - if self.state.FRBdemo.alpha_method==0: - self.FtoE=cos.F_to_E(1,self.zvals,alpha=alpha,bandwidth=bandwidth,Fobs=self.nuObs,Fref=self.nuRef) - elif self.state.FRBdemo.alpha_method==1: - self.FtoE=cos.F_to_E(1,self.zvals,alpha=0.,bandwidth=bandwidth) + if self.state.FRBdemo.alpha_method == 0: + self.FtoE = cos.F_to_E( + 1, + self.zvals, + alpha=alpha, + bandwidth=bandwidth, + Fobs=self.nuObs, + Fref=self.nuRef, + ) + elif self.state.FRBdemo.alpha_method == 1: + self.FtoE = cos.F_to_E(1, self.zvals, alpha=0.0, bandwidth=bandwidth) else: - raise ValueError("alpha method must be 0 or 1, not ",self.alpha_method) - - def set_evolution(self): #,n,alpha=None): + raise ValueError("alpha method must be 0 or 1, not ", self.alpha_method) + + def set_evolution(self): # ,n,alpha=None): """ Scales volumetric rate by SFR """ - #self.sfr1n=n - #if alpha is not None: + # self.sfr1n=n + # if alpha is not None: # self.alpha=alpha - #self.sfr=cos.sfr(self.zvals)**n #old hard-coded value - self.sfr=self.source_function(self.zvals, - self.state.FRBdemo.sfr_n) - if self.state.FRBdemo.alpha_method==1: - self.sfr *= (1.+self.zvals)**(-self.state.energy.alpha) #reduces rate with alpha + # self.sfr=cos.sfr(self.zvals)**n #old hard-coded value + self.sfr = self.source_function(self.zvals, self.state.FRBdemo.sfr_n) + if self.state.FRBdemo.alpha_method == 1: + self.sfr *= (1.0 + self.zvals) ** ( + -self.state.energy.alpha + ) # reduces rate with alpha # changes absolute normalisation at z=0 according to central frequency - self.sfr *= (self.nuObs/self.nuRef)**-self.state.energy.alpha #alpha positive, nuObs dm)[0][0] - DM1=DM2-1 - kDM=(dm-self.dmvals[DM1])/(self.dmvals[DM2]-self.dmvals[DM1]) - priors[i,:]=kDM*self.rates[:,DM2]+(1.-kDM)*self.rates[:,DM1] - priors[i,:] /= np.sum(priors[i,:]) + priors = np.zeros([DMs.size, self.zvals.size]) + for i, dm in enumerate(DMs): + DM2 = np.where(self.dmvals > dm)[0][0] + DM1 = DM2 - 1 + kDM = (dm - self.dmvals[DM1]) / (self.dmvals[DM2] - self.dmvals[DM1]) + priors[i, :] = kDM * self.rates[:, DM2] + (1.0 - kDM) * self.rates[:, DM1] + priors[i, :] /= np.sum(priors[i, :]) return priors - - def GenMCSample(self,N,Poisson=False): + + def GenMCSample(self, N, Poisson=False): """ Generate a MC sample of FRB events @@ -420,27 +460,27 @@ def GenMCSample(self,N,Poisson=False): """ # Boost? - if self.state.energy.luminosity_function in [1,2]: - Emax_boost = 2. + if self.state.energy.luminosity_function in [1, 2]: + Emax_boost = 2.0 else: - Emax_boost = 0. - + Emax_boost = 0.0 + if Poisson: - #from np.random import poisson - NFRB=np.random.poisson(N) + # from np.random import poisson + NFRB = np.random.poisson(N) else: - NFRB=int(N) #just to be sure... - sample=[] - pwb=None #feeds this back to save time. Lots of time. + NFRB = int(N) # just to be sure... + sample = [] + pwb = None # feeds this back to save time. Lots of time. for i in np.arange(NFRB): if (i % 100) == 0: print(i) - frb,pwb=self.GenMCFRB(pwb, Emax_boost=Emax_boost) + frb, pwb = self.GenMCFRB(pwb, Emax_boost=Emax_boost) sample.append(frb) - sample=np.array(sample) + sample = np.array(sample) return sample - - def GenMCFRB(self,pwb=None, Emax_boost=0.): + + def GenMCFRB(self, pwb=None, Emax_boost=0.0): """ Generates a single FRB according to the grid distributions @@ -463,130 +503,142 @@ def GenMCFRB(self,pwb=None, Emax_boost=0.): Returns: tuple: FRBparams=[MCz,MCDM,MCb,j,MCs], pwb values """ - - # shorthand - lEmin=self.state.energy.lEmin - lEmax=self.state.energy.lEmax - gamma=self.state.energy.gamma - Emin=10**lEmin - Emax=10**lEmax - - # grid of beam values, weights - nw=self.eff_weights.size - nb=self.beam_b.size - + + # shorthand + lEmin = self.state.energy.lEmin + lEmax = self.state.energy.lEmax + gamma = self.state.energy.gamma + Emin = 10 ** lEmin + Emax = 10 ** lEmax + + # grid of beam values, weights + nw = self.eff_weights.size + nb = self.beam_b.size + # we do this to allow efficient recalculation of this when generating many FRBs if pwb is not None: - pwbc=np.cumsum(pwb) - pwbc/=pwbc[-1] + pwbc = np.cumsum(pwb) + pwbc /= pwbc[-1] else: - pwb=np.zeros([nw*nb]) - + pwb = np.zeros([nw * nb]) + # Generates a joint distribution in B,w - for i,b in enumerate(self.beam_b): - for j,w in enumerate(self.eff_weights): + for i, b in enumerate(self.beam_b): + for j, w in enumerate(self.eff_weights): # each of the following is a 2D array over DM, z which we sum to generate B,w values - wb_fraction=self.beam_o[i]*w*self.array_cum_lf(self.thresholds[j,:,:]/b,Emin,Emax,gamma) - pdv=np.multiply(wb_fraction.T,self.dV).T - rate=pdv*self.sfr_smear - pwb[i*nw+j]=np.sum(rate) - pwbc=np.cumsum(pwb) - pwbc/=pwbc[-1] - + wb_fraction = ( + self.beam_o[i] + * w + * self.array_cum_lf( + self.thresholds[j, :, :] / b, Emin, Emax, gamma + ) + ) + pdv = np.multiply(wb_fraction.T, self.dV).T + rate = pdv * self.sfr_smear + pwb[i * nw + j] = np.sum(rate) + pwbc = np.cumsum(pwb) + pwbc /= pwbc[-1] + # sample distribution in w,b # we do NOT interpolate here - we treat these as qualitative values # i.e. as if there was an irregular grid of them - r=np.random.rand(1)[0] - which=np.where(pwbc>r)[0][0] - i=int(which/nw) - j=which-i*nw - MCb=self.beam_b[i] - MCw=self.eff_weights[j] - + r = np.random.rand(1)[0] + which = np.where(pwbc > r)[0][0] + i = int(which / nw) + j = which - i * nw + MCb = self.beam_b[i] + MCw = self.eff_weights[j] + # calculate zdm distribution for sampled w,b only - pzDM=self.array_cum_lf(self.thresholds[j,:,:]/MCb,Emin,Emax,gamma) - wb_fraction=self.array_cum_lf(self.thresholds[j,:,:]/MCb,Emin,Emax,gamma) - pdv=np.multiply(wb_fraction.T,self.dV).T - pzDM=pdv*self.sfr_smear - - + pzDM = self.array_cum_lf(self.thresholds[j, :, :] / MCb, Emin, Emax, gamma) + wb_fraction = self.array_cum_lf( + self.thresholds[j, :, :] / MCb, Emin, Emax, gamma + ) + pdv = np.multiply(wb_fraction.T, self.dV).T + pzDM = pdv * self.sfr_smear + # sample distribution in z,DM - pz=np.sum(pzDM,axis=1) - pzc=np.cumsum(pz) + pz = np.sum(pzDM, axis=1) + pzc = np.cumsum(pz) pzc /= pzc[-1] - r=np.random.rand(1)[0] - iz2=np.where(pzc>r)[0][0] + r = np.random.rand(1)[0] + iz2 = np.where(pzc > r)[0][0] if iz2 > 0: - iz1=iz2-1 - dr=r-pzc[iz1] - kz2=dr/(pzc[iz2]-pzc[iz1]) # fraction of way to second value - kz1=1.-kz2 - MCz=self.zvals[iz1]*kz1+self.zvals[iz2]*kz2 - pDM=pzDM[iz1,:]*kz1 + pzDM[iz2,:]*kz2 + iz1 = iz2 - 1 + dr = r - pzc[iz1] + kz2 = dr / (pzc[iz2] - pzc[iz1]) # fraction of way to second value + kz1 = 1.0 - kz2 + MCz = self.zvals[iz1] * kz1 + self.zvals[iz2] * kz2 + pDM = pzDM[iz1, :] * kz1 + pzDM[iz2, :] * kz2 else: # we perform a simple linear interpolation in z from 0 to minimum bin - kz2=r/pzc[iz2] - kz1=1.-kz2 - MCz=self.zvals[iz2]*kz2 - pDM=pzDM[iz2,:] # just use the value of lowest bin - - + kz2 = r / pzc[iz2] + kz1 = 1.0 - kz2 + MCz = self.zvals[iz2] * kz2 + pDM = pzDM[iz2, :] # just use the value of lowest bin + # NOW DO dm - #pDM=pzDM[k,:] - pDMc=np.cumsum(pDM) + # pDM=pzDM[k,:] + pDMc = np.cumsum(pDM) pDMc /= pDMc[-1] - r=np.random.rand(1)[0] - iDM2=np.where(pDMc>r)[0][0] + r = np.random.rand(1)[0] + iDM2 = np.where(pDMc > r)[0][0] if iDM2 > 0: - iDM1=iDM2-1 - dDM=r-pDMc[iDM1] - kDM2=dDM/(pDMc[iDM2] - pDMc[iDM1]) - kDM1=1.-kDM2 - MCDM=self.dmvals[iDM1]*kDM1 + self.dmvals[iDM2]*kDM2 - if iz2>0: - Eth=self.thresholds[j,iz1,iDM1]*kz1*kDM1 \ - + self.thresholds[j,iz1,iDM2]*kz1*kDM2 \ - + self.thresholds[j,iz2,iDM1]*kz2*kDM1 \ - + self.thresholds[j,iz2,iDM2]*kz2*kDM2 - else: - Eth=self.thresholds[j,iz2,iDM1]*kDM1 \ - + self.thresholds[j,iz2,iDM2]*kDM2 - Eth *= kz2**2 #assume threshold goes as Eth~z^2 in the near Universe + iDM1 = iDM2 - 1 + dDM = r - pDMc[iDM1] + kDM2 = dDM / (pDMc[iDM2] - pDMc[iDM1]) + kDM1 = 1.0 - kDM2 + MCDM = self.dmvals[iDM1] * kDM1 + self.dmvals[iDM2] * kDM2 + if iz2 > 0: + Eth = ( + self.thresholds[j, iz1, iDM1] * kz1 * kDM1 + + self.thresholds[j, iz1, iDM2] * kz1 * kDM2 + + self.thresholds[j, iz2, iDM1] * kz2 * kDM1 + + self.thresholds[j, iz2, iDM2] * kz2 * kDM2 + ) + else: + Eth = ( + self.thresholds[j, iz2, iDM1] * kDM1 + + self.thresholds[j, iz2, iDM2] * kDM2 + ) + Eth *= kz2 ** 2 # assume threshold goes as Eth~z^2 in the near Universe else: # interpolate linearly from 0 to the minimum value - kDM2=r/pDMc[iDM2] - MCDM=self.dmvals[iDM2]*kDM2 - if iz2>0: # ignore effect of lowest DM bin on threshold - Eth=self.thresholds[j,iz1,iDM2]*kz1 \ - + self.thresholds[j,iz2,iDM2]*kz2 - else: - Eth=self.thresholds[j,iz2,iDM2]*kDM2 - Eth *= kz2**2 #assume threshold goes as Eth~z^2 in the near Universe - + kDM2 = r / pDMc[iDM2] + MCDM = self.dmvals[iDM2] * kDM2 + if iz2 > 0: # ignore effect of lowest DM bin on threshold + Eth = ( + self.thresholds[j, iz1, iDM2] * kz1 + + self.thresholds[j, iz2, iDM2] * kz2 + ) + else: + Eth = self.thresholds[j, iz2, iDM2] * kDM2 + Eth *= kz2 ** 2 # assume threshold goes as Eth~z^2 in the near Universe + # now account for beamshape Eth /= MCb - + # NOW GET snr - #Eth=self.thresholds[j,k,l]/MCb - Es=np.logspace(np.log10(Eth),np.log10(Emax) + Emax_boost, 1000) - PEs=self.vector_cum_lf(Es,Emin,Emax,gamma) - PEs /= PEs[0] # normalises: this is now cumulative distribution from 1 to 0 - r=np.random.rand(1)[0] - iE1=np.where(PEs>r)[0][-1] #returns list starting at 0 and going upwards - iE2 = iE1+1 + # Eth=self.thresholds[j,k,l]/MCb + Es = np.logspace(np.log10(Eth), np.log10(Emax) + Emax_boost, 1000) + PEs = self.vector_cum_lf(Es, Emin, Emax, gamma) + PEs /= PEs[0] # normalises: this is now cumulative distribution from 1 to 0 + r = np.random.rand(1)[0] + iE1 = np.where(PEs > r)[0][-1] # returns list starting at 0 and going upwards + iE2 = iE1 + 1 # iE1 should never be the highest energy, since it will always have a probability of 0 (or near 0 for Gamma) - kE1=(r-PEs[iE2])/(PEs[iE1]-PEs[iE2]) - kE2=1.-kE1 - MCE=10**(np.log10(Es[iE1])*kE1 + np.log10(Es[iE2])*kE2) - MCs=MCE/Eth - - FRBparams=[MCz,MCDM,MCb,j,MCs] - return FRBparams,pwb - + kE1 = (r - PEs[iE2]) / (PEs[iE1] - PEs[iE2]) + kE2 = 1.0 - kE1 + MCE = 10 ** (np.log10(Es[iE1]) * kE1 + np.log10(Es[iE2]) * kE2) + MCs = MCE / Eth + + FRBparams = [MCz, MCDM, MCb, j, MCs] + return FRBparams, pwb + def build_sz(self): pass - def update(self, vparams:dict, ALL=False, prev_grid=None): + def update(self, vparams: dict, ALL=False, prev_grid=None): """Update the grid based on a set of input parameters @@ -616,12 +668,14 @@ def update(self, vparams:dict, ALL=False, prev_grid=None): Emin Emax gamma + H0 calc_thresholds F0 alpha bandwidth set_evolution sfr_n + H0 smear_grid grid @@ -642,7 +696,7 @@ def update(self, vparams:dict, ALL=False, prev_grid=None): new_sfr_smear, new_pdv_smear, calc_thresh = False, False, False # Cosmology -- Only H0 so far - if self.chk_upd_param('H0', vparams, update=True): + if self.chk_upd_param("H0", vparams, update=True): reset_cos = True get_zdm = True calc_dV = True @@ -653,43 +707,51 @@ def update(self, vparams:dict, ALL=False, prev_grid=None): new_sfr_smear = True # IGM - if self.chk_upd_param('F', vparams, update=True): + if self.chk_upd_param("logF", vparams, update=True): get_zdm = True smear_dm = True - calc_thresh = True - calc_pdv = True - set_evol = True + # calc_thresh = False # JMB + # calc_pdv = False # JMB + # set_evol = False # JMB new_sfr_smear = True - # Mask? + # DM_host # IT IS IMPORTANT TO USE np.any so that each item is executed!! - if np.any([self.chk_upd_param('lmean', vparams, update=True), - self.chk_upd_param('lsigma', vparams, update=True)]): + if np.any( + [ + self.chk_upd_param("lmean", vparams, update=True), + self.chk_upd_param("lsigma", vparams, update=True), + ] + ): smear_mask = True smear_dm = True - new_sfr_smear=True + new_sfr_smear = True # SFR? - if self.chk_upd_param('sfr_n', vparams, update=True): + if self.chk_upd_param("sfr_n", vparams, update=True): set_evol = True - new_sfr_smear=True # True for either alpha_method - if self.chk_upd_param('alpha', vparams, update=True): + new_sfr_smear = True # True for either alpha_method + if self.chk_upd_param("alpha", vparams, update=True): set_evol = True if self.state.FRBdemo.alpha_method == 0: calc_thresh = True calc_pdv = True - new_pdv_smear=True + new_pdv_smear = True elif self.state.FRBdemo.alpha_method == 1: - new_sfr_smear=True + new_sfr_smear = True ##### examines the 'pdv tree' affecting sensitivity ##### # begin with alpha # alpha does not change thresholds under rate scaling, only spec index - if np.any([self.chk_upd_param('lEmin', vparams, update=True), - self.chk_upd_param('lEmax', vparams, update=True), - self.chk_upd_param('gamma', vparams, update=True)]): + if np.any( + [ + self.chk_upd_param("lEmin", vparams, update=True), + self.chk_upd_param("lEmax", vparams, update=True), + self.chk_upd_param("gamma", vparams, update=True), + ] + ): calc_pdv = True - new_pdv_smear=True + new_pdv_smear = True # ########################### # NOW DO THE REAL WORK!! @@ -703,16 +765,26 @@ def update(self, vparams:dict, ALL=False, prev_grid=None): if get_zdm or ALL: if prev_grid is None: - zDMgrid, zvals,dmvals=misc_functions.get_zdm_grid( - self.state, new=True,plot=False,method='analytic', - save=False,nz=self.zvals.size,zmax=self.zvals[-1], - ndm=self.dmvals.size,dmmax=self.dmvals[-1],zlog=self.zlog) - self.parse_grid(zDMgrid,zvals,dmvals) + zDMgrid, zvals, dmvals = misc_functions.get_zdm_grid( + self.state, + new=True, + plot=False, + method="analytic", + save=False, + nz=self.zvals.size, + zmax=self.zvals[-1], + ndm=self.dmvals.size, + dmmax=self.dmvals[-1], + zlog=self.zlog, + ) + self.parse_grid(zDMgrid, zvals, dmvals) else: # Pass a copy (just to be safe) - self.parse_grid(prev_grid.grid.copy(), - prev_grid.zvals.copy(), - prev_grid.dmvals.copy()) + self.parse_grid( + prev_grid.grid.copy(), + prev_grid.zvals.copy(), + prev_grid.dmvals.copy(), + ) if calc_dV or ALL: if prev_grid is None: @@ -723,9 +795,11 @@ def update(self, vparams:dict, ALL=False, prev_grid=None): # Smear? if smear_mask or ALL: if prev_grid is None: - self.smear=pcosmic.get_dm_mask( - self.dmvals,(self.state.host.lmean, - self.state.host.lsigma), self.zvals) + self.smear = pcosmic.get_dm_mask( + self.dmvals, + (self.state.host.lmean, self.state.host.lsigma), + self.zvals, + ) else: self.smear = prev_grid.smear.copy() if smear_dm or ALL: @@ -734,28 +808,30 @@ def update(self, vparams:dict, ALL=False, prev_grid=None): else: self.smear = prev_grid.smear.copy() self.smear_grid = prev_grid.smear_grid.copy() - + if calc_thresh or ALL: self.calc_thresholds( - self.F0,self.eff_table, bandwidth=self.bandwidth, - weights=self.eff_weights) - - + self.F0, + self.eff_table, + bandwidth=self.bandwidth, + weights=self.eff_weights, + ) + if calc_pdv or ALL: self.calc_pdv() if set_evol or ALL: - self.set_evolution() # sets star-formation rate scaling with z - here, no evoltion... + self.set_evolution() # sets star-formation rate scaling with z - here, no evoltion... if new_sfr_smear or ALL: - self.calc_rates() #includes sfr smearing factors and pdv mult + self.calc_rates() # includes sfr smearing factors and pdv mult elif new_pdv_smear: - self.rates=self.pdv*self.sfr_smear #does pdv mult only, 'by hand' + self.rates = self.pdv * self.sfr_smear # does pdv mult only, 'by hand' # Catch all the changes just in case, e.g. lC self.state.update_params(vparams) - def chk_upd_param(self, param:str, vparams:dict, update=False): + def chk_upd_param(self, param: str, vparams: dict, update=False): """ Check to see whether a parameter is differs from that in self.state diff --git a/zdm/misc_functions.py b/zdm/misc_functions.py index 77ae5cff..9683799c 100644 --- a/zdm/misc_functions.py +++ b/zdm/misc_functions.py @@ -26,386 +26,431 @@ from zdm import parameters -def marginalise(pset,grids,surveys,which,vals,disable=None,psnr=True,PenTypes=None,PenParams=None,Verbose=False,steps=None): +def marginalise( + pset, + grids, + surveys, + which, + vals, + disable=None, + psnr=True, + PenTypes=None, + PenParams=None, + Verbose=False, + steps=None, +): """ Calculates limits for a single variable """ - t0=time.process_time() - t1=t0 - lls=np.zeros([vals.size]) - psets=[] + t0 = time.process_time() + t1 = t0 + lls = np.zeros([vals.size]) + psets = [] if disable is not None: disable.append(which) else: - disable=[which] - steps=np.full([8],0.5) - for i,v in enumerate(vals): - pset[which]=v - print("Setting parameter ",which," = ",v) - - C_ll,C_p=it.my_minimise(pset,grids,surveys,disable=disable,psnr=psnr,PenTypes=PenTypes,PenParams=PenParams,Verbose=False,steps=steps) - steps=np.full([8],0.1) - print(i,v,C_ll,pset) - t1=time.process_time() + disable = [which] + steps = np.full([8], 0.5) + for i, v in enumerate(vals): + pset[which] = v + print("Setting parameter ", which, " = ", v) + + C_ll, C_p = it.my_minimise( + pset, + grids, + surveys, + disable=disable, + psnr=psnr, + PenTypes=PenTypes, + PenParams=PenParams, + Verbose=False, + steps=steps, + ) + steps = np.full([8], 0.1) + print(i, v, C_ll, pset) + t1 = time.process_time() psets.append(C_p) - lls[i]=C_ll - t2=time.process_time() - print("Iteration ",i," took ",t2-t1," seconds") - t1=t2 - print("Done - total time ",t1-t0," seconds") - psets=np.array(psets) - np.save('Marginalise1D/'+str(which)+'_lls.npy',lls) - np.save('Marginalise1D/'+str(which)+'_psets.npy',psets) + lls[i] = C_ll + t2 = time.process_time() + print("Iteration ", i, " took ", t2 - t1, " seconds") + t1 = t2 + print("Done - total time ", t1 - t0, " seconds") + psets = np.array(psets) + np.save("Marginalise1D/" + str(which) + "_lls.npy", lls) + np.save("Marginalise1D/" + str(which) + "_psets.npy", psets) -def get_source_counts(grid,plot=None,Slabel=None): +def get_source_counts(grid, plot=None, Slabel=None): """ Calculates the source-counts function for a given grid It does this in terms of p(SNR)dSNR """ # this is closely related to the likelihood for observing a given psnr! - + # calculate vector of grid thresholds - Emax=grid.Emax - Emin=grid.Emin - gamma=grid.gamma - - nsnr=71 - snrmin=0.001 - snrmax=1000. - ndm=grid.dmvals.size - snrs=np.logspace(0,2,nsnr) # histogram array of values for s=SNR/SNR_th - + Emax = grid.Emax + Emin = grid.Emin + gamma = grid.gamma + + nsnr = 71 + snrmin = 0.001 + snrmax = 1000.0 + ndm = grid.dmvals.size + snrs = np.logspace(0, 2, nsnr) # histogram array of values for s=SNR/SNR_th + # holds cumulative and differential source counts - cpsnrs=np.zeros([nsnr]) - psnrs=np.zeros([nsnr-1]) - + cpsnrs = np.zeros([nsnr]) + psnrs = np.zeros([nsnr - 1]) + # holds DM-dependent source counts - dmcpsnrs=np.zeros([nsnr,ndm]) - dmpsnrs=np.zeros([nsnr-1,ndm]) - - backup1=np.copy(grid.thresholds) - Emin=grid.Emin - Emax=grid.Emax - gamma=grid.gamma - + dmcpsnrs = np.zeros([nsnr, ndm]) + dmpsnrs = np.zeros([nsnr - 1, ndm]) + + backup1 = np.copy(grid.thresholds) + Emin = grid.Emin + Emax = grid.Emax + gamma = grid.gamma + # modifies grid to simplify beamshape - grid.beam_b=np.array([grid.beam_b[-1]]) - grid.beam_o=np.array([grid.beam_o[-1]]) - grid.b_fractions=None - - for i,s in enumerate(snrs): - - grid.thresholds=backup1*s - grid.calc_pdv(Emin,Emax,gamma) + grid.beam_b = np.array([grid.beam_b[-1]]) + grid.beam_o = np.array([grid.beam_o[-1]]) + grid.b_fractions = None + + for i, s in enumerate(snrs): + + grid.thresholds = backup1 * s + grid.calc_pdv(Emin, Emax, gamma) grid.calc_rates() - rates=grid.rates - dmcpsnrs[i,:]=np.sum(rates,axis=0) - cpsnrs[i]=np.sum(dmcpsnrs[i,:]) - + rates = grid.rates + dmcpsnrs[i, :] = np.sum(rates, axis=0) + cpsnrs[i] = np.sum(dmcpsnrs[i, :]) + # the last one contains cumulative values - for i,s in enumerate(snrs): - if i==0: + for i, s in enumerate(snrs): + if i == 0: continue - psnrs[i-1]=cpsnrs[i-1]-cpsnrs[i] - dmpsnrs[i-1,:]=dmcpsnrs[i-1,:]-dmcpsnrs[i,:] - - mod=1.5 - snrs=snrs[:-1] - imid=int((nsnr+1)/2) - xmid=snrs[imid] - ymid=psnrs[imid] - slopes=np.linspace(1.3,1.7,5) - ys=[] - for i,s in enumerate(slopes): - ys.append(ymid*xmid**s*snrs**-s) - + psnrs[i - 1] = cpsnrs[i - 1] - cpsnrs[i] + dmpsnrs[i - 1, :] = dmcpsnrs[i - 1, :] - dmcpsnrs[i, :] + + mod = 1.5 + snrs = snrs[:-1] + imid = int((nsnr + 1) / 2) + xmid = snrs[imid] + ymid = psnrs[imid] + slopes = np.linspace(1.3, 1.7, 5) + ys = [] + for i, s in enumerate(slopes): + ys.append(ymid * xmid ** s * snrs ** -s) + if plot is not None: - fixpoint=ys[0][0]*snrs[0]**mod + fixpoint = ys[0][0] * snrs[0] ** mod plt.figure() - plt.xscale('log') - plt.yscale('log') - plt.ylim(1,3) - plt.xlabel('$s=\\frac{\\rm SNR}{\\rm SNR_{\\rm th}}$') - plt.ylabel('$p(s) s^{1.5} d\\,\\log(s)$ [a.u.]') - plt.plot(snrs,psnrs*snrs**mod/fixpoint,label='Prediction ('+Slabel+')',color='black',linewidth=2) # this is in relative units - for i,s in enumerate(slopes): - plt.plot(snrs,ys[i]*snrs**mod/fixpoint,label='slope='+str(s)[0:3]) - ax=plt.gca() - #labels = [item.get_text() for item in ax.get_yticklabels()] - #print("Labels are ",labels) - #labels[0] = '1' - #labels[1] = '2' - #labels[2] = '3' - #ax.set_yticklabels(labels) - ax.set_yticks([1,2,3]) - ax.set_yticklabels(['1','2','3']) - plt.legend(fontsize=12)#,loc=[6,8]) + plt.xscale("log") + plt.yscale("log") + plt.ylim(1, 3) + plt.xlabel("$s=\\frac{\\rm SNR}{\\rm SNR_{\\rm th}}$") + plt.ylabel("$p(s) s^{1.5} d\\,\\log(s)$ [a.u.]") + plt.plot( + snrs, + psnrs * snrs ** mod / fixpoint, + label="Prediction (" + Slabel + ")", + color="black", + linewidth=2, + ) # this is in relative units + for i, s in enumerate(slopes): + plt.plot(snrs, ys[i] * snrs ** mod / fixpoint, label="slope=" + str(s)[0:3]) + ax = plt.gca() + # labels = [item.get_text() for item in ax.get_yticklabels()] + # print("Labels are ",labels) + # labels[0] = '1' + # labels[1] = '2' + # labels[2] = '3' + # ax.set_yticklabels(labels) + ax.set_yticks([1, 2, 3]) + ax.set_yticklabels(["1", "2", "3"]) + plt.legend(fontsize=12) # ,loc=[6,8]) plt.tight_layout() plt.savefig(plot) plt.close() - return snrs,psnrs,dmpsnrs - + return snrs, psnrs, dmpsnrs + + def get_test_pks_surveys(): - + # load Parkes data # generates a set of surveys with fake central beam histograms - pksa=survey.survey() - pksa.process_survey_file('Surveys/parkes_mb.dat') - pksa.meta["BEAM"]="a_b0" - pksa.init_beam(method=3,plot=True) # need more bins for Parkes! - - pkse=survey.survey() - pkse.process_survey_file('Surveys/parkes_mb.dat') - pkse.meta["BEAM"]="e_b0" - pkse.init_beam(method=3,plot=True) # need more bins for Parkes! - - pksk=survey.survey() - pksk.process_survey_file('Surveys/parkes_mb.dat') - pksk.meta["BEAM"]="k_b0" - pksk.init_beam(method=3,plot=True) # need more bins for Parkes! - - pksh=survey.survey() - pksh.process_survey_file('Surveys/parkes_mb.dat') - pksh.meta["BEAM"]="h_b0" - pksh.init_beam(method=3,plot=True) # need more bins for Parkes! - - pksl=survey.survey() - pksl.process_survey_file('Surveys/parkes_mb.dat') - pksl.meta["BEAM"]="l_b0" - pksl.init_beam(method=3,plot=True) # need more bins for Parkes! - - surveys=[pksa,pkse,pksk,pksh,pksl] + pksa = survey.survey() + pksa.process_survey_file("Surveys/parkes_mb.dat") + pksa.meta["BEAM"] = "a_b0" + pksa.init_beam(method=3, plot=True) # need more bins for Parkes! + + pkse = survey.survey() + pkse.process_survey_file("Surveys/parkes_mb.dat") + pkse.meta["BEAM"] = "e_b0" + pkse.init_beam(method=3, plot=True) # need more bins for Parkes! + + pksk = survey.survey() + pksk.process_survey_file("Surveys/parkes_mb.dat") + pksk.meta["BEAM"] = "k_b0" + pksk.init_beam(method=3, plot=True) # need more bins for Parkes! + + pksh = survey.survey() + pksh.process_survey_file("Surveys/parkes_mb.dat") + pksh.meta["BEAM"] = "h_b0" + pksh.init_beam(method=3, plot=True) # need more bins for Parkes! + + pksl = survey.survey() + pksl.process_survey_file("Surveys/parkes_mb.dat") + pksl.meta["BEAM"] = "l_b0" + pksl.init_beam(method=3, plot=True) # need more bins for Parkes! + + surveys = [pksa, pkse, pksk, pksh, pksl] return surveys - -def do_single_errors(grids,surveys,pset,outdir): + +def do_single_errors(grids, surveys, pset, outdir): """ iterates over sensible ranges of all single-parameter errors """ - + # for each parameter, investigate the best-fit as a function of range # in each case, we fix the parameter at the value # then we let the optimisation go while holding it fixed - + # we now set the base ranges - fig1=plt.figure() - plt.xlabel('Relative variation') - plt.ylabel('log-likelihood') - + fig1 = plt.figure() + plt.xlabel("Relative variation") + plt.ylabel("log-likelihood") + ### Emax ### - which=1 - rels=np.linspace(-1,1,3) - Emaxes=pset[1]*10**rels - delta=0.1 - lls1,psets1=one_parameter_error_range(grids,surveys,pset,which,delta,crit=0.5) #0.5 is about 1 sigma - opdir=outdir+it.get_names(1)+'/' + which = 1 + rels = np.linspace(-1, 1, 3) + Emaxes = pset[1] * 10 ** rels + delta = 0.1 + lls1, psets1 = one_parameter_error_range( + grids, surveys, pset, which, delta, crit=0.5 + ) # 0.5 is about 1 sigma + opdir = outdir + it.get_names(1) + "/" if not os.path.exists(opdir): os.mkdir(opdir) - savename=opdir+'correlation_'+it.get_lnames(1)+'.pdf' - do_correlation_plots(Emaxes,lls1,psets1,[0,1],savename) # tells it that parameters 0 and 1 are not to be plotted - - plt.plot(rels,lls1,label=it.get_lnames(1)) - - + savename = opdir + "correlation_" + it.get_lnames(1) + ".pdf" + do_correlation_plots( + Emaxes, lls1, psets1, [0, 1], savename + ) # tells it that parameters 0 and 1 are not to be plotted + + plt.plot(rels, lls1, label=it.get_lnames(1)) + plt.tight_layout() - plt.savefig(outdir+'varying_likelihoods.pdf') + plt.savefig(outdir + "varying_likelihoods.pdf") plt.close() - -def do_correlation_plots(vals,lls,psets,const,savename): + +def do_correlation_plots(vals, lls, psets, const, savename): """ Plots correlations of different variables """ - + plt.figure() - nv,np=psets.shape() + nv, np = psets.shape() for i in np.arange(np): if i in const: continue - plt.plot(vals,psets[:,i],label=it.get_lnames(i)) + plt.plot(vals, psets[:, i], label=it.get_lnames(i)) plt.savefig(savename) - -def one_parameter_error_range(grids,surveys,pset,which,delta,crit=0.5): + + +def one_parameter_error_range(grids, surveys, pset, which, delta, crit=0.5): """ Investigates a range of errors for each parameter in 1D only which is which parameter to investigate rels are the list of relative """ - + # keep original pset - tpset=np.copy(pset) - #lls=np.zeros([values.size]) - #sets=np.zeros([values.size,pset.size]) - - lls=[] - vals=[] - psets=[pset] + tpset = np.copy(pset) + # lls=np.zeros([values.size]) + # sets=np.zeros([values.size,pset.size]) + + lls = [] + vals = [] + psets = [pset] print("About to minimise...") - ll,ps=it.my_minimise(tpset,grids,surveys,disable=[0,which]) - lls=[ll] - psets=[ps] - ll0=ll - llcrit=ll0-crit - vals=[tpset[which]] - - print("Found initial minimum at ",ll,ps) - - tpset[3]=0.1 - + ll, ps = it.my_minimise(tpset, grids, surveys, disable=[0, which]) + lls = [ll] + psets = [ps] + ll0 = ll + llcrit = ll0 - crit + vals = [tpset[which]] + + print("Found initial minimum at ", ll, ps) + + tpset[3] = 0.1 + # goes down - while(ll > llcrit): + while ll > llcrit: tpset[which] -= delta - t0=time.process_time() - ll,ps=it.my_minimise(tpset,grids,surveys,disable=[0,which]) - t1=time.process_time() - lls.insert(0,ll) - psets.insert(0,ps) - vals.insert(0,tpset[which]) - print("In time ",t1-t0," values now ",ll,ps) - if ll==0.: - break # means parameter are meaningless - + t0 = time.process_time() + ll, ps = it.my_minimise(tpset, grids, surveys, disable=[0, which]) + t1 = time.process_time() + lls.insert(0, ll) + psets.insert(0, ps) + vals.insert(0, tpset[which]) + print("In time ", t1 - t0, " values now ", ll, ps) + if ll == 0.0: + break # means parameter are meaningless + # resets tpset = pset - ll=ll0 - + ll = ll0 + # goes up - while(ll > llcrit): + while ll > llcrit: tpset[which] += delta - t0=time.process_time() - ll,ps=it.my_minimise(tpset,grids,surveys,disable=[0,which]) - t1=time.process_time() + t0 = time.process_time() + ll, ps = it.my_minimise(tpset, grids, surveys, disable=[0, which]) + t1 = time.process_time() lls.append(ll) psets.append(ps) vals.append(tpset[which]) - print("In time ",t1-t0," values now ",ll,ps) - if ll==0.: - break # means we got an nan and parameters are meaningless - - return lls,psets - -def get_zgdm_priors(grid,survey,savename): + print("In time ", t1 - t0, " values now ", ll, ps) + if ll == 0.0: + break # means we got an nan and parameters are meaningless + + return lls, psets + + +def get_zgdm_priors(grid, survey, savename): """ Plots priors as a function of redshift for each FRB in the survey Likely outdated, should use the likelihoods function. """ - priors=grid.get_p_zgdm(survey.DMEGs) + priors = grid.get_p_zgdm(survey.DMEGs) plt.figure() - plt.xlabel('$z$') - plt.ylabel('$p(z|{\\rm DM})$') - for i,dm in enumerate(survey.DMs): - if i<10: - style="-" + plt.xlabel("$z$") + plt.ylabel("$p(z|{\\rm DM})$") + for i, dm in enumerate(survey.DMs): + if i < 10: + style = "-" else: - style=":" - plt.plot(grid.zvals,priors[i,:],label=str(dm),linestyle=style) - plt.xlim(0,0.5) - plt.legend(fontsize=8,ncol=2) + style = ":" + plt.plot(grid.zvals, priors[i, :], label=str(dm), linestyle=style) + plt.xlim(0, 0.5) + plt.legend(fontsize=8, ncol=2) plt.tight_layout() plt.savefig(savename) plt.close() -def make_dm_redshift(grid,savename="",DMmax=1000, - zmax=1,loc='upper left',Macquart=None, - H0=None,showplot=False): - ''' generates full dm-redhsift (Macquart) relation ''' + +def make_dm_redshift( + grid, + savename="", + DMmax=1000, + zmax=1, + loc="upper left", + Macquart=None, + H0=None, + showplot=False, +): + """ generates full dm-redhsift (Macquart) relation """ if H0 is None: H0 = cos.cosmo.H0 - ndm=1000 - cvs=[0.025,0.16,0.5,0.84,0.975] - nc=len(cvs) - names=['$2\\sigma$','$1\\sigma$','Median','',''] - styles=[':','--','-','--',':'] - colours=["white","white","black","white","white"] - DMs=np.linspace(DMmax/ndm,DMmax,ndm,endpoint=True) - priors=grid.get_p_zgdm(DMs) - zvals=grid.zvals - means=np.mean(priors,axis=1) - csums=np.cumsum(priors,axis=1) - - crits=np.zeros([nc,ndm]) - + ndm = 1000 + cvs = [0.025, 0.16, 0.5, 0.84, 0.975] + nc = len(cvs) + names = ["$2\\sigma$", "$1\\sigma$", "Median", "", ""] + styles = [":", "--", "-", "--", ":"] + colours = ["white", "white", "black", "white", "white"] + DMs = np.linspace(DMmax / ndm, DMmax, ndm, endpoint=True) + priors = grid.get_p_zgdm(DMs) + zvals = grid.zvals + means = np.mean(priors, axis=1) + csums = np.cumsum(priors, axis=1) + + crits = np.zeros([nc, ndm]) + for i in np.arange(ndm): - for j,c in enumerate(cvs): - ic=np.where(csums[i]>c)[0][0] - if ic>0: - kc=(csums[i,ic]-c)/(csums[i,ic]-csums[i,ic-1]) - crits[j,i]=zvals[ic]*(1-kc)+zvals[ic-1]*kc + for j, c in enumerate(cvs): + ic = np.where(csums[i] > c)[0][0] + if ic > 0: + kc = (csums[i, ic] - c) / (csums[i, ic] - csums[i, ic - 1]) + crits[j, i] = zvals[ic] * (1 - kc) + zvals[ic - 1] * kc else: - crits[j,i]=zvals[ic] - + crits[j, i] = zvals[ic] + # now we convert this between real values and integer units - dz=zvals[1]-zvals[0] + dz = zvals[1] - zvals[0] crits /= dz - + ### concatenate for plotting ### - delete=np.where(zvals > zmax)[0][0] - plotpriors=priors[:,0:delete] - plotz=zvals[0:delete] - + delete = np.where(zvals > zmax)[0][0] + plotpriors = priors[:, 0:delete] + plotz = zvals[0:delete] + plt.figure() - + ############# sets the x and y tics ################3 - ytvals=np.arange(plotz.size) - every=int(plotz.size/5) - ytickpos=np.insert(ytvals[every-1::every],[0],[0]) - yticks=np.insert(plotz[every-1::every],[0],[0]) - - #plt.yticks(ytvals[every-1::every],plotz[every-1::every]) - plt.yticks(ytickpos,yticks) - xtvals=np.arange(ndm) - everx=int(ndm/5) - xtickpos=np.insert(xtvals[everx-1::everx],[0],[0]) - xticks=np.insert(DMs[everx-1::everx],[0],[0]) - plt.xticks(xtickpos,xticks) - #plt.xticks(xtvals[everx-1::everx],DMs[everx-1::everx]) - - ax=plt.gca() + ytvals = np.arange(plotz.size) + every = int(plotz.size / 5) + ytickpos = np.insert(ytvals[every - 1 :: every], [0], [0]) + yticks = np.insert(plotz[every - 1 :: every], [0], [0]) + + # plt.yticks(ytvals[every-1::every],plotz[every-1::every]) + plt.yticks(ytickpos, yticks) + xtvals = np.arange(ndm) + everx = int(ndm / 5) + xtickpos = np.insert(xtvals[everx - 1 :: everx], [0], [0]) + xticks = np.insert(DMs[everx - 1 :: everx], [0], [0]) + plt.xticks(xtickpos, xticks) + # plt.xticks(xtvals[everx-1::everx],DMs[everx-1::everx]) + + ax = plt.gca() labels = [item.get_text() for item in ax.get_xticklabels()] for i in np.arange(len(labels)): - thisl=len(labels[i]) - labels[i]=labels[i][0:thisl-1] + thisl = len(labels[i]) + labels[i] = labels[i][0 : thisl - 1] ax.set_xticklabels(labels) - + #### rescales priors to max value for visibility's sake #### - dm_max=np.max(plotpriors,axis=1) + dm_max = np.max(plotpriors, axis=1) for i in np.arange(ndm): - plotpriors[i,:] /= np.max(plotpriors[i,:]) - - - - cmx = plt.get_cmap('cubehelix') - plt.xlabel('${\\rm DM}_{\\rm EG}$') - plt.ylabel('z') - - aspect=float(ndm)/plotz.size - plt.imshow(plotpriors.T,origin='lower',cmap=cmx,aspect=aspect) - cbar=plt.colorbar() - cbar.set_label('$p(z|{\\rm DM})/p_{\\rm max}(z|{\\rm DM})$') + plotpriors[i, :] /= np.max(plotpriors[i, :]) + + cmx = plt.get_cmap("cubehelix") + plt.xlabel("${\\rm DM}_{\\rm EG}$") + plt.ylabel("z") + + aspect = float(ndm) / plotz.size + plt.imshow(plotpriors.T, origin="lower", cmap=cmx, aspect=aspect) + cbar = plt.colorbar() + cbar.set_label("$p(z|{\\rm DM})/p_{\\rm max}(z|{\\rm DM})$") ###### now we plot the specific thingamies ####### - for i,c in enumerate(cvs): - plt.plot(np.arange(ndm),crits[i,:],linestyle=styles[i],label=names[i],color=colours[i]) - - #Macquart=None + for i, c in enumerate(cvs): + plt.plot( + np.arange(ndm), + crits[i, :], + linestyle=styles[i], + label=names[i], + color=colours[i], + ) + + # Macquart=None if Macquart is not None: - plt.ylim(0,ytvals.size) - nz=zvals.size - - plt.xlim(0,xtvals.size) - zmax=zvals[-1] - DMbar, zeval = igm.average_DM(zmax, cumul=True, neval=nz+1) - DMbar = DMbar*H0/(cos.DEF_H0) # NOT SURE THIS IS RIGHT - DMbar=np.array(DMbar) - DMbar += Macquart #should be interpreted as muDM - - - #idea is that 1 point is 1, hence... - zeval /= (zvals[1]-zvals[0]) - DMbar /= (DMs[1]-DMs[0]) - - plt.plot(DMbar,zeval,linewidth=2,label='Macquart',color='blue') - #l=plt.legend(loc='lower right',fontsize=12) - #l=plt.legend(bbox_to_anchor=(0.2, 0.8),fontsize=8) - #for text in l.get_texts(): - # text.set_color("white") - - #plt.plot([30,40],[0.5,10],linewidth=10) - + plt.ylim(0, ytvals.size) + nz = zvals.size + + plt.xlim(0, xtvals.size) + zmax = zvals[-1] + DMbar, zeval = igm.average_DM(zmax, cumul=True, neval=nz + 1) + DMbar = DMbar * H0 / (cos.DEF_H0) # NOT SURE THIS IS RIGHT + DMbar = np.array(DMbar) + DMbar += Macquart # should be interpreted as muDM + + # idea is that 1 point is 1, hence... + zeval /= zvals[1] - zvals[0] + DMbar /= DMs[1] - DMs[0] + + plt.plot(DMbar, zeval, linewidth=2, label="Macquart", color="blue") + # l=plt.legend(loc='lower right',fontsize=12) + # l=plt.legend(bbox_to_anchor=(0.2, 0.8),fontsize=8) + # for text in l.get_texts(): + # text.set_color("white") + + # plt.plot([30,40],[0.5,10],linewidth=10) + plt.legend(loc=loc) plt.savefig(savename) if H0 is not None: @@ -415,155 +460,170 @@ def make_dm_redshift(grid,savename="",DMmax=1000, plt.close() +def fit_width_test(pset, surveys, grids, names): + x0 = [2.139, 0.997] + x0 = [1.7712265624999926, 0.9284453124999991] + args = [pset, surveys, grids, names] + result = min_wt(x0, args) + print("result of fit is ", result) -def fit_width_test(pset,surveys,grids,names): - x0=[2.139,0.997] - x0=[1.7712265624999926, 0.9284453124999991] - args=[pset,surveys,grids,names] - result=min_wt(x0,args) - print("result of fit is ",result) - -def min_wt(x,args): - - logmean=x[0] - logsigma=x[1] - - pset=args[0] - surveys=args[1] - grids=args[2] - names=args[3] - - oldchi2=1e10 - dlogmean=0.1 - dlogsigma=0.1 - +def min_wt(x, args): + + logmean = x[0] + logsigma = x[1] + + pset = args[0] + surveys = args[1] + grids = args[2] + names = args[3] + + oldchi2 = 1e10 + dlogmean = 0.1 + dlogsigma = 0.1 + for i in np.arange(10): - - while(True): + + while True: logmean -= dlogmean - W,C=basic_width_test(pset,[surveys[0]],[grids[0]],logmean,logsigma) - chi2=np.sum((W-C)**2) + W, C = basic_width_test(pset, [surveys[0]], [grids[0]], logmean, logsigma) + chi2 = np.sum((W - C) ** 2) if chi2 > oldchi2: logmean += dlogmean break else: - oldchi2=chi2 - while(True): + oldchi2 = chi2 + while True: logmean += dlogmean - W,C=basic_width_test(pset,[surveys[0]],[grids[0]],logmean,logsigma) - chi2=np.sum((W-C)**2) + W, C = basic_width_test(pset, [surveys[0]], [grids[0]], logmean, logsigma) + chi2 = np.sum((W - C) ** 2) if chi2 > oldchi2: logmean -= dlogmean break else: - oldchi2=chi2 - while(True): + oldchi2 = chi2 + while True: logsigma += dlogsigma - W,C=basic_width_test(pset,[surveys[0]],[grids[0]],logmean,logsigma) - chi2=np.sum((W-C)**2) + W, C = basic_width_test(pset, [surveys[0]], [grids[0]], logmean, logsigma) + chi2 = np.sum((W - C) ** 2) if chi2 > oldchi2: logsigma -= dlogsigma break else: - oldchi2=chi2 - while(True): + oldchi2 = chi2 + while True: logsigma -= dlogsigma - W,C=basic_width_test(pset,[surveys[0]],[grids[0]],logmean,logsigma) - chi2=np.sum((W-C)**2) + W, C = basic_width_test(pset, [surveys[0]], [grids[0]], logmean, logsigma) + chi2 = np.sum((W - C) ** 2) if chi2 > oldchi2: logsigma += dlogsigma break else: - oldchi2=chi2 - dlogsigma /= 2. - dlogmean /= 2. - print(i,logmean,logsigma,chi2) - return logmean,logsigma,chi2 + oldchi2 = chi2 + dlogsigma /= 2.0 + dlogmean /= 2.0 + print(i, logmean, logsigma, chi2) + return logmean, logsigma, chi2 -def basic_width_test(pset,surveys,grids,logmean=2,logsigma=1): +def basic_width_test(pset, surveys, grids, logmean=2, logsigma=1): """ Tests the effects of intrinsic widths on FRB properties """ - - IGNORE=0. # a parameter that gets ignored - + + IGNORE = 0.0 # a parameter that gets ignored + ############ set default parameters for width distribution ########### # 'real' version - wmin=0.1 - wmax=20 - NW=200 - #short version - #wmin=0.1 - #wmax=50 - #NW=100 - dw=(wmax-wmin)/2. - widths=np.linspace(wmin,wmax,NW) - - probs=pcosmic.linlognormal_dlin(widths,[logmean,logsigma]) #not integrating, just amplitudes + wmin = 0.1 + wmax = 20 + NW = 200 + # short version + # wmin=0.1 + # wmax=50 + # NW=100 + dw = (wmax - wmin) / 2.0 + widths = np.linspace(wmin, wmax, NW) + + probs = pcosmic.linlognormal_dlin( + widths, [logmean, logsigma] + ) # not integrating, just amplitudes # normalise probabilities probs /= np.sum(probs) - - MAX=1 - norm=MAX/np.max(probs) + + MAX = 1 + norm = MAX / np.max(probs) probs *= norm - - Emin=10**pset[0] - Emax=10**pset[1] - alpha=pset[2] - gamma=pset[3] - NS=len(surveys) - rates=np.zeros([NS,NW]) - rp=np.zeros([NS,NW]) - - #calculating total rate compared to what is expected for ~width 0 - sumw=0. - DMvals=grids[0].dmvals - zvals=grids[0].zvals - - dmplots=np.zeros([NS,NW,DMvals.size]) - zplots=np.zeros([NS,NW,zvals.size]) - + + Emin = 10 ** pset[0] + Emax = 10 ** pset[1] + alpha = pset[2] + gamma = pset[3] + NS = len(surveys) + rates = np.zeros([NS, NW]) + rp = np.zeros([NS, NW]) + + # calculating total rate compared to what is expected for ~width 0 + sumw = 0.0 + DMvals = grids[0].dmvals + zvals = grids[0].zvals + + dmplots = np.zeros([NS, NW, DMvals.size]) + zplots = np.zeros([NS, NW, zvals.size]) + #### does this for width distributions ####### - - for i,s in enumerate(surveys): - g=grids[i] - fbar=s.meta['FBAR'] - tres=s.meta['TRES'] - fres=s.meta['FRES'] - thresh=s.meta['THRESH'] + + for i, s in enumerate(surveys): + g = grids[i] + fbar = s.meta["FBAR"] + tres = s.meta["TRES"] + fres = s.meta["FRES"] + thresh = s.meta["THRESH"] ###### "Full" version ###### - for j,w in enumerate(widths): + for j, w in enumerate(widths): # artificially set response function - sens=survey.calc_relative_sensitivity(IGNORE,DMvals,w,fbar,tres,fres,model='Quadrature',dsmear=False) - - g.calc_thresholds(thresh,sens,alpha=alpha) - g.calc_pdv(Emin,Emax,gamma) - + sens = survey.calc_relative_sensitivity( + IGNORE, DMvals, w, fbar, tres, fres, model="Quadrature", dsmear=False + ) + + g.calc_thresholds(thresh, sens, alpha=alpha) + g.calc_pdv(Emin, Emax, gamma) + g.calc_rates() - rates[i,j]=np.sum(g.rates) - dmplots[i,j,:]=np.sum(g.rates,axis=0) - zplots[i,j,:]=np.sum(g.rates,axis=1) - - rates[i,:] /= rates[i,0] - - #norm_orates[i,:] = orates[i,0]/rates[i,0] - rp[i,:]=rates[i,:]*probs - - rp[i,:]*=MAX/np.max(rp[i,:]) - + rates[i, j] = np.sum(g.rates) + dmplots[i, j, :] = np.sum(g.rates, axis=0) + zplots[i, j, :] = np.sum(g.rates, axis=1) + + rates[i, :] /= rates[i, 0] + + # norm_orates[i,:] = orates[i,0]/rates[i,0] + rp[i, :] = rates[i, :] * probs + + rp[i, :] *= MAX / np.max(rp[i, :]) + # shows the distribution of widths using Wayne's method - WAlogmean=np.log(2.67) - WAlogsigma=np.log(2.07) - - waprobs=pcosmic.linlognormal_dlin(widths,[WAlogmean,WAlogsigma]) - wasum=np.sum(waprobs) - - #rename - WAprobs = waprobs*MAX/np.max(waprobs) - - return WAprobs,rp[0,:] #for lat50 + WAlogmean = np.log(2.67) + WAlogsigma = np.log(2.07) + + waprobs = pcosmic.linlognormal_dlin(widths, [WAlogmean, WAlogsigma]) + wasum = np.sum(waprobs) -def width_test(pset,surveys,grids,names,logmean=2,logsigma=1,plot=True,outdir='Plots/',NP=5,scale=3.5): + # rename + WAprobs = waprobs * MAX / np.max(waprobs) + + return WAprobs, rp[0, :] # for lat50 + + +def width_test( + pset, + surveys, + grids, + names, + logmean=2, + logsigma=1, + plot=True, + outdir="Plots/", + NP=5, + scale=3.5, +): """ Tests the effects of intrinsic widths on FRB properties Considers three cases: - width distribution of Wayne Arcus et al (2020) @@ -573,969 +633,1286 @@ def width_test(pset,surveys,grids,names,logmean=2,logsigma=1,plot=True,outdir='P """ - + if plot: print("Performing test of intrinsic width effects") - t0=time.process_time() - - IGNORE=0. # a parameter that gets ignored - + t0 = time.process_time() + + IGNORE = 0.0 # a parameter that gets ignored + ############ set default parameters for width distribution ########### # 'real' version - wmin=0.1 - wmax=30 - NW=300 - #short version - #wmin=0.1 - #wmax=50 - #NW=100 - dw=(wmax-wmin)/2. - widths=np.linspace(wmin,wmax,NW) - - probs=pcosmic.linlognormal_dlin(widths,logmean,logsigma) #not integrating, just amplitudes + wmin = 0.1 + wmax = 30 + NW = 300 + # short version + # wmin=0.1 + # wmax=50 + # NW=100 + dw = (wmax - wmin) / 2.0 + widths = np.linspace(wmin, wmax, NW) + + probs = pcosmic.linlognormal_dlin( + widths, logmean, logsigma + ) # not integrating, just amplitudes # normalise probabilities probs /= np.sum(probs) - pextra,err=sp.integrate.quad(pcosmic.loglognormal_dlog,np.log(wmax+dw/2.),np.log(wmax*2),args=(logmean,logsigma)) - probs *= (1.-pextra) # now sums to 1.-pextra - probs[-1] += pextra # now sums back to 1 - - styles=['--','-.',':'] - - MAX=1 - norm=MAX/np.max(probs[:-1]) + pextra, err = sp.integrate.quad( + pcosmic.loglognormal_dlog, + np.log(wmax + dw / 2.0), + np.log(wmax * 2), + args=(logmean, logsigma), + ) + probs *= 1.0 - pextra # now sums to 1.-pextra + probs[-1] += pextra # now sums back to 1 + + styles = ["--", "-.", ":"] + + MAX = 1 + norm = MAX / np.max(probs[:-1]) probs *= norm - wsum=np.sum(probs) + wsum = np.sum(probs) if plot: plt.figure() - plt.xlabel('w [ms]') - plt.ylabel('p(w)') - plt.xlim(0,wmax) - plt.plot(widths[:-1],probs[:-1],label='This work: $\\mu_w=5.49, \\sigma_w=2.46$',linewidth=2) - - Emin=10**pset[0] - Emax=10**pset[1] - alpha=pset[2] - gamma=pset[3] - NS=len(surveys) - rates=np.zeros([NS,NW]) - rp=np.zeros([NS,NW]) - warp=np.zeros([NS,NW]) - #loop over surveys - #colours=['blue','orange',' - - names=['ASKAP/FE','ASKAP/ICS','Parkes/MB'] - colours=['blue','red','green','orange','black'] - - #calculating total rate compared to what is expected for ~width 0 - sumw=0. - DMvals=grids[0].dmvals - zvals=grids[0].zvals - - dmplots=np.zeros([NS,NW,DMvals.size]) - zplots=np.zeros([NS,NW,zvals.size]) - + plt.xlabel("w [ms]") + plt.ylabel("p(w)") + plt.xlim(0, wmax) + plt.plot( + widths[:-1], + probs[:-1], + label="This work: $\\mu_w=5.49, \\sigma_w=2.46$", + linewidth=2, + ) + + Emin = 10 ** pset[0] + Emax = 10 ** pset[1] + alpha = pset[2] + gamma = pset[3] + NS = len(surveys) + rates = np.zeros([NS, NW]) + rp = np.zeros([NS, NW]) + warp = np.zeros([NS, NW]) + # loop over surveys + # colours=['blue','orange',' + + names = ["ASKAP/FE", "ASKAP/ICS", "Parkes/MB"] + colours = ["blue", "red", "green", "orange", "black"] + + # calculating total rate compared to what is expected for ~width 0 + sumw = 0.0 + DMvals = grids[0].dmvals + zvals = grids[0].zvals + + dmplots = np.zeros([NS, NW, DMvals.size]) + zplots = np.zeros([NS, NW, zvals.size]) + ##### values for 'practical' arrays ##### - - #NP=5 #NP 10 at scale 2 good - #scale=3.5 - - pdmplots=np.zeros([NS,NP,DMvals.size]) - pzplots=np.zeros([NS,NP,zvals.size]) - prates=np.zeros([NS,NP]) - + + # NP=5 #NP 10 at scale 2 good + # scale=3.5 + + pdmplots = np.zeros([NS, NP, DMvals.size]) + pzplots = np.zeros([NS, NP, zvals.size]) + prates = np.zeros([NS, NP]) + # collapsed over width dimension with appropriate weights - spdmplots=np.zeros([NS,DMvals.size]) - spzplots=np.zeros([NS,zvals.size]) - sprates=np.zeros([NS]) - + spdmplots = np.zeros([NS, DMvals.size]) + spzplots = np.zeros([NS, zvals.size]) + sprates = np.zeros([NS]) + ######## gets original rates for DM and z distributions ######### - #norm_orates=([NS,zvals.size,DMvals.size) # normed to width=0! + # norm_orates=([NS,zvals.size,DMvals.size) # normed to width=0! # wait - does this include beamshape and the others not? - orates=np.zeros([NS]) - norates=np.zeros([NS]) #for normed version - odms=np.zeros([NS,DMvals.size]) - ozs=np.zeros([NS,zvals.size]) - for i,g in enumerate(grids): - odms[i,:]=np.sum(g.rates,axis=0) - ozs[i,:]=np.sum(g.rates,axis=1) - orates[i]=np.sum(g.rates) #total rate for grid - 'original' rates - + orates = np.zeros([NS]) + norates = np.zeros([NS]) # for normed version + odms = np.zeros([NS, DMvals.size]) + ozs = np.zeros([NS, zvals.size]) + for i, g in enumerate(grids): + odms[i, :] = np.sum(g.rates, axis=0) + ozs[i, :] = np.sum(g.rates, axis=1) + orates[i] = np.sum(g.rates) # total rate for grid - 'original' rates + ############ Wayne Arcus's fits ##########3 # calculates probabilities and uses this later; WAprobs - WAlogmean=np.log(2.67) - WAlogsigma=np.log(2.07) - waprobs=pcosmic.linlognormal_dlin(widths,WAlogmean,WAlogsigma) + WAlogmean = np.log(2.67) + WAlogsigma = np.log(2.07) + waprobs = pcosmic.linlognormal_dlin(widths, WAlogmean, WAlogsigma) waprobs /= np.sum(waprobs) - pextra,err=sp.integrate.quad(pcosmic.loglognormal_dlog,np.log(wmax+dw/2.),np.log(wmax*2),args=(WAlogmean,WAlogsigma)) - waprobs *= (1.-pextra) # now sums to 1.-pextra - waprobs[-1] += pextra # now sums back to 1 - wasum=np.sum(waprobs) - - #rename - WAprobs = waprobs*MAX/np.max(waprobs) - WAsum=np.sum(WAprobs) - #print(np.max(rates[0,:]),np.max(WAprobs)) - ls=['-','--',':','-.','-.'] - - - + pextra, err = sp.integrate.quad( + pcosmic.loglognormal_dlog, + np.log(wmax + dw / 2.0), + np.log(wmax * 2), + args=(WAlogmean, WAlogsigma), + ) + waprobs *= 1.0 - pextra # now sums to 1.-pextra + waprobs[-1] += pextra # now sums back to 1 + wasum = np.sum(waprobs) + + # rename + WAprobs = waprobs * MAX / np.max(waprobs) + WAsum = np.sum(WAprobs) + # print(np.max(rates[0,:]),np.max(WAprobs)) + ls = ["-", "--", ":", "-.", "-."] + #### does this for width distributions ####### - - for i,s in enumerate(surveys): - g=grids[i] - #DMvals=grids[i].dmvals - + + for i, s in enumerate(surveys): + g = grids[i] + # DMvals=grids[i].dmvals + # gets the 'practical' widths for this survey - pwidths,pprobs=survey.make_widths(s,g.state) - + pwidths, pprobs = survey.make_widths(s, g.state) + pnorm_probs = pprobs / np.max(pprobs) - - #if plot: + + # if plot: # plt.plot(pwidths,pnorm_probs,color=colours[i],marker='o',linestyle='',label='Approx.') # gets the survey parameters - fbar=s.meta['FBAR'] - tres=s.meta['TRES'] - fres=s.meta['FRES'] - thresh=s.meta['THRESH'] - - + fbar = s.meta["FBAR"] + tres = s.meta["TRES"] + fres = s.meta["FRES"] + thresh = s.meta["THRESH"] + ######## "practical" version ### (note: not using default behaviour) ######## - for j,w in enumerate(pwidths): + for j, w in enumerate(pwidths): # artificially set response function - sens=survey.calc_relative_sensitivity(IGNORE,DMvals,w,fbar,tres,fres,model='Quadrature',dsmear=False) - g.calc_thresholds(thresh,sens,alpha=alpha) - g.calc_pdv(Emin,Emax,gamma) - + sens = survey.calc_relative_sensitivity( + IGNORE, DMvals, w, fbar, tres, fres, model="Quadrature", dsmear=False + ) + g.calc_thresholds(thresh, sens, alpha=alpha) + g.calc_pdv(Emin, Emax, gamma) + g.calc_rates() - prates[i,j]=np.sum(g.rates)*pprobs[j] - pdmplots[i,j,:]=np.sum(g.rates,axis=0)*pprobs[j] - pzplots[i,j,:]=np.sum(g.rates,axis=1)*pprobs[j] - #sum over weights - could just do all this later, but whatever - sprates[i]=np.sum(prates[i],axis=0) - spdmplots[i]=np.sum(pdmplots[i],axis=0) - spzplots[i]=np.sum(pzplots[i],axis=0) - + prates[i, j] = np.sum(g.rates) * pprobs[j] + pdmplots[i, j, :] = np.sum(g.rates, axis=0) * pprobs[j] + pzplots[i, j, :] = np.sum(g.rates, axis=1) * pprobs[j] + # sum over weights - could just do all this later, but whatever + sprates[i] = np.sum(prates[i], axis=0) + spdmplots[i] = np.sum(pdmplots[i], axis=0) + spzplots[i] = np.sum(pzplots[i], axis=0) + ######### "Full" (correct) version ######### - for j,w in enumerate(widths): + for j, w in enumerate(widths): # artificially set response function - sens=survey.calc_relative_sensitivity(IGNORE,DMvals,w,fbar,tres,fres,model='Quadrature',dsmear=False) - - g.calc_thresholds(thresh,sens,alpha=alpha) - g.calc_pdv(Emin,Emax,gamma) - + sens = survey.calc_relative_sensitivity( + IGNORE, DMvals, w, fbar, tres, fres, model="Quadrature", dsmear=False + ) + + g.calc_thresholds(thresh, sens, alpha=alpha) + g.calc_pdv(Emin, Emax, gamma) + g.calc_rates() - rates[i,j]=np.sum(g.rates) - - dmplots[i,j,:]=np.sum(g.rates,axis=0) - zplots[i,j,:]=np.sum(g.rates,axis=1) - + rates[i, j] = np.sum(g.rates) + + dmplots[i, j, :] = np.sum(g.rates, axis=0) + zplots[i, j, :] = np.sum(g.rates, axis=1) + # this step divides by the full rates for zero width - norates[i]=orates[i]/rates[i,0] #normalises original weight by rate if no width - sprates[i] /= rates[i,0] - rates[i,:] /= rates[i,0] - - #norm_orates[i,:] = orates[i,0]/rates[i,0] - rp[i,:]=rates[i,:]*probs - warp[i,:]=rates[i,:]*WAprobs - + norates[i] = ( + orates[i] / rates[i, 0] + ) # normalises original weight by rate if no width + sprates[i] /= rates[i, 0] + rates[i, :] /= rates[i, 0] + + # norm_orates[i,:] = orates[i,0]/rates[i,0] + rp[i, :] = rates[i, :] * probs + warp[i, :] = rates[i, :] * WAprobs + if plot: - plt.plot(widths[:-1],rp[i,:-1],linestyle=styles[i],linewidth=1) - - norm=MAX/np.max(rp[i,:-1]) + plt.plot(widths[:-1], rp[i, :-1], linestyle=styles[i], linewidth=1) + + norm = MAX / np.max(rp[i, :-1]) if plot: - plt.plot(widths[:-1],rp[i,:-1]*norm,label=names[i],linestyle=styles[i],color=plt.gca().lines[-1].get_color(),linewidth=2) - + plt.plot( + widths[:-1], + rp[i, :-1] * norm, + label=names[i], + linestyle=styles[i], + color=plt.gca().lines[-1].get_color(), + linewidth=2, + ) + print("The total fraction of events detected as a function of experiment are") print("Survey name [input_grid] WA lognormal practical") - for i,s in enumerate(surveys): - print(i,names[i],norates[i],np.sum(warp[i,:])/WAsum,np.sum(rp[i,:])/wsum,sprates[i]) - #print(i,rates[i,:]) - #print(i,names[i],np.sum(rates[i,:]),np.sum(rp[i,:]),wsum,np.sum(rp[i,:])/wsum) - - - + for i, s in enumerate(surveys): + print( + i, + names[i], + norates[i], + np.sum(warp[i, :]) / WAsum, + np.sum(rp[i, :]) / wsum, + sprates[i], + ) + # print(i,rates[i,:]) + # print(i,names[i],np.sum(rates[i,:]),np.sum(rp[i,:]),wsum,np.sum(rp[i,:])/wsum) + if plot: - plt.plot(widths[:-1],WAprobs[:-1],label='Arcus et al: $\\mu_w=2.67, \\sigma_w=2.07$',color='black',linestyle='-',linewidth=2) - - plt.legend(loc='upper right') + plt.plot( + widths[:-1], + WAprobs[:-1], + label="Arcus et al: $\\mu_w=2.67, \\sigma_w=2.07$", + color="black", + linestyle="-", + linewidth=2, + ) + + plt.legend(loc="upper right") plt.tight_layout() - plt.xlim(0,30) - plt.savefig(outdir+'/width_effect.pdf') + plt.xlim(0, 30) + plt.savefig(outdir + "/width_effect.pdf") plt.close() - t1=time.process_time() - print("Done. Took ",t1-t0," seconds.") - - + t1 = time.process_time() + print("Done. Took ", t1 - t0, " seconds.") + #### we now do DM plots ### plt.figure() - plt.xlabel('DM [pc cm$^{-3}$]') - plt.ylabel('p(DM) [a.u.]') - plt.xlim(0,3000) - #dmplots[i,j,:]=np.sum(g.rates,axis=0) - - twdm=np.zeros([NS,DMvals.size]) - wadm=np.zeros([NS,DMvals.size]) - w0dm=np.zeros([NS,DMvals.size]) - for i,s in enumerate(surveys): - - w0dm[i]=dmplots[i,0,:] - wadm[i]=np.sum((waprobs.T*dmplots[i,:,:].T).T,axis=0)/wasum - twdm[i]=np.sum((probs.T*dmplots[i,:,:].T).T,axis=0)/wsum - - - print("Mean DM for survey ",i," is (0) ",np.sum(DMvals*w0dm[i,:])/np.sum(w0dm[i,:])) - print(" (full verson) ",np.sum(DMvals*twdm[i,:])/np.sum(twdm[i,:])) - print(" (wayne arcus a) ",np.sum(DMvals*wadm[i,:])/np.sum(wadm[i,:])) - print(" (practical) ",np.sum(DMvals*spdmplots[i,:])/np.sum(spdmplots[i,:])) - - #plt.plot(DMvals,w0dm[i]/np.max(w0dm[i]),label=names[i],linewidth=0.1) - #plt.plot(DMvals,twdm[i]/np.max(twdm[i]),color=plt.gca().lines[-1].get_color(),linestyle='--') - #plt.plot(DMvals,wadm[i]/np.max(wadm[i]),color=plt.gca().lines[-1].get_color(),linestyle='-.') - #plt.plot(DMvals,odms[i]/np.max(odms[i]),color=plt.gca().lines[-1].get_color(),linestyle=':') - #plt.plot(DMvals,spdmplots[i]/np.max(spdmplots[i]),color=plt.gca().lines[-1].get_color(),linestyle=':') - if i==0: - plt.plot(DMvals,w0dm[i]/np.max(w0dm[i]),linestyle=ls[0],label='$w_{\\rm inc}=0$',color=colours[0]) - #plt.plot(DMvals,wadm[i]/np.max(wadm[i]),linestyle=ls[2],label='Arcus et al: $\\mu_w=2.67, \\sigma_w=2.07$',color=colours[2]) - #plt.plot(DMvals,twdm[i]/np.max(twdm[i]),linestyle=ls[1],label='This work: $\\mu_w=5.49, \\sigma_w=2.46$',color=colours[1]) - plt.plot(DMvals,wadm[i]/np.max(wadm[i]),linestyle=ls[2],label='Arcus et al.',color=colours[2]) - plt.plot(DMvals,twdm[i]/np.max(twdm[i]),linestyle=ls[1],label='This work',color=colours[1]) - - #plt.plot(DMvals,odms[i]/np.max(odms[i]),linestyle=ls[3],label='old',color=colours[3]) - plt.plot(DMvals,spdmplots[i]/np.max(spdmplots[i]),linestyle=ls[4],label='This work',color=colours[4]) + plt.xlabel("DM [pc cm$^{-3}$]") + plt.ylabel("p(DM) [a.u.]") + plt.xlim(0, 3000) + # dmplots[i,j,:]=np.sum(g.rates,axis=0) + + twdm = np.zeros([NS, DMvals.size]) + wadm = np.zeros([NS, DMvals.size]) + w0dm = np.zeros([NS, DMvals.size]) + for i, s in enumerate(surveys): + + w0dm[i] = dmplots[i, 0, :] + wadm[i] = np.sum((waprobs.T * dmplots[i, :, :].T).T, axis=0) / wasum + twdm[i] = np.sum((probs.T * dmplots[i, :, :].T).T, axis=0) / wsum + + print( + "Mean DM for survey ", + i, + " is (0) ", + np.sum(DMvals * w0dm[i, :]) / np.sum(w0dm[i, :]), + ) + print( + " (full verson) ", + np.sum(DMvals * twdm[i, :]) / np.sum(twdm[i, :]), + ) + print( + " (wayne arcus a) ", + np.sum(DMvals * wadm[i, :]) / np.sum(wadm[i, :]), + ) + print( + " (practical) ", + np.sum(DMvals * spdmplots[i, :]) / np.sum(spdmplots[i, :]), + ) + + # plt.plot(DMvals,w0dm[i]/np.max(w0dm[i]),label=names[i],linewidth=0.1) + # plt.plot(DMvals,twdm[i]/np.max(twdm[i]),color=plt.gca().lines[-1].get_color(),linestyle='--') + # plt.plot(DMvals,wadm[i]/np.max(wadm[i]),color=plt.gca().lines[-1].get_color(),linestyle='-.') + # plt.plot(DMvals,odms[i]/np.max(odms[i]),color=plt.gca().lines[-1].get_color(),linestyle=':') + # plt.plot(DMvals,spdmplots[i]/np.max(spdmplots[i]),color=plt.gca().lines[-1].get_color(),linestyle=':') + if i == 0: + plt.plot( + DMvals, + w0dm[i] / np.max(w0dm[i]), + linestyle=ls[0], + label="$w_{\\rm inc}=0$", + color=colours[0], + ) + # plt.plot(DMvals,wadm[i]/np.max(wadm[i]),linestyle=ls[2],label='Arcus et al: $\\mu_w=2.67, \\sigma_w=2.07$',color=colours[2]) + # plt.plot(DMvals,twdm[i]/np.max(twdm[i]),linestyle=ls[1],label='This work: $\\mu_w=5.49, \\sigma_w=2.46$',color=colours[1]) + plt.plot( + DMvals, + wadm[i] / np.max(wadm[i]), + linestyle=ls[2], + label="Arcus et al.", + color=colours[2], + ) + plt.plot( + DMvals, + twdm[i] / np.max(twdm[i]), + linestyle=ls[1], + label="This work", + color=colours[1], + ) + + # plt.plot(DMvals,odms[i]/np.max(odms[i]),linestyle=ls[3],label='old',color=colours[3]) + plt.plot( + DMvals, + spdmplots[i] / np.max(spdmplots[i]), + linestyle=ls[4], + label="This work", + color=colours[4], + ) else: - plt.plot(DMvals,w0dm[i]/np.max(w0dm[i]),linestyle=ls[0],color=colours[0]) - plt.plot(DMvals,twdm[i]/np.max(twdm[i]),linestyle=ls[1],color=colours[1]) - plt.plot(DMvals,wadm[i]/np.max(wadm[i]),linestyle=ls[2],color=colours[2]) - #plt.plot(DMvals,odms[i]/np.max(odms[i]),linestyle=ls[3],color=colours[3]) - plt.plot(DMvals,spdmplots[i]/np.max(spdmplots[i]),linestyle=ls[4],color=colours[4]) - plt.legend(loc='upper right') + plt.plot( + DMvals, w0dm[i] / np.max(w0dm[i]), linestyle=ls[0], color=colours[0] + ) + plt.plot( + DMvals, twdm[i] / np.max(twdm[i]), linestyle=ls[1], color=colours[1] + ) + plt.plot( + DMvals, wadm[i] / np.max(wadm[i]), linestyle=ls[2], color=colours[2] + ) + # plt.plot(DMvals,odms[i]/np.max(odms[i]),linestyle=ls[3],color=colours[3]) + plt.plot( + DMvals, + spdmplots[i] / np.max(spdmplots[i]), + linestyle=ls[4], + color=colours[4], + ) + plt.legend(loc="upper right") plt.tight_layout() - plt.savefig(outdir+'/width_dm_effect.pdf') + plt.savefig(outdir + "/width_dm_effect.pdf") plt.close() - + ##### z plots #### plt.figure() - plt.xlabel('z') - plt.ylabel('p(z) [a.u.]') - plt.xlim(0,3) - #zplots[i,j,:]=np.sum(g.rates,axis=1) - - twz=np.zeros([NS,zvals.size]) - waz=np.zeros([NS,zvals.size]) - w0z=np.zeros([NS,zvals.size]) - for i,s in enumerate(surveys): - - w0z[i]=zplots[i,0,:] - waz[i]=np.sum((waprobs.T*zplots[i,:,:].T).T,axis=0)/wasum - twz[i]=np.sum((probs.T*zplots[i,:,:].T).T,axis=0)/wsum - - print("Mean z for survey ",i," is (0) ",np.sum(zvals*w0z[i])/np.sum(w0z[i])) - print(" (tw) ",np.sum(zvals*twz[i])/np.sum(twz[i])) - print(" (wa) ",np.sum(zvals*waz[i])/np.sum(waz[i])) - print(" (p) ",np.sum(zvals*spzplots[i,:])/np.sum(spzplots[i,:])) - - #plt.plot(zvals,w0z[i]/np.max(w0z[i]),label=names[i]) - #plt.plot(zvals,twz[i]/np.max(twz[i]),color=plt.gca().lines[-1].get_color(),linestyle='--') - #plt.plot(zvals,waz[i]/np.max(waz[i]),color=plt.gca().lines[-1].get_color(),linestyle='-.') - #plt.plot(zvals,ozs[i]/np.max(ozs[i]),color=plt.gca().lines[-1].get_color(),linestyle=':') - #plt.plot(zvals,spzplots[i]/np.max(spzplots[i]),color=plt.gca().lines[-1].get_color(),linestyle=':') - if i==0: - plt.plot(zvals,w0z[i]/np.max(w0z[i]),label='$w_{\\rm inc}=0$',linestyle=ls[0],color=colours[0]) - #plt.plot(zvals,waz[i]/np.max(waz[i]),linestyle=ls[2],label='Arcus et al: $\\mu_w=2.67, \\sigma_w=2.07$',color=colours[2]) - #plt.plot(zvals,twz[i]/np.max(twz[i]),label='This work: $\\mu_w=5.49, \\sigma_w=2.46$',linestyle=ls[1],color=colours[1]) - plt.plot(zvals,waz[i]/np.max(waz[i]),linestyle=ls[2],label='Arcus et al.',color=colours[2]) - plt.plot(zvals,twz[i]/np.max(twz[i]),label='This work',linestyle=ls[1],color=colours[1]) - #plt.plot(zvals,ozs[i]/np.max(ozs[i]),linestyle=ls[3],label='orig',color=colours[3]) - plt.plot(zvals,spzplots[i]/np.max(spzplots[i]),linestyle=ls[4],label='This work',color=colours[4]) + plt.xlabel("z") + plt.ylabel("p(z) [a.u.]") + plt.xlim(0, 3) + # zplots[i,j,:]=np.sum(g.rates,axis=1) + + twz = np.zeros([NS, zvals.size]) + waz = np.zeros([NS, zvals.size]) + w0z = np.zeros([NS, zvals.size]) + for i, s in enumerate(surveys): + + w0z[i] = zplots[i, 0, :] + waz[i] = np.sum((waprobs.T * zplots[i, :, :].T).T, axis=0) / wasum + twz[i] = np.sum((probs.T * zplots[i, :, :].T).T, axis=0) / wsum + + print( + "Mean z for survey ", + i, + " is (0) ", + np.sum(zvals * w0z[i]) / np.sum(w0z[i]), + ) + print( + " (tw) ", + np.sum(zvals * twz[i]) / np.sum(twz[i]), + ) + print( + " (wa) ", + np.sum(zvals * waz[i]) / np.sum(waz[i]), + ) + print( + " (p) ", + np.sum(zvals * spzplots[i, :]) / np.sum(spzplots[i, :]), + ) + + # plt.plot(zvals,w0z[i]/np.max(w0z[i]),label=names[i]) + # plt.plot(zvals,twz[i]/np.max(twz[i]),color=plt.gca().lines[-1].get_color(),linestyle='--') + # plt.plot(zvals,waz[i]/np.max(waz[i]),color=plt.gca().lines[-1].get_color(),linestyle='-.') + # plt.plot(zvals,ozs[i]/np.max(ozs[i]),color=plt.gca().lines[-1].get_color(),linestyle=':') + # plt.plot(zvals,spzplots[i]/np.max(spzplots[i]),color=plt.gca().lines[-1].get_color(),linestyle=':') + if i == 0: + plt.plot( + zvals, + w0z[i] / np.max(w0z[i]), + label="$w_{\\rm inc}=0$", + linestyle=ls[0], + color=colours[0], + ) + # plt.plot(zvals,waz[i]/np.max(waz[i]),linestyle=ls[2],label='Arcus et al: $\\mu_w=2.67, \\sigma_w=2.07$',color=colours[2]) + # plt.plot(zvals,twz[i]/np.max(twz[i]),label='This work: $\\mu_w=5.49, \\sigma_w=2.46$',linestyle=ls[1],color=colours[1]) + plt.plot( + zvals, + waz[i] / np.max(waz[i]), + linestyle=ls[2], + label="Arcus et al.", + color=colours[2], + ) + plt.plot( + zvals, + twz[i] / np.max(twz[i]), + label="This work", + linestyle=ls[1], + color=colours[1], + ) + # plt.plot(zvals,ozs[i]/np.max(ozs[i]),linestyle=ls[3],label='orig',color=colours[3]) + plt.plot( + zvals, + spzplots[i] / np.max(spzplots[i]), + linestyle=ls[4], + label="This work", + color=colours[4], + ) else: - plt.plot(zvals,w0z[i]/np.max(w0z[i]),linestyle=ls[0],color=colours[0]) - plt.plot(zvals,twz[i]/np.max(twz[i]),linestyle=ls[1],color=colours[1]) - plt.plot(zvals,waz[i]/np.max(waz[i]),linestyle=ls[2],color=colours[2]) - #plt.plot(zvals,ozs[i]/np.max(ozs[i]),linestyle=ls[3],color=colours[3]) - plt.plot(zvals,spzplots[i]/np.max(spzplots[i]),linestyle=ls[4],color=colours[4]) - plt.legend(loc='upper right') + plt.plot( + zvals, w0z[i] / np.max(w0z[i]), linestyle=ls[0], color=colours[0] + ) + plt.plot( + zvals, twz[i] / np.max(twz[i]), linestyle=ls[1], color=colours[1] + ) + plt.plot( + zvals, waz[i] / np.max(waz[i]), linestyle=ls[2], color=colours[2] + ) + # plt.plot(zvals,ozs[i]/np.max(ozs[i]),linestyle=ls[3],color=colours[3]) + plt.plot( + zvals, + spzplots[i] / np.max(spzplots[i]), + linestyle=ls[4], + color=colours[4], + ) + plt.legend(loc="upper right") plt.tight_layout() - plt.savefig(outdir+'/width_z_effect.pdf') + plt.savefig(outdir + "/width_z_effect.pdf") plt.close() - - return WAprobs,rp[0,:] #for lat50 -def test_pks_beam(surveys,zDMgrid, zvals,dmvals,pset,outdir='Plots/BeamTest/',zmax=1,DMmax=1000): - + return WAprobs, rp[0, :] # for lat50 + + +def test_pks_beam( + surveys, zDMgrid, zvals, dmvals, pset, outdir="Plots/BeamTest/", zmax=1, DMmax=1000 +): + if not os.path.isdir(outdir): os.mkdir(outdir) - + # get parameter values - lEmin,lEmax,alpha,gamma,sfr_n,logmean,logsigma=pset - Emin=10**lEmin - Emax=10**lEmax - + lEmin, lEmax, alpha, gamma, sfr_n, logmean, logsigma = pset + Emin = 10 ** lEmin + Emax = 10 ** lEmax + # generates a DM mask # creates a mask of values in DM space to convolve with the DM grid - mask=pcosmic.get_dm_mask(dmvals,(logmean,logsigma),zvals,plot=True) - + mask = pcosmic.get_dm_mask(dmvals, (logmean, logsigma), zvals, plot=True) + # get an initial grid with no beam values - grids=[] - bbs=[] - bos=[] - - + grids = [] + bbs = [] + bos = [] + print("Just got into test parkes beam") - - - #norms=np.zeros([len(surveys)]) - #numbins=np.zeros([len(surveys)]) - rates=[] - New=False - for i,s in enumerate(surveys): - print("Starting",i) - #s.beam_b - #s.beam_o - print("Sum of i is ",np.sum(s.beam_o)) + + # norms=np.zeros([len(surveys)]) + # numbins=np.zeros([len(surveys)]) + rates = [] + New = False + for i, s in enumerate(surveys): + print("Starting", i) + # s.beam_b + # s.beam_o + print("Sum of i is ", np.sum(s.beam_o)) print(s.beam_o) print(s.beam_b) - if New==True: - - grid=zdm_grid.Grid() - grid.pass_grid(zDMgrid,zvals,dmvals) - grid.smear_dm(mask,logmean,logsigma) - efficiencies=s.get_efficiency(dmvals) - grid.calc_thresholds(s.meta['THRESH'],s.mean_efficiencies,alpha=alpha) + if New == True: + + grid = zdm_grid.Grid() + grid.pass_grid(zDMgrid, zvals, dmvals) + grid.smear_dm(mask, logmean, logsigma) + efficiencies = s.get_efficiency(dmvals) + grid.calc_thresholds(s.meta["THRESH"], s.mean_efficiencies, alpha=alpha) grid.calc_dV() - grid.set_evolution(sfr_n) # sets star-formation rate scaling with z - here, no evoltion... - grid.calc_pdv(Emin,Emax,gamma,s.beam_b,s.beam_o) # calculates volumetric-weighted probabilities - grid.calc_rates() # calculates rates by multiplying above with pdm plot - name=outdir+'rates_'+s.meta["BEAM"]+'.pdf' - plot_grid_2(grid.rates,grid.zvals,grid.dmvals,zmax=zmax,DMmax=DMmax,name=name,norm=2,log=True,label='$f(DM,z)p(DM,z)dV$ [Mpc$^3$]',project=True) + grid.set_evolution( + sfr_n + ) # sets star-formation rate scaling with z - here, no evoltion... + grid.calc_pdv( + Emin, Emax, gamma, s.beam_b, s.beam_o + ) # calculates volumetric-weighted probabilities + grid.calc_rates() # calculates rates by multiplying above with pdm plot + name = outdir + "rates_" + s.meta["BEAM"] + ".pdf" + plot_grid_2( + grid.rates, + grid.zvals, + grid.dmvals, + zmax=zmax, + DMmax=DMmax, + name=name, + norm=2, + log=True, + label="$f(DM,z)p(DM,z)dV$ [Mpc$^3$]", + project=True, + ) grids.append(grid) - np.save(outdir+s.meta["BEAM"]+'_rates.npy',grid.rates) - rate=grid.rates + np.save(outdir + s.meta["BEAM"] + "_rates.npy", grid.rates) + rate = grid.rates else: - rate=np.load(outdir+s.meta["BEAM"]+'_rates.npy') - print("Sum of rates: ",np.sum(rate),s.meta["BEAM"]) + rate = np.load(outdir + s.meta["BEAM"] + "_rates.npy") + print("Sum of rates: ", np.sum(rate), s.meta["BEAM"]) rates.append(rate) - fig1=plt.figure() - plt.xlabel('z') - plt.xlim(0,zmax) - fig2=plt.figure() - plt.xlabel('DM') - plt.xlim(0,DMmax) - - fig3=plt.figure() - plt.xlabel('z') - plt.xlim(0,zmax) - fig4=plt.figure() - plt.xlabel('DM') - plt.xlim(0,DMmax) - - #plt.yscale('log') + fig1 = plt.figure() + plt.xlabel("z") + plt.xlim(0, zmax) + fig2 = plt.figure() + plt.xlabel("DM") + plt.xlim(0, DMmax) + + fig3 = plt.figure() + plt.xlabel("z") + plt.xlim(0, zmax) + fig4 = plt.figure() + plt.xlabel("DM") + plt.xlim(0, DMmax) + + # plt.yscale('log') # now does z-only and dm-only projection plots for Parkes - for i,s in enumerate(surveys): - r=rates[i] - z=np.sum(r,axis=1) - dm=np.sum(r,axis=0) + for i, s in enumerate(surveys): + r = rates[i] + z = np.sum(r, axis=1) + dm = np.sum(r, axis=0) plt.figure(fig1.number) - plt.plot(zvals,z,label=s.meta["BEAM"]) + plt.plot(zvals, z, label=s.meta["BEAM"]) plt.figure(fig2.number) - plt.plot(dmvals,dm,label=s.meta["BEAM"]) - + plt.plot(dmvals, dm, label=s.meta["BEAM"]) + z /= np.sum(z) dm /= np.sum(dm) plt.figure(fig3.number) - plt.plot(zvals,z,label=s.meta["BEAM"]) + plt.plot(zvals, z, label=s.meta["BEAM"]) plt.figure(fig4.number) - plt.plot(dmvals,dm,label=s.meta["BEAM"]) - + plt.plot(dmvals, dm, label=s.meta["BEAM"]) + plt.figure(fig1.number) - plt.legend(loc='upper right') + plt.legend(loc="upper right") plt.tight_layout() - plt.savefig(outdir+'z_projections.pdf') + plt.savefig(outdir + "z_projections.pdf") plt.close() - + plt.figure(fig2.number) - plt.legend(loc='upper right') + plt.legend(loc="upper right") plt.tight_layout() - plt.savefig(outdir+'dm_projections.pdf') + plt.savefig(outdir + "dm_projections.pdf") plt.close() - + plt.figure(fig3.number) - plt.legend(loc='upper right') + plt.legend(loc="upper right") plt.tight_layout() - plt.savefig(outdir+'normed_z_projections.pdf') + plt.savefig(outdir + "normed_z_projections.pdf") plt.close() - + plt.figure(fig4.number) - plt.legend(loc='upper right') + plt.legend(loc="upper right") plt.tight_layout() - plt.savefig(outdir+'normed_dm_projections.pdf') + plt.savefig(outdir + "normed_dm_projections.pdf") plt.close() - + ###### makes a 1d set of plots in dm and redshift ######## - font = {'family' : 'normal', - 'weight' : 'normal', - 'size' : 6} + font = {"family": "normal", "weight": "normal", "size": 6} + + matplotlib.rc("font", **font) + fig, ax = plt.subplots( + 3, 2, sharey="row", sharex="col" + ) # ,sharey='row',sharex='col') + + ax[1, 0].set_xlabel("z") + ax[1, 1].set_xlabel("DM") + ax[2, 0].set_xlabel("z") + ax[2, 1].set_xlabel("DM") + ax[0, 0].set_ylabel("Abs") + ax[0, 1].set_ylabel("Abs") + ax[1, 0].set_ylabel("Dabs") + ax[1, 1].set_ylabel("Dabs") + ax[2, 0].set_ylabel("Rel diff") + ax[2, 1].set_ylabel("Rel diff") - matplotlib.rc('font', **font) - fig,ax=plt.subplots(3,2,sharey='row',sharex='col')#,sharey='row',sharex='col') - - ax[1,0].set_xlabel('z') - ax[1,1].set_xlabel('DM') - ax[2,0].set_xlabel('z') - ax[2,1].set_xlabel('DM') - ax[0,0].set_ylabel('Abs') - ax[0,1].set_ylabel('Abs') - ax[1,0].set_ylabel('Dabs') - ax[1,1].set_ylabel('Dabs') - ax[2,0].set_ylabel('Rel diff') - ax[2,1].set_ylabel('Rel diff') - # force relative range only - ax[2,0].set_ylim(-1,1) - ax[2,1].set_ylim(-1,1) - - ax[0,0].set_xlim(0,zmax) - ax[0,1].set_xlim(0,DMmax) - ax[1,0].set_xlim(0,zmax) - ax[2,0].set_xlim(0,zmax) - ax[1,1].set_xlim(0,DMmax) - ax[2,1].set_xlim(0,DMmax) - + ax[2, 0].set_ylim(-1, 1) + ax[2, 1].set_ylim(-1, 1) + + ax[0, 0].set_xlim(0, zmax) + ax[0, 1].set_xlim(0, DMmax) + ax[1, 0].set_xlim(0, zmax) + ax[2, 0].set_xlim(0, zmax) + ax[1, 1].set_xlim(0, DMmax) + ax[2, 1].set_xlim(0, DMmax) + # gets Keith's normalised rates - kr=rates[2] - kz=np.sum(kr,axis=1) - kdm=np.sum(kr,axis=0) + kr = rates[2] + kz = np.sum(kr, axis=1) + kdm = np.sum(kr, axis=0) kz /= np.sum(kz) kdm /= np.sum(kdm) - - ax[0,0].plot(zvals,kz,label=surveys[2].meta["BEAM"],color='black') - ax[0,1].plot(dmvals,kdm,label=surveys[2].meta["BEAM"],color='black') - - for i,s in enumerate(surveys): - if i==2: + + ax[0, 0].plot(zvals, kz, label=surveys[2].meta["BEAM"], color="black") + ax[0, 1].plot(dmvals, kdm, label=surveys[2].meta["BEAM"], color="black") + + for i, s in enumerate(surveys): + if i == 2: continue - - #calculates relative and absolute errors in dm and z space - z=np.sum(rates[i],axis=1) - dm=np.sum(rates[i],axis=0) + + # calculates relative and absolute errors in dm and z space + z = np.sum(rates[i], axis=1) + dm = np.sum(rates[i], axis=0) z /= np.sum(z) dm /= np.sum(dm) - - dz=z-kz - ddm = dm-kdm - rdz=dz/kz - rdm=ddm/kdm - - ax[0,0].plot(zvals,z,label=s.meta["BEAM"]) - ax[0,1].plot(dmvals,dm,label=s.meta["BEAM"]) - ax[1,0].plot(zvals,dz,label=s.meta["BEAM"]) - ax[1,1].plot(dmvals,ddm,label=s.meta["BEAM"]) - ax[2,0].plot(zvals,rdz,label=s.meta["BEAM"]) - ax[2,1].plot(dmvals,rdm,label=s.meta["BEAM"]) - ax[0,0].legend(fontsize=6) + + dz = z - kz + ddm = dm - kdm + rdz = dz / kz + rdm = ddm / kdm + + ax[0, 0].plot(zvals, z, label=s.meta["BEAM"]) + ax[0, 1].plot(dmvals, dm, label=s.meta["BEAM"]) + ax[1, 0].plot(zvals, dz, label=s.meta["BEAM"]) + ax[1, 1].plot(dmvals, ddm, label=s.meta["BEAM"]) + ax[2, 0].plot(zvals, rdz, label=s.meta["BEAM"]) + ax[2, 1].plot(dmvals, rdm, label=s.meta["BEAM"]) + ax[0, 0].legend(fontsize=6) plt.figure(fig.number) plt.tight_layout() - plt.savefig(outdir+'montage.pdf') + plt.savefig(outdir + "montage.pdf") plt.close() -def final_plot_beam_rates(surveys,zDMgrid, zvals,dmvals,pset,binset,names,logsigma,logmean,outdir,LOAD=True): + +def final_plot_beam_rates( + surveys, + zDMgrid, + zvals, + dmvals, + pset, + binset, + names, + logsigma, + logmean, + outdir, + LOAD=True, +): """ For each survey, compare 'full' calculation to 'relative' in dm and z space binset is one for each survey, to be compared to 'all' """ - - #need new ones for new grid shape - + + # need new ones for new grid shape + # hard-coded best values - method=2 - thresh=0 - - + method = 2 + thresh = 0 + ###### makes a 1d set of plots in dm and redshift ######## - font = {'family' : 'normal', - 'weight' : 'normal', - 'size' : 10} + font = {"family": "normal", "weight": "normal", "size": 10} + + matplotlib.rc("font", **font) - matplotlib.rc('font', **font) - - # get parameter values - lEmin,lEmax,alpha,gamma,sfr_n,logmean,logsigma,C=pset - Emin=10**lEmin - Emax=10**lEmax - + lEmin, lEmax, alpha, gamma, sfr_n, logmean, logsigma, C = pset + Emin = 10 ** lEmin + Emax = 10 ** lEmax + # generates a DM mask # creates a mask of values in DM space to convolve with the DM grid - mask=pcosmic.get_dm_mask(dmvals,(logmean,logsigma),zvals) - - f1, (ax11, ax12) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [3, 1]},sharex=True) - + mask = pcosmic.get_dm_mask(dmvals, (logmean, logsigma), zvals) + + f1, (ax11, ax12) = plt.subplots( + 2, 1, gridspec_kw={"height_ratios": [3, 1]}, sharex=True + ) + plt.subplots_adjust(wspace=0, hspace=0) - ax11.set_xlim(0,2) - ax12.set_xlim(0,2) - ax11.set_ylabel('$p(z)$ [a.u.]') - ax12.set_ylabel('$p_{\\rm Full}(z)-p(z)$') - ax12.set_xlabel('z') - - f2, (ax21, ax22) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [3, 1]},sharex=True) + ax11.set_xlim(0, 2) + ax12.set_xlim(0, 2) + ax11.set_ylabel("$p(z)$ [a.u.]") + ax12.set_ylabel("$p_{\\rm Full}(z)-p(z)$") + ax12.set_xlabel("z") + + f2, (ax21, ax22) = plt.subplots( + 2, 1, gridspec_kw={"height_ratios": [3, 1]}, sharex=True + ) plt.subplots_adjust(wspace=0, hspace=0) - ax21.set_xlim(0,2500) - ax22.set_xlim(0,2500) - ax21.set_ylabel('$p(\\rm DM_{\\rm EG})$ [a.u.]') - ax22.set_ylabel('$p(\\rm DM_{\\rm EG})-p_{\\rm Full}(\\rm DM_{\\rm EG})$') - ax22.set_xlabel('${\\rm DM}_{\\rm EG}$') - + ax21.set_xlim(0, 2500) + ax22.set_xlim(0, 2500) + ax21.set_ylabel("$p(\\rm DM_{\\rm EG})$ [a.u.]") + ax22.set_ylabel("$p(\\rm DM_{\\rm EG})-p_{\\rm Full}(\\rm DM_{\\rm EG})$") + ax22.set_xlabel("${\\rm DM}_{\\rm EG}$") + # does this for each survey # for lat50, FE, and Parkes - FWHM0=np.array([32,32,0.54])*(np.pi/180)**2 # nominal deg square + FWHM0 = np.array([32, 32, 0.54]) * (np.pi / 180) ** 2 # nominal deg square print("Generating plots illustrating the effect of beamshape") print("Order is FWHM, Numerical, Gaussian") - for i,s in enumerate(surveys): - #efficiencies=s.get_efficiency(dmvals) - efficiencies=s.efficiencies # two dimensions - weights=s.wplist - + for i, s in enumerate(surveys): + # efficiencies=s.get_efficiency(dmvals) + efficiencies = s.efficiencies # two dimensions + weights = s.wplist + ######## Naive FWHM case - single beam value, single angle ######## - + if LOAD: - rates=np.load('TEMP/'+str(i)+'1.npy') - + rates = np.load("TEMP/" + str(i) + "1.npy") + else: - t0=t0=time.process_time() + t0 = t0 = time.process_time() # set up grid, which should be common for this survey - grid=zdm_grid.Grid() - grid.pass_grid(zDMgrid,zvals,dmvals) - grid.smear_dm(mask,logmean,logsigma) - grid.calc_thresholds(s.meta['THRESH'],efficiencies,alpha=alpha,weights=weights) + grid = zdm_grid.Grid() + grid.pass_grid(zDMgrid, zvals, dmvals) + grid.smear_dm(mask, logmean, logsigma) + grid.calc_thresholds( + s.meta["THRESH"], efficiencies, alpha=alpha, weights=weights + ) grid.calc_dV() - grid.set_evolution(sfr_n) # sets star-formation rate scaling with z - here, no evoltion... - grid.b_fractions=None # trick! - grid.calc_pdv(Emin,Emax,gamma,np.array([1]),np.array([FWHM0[i]])) # calculates volumetric-weighted probabilities - grid.calc_rates() # calculates rates by multiplying above with pdm plot - t1=time.process_time() - np.save('TEMP/'+str(i)+'1.npy',grid.rates) - rates=grid.rates - - total1=np.sum(rates) - rates1=rates / total1 - - fz1=np.sum(rates1,axis=1) - fdm1=np.sum(rates1,axis=0) - + grid.set_evolution( + sfr_n + ) # sets star-formation rate scaling with z - here, no evoltion... + grid.b_fractions = None # trick! + grid.calc_pdv( + Emin, Emax, gamma, np.array([1]), np.array([FWHM0[i]]) + ) # calculates volumetric-weighted probabilities + grid.calc_rates() # calculates rates by multiplying above with pdm plot + t1 = time.process_time() + np.save("TEMP/" + str(i) + "1.npy", grid.rates) + rates = grid.rates + + total1 = np.sum(rates) + rates1 = rates / total1 + + fz1 = np.sum(rates1, axis=1) + fdm1 = np.sum(rates1, axis=0) + ######## full case - very detailed! ######## if LOAD: - rates=np.load('TEMP/'+str(i)+'2.npy') + rates = np.load("TEMP/" + str(i) + "2.npy") else: - s.init_beam(nbins=1,method=3,thresh=thresh) #nbins ignored for method=3 - #s.init_beam(nbins=1,method=2,thresh=thresh) #make it fast! - - grid.b_fractions=None # trick! - grid.calc_pdv(Emin,Emax,gamma,s.beam_b,s.beam_o) # calculates volumetric-weighted probabilities - grid.calc_rates() # calculates rates by multiplying above with pdm plot - np.save('TEMP/'+str(i)+'2.npy',grid.rates) - rates=grid.rates - total2=np.sum(rates) - rates2=rates / total2 - fz2=np.sum(rates2,axis=1) - fdm2=np.sum(rates2,axis=0) - + s.init_beam(nbins=1, method=3, thresh=thresh) # nbins ignored for method=3 + # s.init_beam(nbins=1,method=2,thresh=thresh) #make it fast! + + grid.b_fractions = None # trick! + grid.calc_pdv( + Emin, Emax, gamma, s.beam_b, s.beam_o + ) # calculates volumetric-weighted probabilities + grid.calc_rates() # calculates rates by multiplying above with pdm plot + np.save("TEMP/" + str(i) + "2.npy", grid.rates) + rates = grid.rates + total2 = np.sum(rates) + rates2 = rates / total2 + fz2 = np.sum(rates2, axis=1) + fdm2 = np.sum(rates2, axis=0) + ######## Case of nbins bins - 'standard' ######### if LOAD: - rates=np.load('TEMP/'+str(i)+'3.npy') + rates = np.load("TEMP/" + str(i) + "3.npy") else: - - s.init_beam(nbins=binset[i],method=method,thresh=thresh) - grid.b_fractions=None # trick! - grid.calc_pdv(Emin,Emax,gamma,s.beam_b,s.beam_o) # calculates volumetric-weighted probabilities - grid.calc_rates() # calculates rates by multiplying above with pdm plot - np.save('TEMP/'+str(i)+'3.npy',grid.rates) - rates=grid.rates - total3=np.sum(rates) - rates3=rates / total3 - fz3=np.sum(rates3,axis=1) - fdm3=np.sum(rates3,axis=0) - + + s.init_beam(nbins=binset[i], method=method, thresh=thresh) + grid.b_fractions = None # trick! + grid.calc_pdv( + Emin, Emax, gamma, s.beam_b, s.beam_o + ) # calculates volumetric-weighted probabilities + grid.calc_rates() # calculates rates by multiplying above with pdm plot + np.save("TEMP/" + str(i) + "3.npy", grid.rates) + rates = grid.rates + total3 = np.sum(rates) + rates3 = rates / total3 + fz3 = np.sum(rates3, axis=1) + fdm3 = np.sum(rates3, axis=0) + ######## Gaussian case ######### - + if LOAD: - rates=np.load('TEMP/'+str(i)+'4.npy') + rates = np.load("TEMP/" + str(i) + "4.npy") else: - - thresh=1e-3 #argh! - s.init_beam(nbins=100,method=method,thresh=thresh,Gauss=True) - - grid.b_fractions=None # trick! - grid.calc_pdv(Emin,Emax,gamma,s.beam_b,s.beam_o) # calculates volumetric-weighted probabilities - grid.calc_rates() # calculates rates by multiplying above with pdm plot - np.save('TEMP/'+str(i)+'4.npy',grid.rates) - rates=grid.rates - total4=np.sum(rates) - rates4=rates / total4 - fz4=np.sum(rates4,axis=1) - fdm4=np.sum(rates4,axis=0) - - + + thresh = 1e-3 # argh! + s.init_beam(nbins=100, method=method, thresh=thresh, Gauss=True) + + grid.b_fractions = None # trick! + grid.calc_pdv( + Emin, Emax, gamma, s.beam_b, s.beam_o + ) # calculates volumetric-weighted probabilities + grid.calc_rates() # calculates rates by multiplying above with pdm plot + np.save("TEMP/" + str(i) + "4.npy", grid.rates) + rates = grid.rates + total4 = np.sum(rates) + rates4 = rates / total4 + fz4 = np.sum(rates4, axis=1) + fdm4 = np.sum(rates4, axis=0) + ######## calculate some statistics ######### - + # stats for redshift z - - true_mean=np.sum(fz2*zvals) - dm_mean=np.sum(fdm2*dmvals) - - nerr1=total1/total2 - nerr3=total3/total2 - nerr4=total4/total2 - zerr1=np.sum(fz1*zvals)/true_mean - zerr3=np.sum(fz3*zvals)/true_mean - zerr4=np.sum(fz4*zvals)/true_mean - dmerr1=np.sum(fdm1*dmvals)/dm_mean - dmerr3=np.sum(fdm3*dmvals)/dm_mean - dmerr4=np.sum(fdm4*dmvals)/dm_mean - - print("\n\n\nNormalisation errors: ",nerr1,nerr3,nerr4) - print("zerr : ",zerr1,zerr3,zerr4) - print("dmerr : ",dmerr1,dmerr3,dmerr4) - + + true_mean = np.sum(fz2 * zvals) + dm_mean = np.sum(fdm2 * dmvals) + + nerr1 = total1 / total2 + nerr3 = total3 / total2 + nerr4 = total4 / total2 + zerr1 = np.sum(fz1 * zvals) / true_mean + zerr3 = np.sum(fz3 * zvals) / true_mean + zerr4 = np.sum(fz4 * zvals) / true_mean + dmerr1 = np.sum(fdm1 * dmvals) / dm_mean + dmerr3 = np.sum(fdm3 * dmvals) / dm_mean + dmerr4 = np.sum(fdm4 * dmvals) / dm_mean + + print("\n\n\nNormalisation errors: ", nerr1, nerr3, nerr4) + print("zerr : ", zerr1, zerr3, zerr4) + print("dmerr : ", dmerr1, dmerr3, dmerr4) + ############## plotting ########## # normalise by amplitude of 'true': - normz=np.max(fz2) - normdm=np.max(fdm2) - + normz = np.max(fz2) + normdm = np.max(fdm2) + fz1 /= normz fz2 /= normz fz3 /= normz fz4 /= normz - + fdm1 /= normdm fdm2 /= normdm fdm3 /= normdm fdm4 /= normdm - + plt.sca(ax11) - plt.plot(zvals,fz1,linestyle='--',label=names[i]+' FWHM') - c1=plt.gca().lines[-1].get_color() - + plt.plot(zvals, fz1, linestyle="--", label=names[i] + " FWHM") + c1 = plt.gca().lines[-1].get_color() + plt.sca(ax21) - plt.plot(dmvals,fdm1,linestyle='--',color=c1,label=names[i]+' FWHM') - + plt.plot(dmvals, fdm1, linestyle="--", color=c1, label=names[i] + " FWHM") + plt.sca(ax11) - plt.plot(zvals,fz2,color=c1,linestyle='-',label=' Full beam') - + plt.plot(zvals, fz2, color=c1, linestyle="-", label=" Full beam") + plt.sca(ax21) - plt.plot(dmvals,fdm2,color=c1,linestyle='-',label=' Full beam') - + plt.plot(dmvals, fdm2, color=c1, linestyle="-", label=" Full beam") + plt.sca(ax11) - plt.plot(zvals,fz3,color=plt.gca().lines[-1].get_color(),linestyle=':',label=' This work') - + plt.plot( + zvals, + fz3, + color=plt.gca().lines[-1].get_color(), + linestyle=":", + label=" This work", + ) + plt.sca(ax21) - plt.plot(dmvals,fdm3,color=plt.gca().lines[-1].get_color(),linestyle=':',label=' This work') - + plt.plot( + dmvals, + fdm3, + color=plt.gca().lines[-1].get_color(), + linestyle=":", + label=" This work", + ) + plt.sca(ax11) - plt.plot(zvals,fz4,color=plt.gca().lines[-1].get_color(),linestyle='-.',label=' Gauss') - + plt.plot( + zvals, + fz4, + color=plt.gca().lines[-1].get_color(), + linestyle="-.", + label=" Gauss", + ) + plt.sca(ax21) - plt.plot(dmvals,fdm4,color=plt.gca().lines[-1].get_color(),linestyle='-.',label=' Gauss') - - + plt.plot( + dmvals, + fdm4, + color=plt.gca().lines[-1].get_color(), + linestyle="-.", + label=" Gauss", + ) + ###### now does relative values ####### - dz=fz3-fz2 - ddm=fdm3-fdm2 - - dz0=fz1-fz2 - ddm0=fdm1-fdm2 - - - dzG=fz4-fz2 - ddmG=fdm4-fdm2 - - print("For survey ",i," maximum dz deviation is ",np.max(np.abs(dz0)),np.max(np.abs(dz)),np.max(np.abs(dzG))) - print(" dm deviation is ",np.max(np.abs(ddm0)),np.max(np.abs(ddm)),np.max(np.abs(ddmG))) - + dz = fz3 - fz2 + ddm = fdm3 - fdm2 + + dz0 = fz1 - fz2 + ddm0 = fdm1 - fdm2 + + dzG = fz4 - fz2 + ddmG = fdm4 - fdm2 + + print( + "For survey ", + i, + " maximum dz deviation is ", + np.max(np.abs(dz0)), + np.max(np.abs(dz)), + np.max(np.abs(dzG)), + ) + print( + " dm deviation is ", + np.max(np.abs(ddm0)), + np.max(np.abs(ddm)), + np.max(np.abs(ddmG)), + ) + # plots differences plt.sca(ax12) - ax12.set_ylim(-0.2,0.2) - plt.plot(zvals,dz0,color=c1,linestyle='--') - plt.plot(zvals,dz,color=c1,linestyle=':') - plt.plot(zvals,dzG,color=c1,linestyle='-.') - #ax12.tick_params(axis='y') - - #ax122=ax12.twinx() - #ax122.set_ylim(-0.2,0.2) - - #ax122.tick_params(axis='y') - + ax12.set_ylim(-0.2, 0.2) + plt.plot(zvals, dz0, color=c1, linestyle="--") + plt.plot(zvals, dz, color=c1, linestyle=":") + plt.plot(zvals, dzG, color=c1, linestyle="-.") + # ax12.tick_params(axis='y') + + # ax122=ax12.twinx() + # ax122.set_ylim(-0.2,0.2) + + # ax122.tick_params(axis='y') + plt.sca(ax22) - ax22.set_ylim(-0.2,0.2) - plt.plot(dmvals,ddm0,color=c1,linestyle='--') - plt.plot(dmvals,ddm,color=c1,linestyle=':') - plt.plot(dmvals,ddmG,color=c1,linestyle='-.') - #ax222=ax22.twinx() - #ax222.set_ylim(-0.2,0.2) - - - print("Total rates for are ",i,total1,total2,total3,total4) - + ax22.set_ylim(-0.2, 0.2) + plt.plot(dmvals, ddm0, color=c1, linestyle="--") + plt.plot(dmvals, ddm, color=c1, linestyle=":") + plt.plot(dmvals, ddmG, color=c1, linestyle="-.") + # ax222=ax22.twinx() + # ax222.set_ylim(-0.2,0.2) + + print("Total rates for are ", i, total1, total2, total3, total4) + plt.figure(f1.number) - leg1=ax11.legend(fontsize=8) + leg1 = ax11.legend(fontsize=8) plt.tight_layout() - plt.savefig(outdir+'/beam_z_comp.pdf') + plt.savefig(outdir + "/beam_z_comp.pdf") plt.close() - + plt.figure(f2.number) - leg2=ax21.legend(fontsize=8) + leg2 = ax21.legend(fontsize=8) plt.tight_layout() - plt.savefig(outdir+'/beam_dm_comp.pdf') + plt.savefig(outdir + "/beam_dm_comp.pdf") - -def final_plot_beam_values(surveys,zDMgrid, zvals,dmvals,pset,binset,names,logsigma,logmean,outdir): +def final_plot_beam_values( + surveys, zDMgrid, zvals, dmvals, pset, binset, names, logsigma, logmean, outdir +): """ For each survey, get the beamshape, and plot it vs the dots on the one plot """ # hard-coded best values - method=2 - thresh=0 - + method = 2 + thresh = 0 + # does this for each survey # for lat50, FE, and Parkes - #FWHM0=np.array([32,32,0.54])*(np.pi/180)**2 # nominal deg square - + # FWHM0=np.array([32,32,0.54])*(np.pi/180)**2 # nominal deg square + plt.figure() - plt.yscale('log') - plt.xscale('log') - plt.xlabel('$B$') - plt.ylabel('$\\Omega(B)\\, d\\log_{10}B$ [sr]') # data is dlogB for constant logB - - - markers=['o','o','o'] - lss=["-",":","--"] - names=["ASKAP","ASKAP","Parkes/Mb"] - n=[5,1,1] - for i,s in enumerate(surveys): - if i==1: + plt.yscale("log") + plt.xscale("log") + plt.xlabel("$B$") + plt.ylabel("$\\Omega(B)\\, d\\log_{10}B$ [sr]") # data is dlogB for constant logB + + markers = ["o", "o", "o"] + lss = ["-", ":", "--"] + names = ["ASKAP", "ASKAP", "Parkes/Mb"] + n = [5, 1, 1] + for i, s in enumerate(surveys): + if i == 1: continue - #efficiencies=s.get_efficiency(dmvals) - efficiencies=s.efficiencies # two dimensions - weights=s.wplist - + # efficiencies=s.get_efficiency(dmvals) + efficiencies = s.efficiencies # two dimensions + weights = s.wplist + # gets Gaussian beam - s.init_beam(nbins=binset[i]*10,method=method,thresh=1e-3,Gauss=True) - gb=np.copy(s.beam_b) - go=np.copy(s.beam_o) - gdb=np.log10(gb[0]/gb[1]) - + s.init_beam(nbins=binset[i] * 10, method=method, thresh=1e-3, Gauss=True) + gb = np.copy(s.beam_b) + go = np.copy(s.beam_o) + gdb = np.log10(gb[0] / gb[1]) + # simple point of Nbeams * 1 * FWHM - simple_x=1 - HPBW=1.22*(sp.constants.c/(s.meta["FBAR"]*1e6))/s.meta["DIAM"] - simple_y=np.pi*HPBW**2*s.meta["NBEAMS"] - + simple_x = 1 + HPBW = 1.22 * (sp.constants.c / (s.meta["FBAR"] * 1e6)) / s.meta["DIAM"] + simple_y = np.pi * HPBW ** 2 * s.meta["NBEAMS"] + # standard method - s.init_beam(nbins=binset[i],method=method,thresh=thresh) - - - #calculates normalisation factor: integral B db - orig_db=np.log10(s.orig_beam_b[1]/s.orig_beam_b[0]) + s.init_beam(nbins=binset[i], method=method, thresh=thresh) + + # calculates normalisation factor: integral B db + orig_db = np.log10(s.orig_beam_b[1] / s.orig_beam_b[0]) # log10 grid spacing of original plot # now db is per natural log # first divide by db factor # since d Omega dlogB = d Omega/dB * dB/dlogB = dOmega/dB B # d Omega/dB = d Omega dlogB/B # but we will not do this! - - db=np.log10(s.beam_b[1]/s.beam_b[0]) # also divides this one by the log spacing! - part=np.where(s.orig_beam_b > 1e-3) - to_sqr_deg=(180/np.pi)**2 - #print("The log(10) corrected sums are [deg2]",np.sum(s.orig_beam_o[part])*to_sqr_deg,np.sum(go)/np.log(10)*to_sqr_deg,np.sum(s.beam_o)*to_sqr_deg) - print("The uncorrected sums are [deg2]",np.sum(s.orig_beam_o[part])*to_sqr_deg,np.sum(go)*to_sqr_deg,np.sum(s.beam_o)*to_sqr_deg) - - plt.plot(s.orig_beam_b[::n[i]],s.orig_beam_o[::n[i]]/orig_db,linestyle=lss[i],label=names[i]) - plt.plot(gb,go/gdb,color=plt.gca().lines[-1].get_color(),linestyle=lss[i]) - plt.plot(s.beam_b,s.beam_o/db,marker=markers[i],color=plt.gca().lines[-1].get_color(),linestyle="",markersize=10) - plt.plot(simple_x,simple_y,marker='+',color=plt.gca().lines[-1].get_color(),markersize=10) - + + db = np.log10( + s.beam_b[1] / s.beam_b[0] + ) # also divides this one by the log spacing! + part = np.where(s.orig_beam_b > 1e-3) + to_sqr_deg = (180 / np.pi) ** 2 + # print("The log(10) corrected sums are [deg2]",np.sum(s.orig_beam_o[part])*to_sqr_deg,np.sum(go)/np.log(10)*to_sqr_deg,np.sum(s.beam_o)*to_sqr_deg) + print( + "The uncorrected sums are [deg2]", + np.sum(s.orig_beam_o[part]) * to_sqr_deg, + np.sum(go) * to_sqr_deg, + np.sum(s.beam_o) * to_sqr_deg, + ) + + plt.plot( + s.orig_beam_b[:: n[i]], + s.orig_beam_o[:: n[i]] / orig_db, + linestyle=lss[i], + label=names[i], + ) + plt.plot(gb, go / gdb, color=plt.gca().lines[-1].get_color(), linestyle=lss[i]) + plt.plot( + s.beam_b, + s.beam_o / db, + marker=markers[i], + color=plt.gca().lines[-1].get_color(), + linestyle="", + markersize=10, + ) + plt.plot( + simple_x, + simple_y, + marker="+", + color=plt.gca().lines[-1].get_color(), + markersize=10, + ) + plt.legend() plt.tight_layout() - - plt.savefig(outdir+'/beam_approx.pdf') - -def test_beam_rates(survey,zDMgrid, zvals,dmvals,pset,binset,method=2,outdir='Plots/BeamTest/',thresh=1e-3,zmax=1,DMmax=1000): + plt.savefig(outdir + "/beam_approx.pdf") + + +def test_beam_rates( + survey, + zDMgrid, + zvals, + dmvals, + pset, + binset, + method=2, + outdir="Plots/BeamTest/", + thresh=1e-3, + zmax=1, + DMmax=1000, +): """ For a list of surveys, construct a zDMgrid object binset is the set of bins which we use to simplify the beamset We conclude that method=2, nbeams=5, acc=0 is the best here """ - - #zmax=4 - #DMmax=4000 - + + # zmax=4 + # DMmax=4000 + if not os.path.isdir(outdir): os.mkdir(outdir) - + # get parameter values - lEmin,lEmax,alpha,gamma,sfr_n,logmean,logsigma,C=pset - Emin=10**lEmin - Emax=10**lEmax - + lEmin, lEmax, alpha, gamma, sfr_n, logmean, logsigma, C = pset + Emin = 10 ** lEmin + Emax = 10 ** lEmax + # generates a DM mask # creates a mask of values in DM space to convolve with the DM grid - mask=pcosmic.get_dm_mask(dmvals,(logmean,logsigma),zvals,plot=True) - efficiencies=survey.get_efficiency(dmvals) - + mask = pcosmic.get_dm_mask(dmvals, (logmean, logsigma), zvals, plot=True) + efficiencies = survey.get_efficiency(dmvals) + # get an initial grid with no beam values - grids=[] - bbs=[] - bos=[] - - - norms=np.zeros([len(binset)]) - numbins=np.zeros([len(binset)]) - - for k,nbins in enumerate(binset): - grid=zdm_grid.Grid() - grid.pass_grid(zDMgrid,zvals,dmvals) - grid.smear_dm(mask,logmean,logsigma) - grid.calc_thresholds(survey.meta['THRESH'],survey.mean_efficiencies,alpha=alpha) + grids = [] + bbs = [] + bos = [] + + norms = np.zeros([len(binset)]) + numbins = np.zeros([len(binset)]) + + for k, nbins in enumerate(binset): + grid = zdm_grid.Grid() + grid.pass_grid(zDMgrid, zvals, dmvals) + grid.smear_dm(mask, logmean, logsigma) + grid.calc_thresholds( + survey.meta["THRESH"], survey.mean_efficiencies, alpha=alpha + ) grid.calc_dV() - grid.set_evolution(sfr_n) # sets star-formation rate scaling with z - here, no evoltion... - - if nbins != 0 and nbins != 'all': - survey.init_beam(nbins=nbins,method=method,thresh=thresh) + grid.set_evolution( + sfr_n + ) # sets star-formation rate scaling with z - here, no evoltion... + + if nbins != 0 and nbins != "all": + survey.init_beam(nbins=nbins, method=method, thresh=thresh) bbs.append(np.copy(survey.beam_b)) bos.append(np.copy(survey.beam_o)) - grid.calc_pdv(Emin,Emax,gamma,survey.beam_b,survey.beam_o) # calculates volumetric-weighted probabilities - numbins[k]=nbins - elif nbins ==0: - grid.calc_pdv(Emin,Emax,gamma) # calculates volumetric-weighted probabilities + grid.calc_pdv( + Emin, Emax, gamma, survey.beam_b, survey.beam_o + ) # calculates volumetric-weighted probabilities + numbins[k] = nbins + elif nbins == 0: + grid.calc_pdv( + Emin, Emax, gamma + ) # calculates volumetric-weighted probabilities bbs.append(np.array([1])) bos.append(np.array([1])) - numbins[k]=nbins + numbins[k] = nbins else: - survey.init_beam(nbins=nbins,method=3,thresh=thresh) + survey.init_beam(nbins=nbins, method=3, thresh=thresh) bbs.append(np.copy(survey.beam_b)) bos.append(np.copy(survey.beam_o)) - numbins[k]=survey.beam_o.size - grid.calc_pdv(Emin,Emax,gamma,survey.beam_b,survey.beam_o) # calculates volumetric-weighted probabilities - - - grid.calc_rates() # calculates rates by multiplying above with pdm plot - name=outdir+'beam_test_'+survey.meta["BEAM"]+'_nbins_'+str(nbins)+'.pdf' - plot_grid_2(grid.rates,grid.zvals,grid.dmvals,zmax=zmax,DMmax=DMmax,name=name,norm=2,log=True,label='$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]',project=True) + numbins[k] = survey.beam_o.size + grid.calc_pdv( + Emin, Emax, gamma, survey.beam_b, survey.beam_o + ) # calculates volumetric-weighted probabilities + + grid.calc_rates() # calculates rates by multiplying above with pdm plot + name = ( + outdir + + "beam_test_" + + survey.meta["BEAM"] + + "_nbins_" + + str(nbins) + + ".pdf" + ) + plot_grid_2( + grid.rates, + grid.zvals, + grid.dmvals, + zmax=zmax, + DMmax=DMmax, + name=name, + norm=2, + log=True, + label="$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]", + project=True, + ) grids.append(grid) - + # OK, we now have a list of grids with various interpolating factors - # we produce plots of the rate for each, and also difference plots with the best - #Does a linear plot relative to the best case - - - bestgrid=grids[-1] # we always have the worst grid at 0 - #bestgrid.rates=bestgrid.rates / np.sum(bestgrid.rates) - + # we produce plots of the rate for each, and also difference plots with the best + # Does a linear plot relative to the best case + + bestgrid = grids[-1] # we always have the worst grid at 0 + # bestgrid.rates=bestgrid.rates / np.sum(bestgrid.rates) + # normalises - - for i,grid in enumerate(grids): - norms[i]=np.sum(grid.rates) - grid.rates=grid.rates / norms[i] - - np.save(outdir+survey.meta["BEAM"]+'_total_rates.npy',norms) - np.save(outdir+survey.meta["BEAM"]+'_nbins.npy',numbins) - - bestz=np.sum(grid.rates,axis=1) - bestdm=np.sum(grid.rates,axis=0) - + + for i, grid in enumerate(grids): + norms[i] = np.sum(grid.rates) + grid.rates = grid.rates / norms[i] + + np.save(outdir + survey.meta["BEAM"] + "_total_rates.npy", norms) + np.save(outdir + survey.meta["BEAM"] + "_nbins.npy", numbins) + + bestz = np.sum(grid.rates, axis=1) + bestdm = np.sum(grid.rates, axis=0) + ###### makes a 1d set of plots in dm and redshift ######## - font = {'family' : 'normal', - 'weight' : 'normal', - 'size' : 6} + font = {"family": "normal", "weight": "normal", "size": 6} + + matplotlib.rc("font", **font) + fig, ax = plt.subplots( + 3, 2, sharey="row", sharex="col" + ) # ,sharey='row',sharex='col') + + # ax[0,0]=fig.add_subplot(221) + # ax[0,1]=fig.add_subplot(222) + # ax[1,0]=fig.add_subplot(223) + # ax[1,1]=fig.add_subplot(224) + + # ax[0,0].plot(grid.zvals,bestz,color='black',label='All') + ax[1, 0].set_xlabel("z") + ax[1, 1].set_xlabel("DM_{\\rm EG}") + ax[2, 0].set_xlabel("z") + ax[2, 1].set_xlabel("DM_{\\rm EG}") + ax[0, 0].set_ylabel("Abs") + ax[0, 1].set_ylabel("Abs") + ax[1, 0].set_ylabel("Dabs") + ax[1, 1].set_ylabel("Dabs") + ax[2, 0].set_ylabel("Rel diff") + ax[2, 1].set_ylabel("Rel diff") - matplotlib.rc('font', **font) - fig,ax=plt.subplots(3,2,sharey='row',sharex='col')#,sharey='row',sharex='col') - - #ax[0,0]=fig.add_subplot(221) - #ax[0,1]=fig.add_subplot(222) - #ax[1,0]=fig.add_subplot(223) - #ax[1,1]=fig.add_subplot(224) - - #ax[0,0].plot(grid.zvals,bestz,color='black',label='All') - ax[1,0].set_xlabel('z') - ax[1,1].set_xlabel('DM_{\\rm EG}') - ax[2,0].set_xlabel('z') - ax[2,1].set_xlabel('DM_{\\rm EG}') - ax[0,0].set_ylabel('Abs') - ax[0,1].set_ylabel('Abs') - ax[1,0].set_ylabel('Dabs') - ax[1,1].set_ylabel('Dabs') - ax[2,0].set_ylabel('Rel diff') - ax[2,1].set_ylabel('Rel diff') - # force relative range only - ax[2,0].set_ylim(-1,1) - ax[2,1].set_ylim(-1,1) - - ax[0,0].set_xlim(0,zmax) - ax[0,1].set_xlim(0,DMmax) - ax[1,0].set_xlim(0,zmax) - ax[2,0].set_xlim(0,zmax) - ax[1,1].set_xlim(0,DMmax) - ax[2,1].set_xlim(0,DMmax) - - ax[0,0].plot(grid.zvals,np.sum(bestgrid.rates,axis=1),label='All',color='black') - ax[0,1].plot(grid.dmvals,np.sum(bestgrid.rates,axis=0),label='All',color='black') - - for i,grid in enumerate(grids[:-1]): - - diff=grid.rates-bestgrid.rates - - #calculates relative and absolute errors in dm and z space - dz=np.sum(diff,axis=1) - ddm=np.sum(diff,axis=0) - rdz=dz/bestz - rdm=ddm/bestdm - - thisz=np.sum(grid.rates,axis=1) - thisdm=np.sum(grid.rates,axis=0) - - ax[0,0].plot(grid.zvals,thisz,label=str(binset[i])) - ax[0,1].plot(grid.dmvals,thisdm,label=str(binset[i])) - ax[1,0].plot(grid.zvals,dz,label=str(binset[i])) - ax[1,1].plot(grid.dmvals,ddm,label=str(binset[i])) - ax[2,0].plot(grid.zvals,rdz,label=str(binset[i])) - ax[2,1].plot(grid.dmvals,rdm,label=str(binset[i])) - ax[0,0].legend(fontsize=6) + ax[2, 0].set_ylim(-1, 1) + ax[2, 1].set_ylim(-1, 1) + + ax[0, 0].set_xlim(0, zmax) + ax[0, 1].set_xlim(0, DMmax) + ax[1, 0].set_xlim(0, zmax) + ax[2, 0].set_xlim(0, zmax) + ax[1, 1].set_xlim(0, DMmax) + ax[2, 1].set_xlim(0, DMmax) + + ax[0, 0].plot( + grid.zvals, np.sum(bestgrid.rates, axis=1), label="All", color="black" + ) + ax[0, 1].plot( + grid.dmvals, np.sum(bestgrid.rates, axis=0), label="All", color="black" + ) + + for i, grid in enumerate(grids[:-1]): + + diff = grid.rates - bestgrid.rates + + # calculates relative and absolute errors in dm and z space + dz = np.sum(diff, axis=1) + ddm = np.sum(diff, axis=0) + rdz = dz / bestz + rdm = ddm / bestdm + + thisz = np.sum(grid.rates, axis=1) + thisdm = np.sum(grid.rates, axis=0) + + ax[0, 0].plot(grid.zvals, thisz, label=str(binset[i])) + ax[0, 1].plot(grid.dmvals, thisdm, label=str(binset[i])) + ax[1, 0].plot(grid.zvals, dz, label=str(binset[i])) + ax[1, 1].plot(grid.dmvals, ddm, label=str(binset[i])) + ax[2, 0].plot(grid.zvals, rdz, label=str(binset[i])) + ax[2, 1].plot(grid.dmvals, rdm, label=str(binset[i])) + ax[0, 0].legend(fontsize=6) plt.figure(fig.number) plt.tight_layout() - plt.savefig(outdir+'d_dm_z_'+survey.meta["BEAM"]+'_nbins_'+str(binset[i])+'.pdf') + plt.savefig( + outdir + "d_dm_z_" + survey.meta["BEAM"] + "_nbins_" + str(binset[i]) + ".pdf" + ) plt.close() - - acc=open(outdir+'accuracy.dat','w') - mean=np.mean(bestgrid.rates) - size=bestgrid.rates.size - string='#Nbins Acc StdDev StdDev/mean; mean={:.2E}\n'.format(mean) - acc.write('#Nbins Acc StdDev StdDev/mean; mean='+str(mean)+'\n') - - for i,grid in enumerate(grids[:-1]): - - diff=grid.rates-bestgrid.rates - - inaccuracy=np.sum(diff**2) - std_dev=(inaccuracy/size)**0.5 - rel_std_dev=std_dev/mean - #print("Beam with bins ",binset[i]," has total inaccuracy ",inaccuracy) - string="{:.0f} {:.2E} {:.2E} {:.2E}".format(binset[i],inaccuracy,std_dev,rel_std_dev) - acc.write(string+'\n') - name=outdir+'diff_beam_test_'+survey.meta["BEAM"]+'_nbins_'+str(binset[i])+'.pdf' - - plot_grid_2(diff,grid.zvals,grid.dmvals,zmax=zmax,DMmax=DMmax,name=name,norm=0,log=False,label='$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]',project=True) - diff=diff/bestgrid.rates - nans=np.isnan(diff) - diff[nans]=0. - name=outdir+'rel_diff_beam_test_'+survey.meta["BEAM"]+'_nbins_'+str(binset[i])+'.pdf' - plot_grid_2(diff,grid.zvals,grid.dmvals,zmax=zmax,DMmax=DMmax,name=name,norm=0,log=False,label='$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]',project=True) - - + + acc = open(outdir + "accuracy.dat", "w") + mean = np.mean(bestgrid.rates) + size = bestgrid.rates.size + string = "#Nbins Acc StdDev StdDev/mean; mean={:.2E}\n".format(mean) + acc.write("#Nbins Acc StdDev StdDev/mean; mean=" + str(mean) + "\n") + + for i, grid in enumerate(grids[:-1]): + + diff = grid.rates - bestgrid.rates + + inaccuracy = np.sum(diff ** 2) + std_dev = (inaccuracy / size) ** 0.5 + rel_std_dev = std_dev / mean + # print("Beam with bins ",binset[i]," has total inaccuracy ",inaccuracy) + string = "{:.0f} {:.2E} {:.2E} {:.2E}".format( + binset[i], inaccuracy, std_dev, rel_std_dev + ) + acc.write(string + "\n") + name = ( + outdir + + "diff_beam_test_" + + survey.meta["BEAM"] + + "_nbins_" + + str(binset[i]) + + ".pdf" + ) + + plot_grid_2( + diff, + grid.zvals, + grid.dmvals, + zmax=zmax, + DMmax=DMmax, + name=name, + norm=0, + log=False, + label="$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]", + project=True, + ) + diff = diff / bestgrid.rates + nans = np.isnan(diff) + diff[nans] = 0.0 + name = ( + outdir + + "rel_diff_beam_test_" + + survey.meta["BEAM"] + + "_nbins_" + + str(binset[i]) + + ".pdf" + ) + plot_grid_2( + diff, + grid.zvals, + grid.dmvals, + zmax=zmax, + DMmax=DMmax, + name=name, + norm=0, + log=False, + label="$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]", + project=True, + ) + acc.close() -def initialise_grids(surveys: list, zDMgrid: np.ndarray, - zvals: np.ndarray, - dmvals: np.ndarray, state:parameters.State, - wdist=True): + +def initialise_grids( + surveys: list, + zDMgrid: np.ndarray, + zvals: np.ndarray, + dmvals: np.ndarray, + state: parameters.State, + wdist=True, +): """ For a list of surveys, construct a zDMgrid object wdist indicates a distribution of widths in the survey, i.e. do not use the mean efficiency @@ -1553,115 +1930,205 @@ def initialise_grids(surveys: list, zDMgrid: np.ndarray, Returns: list: list of Grid objects """ - if not isinstance(surveys,list): - surveys=[surveys] - + if not isinstance(surveys, list): + surveys = [surveys] + # generates a DM mask # creates a mask of values in DM space to convolve with the DM grid - mask=pcosmic.get_dm_mask( - dmvals,(state.host.lmean,state.host.lsigma), - zvals,plot=True) - grids=[] + mask = pcosmic.get_dm_mask( + dmvals, (state.host.lmean, state.host.lsigma), zvals, plot=True + ) + grids = [] for survey in surveys: print(f"Working on {survey.name}") - - grid=zdm_grid.Grid(survey, copy.deepcopy(state), - zDMgrid, zvals, dmvals, mask, wdist) + + grid = zdm_grid.Grid( + survey, copy.deepcopy(state), zDMgrid, zvals, dmvals, mask, wdist + ) grids.append(grid) - + return grids - + + def generate_example_plots(): """ Loads the lat50survey and generates some example plots """ - - #cos.set_cosmology(Omega_m=1.2) setup for cosmology + + # cos.set_cosmology(Omega_m=1.2) setup for cosmology cos.init_dist_measures() - - #parser.add_argument(", help + + # parser.add_argument(", help # get the grid of p(DM|z) - zDMgrid, zvals,dmvals=get_zdm_grid(new=False,plot=False,method='analytic') - pcosmic.plot_mean(zvals,'Plots/mean_DM.pdf') - - #load the lat50 survey data - lat50=survey.survey() - lat50.process_survey_file('Surveys/CRAFT_lat50.dat') - - efficiencies=lat50.get_efficiency(dmvals) + zDMgrid, zvals, dmvals = get_zdm_grid(new=False, plot=False, method="analytic") + pcosmic.plot_mean(zvals, "Plots/mean_DM.pdf") + + # load the lat50 survey data + lat50 = survey.survey() + lat50.process_survey_file("Surveys/CRAFT_lat50.dat") + + efficiencies = lat50.get_efficiency(dmvals) plot_efficiencies(lat50) - + # we now do the mean efficiency approximation - #mean_efficiencies=np.mean(efficiencies,axis=0) - #Fth=lat50.meta('THRESH') - + # mean_efficiencies=np.mean(efficiencies,axis=0) + # Fth=lat50.meta('THRESH') + # create a grid object - grid=zdm_grid.Grid() - grid.pass_grid(zDMgrid,zvals,dmvals) - + grid = zdm_grid.Grid() + grid.pass_grid(zDMgrid, zvals, dmvals) + # plots the grid of intrinsic p(DM|z) - plot_grid_2(grid.grid,grid.zvals,grid.dmvals,zmax=1,DMmax=1000,name='Plots/p_dm_z_grid_image.pdf',norm=1,log=True,label='$\\log_{10}p(DM_{\\rm EG}|z)$',conts=[0.16,0.5,0.88]) - + plot_grid_2( + grid.grid, + grid.zvals, + grid.dmvals, + zmax=1, + DMmax=1000, + name="Plots/p_dm_z_grid_image.pdf", + norm=1, + log=True, + label="$\\log_{10}p(DM_{\\rm EG}|z)$", + conts=[0.16, 0.5, 0.88], + ) + # creates a mask of values in DM space to convolve with the DM # grid # best-fit values-ish from green curves in fig 3 of cosmic dm paper - mean=125 - sigma=10**0.25 - logmean=np.log10(mean) - logsigma=np.log10(sigma) - mask=pcosmic.get_dm_mask(grid.dmvals,(logmean,logsigma),zvals,plot=True) - - grid.smear_dm(mask,logmean,logsigma) + mean = 125 + sigma = 10 ** 0.25 + logmean = np.log10(mean) + logsigma = np.log10(sigma) + mask = pcosmic.get_dm_mask(grid.dmvals, (logmean, logsigma), zvals, plot=True) + + grid.smear_dm(mask, logmean, logsigma) # plots the grid of intrinsic p(DM|z) - plot_grid_2(grid.smear_grid,grid.zvals,grid.dmvals,zmax=1,DMmax=1000,name='Plots/DMX_grid_image.pdf',norm=1,log=True,label='$\\log_{10}p(DM_{\\rm EG}|z)$') - #plot_grid_2(grid.smear_grid2,grid.zvals,grid.dmvals,zmax=1,DMmax=1000,name='DMX_grid_image2.pdf',norm=True,log=True,label='$\\log_{10}p(DM_{\\rm EG}|z)$') - + plot_grid_2( + grid.smear_grid, + grid.zvals, + grid.dmvals, + zmax=1, + DMmax=1000, + name="Plots/DMX_grid_image.pdf", + norm=1, + log=True, + label="$\\log_{10}p(DM_{\\rm EG}|z)$", + ) + # plot_grid_2(grid.smear_grid2,grid.zvals,grid.dmvals,zmax=1,DMmax=1000,name='DMX_grid_image2.pdf',norm=True,log=True,label='$\\log_{10}p(DM_{\\rm EG}|z)$') + # plots grid of effective thresholds - alpha=1.6 - grid.calc_thresholds(lat50.meta['THRESH'],lat50.mean_efficiencies,alpha=alpha) - plot_grid_2(grid.thresholds,grid.zvals,grid.dmvals,zmax=1,DMmax=1000,name='Plots/thresholds_dm_z_grid_image.pdf',norm=1,log=True,label='$\\log (E_{\\rm th})$ [erg]') - + alpha = 1.6 + grid.calc_thresholds(lat50.meta["THRESH"], lat50.mean_efficiencies, alpha=alpha) + plot_grid_2( + grid.thresholds, + grid.zvals, + grid.dmvals, + zmax=1, + DMmax=1000, + name="Plots/thresholds_dm_z_grid_image.pdf", + norm=1, + log=True, + label="$\\log (E_{\\rm th})$ [erg]", + ) + # calculates rates for given gamma etc - gamma=-0.7 - Emax=1e42 - Emin=1e30 + gamma = -0.7 + Emax = 1e42 + Emin = 1e30 grid.calc_dV() - - grid.calc_pdv(Emin,Emax,gamma) # calculates volumetric-weighted probabilities - grid.set_evolution(0) # sets star-formation rate scaling with z - here, no evoltion... - grid.calc_rates() # calculates rates by multiplying above with pdm plot - plot_grid_2(grid.pdv,grid.zvals,grid.dmvals,zmax=1,DMmax=1000,name='Plots/pdv.pdf',norm=True,log=True,label='$p(DM_{\\rm EG},z)dV$ [Mpc$^3$]') - plot_grid_2(grid.rates,grid.zvals,grid.dmvals,zmax=1,DMmax=1000,name='Plots/base_rate_dm_z_grid_image.pdf',norm=2,log=True,label='$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]') - plot_grid_2(grid.rates,grid.zvals,grid.dmvals,zmax=1,DMmax=1000,name='Plots/project_rate_dm_z_grid_image.pdf',norm=2,log=True,label='$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]',project=True) - - - it.calc_likelihoods_1D(grid.rates,grid.zvals,grid.dmvals,lat50.DMEGs) - plot_grid_2(grid.rates,grid.zvals,grid.dmvals,zmax=1,DMmax=1000,name='Plots/wFRB_project_rate.pdf',norm=2,log=True,label='$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]',project=True,FRBDM=lat50.DMEGs) - + + grid.calc_pdv(Emin, Emax, gamma) # calculates volumetric-weighted probabilities + grid.set_evolution( + 0 + ) # sets star-formation rate scaling with z - here, no evoltion... + grid.calc_rates() # calculates rates by multiplying above with pdm plot + plot_grid_2( + grid.pdv, + grid.zvals, + grid.dmvals, + zmax=1, + DMmax=1000, + name="Plots/pdv.pdf", + norm=True, + log=True, + label="$p(DM_{\\rm EG},z)dV$ [Mpc$^3$]", + ) + plot_grid_2( + grid.rates, + grid.zvals, + grid.dmvals, + zmax=1, + DMmax=1000, + name="Plots/base_rate_dm_z_grid_image.pdf", + norm=2, + log=True, + label="$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]", + ) + plot_grid_2( + grid.rates, + grid.zvals, + grid.dmvals, + zmax=1, + DMmax=1000, + name="Plots/project_rate_dm_z_grid_image.pdf", + norm=2, + log=True, + label="$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]", + project=True, + ) + + it.calc_likelihoods_1D(grid.rates, grid.zvals, grid.dmvals, lat50.DMEGs) + plot_grid_2( + grid.rates, + grid.zvals, + grid.dmvals, + zmax=1, + DMmax=1000, + name="Plots/wFRB_project_rate.pdf", + norm=2, + log=True, + label="$f(DM_{\\rm EG},z)p(DM_{\\rm EG},z)dV$ [Mpc$^3$]", + project=True, + FRBDM=lat50.DMEGs, + ) + ###### shows how to do a 1D scan of parameter values ####### - pset=it.set_defaults(grid) + pset = it.set_defaults(grid) it.print_pset(pset) # define set of values to scan over - lEmaxs=np.linspace(40,44,21) - likes=it.scan_likelihoods_1D(grid,pset,lat50,1,lEmaxs,norm=True) - plot_1d(lEmaxs,likes,'$E_{\\rm max}$','Plots/test_lik_fn_emax.pdf') - + lEmaxs = np.linspace(40, 44, 21) + likes = it.scan_likelihoods_1D(grid, pset, lat50, 1, lEmaxs, norm=True) + plot_1d(lEmaxs, likes, "$E_{\\rm max}$", "Plots/test_lik_fn_emax.pdf") + -def plot_1d(pvec,lset,xlabel,savename,showplot=False): +def plot_1d(pvec, lset, xlabel, savename, showplot=False): plt.figure() plt.xlabel(xlabel) - plt.ylabel('$\\ell($'+xlabel+'$)$') - plt.plot(pvec,lset) + plt.ylabel("$\\ell($" + xlabel + "$)$") + plt.plot(pvec, lset) plt.tight_layout() plt.savefig(savename) if showplot: plt.show() plt.close() - + + # generates grid based on Monte Carlo model -def get_zdm_grid(state:parameters.State, new=True, - plot=False,method='analytic', - nz=500,zmin=0.01,zmax=5,ndm=1400,dmmax=7000., - datdir='GridData',tag="", orig=False, - verbose=False, save=False, zlog=False): +def get_zdm_grid( + state: parameters.State, + new=True, + plot=False, + method="analytic", + nz=500, + zmin=0.01, + zmax=5, + ndm=1400, + dmmax=7000.0, + datdir="GridData", + tag="", + orig=False, + verbose=False, + save=False, + zlog=False, +): """Generate a grid of z vs. DM for an assumed F value for a specified z range and DM range. @@ -1696,248 +2163,334 @@ def get_zdm_grid(state:parameters.State, new=True, os.mkdir(datdir) except: pass - if method=='MC': - savefile=datdir+'/'+tag+'zdm_MC_grid_'+str(state.IGM.F)+'.npy' - datfile=datdir+'/'+tag+'zdm_MC_data_'+str(state.IGM.F)+'.npy' - zfile=datdir+'/'+tag+'zdm_MC_z_'+str(state.IGM.F)+'.npy' - dmfile=datdir+'/'+tag+'zdm_MC_dm_'+str(state.IGM.F)+'.npy' - elif method=='analytic': - savefile=datdir+'/'+tag+'zdm_A_grid_'+str(state.IGM.F)+'H0_'+str(state.cosmo.H0)+'.npy' - datfile=datdir+'/'+tag+'zdm_A_data_'+str(state.IGM.F)+'H0_'+str(state.cosmo.H0)+'.npy' - zfile=datdir+'/'+tag+'zdm_A_z_'+str(state.IGM.F)+'H0_'+str(state.cosmo.H0)+'.npy' - dmfile=datdir+'/'+tag+'zdm_A_dm_'+str(state.IGM.F)+'H0_'+str(state.cosmo.H0)+'.npy' - C0file=datdir+'/'+tag+'zdm_A_C0_'+str(state.IGM.F)+'H0_'+str(state.cosmo.H0)+'.npy' - #labelled pickled files with H0 + if method == "MC": + savefile = datdir + "/" + tag + "zdm_MC_grid_" + str(state.IGM.logF) + ".npy" + datfile = datdir + "/" + tag + "zdm_MC_data_" + str(state.IGM.logF) + ".npy" + zfile = datdir + "/" + tag + "zdm_MC_z_" + str(state.IGM.logF) + ".npy" + dmfile = datdir + "/" + tag + "zdm_MC_dm_" + str(state.IGM.logF) + ".npy" + elif method == "analytic": + savefile = ( + datdir + + "/" + + tag + + "zdm_A_grid_" + + str(state.IGM.logF) + + "H0_" + + str(state.cosmo.H0) + + ".npy" + ) + datfile = ( + datdir + + "/" + + tag + + "zdm_A_data_" + + str(state.IGM.logF) + + "H0_" + + str(state.cosmo.H0) + + ".npy" + ) + zfile = ( + datdir + + "/" + + tag + + "zdm_A_z_" + + str(state.IGM.logF) + + "H0_" + + str(state.cosmo.H0) + + ".npy" + ) + dmfile = ( + datdir + + "/" + + tag + + "zdm_A_dm_" + + str(state.IGM.logF) + + "H0_" + + str(state.cosmo.H0) + + ".npy" + ) + C0file = ( + datdir + + "/" + + tag + + "zdm_A_C0_" + + str(state.IGM.logF) + + "H0_" + + str(state.cosmo.H0) + + ".npy" + ) + # labelled pickled files with H0 if new: - - ddm=dmmax/ndm - + + ddm = dmmax / ndm + if zlog: # generates a pseudo-log spacing # grid values increase with \sqrt(log) - lzmax=np.log10(zmax) - lzmin=np.log10(zmin) - zvals=np.logspace(lzmin,lzmax,nz) + lzmax = np.log10(zmax) + lzmin = np.log10(zmin) + zvals = np.logspace(lzmin, lzmax, nz) else: - dz=zmax/nz - zvals=(np.arange(nz)+1)*dz - dmvals=(np.arange(ndm)+1)*ddm - - dmmeans=dmvals[1:] - (dmvals[1]-dmvals[0])/2. - zdmgrid=np.zeros([nz,ndm]) - - if method=='MC': + dz = zmax / nz + zvals = (np.arange(nz) + 1) * dz + dmvals = (np.arange(ndm) + 1) * ddm + + dmmeans = dmvals[1:] - (dmvals[1] - dmvals[0]) / 2.0 + zdmgrid = np.zeros([nz, ndm]) + + if method == "MC": # generate DM grid from the models if verbose: print("Generating the zdm Monte Carlo grid") - nfrb=10000 - t0=time.process_time() - DMs = dlas.monte_DM(np.array(zvals)*3000, nrand=nfrb) - #DMs *= 200000 #seems to be a good fit... - t1=time.process_time() - dt=t1-t0 - hists=[] - for i,z in enumerate(zvals): - hist,bins=np.histogram(DMs[:,i],bins=dmvals) + nfrb = 10000 + t0 = time.process_time() + DMs = dlas.monte_DM(np.array(zvals) * 3000, nrand=nfrb) + # DMs *= 200000 #seems to be a good fit... + t1 = time.process_time() + dt = t1 - t0 + hists = [] + for i, z in enumerate(zvals): + hist, bins = np.histogram(DMs[:, i], bins=dmvals) hists.append(hist) - all_hists=np.array(hists) - elif method=='analytic': + all_hists = np.array(hists) + elif method == "analytic": if verbose: print("Generating the zdm analytic grid") - t0=time.process_time() + t0 = time.process_time() # calculate constants for p_DM distribution if orig: - C0s=pcosmic.make_C0_grid(zvals,state.IGM.F) + C0s = pcosmic.make_C0_grid(zvals, state.IGM.logF) else: f_C0_3 = cosmic.grab_C0_spline() - sigma = state.IGM.F / np.sqrt(zvals) + actual_F = 10 ** (state.IGM.logF) + sigma = actual_F / np.sqrt(zvals) C0s = f_C0_3(sigma) # generate pDM grid using those COs - zDMgrid=pcosmic.get_pDM_grid(state,dmvals,zvals,C0s,zlog=zlog) - - metadata=np.array([nz,ndm,state.IGM.F]) + zDMgrid = pcosmic.get_pDM_grid(state, dmvals, zvals, C0s, zlog=zlog) + + metadata = np.array([nz, ndm, state.IGM.logF]) if save: - np.save(savefile,zDMgrid) - np.save(datfile,metadata) - np.save(zfile,zvals) - np.save(dmfile,dmvals) + np.save(savefile, zDMgrid) + np.save(datfile, metadata) + np.save(zfile, zvals) + np.save(dmfile, dmvals) else: - zDMgrid=np.load(savefile) - zvals=np.load(zfile) - dmvals=np.load(dmfile) - metadata=np.load(datfile) - nz,ndm,F=metadata - + zDMgrid = np.load(savefile) + zvals = np.load(zfile) + dmvals = np.load(dmfile) + metadata = np.load(datfile) + nz, ndm, F = metadata + if plot: plt.figure() - plt.xlabel('DM_{\\rm EG} [pc cm$^{-3}$]') - plt.ylabel('p(DM_{\\rm EG})') - - nplot=int(zvals.size/10) - for i,z in enumerate(zvals): - if i%nplot==0: - plt.plot(dmvals,zDMgrid[i,:],label='z='+str(z)[0:4]) + plt.xlabel("DM_{\\rm EG} [pc cm$^{-3}$]") + plt.ylabel("p(DM_{\\rm EG})") + + nplot = int(zvals.size / 10) + for i, z in enumerate(zvals): + if i % nplot == 0: + plt.plot(dmvals, zDMgrid[i, :], label="z=" + str(z)[0:4]) plt.legend() plt.tight_layout() - plt.savefig('p_dm_slices.pdf') + plt.savefig("p_dm_slices.pdf") plt.close() - - return zDMgrid, zvals,dmvals -def plot_zdm_basic_paper(zDMgrid,zvals,dmvals,zmax=1,DMmax=1000, - norm=0,log=True,name='temp.pdf',ylabel=None, - label='$\\log_{10}p(DM_{\\rm EG},z)$',project=False,conts=False,FRBZ=None, - FRBDM=None,title='Plot',H0=None,showplot=False): - ''' Plots basic distributions of z and dm for the paper ''' + return zDMgrid, zvals, dmvals + + +def plot_zdm_basic_paper( + zDMgrid, + zvals, + dmvals, + zmax=1, + DMmax=1000, + norm=0, + log=True, + name="temp.pdf", + ylabel=None, + label="$\\log_{10}p(DM_{\\rm EG},z)$", + project=False, + conts=False, + FRBZ=None, + FRBDM=None, + title="Plot", + H0=None, + showplot=False, +): + """ Plots basic distributions of z and dm for the paper """ if H0 is None: H0 = cos.cosmo.H0 - cmx = plt.get_cmap('cubehelix') - + cmx = plt.get_cmap("cubehelix") + ##### imshow of grid ####### - + # we protect these variables - zDMgrid=np.copy(zDMgrid) - zvals=np.copy(zvals) - dmvals=np.copy(dmvals) - + zDMgrid = np.copy(zDMgrid) + zvals = np.copy(zvals) + dmvals = np.copy(dmvals) + plt.figure() - #rect_2D=[0,0,1,1] - ax1=plt.axes() - + # rect_2D=[0,0,1,1] + ax1 = plt.axes() + plt.sca(ax1) - - plt.xlabel('z') + + plt.xlabel("z") if ylabel is not None: plt.ylabel(ylabel) else: - plt.ylabel('${\\rm DM}_{\\rm EG}$') - - nz,ndm=zDMgrid.shape - - - ixmax=np.where(zvals > zmax)[0] - if len(ixmax) >0: - zvals=zvals[:ixmax[0]] - nz=zvals.size - zDMgrid=zDMgrid[:ixmax[0],:] - + plt.ylabel("${\\rm DM}_{\\rm EG}$") + + nz, ndm = zDMgrid.shape + + ixmax = np.where(zvals > zmax)[0] + if len(ixmax) > 0: + zvals = zvals[: ixmax[0]] + nz = zvals.size + zDMgrid = zDMgrid[: ixmax[0], :] + ### generates contours *before* cutting array in DM ### ### might need to normalise contours by integer lengths, oh well! ### if conts: nc = len(conts) - carray=np.zeros([nc,nz]) + carray = np.zeros([nc, nz]) for i in np.arange(nz): - cdf=np.cumsum(zDMgrid[i,:]) + cdf = np.cumsum(zDMgrid[i, :]) cdf /= cdf[-1] - - for j,c in enumerate(conts): - less=np.where(cdf < c)[0] - - if len(less)==0: - carray[j,i]=0. - dmc=0. - il1=0 - il2=0 + + for j, c in enumerate(conts): + less = np.where(cdf < c)[0] + + if len(less) == 0: + carray[j, i] = 0.0 + dmc = 0.0 + il1 = 0 + il2 = 0 else: - il1=less[-1] - - if il1 == ndm-1: - il1=ndm-2 - - il2=il1+1 - k1=(cdf[il2]-c)/(cdf[il2]-cdf[il1]) - dmc=k1*dmvals[il1]+(1.-k1)*dmvals[il2] - carray[j,i]=dmc - - ddm=dmvals[1]-dmvals[0] - carray /= ddm # turns this into integer units for plotting - - iymax=np.where(dmvals > DMmax)[0] - if len(iymax)>0: - dmvals=dmvals[:iymax[0]] - zDMgrid=zDMgrid[:,:iymax[0]] - ndm=dmvals.size - + il1 = less[-1] + + if il1 == ndm - 1: + il1 = ndm - 2 + + il2 = il1 + 1 + k1 = (cdf[il2] - c) / (cdf[il2] - cdf[il1]) + dmc = k1 * dmvals[il1] + (1.0 - k1) * dmvals[il2] + carray[j, i] = dmc + + ddm = dmvals[1] - dmvals[0] + carray /= ddm # turns this into integer units for plotting + + iymax = np.where(dmvals > DMmax)[0] + if len(iymax) > 0: + dmvals = dmvals[: iymax[0]] + zDMgrid = zDMgrid[:, : iymax[0]] + ndm = dmvals.size + # currently this is "per cell" - now to change to "per DM" # normalises the grid by the bin width, i.e. probability per bin, not probability density - ddm=dmvals[1]-dmvals[0] - dz=zvals[1]-zvals[0] - - zDMgrid /= ddm # norm=1 - + ddm = dmvals[1] - dmvals[0] + dz = zvals[1] - zvals[0] + + zDMgrid /= ddm # norm=1 + # checks against zeros for a log-plot - orig=np.copy(zDMgrid) - zDMgrid=zDMgrid.reshape(zDMgrid.size) - setzero=np.where(zDMgrid==0.) - zDMgrid=np.log10(zDMgrid) - zDMgrid[setzero]=-100 - zDMgrid=zDMgrid.reshape(nz,ndm) - + orig = np.copy(zDMgrid) + zDMgrid = zDMgrid.reshape(zDMgrid.size) + setzero = np.where(zDMgrid == 0.0) + zDMgrid = np.log10(zDMgrid) + zDMgrid[setzero] = -100 + zDMgrid = zDMgrid.reshape(nz, ndm) + # gets a square plot - aspect=nz/float(ndm) - - # sets the x and y tics - xtvals=np.arange(zvals.size) - everx=int(zvals.size/5) - plt.xticks(xtvals[everx-1::everx],zvals[everx-1::everx]) - - ytvals=np.arange(dmvals.size) - every=int(dmvals.size/5) - plt.yticks(ytvals[every-1::every],dmvals[every-1::every]) - - im=plt.imshow(zDMgrid.T,cmap=cmx,origin='lower', interpolation='None',aspect=aspect) - + aspect = nz / float(ndm) + + # sets the x and y tics + xtvals = np.arange(zvals.size) + everx = int(zvals.size / 5) + plt.xticks(xtvals[everx - 1 :: everx], zvals[everx - 1 :: everx]) + + ytvals = np.arange(dmvals.size) + every = int(dmvals.size / 5) + plt.yticks(ytvals[every - 1 :: every], dmvals[every - 1 :: every]) + + im = plt.imshow( + zDMgrid.T, cmap=cmx, origin="lower", interpolation="None", aspect=aspect + ) + ###### gets decent axis labels, down to 1 decimal place ####### - ax=plt.gca() + ax = plt.gca() labels = [item.get_text() for item in ax.get_xticklabels()] for i in np.arange(len(labels)): - labels[i]=labels[i][0:4] + labels[i] = labels[i][0:4] ax.set_xticklabels(labels) labels = [item.get_text() for item in ax.get_yticklabels()] for i in np.arange(len(labels)): - if '.' in labels[i]: - labels[i]=labels[i].split('.')[0] + if "." in labels[i]: + labels[i] = labels[i].split(".")[0] ax.set_yticklabels(labels) ax.yaxis.labelpad = 0 - + # plots contours i there - cls=[":","--","-","--",":"] + cls = [":", "--", "-", "--", ":"] if conts: - plt.ylim(0,ndm-1) + plt.ylim(0, ndm - 1) for i in np.arange(nc): - j=int(nc-i-1) - plt.plot(np.arange(nz),carray[j,:],label=str(conts[j]),color='white',linestyle=cls[i]) - l=plt.legend(loc='lower right',fontsize=12) - #l=plt.legend(bbox_to_anchor=(0.2, 0.8),fontsize=8) + j = int(nc - i - 1) + plt.plot( + np.arange(nz), + carray[j, :], + label=str(conts[j]), + color="white", + linestyle=cls[i], + ) + l = plt.legend(loc="lower right", fontsize=12) + # l=plt.legend(bbox_to_anchor=(0.2, 0.8),fontsize=8) for text in l.get_texts(): - text.set_color("white") - - + text.set_color("white") + # limit to a reasonable range if logscale - themax=zDMgrid.max() - themin=int(themax-4) - themax=int(themax) - plt.clim(themin,themax) - - cbar=plt.colorbar(im,fraction=0.046, shrink=1.2,aspect=15,pad=0.05) + themax = zDMgrid.max() + themin = int(themax - 4) + themax = int(themax) + plt.clim(themin, themax) + + cbar = plt.colorbar(im, fraction=0.046, shrink=1.2, aspect=15, pad=0.05) cbar.set_label(label) - plt.clim(-4,0) + plt.clim(-4, 0) plt.tight_layout() - + plt.savefig(name) - plt.title(title+str(H0)) + plt.title(title + str(H0)) if showplot: plt.show() - plt.close() - -def plot_grid_2(zDMgrid,zvals,dmvals, - zmax=1,DMmax=1000,norm=0,log=True,name='temp.pdf', - label='$\\log_{10}p(DM_{\\rm EG},z)$',ylabel='${\\rm DM}_{\\rm EG}$', - project=False,conts=False, - FRBZ=None,FRBDM=None,Aconts=False, - Macquart=None,title="Plot", cmap=None, - H0=None,showplot=False,DMlines=None, - data_clr='red',special=None): + plt.close() + + +def plot_grid_2( + zDMgrid, + zvals, + dmvals, + zmax=1, + DMmax=1000, + norm=0, + log=True, + name="temp.pdf", + label="$\\log_{10}p(DM_{\\rm EG},z)$", + ylabel="${\\rm DM}_{\\rm EG}$", + project=False, + conts=False, + FRBZ=None, + FRBDM=None, + Aconts=False, + Macquart=None, + title="Plot", + cmap=None, + H0=None, + showplot=False, + DMlines=None, + data_clr="red", + special=None, +): """ Very complicated routine for plotting 2D zdm grids @@ -1969,83 +2522,82 @@ def plot_grid_2(zDMgrid,zvals,dmvals, if H0 is None: H0 = cos.cosmo.H0 if cmap is None: - cmx = plt.get_cmap('cubehelix') + cmx = plt.get_cmap("cubehelix") else: cmx = plt.get_cmap(cmap) - + ##### imshow of grid ####### - + # we protect these variables - zDMgrid=np.copy(zDMgrid) - zvals=np.copy(zvals) - dmvals=np.copy(dmvals) - - if (project): + zDMgrid = np.copy(zDMgrid) + zvals = np.copy(zvals) + dmvals = np.copy(dmvals) + + if project: plt.figure(1, figsize=(8, 8)) left, width = 0.1, 0.65 bottom, height = 0.1, 0.65 - gap=0.02 - woff=width+gap+left - hoff=height+gap+bottom - dw=1.-woff-gap - dh=1.-hoff-gap - - delta=1-height-bottom-0.05 - gap=0.11 + gap = 0.02 + woff = width + gap + left + hoff = height + gap + bottom + dw = 1.0 - woff - gap + dh = 1.0 - hoff - gap + + delta = 1 - height - bottom - 0.05 + gap = 0.11 rect_2D = [left, bottom, width, height] rect_1Dx = [left, hoff, width, dh] rect_1Dy = [woff, bottom, dw, height] - rect_cb = [woff,hoff,dw*0.5,dh] - ax1=plt.axes(rect_2D) - axx=plt.axes(rect_1Dx) - axy=plt.axes(rect_1Dy) - acb=plt.axes(rect_cb) - #axx.xaxis.set_major_formatter(NullFormatter()) - #axy.yaxis.set_major_formatter(NullFormatter()) + rect_cb = [woff, hoff, dw * 0.5, dh] + ax1 = plt.axes(rect_2D) + axx = plt.axes(rect_1Dx) + axy = plt.axes(rect_1Dy) + acb = plt.axes(rect_cb) + # axx.xaxis.set_major_formatter(NullFormatter()) + # axy.yaxis.set_major_formatter(NullFormatter()) else: plt.figure() - #rect_2D=[0,0,1,1] - ax1=plt.axes() - + # rect_2D=[0,0,1,1] + ax1 = plt.axes() + plt.sca(ax1) - - plt.xlabel('z') + + plt.xlabel("z") plt.ylabel(ylabel) - #plt.title(title+str(H0)) # I have removed this default title, use a file naming convention instead - - nz,ndm=zDMgrid.shape - - - ixmax=np.where(zvals > zmax)[0] - if len(ixmax) >0: - zvals=zvals[:ixmax[0]] - nz=zvals.size - zDMgrid=zDMgrid[:ixmax[0],:] - + # plt.title(title+str(H0)) # I have removed this default title, use a file naming convention instead + + nz, ndm = zDMgrid.shape + + ixmax = np.where(zvals > zmax)[0] + if len(ixmax) > 0: + zvals = zvals[: ixmax[0]] + nz = zvals.size + zDMgrid = zDMgrid[: ixmax[0], :] + # currently this is "per cell" - now to change to "per DM" # normalises the grid by the bin width, i.e. probability per bin, not probability density - ddm=dmvals[1]-dmvals[0] - dz=zvals[1]-zvals[0] - if norm==1: + ddm = dmvals[1] - dmvals[0] + dz = zvals[1] - zvals[0] + if norm == 1: zDMgrid /= ddm - #if Aconts: + # if Aconts: # alevels /= ddm - elif norm==2: - xnorm=np.sum(zDMgrid) + elif norm == 2: + xnorm = np.sum(zDMgrid) zDMgrid /= xnorm - #if Aconts: + # if Aconts: # alevels /= xnorm - elif norm==3: + elif norm == 3: zDMgrid /= np.max(zDMgrid) - + # sets contours according to norm if Aconts: - slist=np.sort(zDMgrid.flatten()) - cslist=np.cumsum(slist) + slist = np.sort(zDMgrid.flatten()) + cslist = np.cumsum(slist) cslist /= cslist[-1] - nAc=len(Aconts) - alevels=np.zeros([nAc]) - for i,ac in enumerate(Aconts): + nAc = len(Aconts) + alevels = np.zeros([nAc]) + for i, ac in enumerate(Aconts): # cslist is the cumulative probability distribution # Where cslist > ac determines the integer locations # of all cells exceeding the threshold @@ -2053,316 +2605,342 @@ def plot_grid_2(zDMgrid,zvals,dmvals, # the threshold # The value of slist at that point is the # level of the countour to draw - iwhich=np.where(cslist > ac)[0][0] - alevels[i]=slist[iwhich] - + iwhich = np.where(cslist > ac)[0][0] + alevels[i] = slist[iwhich] + if norm == 1: alevels /= ddm elif norm == 2: alevels /= xnorm - + ### generates contours *before* cutting array in DM ### ### might need to normalise contours by integer lengths, oh well! ### if conts: nc = len(conts) - carray=np.zeros([nc,nz]) + carray = np.zeros([nc, nz]) for i in np.arange(nz): - cdf=np.cumsum(zDMgrid[i,:]) + cdf = np.cumsum(zDMgrid[i, :]) cdf /= cdf[-1] - - for j,c in enumerate(conts): - less=np.where(cdf < c)[0] - - if len(less)==0: - carray[j,i]=0. - dmc=0. - il1=0 - il2=0 + + for j, c in enumerate(conts): + less = np.where(cdf < c)[0] + + if len(less) == 0: + carray[j, i] = 0.0 + dmc = 0.0 + il1 = 0 + il2 = 0 else: - il1=less[-1] - - if il1 == ndm-1: - il1=ndm-2 - - il2=il1+1 - k1=(cdf[il2]-c)/(cdf[il2]-cdf[il1]) - dmc=k1*dmvals[il1]+(1.-k1)*dmvals[il2] - carray[j,i]=dmc - - ddm=dmvals[1]-dmvals[0] - carray /= ddm # turns this into integer units for plotting - - iymax=np.where(dmvals > DMmax)[0] - if len(iymax)>0: - dmvals=dmvals[:iymax[0]] - zDMgrid=zDMgrid[:,:iymax[0]] - ndm=dmvals.size - + il1 = less[-1] + + if il1 == ndm - 1: + il1 = ndm - 2 + + il2 = il1 + 1 + k1 = (cdf[il2] - c) / (cdf[il2] - cdf[il1]) + dmc = k1 * dmvals[il1] + (1.0 - k1) * dmvals[il2] + carray[j, i] = dmc + + ddm = dmvals[1] - dmvals[0] + carray /= ddm # turns this into integer units for plotting + + iymax = np.where(dmvals > DMmax)[0] + if len(iymax) > 0: + dmvals = dmvals[: iymax[0]] + zDMgrid = zDMgrid[:, : iymax[0]] + ndm = dmvals.size + if log: # checks against zeros for a log-plot - orig=np.copy(zDMgrid) - zDMgrid=zDMgrid.reshape(zDMgrid.size) - setzero=np.where(zDMgrid==0.) - zDMgrid=np.log10(zDMgrid) - zDMgrid[setzero]=-100 - zDMgrid=zDMgrid.reshape(nz,ndm) + orig = np.copy(zDMgrid) + zDMgrid = zDMgrid.reshape(zDMgrid.size) + setzero = np.where(zDMgrid == 0.0) + zDMgrid = np.log10(zDMgrid) + zDMgrid[setzero] = -100 + zDMgrid = zDMgrid.reshape(nz, ndm) if Aconts: - alevels=np.log10(alevels) + alevels = np.log10(alevels) else: - orig=zDMgrid - + orig = zDMgrid + # gets a square plot - aspect=nz/float(ndm) - - # sets the x and y tics - xtvals=np.arange(zvals.size) - everx=int(zvals.size/5) - plt.xticks(xtvals[everx-1::everx],zvals[everx-1::everx]) - - ytvals=np.arange(dmvals.size) - every=int(dmvals.size/5) - plt.yticks(ytvals[every-1::every],dmvals[every-1::every]) - - im=plt.imshow(zDMgrid.T,cmap=cmx,origin='lower', interpolation='None',aspect=aspect) - + aspect = nz / float(ndm) + + # sets the x and y tics + xtvals = np.arange(zvals.size) + everx = int(zvals.size / 5) + plt.xticks(xtvals[everx - 1 :: everx], zvals[everx - 1 :: everx]) + + ytvals = np.arange(dmvals.size) + every = int(dmvals.size / 5) + plt.yticks(ytvals[every - 1 :: every], dmvals[every - 1 :: every]) + + im = plt.imshow( + zDMgrid.T, cmap=cmx, origin="lower", interpolation="None", aspect=aspect + ) + if Aconts: - styles=['--','-.',':'] - ax=plt.gca() - cs=ax.contour(zDMgrid.T,levels=alevels,origin='lower',colors="white",linestyles=styles) - #plt.clim(0,2e-5) - #ax.clabel(cs, cs.levels, inline=True, fontsize=10,fmt=['0.5','0.1','0.01']) + styles = ["--", "-.", ":"] + ax = plt.gca() + cs = ax.contour( + zDMgrid.T, levels=alevels, origin="lower", colors="white", linestyles=styles + ) + # plt.clim(0,2e-5) + # ax.clabel(cs, cs.levels, inline=True, fontsize=10,fmt=['0.5','0.1','0.01']) ###### gets decent axis labels, down to 1 decimal place ####### - ax=plt.gca() + ax = plt.gca() labels = [item.get_text() for item in ax.get_xticklabels()] for i in np.arange(len(labels)): - labels[i]=labels[i][0:4] + labels[i] = labels[i][0:4] ax.set_xticklabels(labels) labels = [item.get_text() for item in ax.get_yticklabels()] for i in np.arange(len(labels)): - if '.' in labels[i]: - labels[i]=labels[i].split('.')[0] + if "." in labels[i]: + labels[i] = labels[i].split(".")[0] ax.set_yticklabels(labels) ax.yaxis.labelpad = 0 - + # draw horizontal lines for a fixed DM if DMlines is not None: if log: - tempgrid=np.copy(zDMgrid) + tempgrid = np.copy(zDMgrid) tempgrid = zDMgrid - np.max(zDMgrid) - tempgrid = 10.**zDMgrid + tempgrid = 10.0 ** zDMgrid else: - tempgrid=zDMgrid + tempgrid = zDMgrid for DM in DMlines: - if DM>np.max(dmvals): - print("Cannot draw DM line ",DM," - range ",np.max(dmvals)," too small...") + if DM > np.max(dmvals): + print( + "Cannot draw DM line ", + DM, + " - range ", + np.max(dmvals), + " too small...", + ) continue # determines how far to draw line - iDM2=np.where(dmvals > DM)[0][0] # lowest value - iDM1=iDM2-1 - kDM=(DM-dmvals[iDM1])/(dmvals[iDM2]-dmvals[iDM1]) - cDM1=np.cumsum(tempgrid[:,iDM1]) + iDM2 = np.where(dmvals > DM)[0][0] # lowest value + iDM1 = iDM2 - 1 + kDM = (DM - dmvals[iDM1]) / (dmvals[iDM2] - dmvals[iDM1]) + cDM1 = np.cumsum(tempgrid[:, iDM1]) cDM1 /= cDM1[-1] - cDM2=np.cumsum(tempgrid[:,iDM2]) + cDM2 = np.cumsum(tempgrid[:, iDM2]) cDM2 /= cDM2[-1] - stop1=np.where(cDM1 < 0.99)[0][-1] - stop2=np.where(cDM2 < 0.99)[0][-1] - zstop = kDM*zvals[stop2] + (1.-kDM)*zvals[stop1] - zstop /= (zvals[1]-zvals[0]) - DM /= (dmvals[1]-dmvals[0]) - plt.plot([0,zstop],[DM,DM],color=data_clr, linestyle=':') - + stop1 = np.where(cDM1 < 0.99)[0][-1] + stop2 = np.where(cDM2 < 0.99)[0][-1] + zstop = kDM * zvals[stop2] + (1.0 - kDM) * zvals[stop1] + zstop /= zvals[1] - zvals[0] + DM /= dmvals[1] - dmvals[0] + plt.plot([0, zstop], [DM, DM], color=data_clr, linestyle=":") + # plots contours i there if conts: - plt.ylim(0,ndm-1) + plt.ylim(0, ndm - 1) for i in np.arange(nc): - j=int(nc-i-1) - plt.plot(np.arange(nz),carray[j,:],label=str(conts[j]),color='white') - l=plt.legend(loc='upper left',fontsize=8) - #l=plt.legend(bbox_to_anchor=(0.2, 0.8),fontsize=8) + j = int(nc - i - 1) + plt.plot(np.arange(nz), carray[j, :], label=str(conts[j]), color="white") + l = plt.legend(loc="upper left", fontsize=8) + # l=plt.legend(bbox_to_anchor=(0.2, 0.8),fontsize=8) for text in l.get_texts(): - text.set_color("white") + text.set_color("white") if Macquart is not None: # Note this is the Median for the lognormal, not the mean - muDMhost=np.log(10**Macquart.host.lmean) - sigmaDMhost=np.log(10**Macquart.host.lsigma) - meanHost = np.exp(muDMhost + sigmaDMhost**2/2.) - medianHost = np.exp(muDMhost) - #print(f"Host: mean={meanHost}, median={medianHost}") - plt.ylim(0,ndm-1) - plt.xlim(0,nz-1) - zmax=zvals[-1] - nz=zvals.size - #DMbar, zeval = igm.average_DM(zmax, cumul=True, neval=nz+1) + muDMhost = np.log(10 ** Macquart.host.lmean) + sigmaDMhost = np.log(10 ** Macquart.host.lsigma) + meanHost = np.exp(muDMhost + sigmaDMhost ** 2 / 2.0) + medianHost = np.exp(muDMhost) + # print(f"Host: mean={meanHost}, median={medianHost}") + plt.ylim(0, ndm - 1) + plt.xlim(0, nz - 1) + zmax = zvals[-1] + nz = zvals.size + # DMbar, zeval = igm.average_DM(zmax, cumul=True, neval=nz+1) DM_cosmic = pcosmic.get_mean_DM(zvals, Macquart) - - #idea is that 1 point is 1, hence... - zeval = zvals/dz - DMEG_mean = (DM_cosmic+meanHost)/ddm - DMEG_median = (DM_cosmic+medianHost)/ddm - plt.plot(zeval,DMEG_mean,color='blue',linewidth=2, - label='Macquart relation (mean)') + + # idea is that 1 point is 1, hence... + zeval = zvals / dz + DMEG_mean = (DM_cosmic + meanHost) / ddm + DMEG_median = (DM_cosmic + medianHost) / ddm + plt.plot( + zeval, + DMEG_mean, + color="blue", + linewidth=2, + label="Macquart relation (mean)", + ) # removed median, because it is only media of HOST not DM cosmic - #plt.plot(zeval,DMEG_median,color='blue', + # plt.plot(zeval,DMEG_median,color='blue', # linewidth=2, ls='--', # label='Macquart relation (median)') - l=plt.legend(loc='lower right',fontsize=12) - #l=plt.legend(bbox_to_anchor=(0.2, 0.8),fontsize=8) - #for text in l.get_texts(): - # text.set_color("white") - + l = plt.legend(loc="lower right", fontsize=12) + # l=plt.legend(bbox_to_anchor=(0.2, 0.8),fontsize=8) + # for text in l.get_texts(): + # text.set_color("white") + # limit to a reasonable range if logscale if log: - themax=np.nanmax(zDMgrid) - themin=int(themax-4) - themax=int(themax) - plt.clim(themin,themax) - + themax = np.nanmax(zDMgrid) + themin = int(themax - 4) + themax = int(themax) + plt.clim(themin, themax) + ##### add FRB host galaxies at some DM/redshift ##### if FRBZ is not None: - iDMs=FRBDM/ddm - iZ=FRBZ/dz - OK = np.where(FRBZ>0)[0] - plt.plot(iZ[OK],iDMs[OK],'o', color=data_clr, linestyle="") - + iDMs = FRBDM / ddm + iZ = FRBZ / dz + OK = np.where(FRBZ > 0)[0] + plt.plot(iZ[OK], iDMs[OK], "o", color=data_clr, linestyle="") + if special is not None: - iDM=special[0]/ddm - iz=special[1]/dz - plt.plot([iz],[iDM],'*', markersize=10,color="blue", linestyle="") - + iDM = special[0] / ddm + iz = special[1] / dz + plt.plot([iz], [iDM], "*", markersize=10, color="blue", linestyle="") + # do 1-D projected plots if project: plt.sca(acb) - cbar=plt.colorbar(im,fraction=0.046, shrink=1.2,aspect=20,pad=0.00,cax = acb) + cbar = plt.colorbar( + im, fraction=0.046, shrink=1.2, aspect=20, pad=0.00, cax=acb + ) cbar.ax.tick_params(labelsize=6) - cbar.set_label(label,fontsize=8) - + cbar.set_label(label, fontsize=8) + axy.set_yticklabels([]) - #axy.set_xticklabels([]) - #axx.set_yticklabels([]) + # axy.set_xticklabels([]) + # axx.set_yticklabels([]) axx.set_xticklabels([]) - yonly=np.sum(orig,axis=0) - xonly=np.sum(orig,axis=1) - - axy.plot(yonly,dmvals) # DM is the vertical axis now - axx.plot(zvals,xonly) - + yonly = np.sum(orig, axis=0) + xonly = np.sum(orig, axis=1) + + axy.plot(yonly, dmvals) # DM is the vertical axis now + axx.plot(zvals, xonly) + # if plotting DM only, put this on the axy axis showing DM distribution if FRBDM is not None: - hvals=np.zeros(FRBDM.size) - for i,DM in enumerate(FRBDM): - hvals[i]=yonly[np.where(dmvals > DM)[0][0]] - - axy.plot(hvals,FRBDM,'ro',linestyle="") + hvals = np.zeros(FRBDM.size) + for i, DM in enumerate(FRBDM): + hvals[i] = yonly[np.where(dmvals > DM)[0][0]] + + axy.plot(hvals, FRBDM, "ro", linestyle="") for tick in axy.yaxis.get_major_ticks(): - tick.label.set_fontsize(6) - + tick.label.set_fontsize(6) + if FRBZ is not None: - OK = np.where(FRBZ>0)[0] - hvals=np.zeros(FRBZ[OK].size) - for i,Z in enumerate(FRBZ[OK]): - hvals[i]=xonly[np.where(zvals > Z)[0][0]] - axx.plot(FRBZ[OK],hvals,'o', color=data_clr, linestyle="") + OK = np.where(FRBZ > 0)[0] + hvals = np.zeros(FRBZ[OK].size) + for i, Z in enumerate(FRBZ[OK]): + hvals[i] = xonly[np.where(zvals > Z)[0][0]] + axx.plot(FRBZ[OK], hvals, "o", color=data_clr, linestyle="") for tick in axx.xaxis.get_major_ticks(): - tick.label.set_fontsize(6) + tick.label.set_fontsize(6) else: - cbar=plt.colorbar(im,fraction=0.046, shrink=1.2,aspect=15,pad=0.05) + cbar = plt.colorbar(im, fraction=0.046, shrink=1.2, aspect=15, pad=0.05) cbar.set_label(label) plt.tight_layout() - + plt.savefig(name, dpi=300) if showplot: plt.show() plt.close() -def plot_grid(grid,zvals,dmvals,showplot=False): - ''' Plots a simple 2D grid ''' - cmx = plt.get_cmap('cubehelix') - + +def plot_grid(grid, zvals, dmvals, showplot=False): + """ Plots a simple 2D grid """ + cmx = plt.get_cmap("cubehelix") + plt.figure() - plt.zlabel('z') - plt.ylabel('DM_{\\rm EG}') - - plt.xtics(np.arange(zvals.size)[::10],zvals[::10]) - plt.ytics(np.arange(dmvals.size)[::10],dmvals[::10]) - plt.imshow(grid,extent=(zvals[0],zvals[-1],dmvals[0],dmvals[-1]),origin='lower',cmap=cmx) - cbar=plt.colorbar() - cbar.set_label('$p(DM_{\\rm EG}|z)') + plt.zlabel("z") + plt.ylabel("DM_{\\rm EG}") + + plt.xtics(np.arange(zvals.size)[::10], zvals[::10]) + plt.ytics(np.arange(dmvals.size)[::10], dmvals[::10]) + plt.imshow( + grid, + extent=(zvals[0], zvals[-1], dmvals[0], dmvals[-1]), + origin="lower", + cmap=cmx, + ) + cbar = plt.colorbar() + cbar.set_label("$p(DM_{\\rm EG}|z)") if showplot: plt.show() -def plot_efficiencies_paper(survey,savename,label): - ''' Plots a final version of efficiencies for the purpose of the paper ''' - dm=survey.DMlist - eff1s=survey.get_efficiency(dm,model="Quadrature",dsmear=True) - eff1mean=np.copy(survey.mean_efficiencies) - eff2s=survey.get_efficiency(dm,model="Sammons",dsmear=True) - eff2mean=np.copy(survey.mean_efficiencies) - DMobs=survey.DMs - NDM=DMobs.size - DMx=np.zeros([NDM]) - DMy=np.zeros([NDM]) - for i,DMo in enumerate(DMobs): - pos=np.where(dm > DMo)[0][0] - DMy[i]=eff1s[i,pos] - DMx[i]=dm[pos] - - + +def plot_efficiencies_paper(survey, savename, label): + """ Plots a final version of efficiencies for the purpose of the paper """ + dm = survey.DMlist + eff1s = survey.get_efficiency(dm, model="Quadrature", dsmear=True) + eff1mean = np.copy(survey.mean_efficiencies) + eff2s = survey.get_efficiency(dm, model="Sammons", dsmear=True) + eff2mean = np.copy(survey.mean_efficiencies) + DMobs = survey.DMs + NDM = DMobs.size + DMx = np.zeros([NDM]) + DMy = np.zeros([NDM]) + for i, DMo in enumerate(DMobs): + pos = np.where(dm > DMo)[0][0] + DMy[i] = eff1s[i, pos] + DMx[i] = dm[pos] + plt.figure() - plt.ylim(0,1) - - plt.text(1500,0.9,label) - - eff=survey.efficiencies + plt.ylim(0, 1) + + plt.text(1500, 0.9, label) + + eff = survey.efficiencies if "ID" in survey.frbs: - labels=survey.frbs["ID"] + labels = survey.frbs["ID"] else: - labels=np.arange(survey.NFRB) - - plt.xlabel('DM [pc cm$^{-3}$]') - plt.ylabel('Efficiency $\\epsilon$')#\\dfrac{F_{\\rm 1\,ms}}{F_{\\rm th}}$') - - ls=['-',':','--','-.'] - + labels = np.arange(survey.NFRB) + + plt.xlabel("DM [pc cm$^{-3}$]") + plt.ylabel("Efficiency $\\epsilon$") # \\dfrac{F_{\\rm 1\,ms}}{F_{\\rm th}}$') + + ls = ["-", ":", "--", "-."] + for i in np.arange(survey.NFRB): - ils=int(i/10) - if i==0: - plt.plot(dm,eff1s[i],linestyle=':',color='black',label='$\\epsilon_i$') + ils = int(i / 10) + if i == 0: + plt.plot(dm, eff1s[i], linestyle=":", color="black", label="$\\epsilon_i$") else: - plt.plot(dm,eff1s[i],linestyle=':',color='black') - #plt.plot(dm,eff2s[i],linestyle=ls[ils],lw=1) - plt.plot(dm,eff1mean,linewidth=3,color='blue',ls='-',label='$\\bar{\\epsilon}$') - plt.plot(DMx,DMy,'ro',label='${\\rm DM}_i$') - - #plt.plot(dm,eff2mean,linewidth=1,color='black',ls='-') - ncol=int((survey.NFRB+9)/10) - plt.legend(loc='upper right') + plt.plot(dm, eff1s[i], linestyle=":", color="black") + # plt.plot(dm,eff2s[i],linestyle=ls[ils],lw=1) + plt.plot( + dm, eff1mean, linewidth=3, color="blue", ls="-", label="$\\bar{\\epsilon}$" + ) + plt.plot(DMx, DMy, "ro", label="${\\rm DM}_i$") + + # plt.plot(dm,eff2mean,linewidth=1,color='black',ls='-') + ncol = int((survey.NFRB + 9) / 10) + plt.legend(loc="upper right") plt.tight_layout() plt.savefig(savename) plt.close() -def plot_efficiencies(survey,savename='Plots/efficiencies.pdf',showplot=False): + +def plot_efficiencies(survey, savename="Plots/efficiencies.pdf", showplot=False): """ Plots efficiency as function of DM """ plt.figure() - - eff=survey.efficiencies - dm=survey.DMlist + + eff = survey.efficiencies + dm = survey.DMlist if "ID" in survey.frbs: - labels=survey.frbs["ID"] + labels = survey.frbs["ID"] else: - labels=np.arange(survey.NFRB) - - plt.xlabel('DM [pc cm$^{-3}$]') - plt.ylabel('Efficiency $\\epsilon$') - - ls=['-',':','--','-.'] - + labels = np.arange(survey.NFRB) + + plt.xlabel("DM [pc cm$^{-3}$]") + plt.ylabel("Efficiency $\\epsilon$") + + ls = ["-", ":", "--", "-."] + for i in np.arange(survey.NFRB): - ils=int(i/10) - plt.plot(dm,eff[i],label=labels[i],linestyle=ls[ils]) - plt.plot(dm,survey.mean_efficiencies,linewidth=2,color='black',ls='-') - ncol=int((survey.NFRB+9)/10) - plt.legend(loc='upper right',fontsize=min(14,200./survey.NFRB),ncol=ncol) + ils = int(i / 10) + plt.plot(dm, eff[i], label=labels[i], linestyle=ls[ils]) + plt.plot(dm, survey.mean_efficiencies, linewidth=2, color="black", ls="-") + ncol = int((survey.NFRB + 9) / 10) + plt.legend(loc="upper right", fontsize=min(14, 200.0 / survey.NFRB), ncol=ncol) plt.tight_layout() plt.savefig(savename) if showplot: @@ -2371,119 +2949,119 @@ def plot_efficiencies(survey,savename='Plots/efficiencies.pdf',showplot=False): def plot_beams(prefix): - ''' Plots something to do with beams ''' - logb,omega_b=beams.load_beam(prefix) - total=np.sum(omega_b) - print("Total length of histogram is ",omega_b.size) - + """ Plots something to do with beams """ + logb, omega_b = beams.load_beam(prefix) + total = np.sum(omega_b) + print("Total length of histogram is ", omega_b.size) + # rate of -1.5 - b=10**logb - rate=omega_b*b**1.5 - nbins=10 - b2,o2=beams.simplify_beam(logb,omega_b,nbins) - print(b2,o2) - + b = 10 ** logb + rate = omega_b * b ** 1.5 + nbins = 10 + b2, o2 = beams.simplify_beam(logb, omega_b, nbins) + print(b2, o2) + # note that omega_b is just unscaled total solid angle plt.figure() - plt.xlabel('$B$') - plt.ylabel('$\\Omega(B)$/bin') - plt.yscale('log') - plt.xscale('log') - plt.plot(b,omega_b,label='original_binning') - plt.plot(b2,o2,'ro',label='simplified',linestyle=':') - plt.plot(b,rate,label='Relative rate') - plt.legend(loc='upper left') + plt.xlabel("$B$") + plt.ylabel("$\\Omega(B)$/bin") + plt.yscale("log") + plt.xscale("log") + plt.plot(b, omega_b, label="original_binning") + plt.plot(b2, o2, "ro", label="simplified", linestyle=":") + plt.plot(b, rate, label="Relative rate") + plt.legend(loc="upper left") plt.tight_layout() - plt.savefig('Plots/lat50_beam.pdf') + plt.savefig("Plots/lat50_beam.pdf") plt.close() - - - - crate=np.cumsum(rate) + + crate = np.cumsum(rate) crate /= crate[-1] plt.figure() - plt.xlabel('$\\log_{10}(B)$') - plt.ylabel('cumulative rate') - #plt.yscale('log') - plt.plot(logb,crate) + plt.xlabel("$\\log_{10}(B)$") + plt.ylabel("cumulative rate") + # plt.yscale('log') + plt.plot(logb, crate) plt.tight_layout() - plt.savefig('Plots/crate_lat50_beam.pdf') + plt.savefig("Plots/crate_lat50_beam.pdf") plt.close() - crate=np.cumsum(rate) - -def process_missing_pfile(pfile,number,howmany): - ''' searches for missing data in cube output and iterates for that only ''' - NPARAMS=8 - current=np.zeros([1,NPARAMS]) - last=np.zeros([NPARAMS]) - this=np.zeros([NPARAMS]) - n=0 # counts number of lines in this calculation - new=0 # counts new significant calculations - count=0 # counts total lines - + crate = np.cumsum(rate) + + +def process_missing_pfile(pfile, number, howmany): + """ searches for missing data in cube output and iterates for that only """ + NPARAMS = 8 + current = np.zeros([1, NPARAMS]) + last = np.zeros([NPARAMS]) + this = np.zeros([NPARAMS]) + n = 0 # counts number of lines in this calculation + new = 0 # counts new significant calculations + count = 0 # counts total lines + # the range of calculations to do. These are *inclusive* values - start=(number-1)*howmany+1 - stop=number*howmany - print("Calculated start and stop as ",start,stop) - - max_number=np.zeros([howmany*11,NPARAMS]) - - #I am now testing how many in the file in total - + start = (number - 1) * howmany + 1 + stop = number * howmany + print("Calculated start and stop as ", start, stop) + + max_number = np.zeros([howmany * 11, NPARAMS]) + + # I am now testing how many in the file in total + with open(pfile) as pf: - + for line in pf: - #if count==NPARAMS: + # if count==NPARAMS: # break - vals=line.split() - for j,v in enumerate(vals): - this[j]=float(v) - + vals = line.split() + for j, v in enumerate(vals): + this[j] = float(v) + # tests to see if this is a serious calculation - for j in np.arange(NPARAMS-1): - if j==4: + for j in np.arange(NPARAMS - 1): + if j == 4: continue if this[j] != last[j]: new += 1 break - + # tests to see if we have gone far enough if new > stop: break - + # test to see if we now do this if new >= start: - max_number[n,:]=this[:] + max_number[n, :] = this[:] n += 1 - - + # sets last to this one - last[:]=this[:] - + last[:] = this[:] + count += 1 - - if n==0: + + if n == 0: print("Reached the end of the file, exiting") exit() # concatenate max number to true size - todo=max_number[0:n,:] - starti=count-n+1 - return todo,starti + todo = max_number[0:n, :] + starti = count - n + 1 + return todo, starti + def process_pfile(pfile): - ''' used for cube.py to input multi-dimensional grid to iterate over''' - NPARAMS=8 - mins=np.zeros([NPARAMS]) - maxs=np.zeros([NPARAMS]) - Nits=np.zeros([NPARAMS],dtype='int') + """ used for cube.py to input multi-dimensional grid to iterate over""" + NPARAMS = 8 + mins = np.zeros([NPARAMS]) + maxs = np.zeros([NPARAMS]) + Nits = np.zeros([NPARAMS], dtype="int") with open(pfile) as pf: - count=0 + count = 0 for line in pf: - if count==NPARAMS: + if count == NPARAMS: break - vals=line.split() - mins[count]=float(vals[0]) - maxs[count]=float(vals[1]) - Nits[count]=int(vals[2]) + vals = line.split() + mins[count] = float(vals[0]) + maxs[count] = float(vals[1]) + Nits[count] = int(vals[2]) count += 1 - return mins,maxs,Nits + return mins, maxs, Nits + diff --git a/zdm/parameters.py b/zdm/parameters.py index d258e71f..2f9abfc2 100644 --- a/zdm/parameters.py +++ b/zdm/parameters.py @@ -11,236 +11,309 @@ # Analysis parameters @dataclass class AnalysisParams(data_class.myDataClass): - NewGrids: bool = field( - default=True, - metadata={'help': 'Generate new z, DM grids?'}) + NewGrids: bool = field(default=True, metadata={"help": "Generate new z, DM grids?"}) sprefix: str = field( - default='Std', - metadata={'help': 'Full: more detailed estimates. Takes more space and time \n'+\ - 'Std: faster - fine for max likelihood calculations, not as pretty'}) + default="Std", + metadata={ + "help": "Full: more detailed estimates. Takes more space and time \n" + + "Std: faster - fine for max likelihood calculations, not as pretty" + }, + ) + # Beam parameters @dataclass class BeamParams(data_class.myDataClass): Bmethod: int = field( default=2, - metadata={'help': 'Method for calculation. See beams.py:simplify_beam() for options', - 'unit': ''}) + metadata={ + "help": "Method for calculation. See beams.py:simplify_beam() for options", + "unit": "", + }, + ) Bthresh: float = field( default=0.0, - metadata={'help': 'Minimum value of beam sensitivity to consider', - 'unit': '', - 'Notation': 'B_{\rm min}'}) - #def __post_init__(self): + metadata={ + "help": "Minimum value of beam sensitivity to consider", + "unit": "", + "Notation": "B_{\rm min}", + }, + ) + # def __post_init__(self): # self.Nbeams = [5,5,5,10] + # Cosmology parameters @dataclass class CosmoParams(data_class.myDataClass): H0: float = field( default=Planck18.H0.value, - metadata={'help': "Hubble's constant", - 'unit': 'km s$^{-1}$ Mpc$^{-1}$', - 'Notation': 'H_0', - }) + metadata={ + "help": "Hubble's constant", + "unit": "km s$^{-1}$ Mpc$^{-1}$", + "Notation": "H_0", + }, + ) Omega_k: float = field( - default=0., - metadata={'help': 'photo density. Ignored here (we do not go back far enough)'}) + default=0.0, + metadata={"help": "photo density. Ignored here (we do not go back far enough)"}, + ) Omega_lambda: float = field( default=Planck18.Ode0, - metadata={'help': 'dark energy / cosmological constant (in current epoch)', - 'unit': '', - 'Notation': '\Omega_{\Lambda}', - }) + metadata={ + "help": "dark energy / cosmological constant (in current epoch)", + "unit": "", + "Notation": "\Omega_{\Lambda}", + }, + ) Omega_m: float = field( default=Planck18.Om0, - metadata={'help': 'matter density in current epoch', - 'unit': '', - 'Notation': '\Omega_m', - }) + metadata={ + "help": "matter density in current epoch", + "unit": "", + "Notation": "\Omega_m", + }, + ) Omega_b: float = field( default=Planck18.Ob0, - metadata={'help': 'baryon density in current epoch', - 'unit': '', - 'Notation': '\Omega_b', - }) + metadata={ + "help": "baryon density in current epoch", + "unit": "", + "Notation": "\Omega_b", + }, + ) Omega_b_h2: float = field( - default=Planck18.Ob0 * (Planck18.H0.value/100.)**2, - metadata={'help': 'baryon density weighted by $h_{100}^2$', - 'unit': '', - 'Notation': '\Omega_b h^2', - }) + default=Planck18.Ob0 * (Planck18.H0.value / 100.0) ** 2, + metadata={ + "help": "baryon density weighted by $h_{100}^2$", + "unit": "", + "Notation": "\Omega_b h^2", + }, + ) fix_Omega_b_h2: bool = field( - default=True, - metadata={'help': 'Fix Omega_b_h2 by the Placnk18 value?'}) + default=True, metadata={"help": "Fix Omega_b_h2 by the Placnk18 value?"} + ) + # FRB Demographics -- FRBdemo @dataclass class FRBDemoParams(data_class.myDataClass): source_evolution: int = field( default=0, - metadata={'help': 'Integer flag specifying the function used. '+\ - '0: SFR^n; 1: (1+z)^(2.7n)', - 'options': [0,1]}) + metadata={ + "help": "Integer flag specifying the function used. " + + "0: SFR^n; 1: (1+z)^(2.7n)", + "options": [0, 1], + }, + ) alpha_method: int = field( - default=0, - metadata={'help': 'Integer flag specifying the nature of scaling. '+\ - '0: spectral index interpretation: includes k-correction. Slower to update ' +\ - '1: rate interpretation: extra factor of (1+z)^alpha in source evolution', - 'options': [0,1]}) + default=0, + metadata={ + "help": "Integer flag specifying the nature of scaling. " + + "0: spectral index interpretation: includes k-correction. Slower to update " + + "1: rate interpretation: extra factor of (1+z)^alpha in source evolution", + "options": [0, 1], + }, + ) sfr_n: float = field( - default = 1.77, - metadata={'help': 'scaling of FRB rate density with star-formation rate', - 'unit': '', - 'Notation': 'n_{\\rm sfr}', - }) + default=1.77, + metadata={ + "help": "scaling of FRB rate density with star-formation rate", + "unit": "", + "Notation": "n_{\\rm sfr}", + }, + ) lC: float = field( - default = 4.19, - metadata={'help': 'log10 constant in number per Gpc^-3 yr^-1 at z=0'}) + default=4.19, + metadata={"help": "log10 constant in number per Gpc^-3 yr^-1 at z=0"}, + ) + # Galactic parameters @dataclass class MWParams(data_class.myDataClass): ISM: float = field( - default=35., - metadata={'help': 'Assumed DM for the Galactic ISM in units of pc/cm^3'}) + default=35.0, + metadata={"help": "Assumed DM for the Galactic ISM in units of pc/cm^3"}, + ) DMhalo: float = field( - default=50., - metadata={'help': 'DM for the Galactic halo', - 'unit': 'pc cm$^{-3}$', - 'Notation': '{\\rm DM}_{\\rm halo}', - }) + default=50.0, + metadata={ + "help": "DM for the Galactic halo", + "unit": "pc cm$^{-3}$", + "Notation": "{\\rm DM}_{\\rm halo}", + }, + ) + # Host parameters -- host @dataclass class HostParams(data_class.myDataClass): lmean: float = field( default=2.16, - metadata={'help': '$\log_{10}$ mean of DM host contribution in pc cm$^{-3}$', - 'unit': '', - 'Notation': '\mu_{\\rm host}', - }) + metadata={ + "help": "$\log_{10}$ mean of DM host contribution in pc cm$^{-3}$", + "unit": "pc cm$^{-3}$", + "Notation": "\mu_{\\rm host}", + }, + ) lsigma: float = field( default=0.51, - metadata={'help': '$\log_{10}$ sigma of DM host contribution in pc cm$^{-3}$', - 'unit': '', - 'Notation': '\sigma_{\\rm host}', - }) + metadata={ + "help": "$\log_{10}$ sigma of DM host contribution in pc cm$^{-3}$", + "unit": "pc cm$^{-3}$", + "Notation": "\sigma_{\\rm host}", + }, + ) + # IGM parameters @dataclass class IGMParams(data_class.myDataClass): - F: float = field( - default=0.32, - metadata={'help': 'F parameter in DM$_{\\rm cosmic}$ PDF for the Cosmic web', - 'unit': '', - 'Notation': 'F', - }) + logF: float = field( + default=np.log10(0.32), + metadata={ + "help": "logF parameter in DM$_{\\rm cosmic}$ PDF for the Cosmic web", + "unit": "", + "Notation": "$\log_{10} F$", + }, + ) # FRB intrinsic width parameters @dataclass class WidthParams(data_class.myDataClass): Wlogmean: float = field( - default = 1.70267, - metadata={'help': '$\log_{10}$ mean of intrinsic width distribution in ms', - 'unit': 'ms', - 'Notation': '\mu_{w}', - }) + default=1.70267, + metadata={ + "help": "$\log_{10}$ mean of intrinsic width distribution in ms", + "unit": "ms", + "Notation": "\mu_{w}", + }, + ) Wlogsigma: float = field( - default = 0.899148, - metadata={'help': '$\log_{10}$ sigma of intrinsic width distribution in ms', - 'unit': 'ms', - 'Notation': '\sigma_{w}', - }) + default=0.899148, + metadata={ + "help": "$\log_{10}$ sigma of intrinsic width distribution in ms", + "unit": "ms", + "Notation": "\sigma_{w}", + }, + ) Wthresh: int = field( default=0.5, - metadata={'help': 'Starting fraction of intrinsic width for histogramming', - 'unit': '', - 'Notation': 'w_{\\rm min}'}) + metadata={ + "help": "Starting fraction of intrinsic width for histogramming", + "unit": "", + "Notation": "w_{\\rm min}", + }, + ) Wmethod: int = field( default=2, - metadata={'help': 'Method of calculating FRB widths; 1 std, 2 includes scattering', - 'unit': ''}) + metadata={ + "help": "Method of calculating FRB widths; 1 std, 2 includes scattering", + "unit": "", + }, + ) Wbins: int = field( default=5, - metadata={'help': 'Number of bins for FRB width distribution', - 'unit': ''}) + metadata={"help": "Number of bins for FRB width distribution", "unit": ""}, + ) Wscale: int = field( default=3.5, - metadata={'help': 'Log-scaling of bins for width distribution', - 'unit': ''}) - + metadata={"help": "Log-scaling of bins for width distribution", "unit": ""}, + ) + + # FRB intrinsic scattering parameters @dataclass class ScatParams(data_class.myDataClass): Slogmean: float = field( - default = 0.7, - metadata={'help': 'Mean of log-scattering distribution at 600\,Mhz', - 'unit': 'ms', - 'Notation': '\log \mu_{s}', - }) + default=0.7, + metadata={ + "help": "Mean of log-scattering distribution at 600\,Mhz", + "unit": "ms", + "Notation": "\log \mu_{s}", + }, + ) Slogsigma: float = field( - default = 1.9, - metadata={'help': ' Standard deviation of log-scattering distribution at 600\,MHz ', - 'unit': 'ms', - 'Notation': '\log \sigma_{s}', - }) + default=1.9, + metadata={ + "help": " Standard deviation of log-scattering distribution at 600\,MHz ", + "unit": "ms", + "Notation": "\log \sigma_{s}", + }, + ) Sfnorm: float = field( - default = 600, - metadata={'help': 'Frequency of scattering width', - 'unit': 'MHz', - 'Notation': '\\nu_{\\tau}', - }) + default=600, + metadata={ + "help": "Frequency of scattering width", + "unit": "MHz", + "Notation": "\\nu_{\\tau}", + }, + ) Sfpower: float = field( - default = -4., - metadata={'help': 'Power-law scaling with frequency, nu^lambda', - 'unit': '', - 'Notation': '\lambda', - }) + default=-4.0, + metadata={ + "help": "Power-law scaling with frequency, nu^lambda", + "unit": "", + "Notation": "\lambda", + }, + ) + # FRB Energetics -- energy @dataclass class EnergeticsParams(data_class.myDataClass): lEmin: float = field( - default = 30., - metadata={'help': '$\log_{10}$ of minimum FRB energy ', - 'unit': 'erg', - 'Notation': '\\log_{10} E_{\\rm min}', - }) + default=30.0, + metadata={ + "help": "$\log_{10}$ of minimum FRB energy ", + "unit": "erg", + "Notation": "\\log_{10} E_{\\rm min}", + }, + ) lEmax: float = field( - default = 41.84, - metadata={'help': '$\log_{10}$ of maximum FRB energy', - 'unit': 'erg', - 'Notation': '\\log_{10} E_{\\rm max}', - }) + default=41.84, + metadata={ + "help": "$\log_{10}$ of maximum FRB energy", + "unit": "erg", + "Notation": "\\log_{10} E_{\\rm max}", + }, + ) alpha: float = field( - default = 1.54, - metadata={'help': 'power-law index of frequency dependent FRB rate, $R \sim \\nu^\\alpha$', - 'unit': '', - 'Notation': '\\alpha', - }) + default=1.54, + metadata={ + "help": "power-law index of frequency dependent FRB rate, $R \sim \\nu^\\alpha$", + "unit": "", + "Notation": "\\alpha", + }, + ) gamma: float = field( - default = -1.16, - metadata={'help': 'slope of luminosity distribution function', - 'unit': '', - 'Notation': '\gamma', - }) + default=-1.16, + metadata={ + "help": "slope of luminosity distribution function", + "unit": "", + "Notation": "\gamma", + }, + ) luminosity_function: int = field( - default = 2, - metadata={'help': 'luminosity function applied (0=power-law, 1=gamma, 2=spline+gamma, 3=gamma+linear+log10)'}) + default=2, + metadata={ + "help": "luminosity function applied (0=power-law, 1=gamma, 2=spline+gamma, 3=gamma+linear+log10)" + }, + ) + class State(data_class.myData): - """ Initialize the full state for the analysis + """Initialize the full state for the analysis with the default parameters """ - def __init__(self): + def __init__(self): self.set_dataclasses() self.set_params() - def set_dataclasses(self): self.scat = ScatParams() self.width = WidthParams() @@ -253,15 +326,15 @@ def set_dataclasses(self): self.IGM = IGMParams() self.energy = EnergeticsParams() - - def update_param(self, param:str, value): + def update_param(self, param: str, value): DC = self.params[param] setattr(self[DC], param, value) # Special treatment - if DC == 'cosmo' and param == 'H0': + if DC == "cosmo" and param == "H0": if self.cosmo.fix_Omega_b_h2: - self.cosmo.Omega_b = self.cosmo.Omega_b_h2/( - self.cosmo.H0/100.)**2 + self.cosmo.Omega_b = ( + self.cosmo.Omega_b_h2 / (self.cosmo.H0 / 100.0) ** 2 + ) def set_astropy_cosmo(self, cosmo): """Slurp the values from an astropy Cosmology object @@ -274,5 +347,5 @@ def set_astropy_cosmo(self, cosmo): self.cosmo.Omega_lambda = cosmo.Ode0 self.cosmo.Omega_m = cosmo.Om0 self.cosmo.Omega_b = cosmo.Ob0 - self.cosmo.Omega_b_h2 = cosmo.Ob0 * (cosmo.H0.value/100.)**2 + self.cosmo.Omega_b_h2 = cosmo.Ob0 * (cosmo.H0.value / 100.0) ** 2 return diff --git a/zdm/pcosmic.py b/zdm/pcosmic.py index b589ce45..f3045011 100644 --- a/zdm/pcosmic.py +++ b/zdm/pcosmic.py @@ -7,37 +7,42 @@ ############################# +# from fcntl import F_ADD_SEALS import sys -#sys.path.insert(1, '/Users/cjames/CRAFT/FRB_library/ne2001-master/src/ne2001') +# sys.path.insert(1, '/Users/cjames/CRAFT/FRB_library/ne2001-master/src/ne2001') import matplotlib.pyplot as plt import numpy as np from astropy.cosmology import FlatLambdaCDM -#from frb import dlas +# from frb import dlas from frb.dm import igm from zdm import cosmology as cos from zdm import parameters -#from zdm import c_code + +# from zdm import c_code import scipy as sp -#import astropy.units as u + +# import astropy.units as u from IPython import embed # these are fitted values, which are shown to best-match data -alpha=3 -beta=3 -#F=0.32 ##### feedback best fit, but FIT IT!!! ##### +alpha = 3 +beta = 3 +# F=0.32 ##### feedback best fit, but FIT IT!!! ##### + + +def p(DM, z, F): + mean = z * 1000 # NOT true, just testing! + delta = DM / mean + p = pcosmic(delta, z, F) -def p(DM,z,F): - mean=z*1000 #NOT true, just testing! - delta=DM/mean - p=pcosmic(delta,z,F) -def pcosmic(delta,z,F,C0): +def pcosmic(delta, z, logF, C0): """ Equation 4 page 33 delta: = DM_cosmic/ @@ -48,49 +53,56 @@ def pcosmic(delta,z,F,C0): A: arbitrary amplitude of relative probability, ignore... """ - global beta,alpha - sigma=F*z**-0.5 - return delta**-beta * np.exp(-(delta**-alpha - C0)**2./(2.*alpha**2*sigma**2)) + ### logF compensation + F = 10 ** (logF) + ### -def p_delta_DM(z,F,C0,deltas=None,dmin=1e-3,dmax=10,ndelta=10000): + global beta, alpha + sigma = F * z ** -0.5 + return delta ** -beta * np.exp( + -((delta ** -alpha - C0) ** 2.0) / (2.0 * alpha ** 2 * sigma ** 2) + ) + + +def p_delta_DM(z, F, C0, deltas=None, dmin=1e-3, dmax=10, ndelta=10000): """ Calculates probability distribution of delta DM as function of feedback redshift and the constant C0 """ if not deltas: - deltas=np.linspace(dmin,dmax,ndelta) - pdeltas=pcosmic(deltas,z,F,C0) - return deltas,pdeltas - + deltas = np.linspace(dmin, dmax, ndelta) + pdeltas = pcosmic(deltas, z, F, C0) + return deltas, pdeltas -def iterate_C0(z,F,C0=1,Niter=10): +def iterate_C0(z, F, C0=1, Niter=10): """ Iteratively solves for C_0 as a function of z and F """ - dmin=1e-3 - dmax=10 - ndelta=10000 - deltas=np.linspace(dmin,dmax,ndelta) + dmin = 1e-3 + dmax = 10 + ndelta = 10000 + deltas = np.linspace(dmin, dmax, ndelta) for i in np.arange(Niter): - pdeltas=pcosmic(deltas,z,F,C0) - bin_w=deltas[1]-deltas[0] - norm=bin_w*np.sum(pdeltas) - mean=bin_w*np.sum(pdeltas*deltas)/norm - C0 += (mean-1.) - + pdeltas = pcosmic(deltas, z, F, C0) + bin_w = deltas[1] - deltas[0] + norm = bin_w * np.sum(pdeltas) + mean = bin_w * np.sum(pdeltas * deltas) / norm + C0 += mean - 1.0 + return C0 -def make_C0_grid(zeds,F): +def make_C0_grid(zeds, F): """ Pre-generates normalisation constants for C0 Does this from a grid of z and a given F """ - C0s=np.zeros([zeds.size]) - for i,z in enumerate(zeds): - C0s[i]=iterate_C0(z,F) + C0s = np.zeros([zeds.size]) + for i, z in enumerate(zeds): + C0s[i] = iterate_C0(z, F) return C0s -def get_mean_DM(zeds:np.ndarray, state:parameters.State): + +def get_mean_DM(zeds: np.ndarray, state: parameters.State): """ Gets mean average z to which can be applied deltas Args: @@ -101,21 +113,21 @@ def get_mean_DM(zeds:np.ndarray, state:parameters.State): np.ndarray: DM_cosmic """ # Generate the cosmology - cosmo = FlatLambdaCDM(H0=state.cosmo.H0, - Ob0=state.cosmo.Omega_b, - Om0=state.cosmo.Omega_m) + cosmo = FlatLambdaCDM( + H0=state.cosmo.H0, Ob0=state.cosmo.Omega_b, Om0=state.cosmo.Omega_m + ) # - zmax=zeds[-1] - nz=zeds.size - DMbar, zeval = igm.average_DM( - zmax, cosmo=cosmo, cumul=True, neval=nz+1) - + zmax = zeds[-1] + nz = zeds.size + DMbar, zeval = igm.average_DM(zmax, cosmo=cosmo, cumul=True, neval=nz + 1) + # Check assert np.allclose(zeds, zeval[1:]) - #wrong dimension + # wrong dimension return DMbar[1:].value - -def get_log_mean_DM(zeds:np.ndarray, state:parameters.State): + + +def get_log_mean_DM(zeds: np.ndarray, state: parameters.State): """ Gets mean average z to which can be applied deltas Does NOT assume that the zeds are linearly spaced. @@ -127,62 +139,72 @@ def get_log_mean_DM(zeds:np.ndarray, state:parameters.State): np.ndarray: DM_cosmic """ # Generate the cosmology - cosmo = FlatLambdaCDM(H0=state.cosmo.H0, - Ob0=state.cosmo.Omega_b, - Om0=state.cosmo.Omega_m) + cosmo = FlatLambdaCDM( + H0=state.cosmo.H0, Ob0=state.cosmo.Omega_b, Om0=state.cosmo.Omega_m + ) # - nz=zeds.size - dms=np.zeros([nz]) - for i,z in enumerate(zeds): + nz = zeds.size + dms = np.zeros([nz]) + for i, z in enumerate(zeds): # neval probably should be a function of max z - DMbar, zeval = igm.average_DM( - z, cosmo=cosmo, cumul=True, neval=nz+1)# - dms[i]=DMbar[-1].value - #wrong dimension - return dms + DMbar, zeval = igm.average_DM(z, cosmo=cosmo, cumul=True, neval=nz + 1) # + dms[i] = DMbar[-1].value + # wrong dimension + return dms + -def get_C0(z,F,zgrid,Fgrid,C0grid): +def get_C0(z, F, zgrid, Fgrid, C0grid): """ Takes a pre-generated table of C0 values, and calculates the p(DM) distribution based on this """ - - if z < zgrid[0] or z>zgrid[-1]: + + F = 10 ** F + Fgrid = 10 ** Fgrid + + if z < zgrid[0] or z > zgrid[-1]: print("Z value out of range") exit() - if F < Fgrid[0] or F>Fgrid[-1]: + if F < Fgrid[0] or F > Fgrid[-1]: print("F value out of range") exit() - - iz2=np.where(zgrid>z)[0] # gets first element greater than - iz1=iz2-1 - kz1=(zgrid[iz2]-z)/(zgrid[iz2]-zgrid[iz1]) - kz2=1.-kz1 - - iF2=np.where(Fgrid>F)[0] # gets first element greater than - iF1=iF2-1 - kF1=(Fgrid[iF2]-F)/(Fgrid[iF2]-Fgrid[iF1]) - kF2=1.-kF1 - - C0=kz1*kF1*C0grid[iz1,iF1] + kz2*kF1*C0grid[iz2,iF1] + kz1*kF2*C0grid[iz1,iF2] + kz2*kF2*C0grid[iz2,iF2] + + iz2 = np.where(zgrid > z)[0] # gets first element greater than + iz1 = iz2 - 1 + kz1 = (zgrid[iz2] - z) / (zgrid[iz2] - zgrid[iz1]) + kz2 = 1.0 - kz1 + + iF2 = np.where(Fgrid > F)[0] # gets first element greater than + iF1 = iF2 - 1 + kF1 = (Fgrid[iF2] - F) / (Fgrid[iF2] - Fgrid[iF1]) + kF2 = 1.0 - kF1 + + C0 = ( + kz1 * kF1 * C0grid[iz1, iF1] + + kz2 * kF1 * C0grid[iz2, iF1] + + kz1 * kF2 * C0grid[iz1, iF2] + + kz2 * kF2 * C0grid[iz2, iF2] + ) return C0 - - -def get_pDM(z,F,DMgrid,zgrid,Fgrid,C0grid,zlog=False): + + +def get_pDM(z, F, DMgrid, zgrid, Fgrid, C0grid, zlog=False): """ Gets pDM for an arbitrary z value zlog (bool): True if zs are log-spaced False if linearly spaced """ - C0=get_C0(z,F,zgrid,Fgrid,C0grid) + C0 = get_C0(z, F, zgrid, Fgrid, C0grid) if zlog: - DMbar=get_mean_DM(z) + DMbar = get_mean_DM(z) else: - DMbar=get_log_mean_DM(z) - deltas=DMgrid/DMbar #in units of fractional DM - pDM=pcosmic(deltas,z,F,C0) + DMbar = get_log_mean_DM(z) + deltas = DMgrid / DMbar # in units of fractional DM + pDM = pcosmic(deltas, z, F, C0) return pDM -def get_pDM_grid(state:parameters.State, DMgrid,zgrid,C0s, verbose=False, zlog=False): +def get_pDM_grid( + state: parameters.State, DMgrid, zgrid, C0s, verbose=False, zlog=False +): """ Gets pDM when the zvals are the same as the zgrid state C0grid: C0 values obtained by convergence @@ -194,23 +216,22 @@ def get_pDM_grid(state:parameters.State, DMgrid,zgrid,C0s, verbose=False, zlog=F """ - #added H0 dependency + # added H0 dependency if zlog: - DMbars=get_log_mean_DM(zgrid, state) + DMbars = get_log_mean_DM(zgrid, state) else: - DMbars=get_mean_DM(zgrid, state) - - pDMgrid=np.zeros([zgrid.size,DMgrid.size]) + DMbars = get_mean_DM(zgrid, state) + + pDMgrid = np.zeros([zgrid.size, DMgrid.size]) if verbose: - print("shapes and sizes are ",C0s.size,pDMgrid.shape,DMbars.shape) + print("shapes and sizes are ", C0s.size, pDMgrid.shape, DMbars.shape) # iterates over zgrid to calculate p_delta_DM - for i,z in enumerate(zgrid): - deltas=DMgrid/DMbars[i] # since pDM is defined such that the mean is 1 - - pDMgrid[i,:]=pcosmic(deltas,z,state.IGM.F,C0s[i]) - pDMgrid[i,:] /= np.sum(pDMgrid[i,:]) #normalisation - return pDMgrid + for i, z in enumerate(zgrid): + deltas = DMgrid / DMbars[i] # since pDM is defined such that the mean is 1 + pDMgrid[i, :] = pcosmic(deltas, z, state.IGM.logF, C0s[i]) + pDMgrid[i, :] /= np.sum(pDMgrid[i, :]) # normalisation + return pDMgrid #### defines DMx (excess contribution) #### @@ -218,40 +239,43 @@ def get_pDM_grid(state:parameters.State, DMgrid,zgrid,C0s, verbose=False, zlog=F # and either do or do not include the 1/x fatcor when converting log to dlin. # the DM part is because integral p(logDM)dlogDM = 1 # DM is normal, logmean and logsigma are natural logs of these parameters -def linlognormal_dlin(DM,*args): - ''' x values are in linear space, +def linlognormal_dlin(DM, *args): + """ x values are in linear space, args in logspace, - returns p dx ''' - logmean=args[0] - logsigma=args[1] - logDM=np.log(DM) - norm=(2.*np.pi)**-0.5/DM/logsigma - return norm*np.exp(-0.5*((logDM-logmean)/logsigma)**2) - -def loglognormal_dlog(logDM,*args): - '''x values, mean and sigma are already in logspace + returns p dx """ + logmean = args[0] + logsigma = args[1] + logDM = np.log(DM) + norm = (2.0 * np.pi) ** -0.5 / DM / logsigma + return norm * np.exp(-0.5 * ((logDM - logmean) / logsigma) ** 2) + + +def loglognormal_dlog(logDM, *args): + """x values, mean and sigma are already in logspace returns p dlogx That is, this function is simply a Gaussian, and the arguments happen to be in log space. - ''' - logmean=args[0] - logsigma=args[1] - norm=args[2] - return norm*np.exp(-0.5*((logDM-logmean)/logsigma)**2) + """ + logmean = args[0] + logsigma = args[1] + norm = args[2] + return norm * np.exp(-0.5 * ((logDM - logmean) / logsigma) ** 2) -def plot_mean(zvals,saveas, title="Mean DM"): - - mean=get_mean_DM(zvals) + +def plot_mean(zvals, saveas, title="Mean DM"): + + mean = get_mean_DM(zvals) plt.figure() - plt.xlabel('z') - plt.ylabel('$\\overline{\\rm DM}$') - plt.plot(zvals,mean,linewidth=2) + plt.xlabel("z") + plt.ylabel("$\\overline{\\rm DM}$") + plt.plot(zvals, mean, linewidth=2) plt.tight_layout() plt.title(title) plt.savefig(saveas) plt.show() plt.close() + def get_dm_mask(dmvals, params, zvals=None, plot=False): """ Generates a mask over which to integrate the lognormal Apply this mask as DM[i] = DM[set[i]]*mask[i] @@ -266,43 +290,47 @@ def get_dm_mask(dmvals, params, zvals=None, plot=False): params [vector, 2]: mean and sigma of the lognormal (log10) distribution """ - + if len(params) != 2: - raise ValueError("Incorrect number of DM parameters!",params," (expected log10mean, log10sigma)") + raise ValueError( + "Incorrect number of DM parameters!", + params, + " (expected log10mean, log10sigma)", + ) exit() - #expect the params to be log10 of actual values for simplicity + # expect the params to be log10 of actual values for simplicity # this converts to natural log - logmean=params[0]/0.4342944619 - logsigma=params[1]/0.4342944619 - - ddm=dmvals[1]-dmvals[0] - + logmean = params[0] / 0.4342944619 + logsigma = params[1] / 0.4342944619 + + ddm = dmvals[1] - dmvals[0] + ##### first generates a mask from the lognormal distribution ##### # in theory allows a mask up to length of the DN values, but will # get truncated # the first value has half weight (0 to 0.5) # the rest have width of 1 - mask=np.zeros([dmvals.size]) + mask = np.zeros([dmvals.size]) if zvals is not None: - ndm=dmvals.size - nz=zvals.size - mask=np.zeros([nz,ndm]) - for j,z in enumerate(zvals): + ndm = dmvals.size + nz = zvals.size + mask = np.zeros([nz, ndm]) + for j, z in enumerate(zvals): # with each redshift, we reduce the effects of a 'host' contribution by (1+z) # this means that we divide the value of logmean by 1/(1+z) # or equivalently, we multiply the ddm by this factor # here we choose the latter, but it is the same - mask[j,:]=integrate_pdm(ddm*(1.+z),ndm,logmean,logsigma) - mask[j,:] /= np.sum(mask[j,:]) # the mask must integrate to unity + mask[j, :] = integrate_pdm(ddm * (1.0 + z), ndm, logmean, logsigma) + mask[j, :] /= np.sum(mask[j, :]) # the mask must integrate to unity else: # do this for the z=0 case - #dmmin=0 - #dmmax=ddm*0.5 - #pdm,err=sp.integrate.quad(lognormal,dmmin,dmmax,args=(logmean,logsigma)) - #mask[0]=pdm - #csum=pdm - #imax=dmvals.size - #for i in np.arange(1,dmvals.size): + # dmmin=0 + # dmmax=ddm*0.5 + # pdm,err=sp.integrate.quad(lognormal,dmmin,dmmax,args=(logmean,logsigma)) + # mask[0]=pdm + # csum=pdm + # imax=dmvals.size + # for i in np.arange(1,dmvals.size): # if csum > CSUMCUT: # imax=i # break @@ -311,23 +339,30 @@ def get_dm_mask(dmvals, params, zvals=None, plot=False): # pdm,err=sp.integrate.quad(lognormal,dmmin,dmmax,args=(logmean,logsigma)) # csum += pdm # mask[i]=pdm - mask=integrate_pdm(ddm,dmvals.size,logmean,logsigma) - mask /= np.sum(mask) #ensures correct normalisation - #mask=mask[0:imax] - + mask = integrate_pdm(ddm, dmvals.size, logmean, logsigma) + mask /= np.sum(mask) # ensures correct normalisation + # mask=mask[0:imax] + if plot and (not (zvals is not None)): plt.figure() - plt.xlabel('${\\rm DM}_{\\rm X}$') - plt.ylabel('$p({\\rm DM}_{\\rm X})$') - label='$e^\\sigma='+str(np.exp(logsigma))[0:4]+'$, $e^\\mu='+str(np.exp(logmean))[0:4]+'$' - plt.plot(dmvals[0:imax],mask,linewidth=2,label=label) + plt.xlabel("${\\rm DM}_{\\rm X}$") + plt.ylabel("$p({\\rm DM}_{\\rm X})$") + label = ( + "$e^\\sigma=" + + str(np.exp(logsigma))[0:4] + + "$, $e^\\mu=" + + str(np.exp(logmean))[0:4] + + "$" + ) + plt.plot(dmvals[0:imax], mask, linewidth=2, label=label) plt.tight_layout() - plt.savefig('Plots/p_DM_X.pdf') + plt.savefig("Plots/p_DM_X.pdf") plt.close() return mask -def integrate_pdm(ddm,ndm,logmean,logsigma,quick=True,plot=False): - ''' + +def integrate_pdm(ddm, ndm, logmean, logsigma, quick=True, plot=False): + """ Assigns probabilities of DM smearing (e.g. due to the host galaxy contribution) to a histogram in dm space. @@ -350,50 +385,59 @@ def integrate_pdm(ddm,ndm,logmean,logsigma,quick=True,plot=False): Returns: mask (np.ndarray) - ''' + """ # do this for the z=0 case - - norm=(2.*np.pi)**-0.5/logsigma - - #csum=pdm - #imax=ndm - #if quick: + + norm = (2.0 * np.pi) ** -0.5 / logsigma + + # csum=pdm + # imax=ndm + # if quick: if plot or quick: # does not integrate, takes central values, here in linear space- tiny bias - dmmeans=np.linspace(ddm/2.,ndm*ddm-ddm/2.,ndm) - logdmmeans=np.log(dmmeans) - dlogs=ddm/dmmeans - m1=loglognormal_dlog(logdmmeans,logmean,logsigma,norm)*dlogs #worst errors in lowest bins - #else: + dmmeans = np.linspace(ddm / 2.0, ndm * ddm - ddm / 2.0, ndm) + logdmmeans = np.log(dmmeans) + dlogs = ddm / dmmeans + m1 = ( + loglognormal_dlog(logdmmeans, logmean, logsigma, norm) * dlogs + ) # worst errors in lowest bins + # else: if plot or not quick: - m2=np.zeros([ndm]) - args=(logmean,logsigma,norm) - pdm,err=sp.integrate.quad(loglognormal_dlog,np.log(ddm*0.5)-logsigma*10,np.log(ddm*0.5),args=args) - m2[0]=pdm - - for i in np.arange(1,ndm): - #if csum > CSUMCUT: + m2 = np.zeros([ndm]) + args = (logmean, logsigma, norm) + pdm, err = sp.integrate.quad( + loglognormal_dlog, + np.log(ddm * 0.5) - logsigma * 10, + np.log(ddm * 0.5), + args=args, + ) + m2[0] = pdm + + for i in np.arange(1, ndm): + # if csum > CSUMCUT: # imax=i # break - dmmin=(i-0.5)*ddm - dmmax=dmmin+ddm - pdm,err=sp.integrate.quad(loglognormal_dlog,np.log(dmmin),np.log(dmmax),args=args) - m2[i]=pdm + dmmin = (i - 0.5) * ddm + dmmax = dmmin + ddm + pdm, err = sp.integrate.quad( + loglognormal_dlog, np.log(dmmin), np.log(dmmax), args=args + ) + m2[i] = pdm if quick: - mask=m1 + mask = m1 else: - mask=m2 + mask = m2 if plot: plt.figure() - plt.plot(dmmeans,m2,label='quick') - plt.plot(dmmeans,mask,label='slow') - plt.xlabel('DM') - plt.ylabel('p(DM)') + plt.plot(dmmeans, m2, label="quick") + plt.plot(dmmeans, mask, label="slow") + plt.xlabel("DM") + plt.ylabel("p(DM)") plt.legend() - plt.xlim(0,1000) + plt.xlim(0, 1000) plt.tight_layout() - plt.savefig('dm_mask_comparison_plot.pdf') + plt.savefig("dm_mask_comparison_plot.pdf") plt.close() print("Generated plot of dm masks, exiting...") - exit() #quit to avoid infinite plots + exit() # quit to avoid infinite plots return mask diff --git a/zdm/real_loading.py b/zdm/real_loading.py index d752a7d3..8ededaf0 100644 --- a/zdm/real_loading.py +++ b/zdm/real_loading.py @@ -84,8 +84,11 @@ def set_state(alpha_method=1, cosmo=Planck18): return state -def surveys_and_grids(init_state=None, alpha_method=1, add_20220610A=False): - """ Load up a survey and grid for a CRACO mock dataset +def surveys_and_grids(init_state=None, alpha_method=1, + survey_names=None, + add_20220610A=False, + nz:int=2000, ndm:int=5600): + """ Load up a survey and grid for a real dataset Args: init_state (State, optional): @@ -93,8 +96,14 @@ def surveys_and_grids(init_state=None, alpha_method=1, add_20220610A=False): survey_name (str, optional): Defaults to 'CRAFT/CRACO_1_5000'. state_dict (dict, optional): Used to init state instead of alpha_method, lum_func parameters + survey_names (list, optional): + List of surveys to load add_20220610A (bool, optional): Include this FRB (a bit of a hack) + nz (int, optional): + Number of redshift bins + ndm (int, optional): + Number of DM bins Raises: IOError: [description] @@ -114,14 +123,16 @@ def surveys_and_grids(init_state=None, alpha_method=1, add_20220610A=False): # get the grid of p(DM|z) zDMgrid, zvals,dmvals = misc_functions.get_zdm_grid( - state, new=True, plot=False, method='analytic', nz=5000, + state, new=True, plot=False, method='analytic', + nz=nz, ndm=ndm, datdir=resource_filename('zdm', 'GridData')) ############## Initialise surveys ############## - survey_names = ['CRAFT/FE', - 'private_CRAFT_ICS_1632', - 'private_CRAFT_ICS_892', - 'private_CRAFT_ICS', + if survey_names is None: + survey_names = ['CRAFT/FE', + 'CRAFT_ICS_1632', + 'CRAFT_ICS_892', + 'CRAFT_ICS_1272', 'PKS/Mb'] if add_20220610A: survey_names[3] = 'CRAFT_ICS_w_220610' @@ -132,7 +143,7 @@ def surveys_and_grids(init_state=None, alpha_method=1, add_20220610A=False): print(f"Initializing {survey_name}") surveys.append(survey.load_survey(survey_name, state, dmvals, - Nbeams=nbeam)) + nbins=nbeam)) print("Initialised surveys") # generates zdm grid diff --git a/zdm/scripts/plot_grid_components.py b/zdm/scripts/plot_grid_components.py index 49648b06..cb76c293 100644 --- a/zdm/scripts/plot_grid_components.py +++ b/zdm/scripts/plot_grid_components.py @@ -47,10 +47,10 @@ def main(): H0=80 - F=0.32 + logF=np.log10(0.32) # in case you wish to switch to another output directory - opdir='GridComponents_H'+str(H0)+'_F'+str(F)+'/' + opdir='GridComponents_H'+str(H0)+'_logF'+str(logF)+'/' if not os.path.exists(opdir): os.mkdir(opdir) @@ -61,7 +61,7 @@ def main(): # approximate best-fit values from recent analysis vparams = {} vparams['H0'] = H0 #real one is 73 - vparams['F'] = F + vparams['logF'] = logF vparams['lEmax'] = 41.3 vparams['gamma'] = -0.9 vparams['alpha'] = 1 diff --git a/zdm/scripts/plot_limits_from_cube.py b/zdm/scripts/plot_limits_from_cube.py new file mode 100644 index 00000000..40dacd49 --- /dev/null +++ b/zdm/scripts/plot_limits_from_cube.py @@ -0,0 +1,235 @@ +""" +This is a script to produce limit plots for a cube + +It produces three sets of plots: +- single parameter limits with a prior on H0 between Planck and SN1a values +- single parameter limits also showing results with priors on H0 equal to: + a) Planck + b) Reiss + c) No prior +- 2D correlation plots with no prior onH0 + +It also collects data to plot a result on H0 for best-fit values of all +other parameters, but currently does not produce that plot + +""" + +import numpy as np +import os +import zdm +from zdm import analyze_cube as ac + +from matplotlib import pyplot as plt + + +def main(verbose=False): + ######### sets the values of H0 for priors ##### + Planck_H0 = 67.4 + Planck_sigma = 0.5 + Reiss_H0 = 73.04 + Reiss_sigma = 1.42 + + ##### loads cube data ##### + # cube = "../../papers/F/Analysis/Real/Cubes/craco_real_cube.npz" + cube = "../../papers/F/Analysis/CRACO/Cubes/craco_full_cube.npz" + data = np.load(cube) + if verbose: + for thing in data: + print(thing) + print(data["params"]) + + # gets values of cube parameters + # param_vals=get_param_values(data,verbose) + + # gets latex names + uvals, latexnames = get_names_values(data) + + ################ single plots, no priors ############ + deprecated, uw_vectors, wvectors = ac.get_bayesian_data(data["ll"]) + ac.do_single_plots( + uvals, + uw_vectors, + None, + data["params"], + tag="", + log=False, + logspline=False, + # kind="linear", + truth=None, + dolevels=True, + latexnames=latexnames, + ) + + ########### H0 data for fixed values of other parameters ########### + # extracts best-fit values + list1 = [] + vals1 = [] + list2 = [] + vals2 = [] + vals3 = [] + for i, vec in enumerate(uw_vectors): + n = np.argmax(vec) # selects the most likely value + val = uvals[i][n] + if data["params"][i] == "H0": + # enables us to select a slice corresponding to particular H0 values + list1.append(data["params"][i]) + vals1.append(Reiss_H0) + + vals3.append(Planck_H0) + + iH0 = i # setting index for Hubble + else: + # enables us to select a slice correspondng to the best-fit values of all other params + # i.e. ignoring uncertainty in them + list2.append(data["params"][i]) + vals2.append(val) + + # gets the slice corresponding to specific values of H0 + Reiss_H0_selection = ac.get_slice_from_parameters(data, list1, vals1, verbose=True) + Planck_H0_selection = ac.get_slice_from_parameters(data, list1, vals3, verbose=True) + + # will have Bayesian limits on all parameters over everything but H0 + deprecated, ReissH0_vectors, deprecated = ac.get_bayesian_data(Reiss_H0_selection) + deprecated, PlanckH0_vectors, deprecated = ac.get_bayesian_data(Planck_H0_selection) + + # gets the slice corresponding to the best-fit values of all other parameters + # this is 1D, so is our limit on H0 keeping all others fixed + pH0_fixed = ac.get_slice_from_parameters(data, list2, vals2) + + ####### 1D plots for prior on H0 ######## + # generates plots for our standard prior on H0 only + # applies a prior on H0, which is flat between systematic differences, then falls off as a Gaussian either side + H0_dim = np.where(data["params"] == "H0")[0][0] + wlls = ac.apply_H0_prior( + data["ll"], H0_dim, data["H0"], Planck_H0, Planck_sigma, Reiss_H0, Reiss_sigma + ) + deprecated, wH0_vectors, wvectors = ac.get_bayesian_data(wlls) + ac.do_single_plots( + uvals, + wH0_vectors, + None, + data["params"], + tag="wH0_", + truth=None, + dolevels=True, + latexnames=latexnames, + logspline=False, + ) + + # now do this with others... + # builds others... + others = [] + for i, p in enumerate(data["params"]): + if i == iH0: + oset = None + others.append(oset) + else: + if i < iH0: + modi = i + else: + modi = i - 1 + oset = [uw_vectors[i], ReissH0_vectors[modi], PlanckH0_vectors[modi]] + others.append(oset) + + # generates plots for our standard prior on H0, Planck and SN1a values, and no prior also + ac.do_single_plots( + uvals, + wH0_vectors, + None, + data["params"], + tag="wH0_others_", + truth=None, + dolevels=True, + latexnames=latexnames, + logspline=False, + others=others, + others_labels=["No Prior", r"$H_0 = 73.04$", r"$H_0 = 67.4$"], + ) + + ############## 2D plots for total likelihood ########### + # these are for nor priors on anything + baduvals, ijs, arrays, warrays = ac.get_2D_bayesian_data(data["ll"]) + for which, array in enumerate(arrays): + i = ijs[which][0] + j = ijs[which][1] + + savename = "2D/lls_" + data["params"][i] + "_" + data["params"][j] + ".png" + ac.make_2d_plot( + array, latexnames[i], latexnames[j], uvals[i], uvals[j], savename=savename + ) + # ac.make_2d_plot(array,latexnames[i],latexnames[j], + # param_vals[i],param_vals[j], + # savename=savename) + if False and data["params"][i] == "H0": + savename = ( + "normed2D/lls_" + data["params"][j] + "_" + data["params"][i] + ".png" + ) + + ac.make_2d_plot( + array.T, + latexnames[j], + latexnames[i], + uvals[j], + uvals[i], + savename=savename, + norm=1, + ) + + +def get_names_values(data): + """ + Gets a list of latex names and corrected parameter values + """ + # builds uvals list + uvals = [] + latexnames = [] + for ip, param in enumerate(data["params"]): + # switches for alpha + if param == "alpha": + uvals.append(data[param] * -1.0) + else: + uvals.append(data[param]) + if param == "alpha": + latexnames.append("$\\alpha$") + ialpha = ip + elif param == "lEmax": + latexnames.append("$\\log_{10} E_{\\rm max}$") + elif param == "H0": + latexnames.append("$H_0$") + elif param == "gamma": + latexnames.append("$\\gamma$") + elif param == "sfr_n": + latexnames.append("$n_{\\rm sfr}$") + elif param == "lmean": + latexnames.append("$\\mu_{\\rm host}$") + elif param == "lsigma": + latexnames.append("$\\sigma_{\\rm host}$") + elif param == "logF": + latexnames.append("$\\log F$") + return uvals, latexnames + + +def get_param_values(data, verbose=False): + """ + Returns the unique cube values for each parameter in the cube + + Input: + data cube (tuple from reading the .npz) + + Output: + list of numpy arrays for each parameter giving their values + """ + # gets unique values for each axis + param_vals = [] + + # for col in param_list: + for col in data["params"]: + # unique=np.unique(col) + unique = np.unique(data[col]) + param_vals.append(unique) + if verbose: + print("For parameter ", col, " cube values are ", unique) + return param_vals + + +main() diff --git a/zdm/scripts/plot_pzdm_grid.py b/zdm/scripts/plot_pzdm_grid.py index ec3df435..e7b44cf7 100644 --- a/zdm/scripts/plot_pzdm_grid.py +++ b/zdm/scripts/plot_pzdm_grid.py @@ -19,60 +19,66 @@ from zdm import survey from matplotlib import pyplot as plt + def main(): - + # in case you wish to switch to another output directory - opdir='Localised_FRBs/' + opdir = "Localised_FRBs/" if not os.path.exists(opdir): os.mkdir(opdir) - + # Initialise surveys and grids - + # The below is for private, unpublished FRBs. You will NOT see this in the repository! - names = ['private_CRAFT_ICS','private_CRAFT_ICS_892','private_CRAFT_ICS_1632'] - sdir='../data/Surveys/' - + # names = ['private_CRAFT_ICS','private_CRAFT_ICS_892','private_CRAFT_ICS_1632'] + sdir = "../data/Surveys/" + # Public CRAFT FRBs - #names = ['CRAFT_ICS','CRAFT_ICS_892','CRAFT_ICS_1632'] - - #Examples for other FRB surveys - #names = ['FAST','Arecibo','parkes_mb_class_I_and_II'] - + # names = ["CRAFT_ICS", "CRAFT_ICS_892", "CRAFT_ICS_1632"] + + # Examples for other FRB surveys + # names = ["FAST", "Arecibo", "parkes_mb_class_I_and_II"] + + names = ["parkes_mb_class_I_and_II"] + # if True, this generates a summed histogram of all the surveys, weighted by # the observation time - sumit=True - + sumit = True + # approximate best-fit values from recent analysis vparams = {} - vparams['H0'] = 73 - vparams['lEmax'] = 41.3 - vparams['gamma'] = -0.9 - vparams['alpha'] = 1 - vparams['sfr_n'] = 1.15 - vparams['lmean'] = 2.25 - vparams['lsigma'] = 0.55 - - zvals=[] - dmvals=[] - grids=[] - surveys=[] - nozlist=[] - for i,name in enumerate(names): - s,g = loading.survey_and_grid( - survey_name=name,NFRB=None,sdir=sdir) # should be equal to actual number of FRBs, but for this purpose it doesn't matter + vparams["H0"] = 73 + vparams["lEmax"] = 41.3 + vparams["gamma"] = -0.9 + vparams["alpha"] = 1 + vparams["sfr_n"] = 1.15 + vparams["lmean"] = 2.25 + vparams["lsigma"] = 0.55 + + zvals = [] + dmvals = [] + grids = [] + surveys = [] + nozlist = [] + for i, name in enumerate(names): + s, g = loading.survey_and_grid( + survey_name=name, NFRB=10, sdir=sdir + ) # should be equal to actual number of FRBs, but for this purpose it doesn't matter grids.append(g) surveys.append(s) - + + print("[TEST] s_type: ", s.TOBS) + # set up new parameters g.update(vparams) - + # gets cumulative rate distribution - if i==0: - rtot = np.copy(g.rates)*s.TOBS + if i == 0: + rtot = np.copy(g.rates) * s.TOBS else: - rtot += g.rates*s.TOBS - - if name=='Arecibo': + rtot += g.rates * s.TOBS + + if name == "Arecibo": # remove high DM vals from rates as per ALFA survey limit delete=np.where(g.dmvals > 2038)[0] g.rates[:,delete]=0. @@ -84,21 +90,43 @@ def main(): nozlist.append(dm) print("About to plot") ############# do 2D plots ########## - misc_functions.plot_grid_2(g.rates,g.zvals,g.dmvals, - name=opdir+name+'.pdf',norm=3,log=True,label='$\\log_{10} p({\\rm DM}_{\\rm EG},z)$ [a.u.]', - project=False,FRBDM=s.DMEGs,FRBZ=s.frbs["Z"],Aconts=[0.01,0.1,0.5],zmax=1.5, - DMmax=1500)#,DMlines=s.DMEGs[s.nozlist]) - + misc_functions.plot_grid_2( + g.rates, + g.zvals, + g.dmvals, + name=opdir + name + ".pdf", + norm=3, + log=True, + label="$\\log_{10} p({\\rm DM}_{\\rm EG},z)$ [a.u.]", + project=False, + FRBDM=s.DMEGs, + FRBZ=s.frbs["Z"], + Aconts=[0.01, 0.1, 0.5], + zmax=1.5, + DMmax=1500, + ) # ,DMlines=s.DMEGs[s.nozlist]) + if sumit: # does the final plot of all data - frbzvals=np.array(zvals) - frbdmvals=np.array(dmvals) + frbzvals = np.array(zvals) + frbdmvals = np.array(dmvals) ############# do 2D plots ########## - misc_functions.plot_grid_2(g.rates,g.zvals,g.dmvals, - name=opdir+'combined_localised_FRBs.pdf',norm=3,log=True, - label='$\\log_{10} p({\\rm DM}_{\\rm EG},z)$ [a.u.]', - project=False,FRBDM=frbdmvals,FRBZ=frbzvals,Aconts=[0.01,0.1,0.5], - zmax=1.5,DMmax=2000,DMlines=nozlist) - - + misc_functions.plot_grid_2( + g.rates, + g.zvals, + g.dmvals, + name=opdir + "combined_localised_FRBs.pdf", + norm=3, + log=True, + label="$\\log_{10} p({\\rm DM}_{\\rm EG},z)$ [a.u.]", + project=False, + FRBDM=frbdmvals, + FRBZ=frbzvals, + Aconts=[0.01, 0.1, 0.5], + zmax=1.5, + DMmax=2000, + DMlines=nozlist, + ) + + main() diff --git a/zdm/survey.py b/zdm/survey.py index 14c77990..a83a8e48 100644 --- a/zdm/survey.py +++ b/zdm/survey.py @@ -531,13 +531,13 @@ def process_survey_file(self,filename:str, if self.NFRB < NFRB+iFRB: raise ValueError("Cannot return sufficient FRBs, did you mean NFRB=None?") # Not sure the following linematters given the Error above - themax = min(NFRB+iFRB,self.NFRB) + themax = max(NFRB+iFRB,self.NFRB) self.frbs=self.frbs[iFRB:themax] # Vet vet_frb_table(self.frbs, mandatory=True) # Pandas resolves None to Nan - if np.isfinite(self.frbs["Z"][0]): + if np.isfinite(self.frbs["Z"].values[0]): self.Zs=self.frbs["Z"].values # checks for any redhsifts identically equal to zero @@ -982,7 +982,6 @@ def load_survey(survey_name:str, state:parameters.State, Returns: Survey: instance of the class """ - print(f"Loading survey: {survey_name}") if sdir is None: sdir = os.path.join( resource_filename('zdm', 'data'), 'Surveys') @@ -998,6 +997,7 @@ def load_survey(survey_name:str, state:parameters.State, dfile = 'CRAFT_ICS_892' elif survey_name == 'CRAFT/ICS1632': dfile = 'CRAFT_ICS_1632' + elif survey_name == 'PKS/Mb': dfile = 'parkes_mb_class_I_and_II' elif 'private' in survey_name: @@ -1016,6 +1016,8 @@ def load_survey(survey_name:str, state:parameters.State, else: dfile += '.ecsv' + print(f"Loading survey: {survey_name} from {dfile}") + # Do it if original: srvy=OldSurvey() @@ -1052,9 +1054,16 @@ def refactor_old_survey_file(survey_name:str, outfile:str, srvy_data = survey_data.SurveyData() # Load up original + + # temporary workaround for private survey files... sorry X! + + nbins = None + if 'private' in survey_name: + nbins = 5 # only works for the CRAFT private samples + isurvey = load_survey(survey_name, state, np.linspace(0., 2000., 1000), - original=True) + original=True, nbins=nbins) # FRBs frbs = pandas.DataFrame(isurvey.frbs) @@ -1115,7 +1124,7 @@ def refactor_old_survey_file(survey_name:str, outfile:str, separators=(',', ': ')) # Write me - frbs.write(outfile, overwrite=clobber) + frbs.write(outfile, overwrite=clobber, format='ascii.ecsv') print(f"Wrote: {outfile}") def vet_frb_table(frb_tbl:pandas.DataFrame, diff --git a/zdm/tests/Performance/test_update_performance.py b/zdm/tests/Performance/test_update_performance.py index 44f152d9..b21c1fe8 100644 --- a/zdm/tests/Performance/test_update_performance.py +++ b/zdm/tests/Performance/test_update_performance.py @@ -127,9 +127,9 @@ def test_performance(likelihoods=True,detail=0,verbose=True): # retrieves a state state=grids[0].state #list of parameters to vary - plist=['H0','F','lEmin','lEmax','gamma','alpha','sfr_n','lmean','lsigma'] + plist=['H0','logF','lEmin','lEmax','gamma','alpha','sfr_n','lmean','lsigma'] # original values for the loop - ovals=[state.cosmo.H0,state.IGM.F, + ovals=[state.cosmo.H0,state.IGM.logF, state.energy.lEmin,state.energy.lEmax,state.energy.gamma,state.energy.alpha, state.FRBdemo.sfr_n, state.host.lmean,state.host.lsigma] diff --git a/zdm/tests/files/craco_H0_Emax_state.json b/zdm/tests/files/craco_H0_Emax_state.json index 0efc21a7..f5f20b13 100644 --- a/zdm/tests/files/craco_H0_Emax_state.json +++ b/zdm/tests/files/craco_H0_Emax_state.json @@ -6,7 +6,7 @@ "source_evolution": 0 }, "IGM": { - "F": 0.32 + "logF": -0.49485 }, "MW": { "DMhalo": 50, diff --git a/zdm/tests/files/scat_test_new.json b/zdm/tests/files/scat_test_new.json index 6a604e2c..a8148fe1 100644 --- a/zdm/tests/files/scat_test_new.json +++ b/zdm/tests/files/scat_test_new.json @@ -6,7 +6,7 @@ "source_evolution": 0 }, "IGM": { - "F": 0.32 + "logF": -0.49485 }, "MW": { "DMhalo": 50, @@ -54,4 +54,4 @@ "Sfnorm": 600, "Sfpower": -4 } -} +} \ No newline at end of file diff --git a/zdm/tests/files/scat_test_old.json b/zdm/tests/files/scat_test_old.json index 35fcee09..6b661134 100644 --- a/zdm/tests/files/scat_test_old.json +++ b/zdm/tests/files/scat_test_old.json @@ -6,7 +6,7 @@ "source_evolution": 0 }, "IGM": { - "F": 0.32 + "logF": -0.49485 }, "MW": { "DMhalo": 50, @@ -54,4 +54,4 @@ "Sfnorm": 600, "Sfpower": -4 } -} +} \ No newline at end of file diff --git a/zdm/tests/test_cube.py b/zdm/tests/test_cube.py index 10da3bc1..eb5470f4 100644 --- a/zdm/tests/test_cube.py +++ b/zdm/tests/test_cube.py @@ -9,7 +9,7 @@ import pandas from zdm import iteration as it -from zdm.craco import loading +from zdm import real_loading from zdm import io from zdm.tests import tstutils @@ -30,16 +30,23 @@ def test_cube_run(): # Initialise survey and grid # For this purporse, we only need two different surveys #names=['CRAFT/FE','CRAFT/ICS','CRAFT/ICS892','CRAFT/ICS1632','PKS/Mb'] - names=['CRAFT/FE','CRAFT/ICS','CRAFT/ICS892','PKS/Mb'] - sdir = os.path.join(resource_filename('zdm', 'data'), 'Surveys') - surveys=[] - grids=[] + names=['CRAFT/FE','CRAFT/ICS','CRAFT/ICS892', + 'PKS/Mb'] + #sdir = os.path.join(resource_filename('zdm', 'data'), 'Surveys') + #surveys=[] + #grids=[] + + ''' + # We should be using real_loading for name in names: - # We should be using real_loading s,g = loading.survey_and_grid( survey_name=name,NFRB=None,sdir=sdir) # should be equal to actual number of FRBs, but for this purpose it doesn't matter surveys.append(s) grids.append(g) + ''' + surveys, grids = real_loading.surveys_and_grids( + survey_names=names, + nz=500, ndm=1400) # Small number to keep this cheap ### gets cube files @@ -108,33 +115,5 @@ def test_cube_run(): zdm_v2= ds.p_DMgz + ds.p_z assert check_accuracy(zdm_v1,zdm_v2) - ''' - # now check it has the right dimensions - with open(outfile, 'r') as infile: - lines=infile.readlines() - assert len(lines)==howmany+1 - for i,line in enumerate(lines): - if i==0: - colmns = line.split(',') - continue - words=line.split(',') - - embed(header='106 of test_cube') - # three ways of calculating lltot - lltot_v0=float(words[-8]) - lltot_v1=0 - for j in np.arange(ns): - lltot_v1 += float(words[9+5*j]) - lltot_v2=float(words[-5])+float(words[-6])+float(words[-7]) - - # three ways of calculating p(z,DM) - zdm_v1=float(words[-3])+float(words[-4]) - zdm_v2=float(words[-1])+float(words[-2]) - - assert check_accuracy(zdm_v1,zdm_v2) - - assert check_accuracy(lltot_v0,lltot_v1) - assert check_accuracy(lltot_v0,lltot_v2) - ''' -#test_cube_run() \ No newline at end of file +#test_cube_run() \ No newline at end of file