diff options
| author | tlatorre <tlatorre@uchicago.edu> | 2019-06-26 17:05:13 -0500 | 
|---|---|---|
| committer | tlatorre <tlatorre@uchicago.edu> | 2019-06-26 17:05:13 -0500 | 
| commit | e331bf9b2a87aa83be41bdf785ecd65aec46947f (patch) | |
| tree | 12ed84b50ed72b19a32d53e79968d4c279a7656f /utils/plot-energy | |
| parent | 5016143a42b57c47e9916bbb70de2ae2669cbc8f (diff) | |
| download | sddm-e331bf9b2a87aa83be41bdf785ecd65aec46947f.tar.gz sddm-e331bf9b2a87aa83be41bdf785ecd65aec46947f.tar.bz2 sddm-e331bf9b2a87aa83be41bdf785ecd65aec46947f.zip | |
update plot-energy script
Tidy up the code in the script by creating a function to plot the energy
distributions for each particle combo. Also fixed a bug which was causing the
neutron follower cut not to be applied.
Diffstat (limited to 'utils/plot-energy')
| -rwxr-xr-x | utils/plot-energy | 199 | 
1 files changed, 59 insertions, 140 deletions
| diff --git a/utils/plot-energy b/utils/plot-energy index f62ac0e..705e53e 100755 --- a/utils/plot-energy +++ b/utils/plot-energy @@ -51,13 +51,36 @@ DC_OWL            = 0x80  DC_OWL_TRIGGER    = 0x100  DC_FTS            = 0x200 -def plot_hist(x, label=None): -    # determine the bin width using the Freedman Diaconis rule -    # see https://en.wikipedia.org/wiki/Freedman%E2%80%93Diaconis_rule -    h = 2*iqr(x)/len(x)**(1/3) -    n = max(int((np.max(x)-np.min(x))/h),10) -    bins = np.linspace(np.min(x),np.max(x),n) -    plt.hist(x, bins=bins, histtype='step', label=label) +def plot_hist(df, title=None): +    for id, df_id in sorted(df.groupby('id')): +        if id == 20: +            plt.subplot(3,4,1) +        elif id == 22: +            plt.subplot(3,4,2) +        elif id == 2020: +            plt.subplot(3,4,5) +        elif id == 2022: +            plt.subplot(3,4,6) +        elif id == 2222: +            plt.subplot(3,4,7) +        elif id == 202020: +            plt.subplot(3,4,9) +        elif id == 202022: +            plt.subplot(3,4,10) +        elif id == 202222: +            plt.subplot(3,4,11) +        elif id == 222222: +            plt.subplot(3,4,12) + +        plt.hist(df_id.ke.values, bins=np.linspace(20,10e3,100), histtype='step') +        plt.xlabel("Energy (MeV)") +        plt.title(str(id)) + +    if title: +        plt.suptitle(title) + +    if len(df): +        plt.tight_layout()  def chunks(l, n):      """Yield successive n-sized chunks from l.""" @@ -195,27 +218,26 @@ if __name__ == '__main__':      print("number of events = %i" % len(df_ev)) -    # First, do basic data cleaning which is done for all events +    # First, do basic data cleaning which is done for all events.      df_ev = df_ev[df_ev.dc & (DC_JUNK | DC_CRATE_ISOTROPY | DC_QVNHIT | DC_FLASHER | DC_NECK) == 0]      print("number of events after data cleaning = %i" % len(df_ev)) -    # Now, we select events tagged by the muon tag which should tag only external muons -    # We keep the sample of muons since it's needed later to identify Michel -    # electrons and to apply the muon follower cut +    # Now, we select events tagged by the muon tag which should tag only +    # external muons. We keep the sample of muons since it's needed later to +    # identify Michel electrons and to apply the muon follower cut      muons = df_ev[(df_ev.dc & DC_MUON) != 0]      print("number of muons = %i" % len(muons)) -    # select prompt events -    # FIXME: how to deal with two prompt events one after another -    prompt = df_ev[df_ev.nhit >= 100] - +    # Now, select prompt events. +    #      # We define a prompt event here as any event with an NHIT > 100 and whose      # previous > 100 nhit event was more than 250 ms ago      #      # Should I use 10 MHz clock here since the time isn't critical and then I      # don't have to worry about 50 MHz clock rollover? +    prompt = df_ev[df_ev.nhit >= 100]      prompt_mask = np.concatenate(([True],np.diff(prompt.gtr.values) > 250e6))      # Michel electrons and neutrons can be any event which is not a prompt @@ -244,12 +266,13 @@ if __name__ == '__main__':          # The 800 nanoseconds cut comes from Richie's thesis. He also mentions          # that the In Time Channel Spread Cut is very effective at cutting          # electrons events caused by muons, so I should implement that -        michel = michel[np.any((michel.gtr.values > prompt_plus_muons.gtr.values[:,np.newaxis] + 800) & (michel.gtr.values < prompt_plus_muons.gtr.values[:,np.newaxis] + 20e3),axis=0)] +        michel = michel[np.any((michel.run.values == prompt_plus_muons.run.values[:,np.newaxis]) & \ +                               (michel.gtr.values > prompt_plus_muons.gtr.values[:,np.newaxis] + 800) & \ +                               (michel.gtr.values < prompt_plus_muons.gtr.values[:,np.newaxis] + 20e3),axis=0)]      else: -        michel = prompt_plus_muons.copy() +        michel = pd.DataFrame().reindex_like(follower)      if prompt.size and follower.size: -        # FIXME: need to deal with 50 MHz clock rollover          # neutron followers have to obey stricter set of data cleaning cuts          neutron = follower[follower.dc & (DC_JUNK | DC_CRATE_ISOTROPY | DC_QVNHIT | DC_FLASHER | DC_NECK | DC_ESUM | DC_OWL | DC_OWL_TRIGGER | DC_FTS) == DC_FTS]          neutron = neutron[~np.isnan(neutron.ftpx) & ~np.isnan(neutron.rsp_energy)] @@ -257,11 +280,15 @@ if __name__ == '__main__':          neutron = neutron[r < AV_RADIUS]          neutron = neutron[neutron.rsp_energy > 4.0]          # neutron events accepted after 20 microseconds and before 250 ms (50 ms during salt) -        df_atm = prompt[np.any((neutron.gtr.values > prompt.gtr.values[:,np.newaxis] + 20e3) & (neutron.gtr.values < prompt.gtr.values[:,np.newaxis] + 250e6),axis=1)] -        df_ev = prompt[~np.any((neutron.gtr.values > prompt.gtr.values[:,np.newaxis] + 20e3) & (neutron.gtr.values < prompt.gtr.values[:,np.newaxis] + 250e6),axis=1)] +        # FIXME: need to deal with 50 MHz clock rollover +        neutron_mask = np.any((neutron.run.values == prompt.run.values[:,np.newaxis]) & \ +                              (neutron.gtr.values > prompt.gtr.values[:,np.newaxis] + 20e3) & \ +                              (neutron.gtr.values < prompt.gtr.values[:,np.newaxis] + 250e6),axis=1) +        df_atm = prompt[neutron_mask] +        prompt = prompt[~neutron_mask]      else: -        df_ev = prompt -        df_atm = prompt +        prompt = prompt +        df_atm = pd.DataFrame().reindex_like(prompt)      print("number of events after neutron follower cut = %i" % len(df_ev)) @@ -273,9 +300,9 @@ if __name__ == '__main__':      if muons.size:          # FIXME: need to deal with 50 MHz clock rollover          # remove events 200 microseconds after a muon -        prompt = prompt[~np.any((prompt.gtr.values > muons.gtr.values[:,np.newaxis]) & (prompt.gtr.values <= (muons.gtr.values[:,np.newaxis] + 200e3)),axis=0)] - -    print("number of events after muon follower cut = %i" % len(df_ev)) +        prompt = prompt[~np.any((prompt.run.values == muons.run.values[:,np.newaxis]) & \ +                                (prompt.gtr.values > muons.gtr.values[:,np.newaxis]) & \ +                                (prompt.gtr.values <= (muons.gtr.values[:,np.newaxis] + 200e3)),axis=0)]      df_atm = pd.merge(df,df_atm,how='inner',on=['run','gtid'])      muons = pd.merge(df,muons,how='inner',on=['run','gtid']) @@ -314,125 +341,15 @@ if __name__ == '__main__':      # Note: Need to design and apply a psi based cut here      plt.figure() -    for id, df_id in sorted(df.groupby('id')): -        if id == 20: -            plt.subplot(3,4,1) -        elif id == 22: -            plt.subplot(3,4,2) -        elif id == 2020: -            plt.subplot(3,4,5) -        elif id == 2022: -            plt.subplot(3,4,6) -        elif id == 2222: -            plt.subplot(3,4,7) -        elif id == 202020: -            plt.subplot(3,4,9) -        elif id == 202022: -            plt.subplot(3,4,10) -        elif id == 202222: -            plt.subplot(3,4,11) -        elif id == 222222: -            plt.subplot(3,4,12) - -        plt.hist(df_id.ke.values, bins=np.linspace(20,10e3,100), histtype='step') -        plt.xlabel("Energy (MeV)") -        plt.title(str(id)) - -    plt.suptitle("Without Neutron Follower") - -    if len(df): -        plt.tight_layout() - +    plot_hist(df,"Without Neutron Follower")      plt.figure() -    for id, df_atm_id in sorted(df_atm.groupby('id')): -        if id == 20: -            plt.subplot(3,4,1) -        elif id == 22: -            plt.subplot(3,4,2) -        elif id == 2020: -            plt.subplot(3,4,5) -        elif id == 2022: -            plt.subplot(3,4,6) -        elif id == 2222: -            plt.subplot(3,4,7) -        elif id == 202020: -            plt.subplot(3,4,9) -        elif id == 202022: -            plt.subplot(3,4,10) -        elif id == 202222: -            plt.subplot(3,4,11) -        elif id == 222222: -            plt.subplot(3,4,12) - -        plt.hist(df_atm_id.ke.values, bins=np.linspace(20,10e3,100), histtype='step') -        plt.xlabel("Energy (MeV)") -        plt.title(str(id)) - -    plt.suptitle("With Neutron Follower") - -    if len(df_atm): -        plt.tight_layout() - +    plot_hist(df_atm,"With Neutron Follower")      plt.figure() -    for id, michel_id in sorted(michel_best_fit.groupby('id')): -        if id == 20: -            plt.subplot(3,4,1) -        elif id == 22: -            plt.subplot(3,4,2) -        elif id == 2020: -            plt.subplot(3,4,5) -        elif id == 2022: -            plt.subplot(3,4,6) -        elif id == 2222: -            plt.subplot(3,4,7) -        elif id == 202020: -            plt.subplot(3,4,9) -        elif id == 202022: -            plt.subplot(3,4,10) -        elif id == 202222: -            plt.subplot(3,4,11) -        elif id == 222222: -            plt.subplot(3,4,12) - -        plt.hist(michel_id.ke.values, bins=np.linspace(20,10e3,100), histtype='step') -        plt.xlabel("Energy (MeV)") -        plt.title(str(id)) - -    plt.suptitle("Michel Electrons") - -    if len(michel): -        plt.tight_layout() - +    plot_hist(michel_best_fit,"Michel Electrons")      plt.figure() -    for id, muon_id in sorted(muon_best_fit.groupby('id')): -        if id == 20: -            plt.subplot(3,4,1) -        elif id == 22: -            plt.subplot(3,4,2) -        elif id == 2020: -            plt.subplot(3,4,5) -        elif id == 2022: -            plt.subplot(3,4,6) -        elif id == 2222: -            plt.subplot(3,4,7) -        elif id == 202020: -            plt.subplot(3,4,9) -        elif id == 202022: -            plt.subplot(3,4,10) -        elif id == 202222: -            plt.subplot(3,4,11) -        elif id == 222222: -            plt.subplot(3,4,12) - -        plt.hist(muon_id.ke.values, bins=np.linspace(20,10e3,100), histtype='step') -        plt.xlabel("Energy (MeV)") -        plt.title(str(id)) - -    plt.suptitle("External Muons") - -    if len(muon_best_fit): -        plt.tight_layout() +    plot_hist(muon_best_fit,"External Muons") +    # Plot the energy and angular distribution for external muons      plt.figure()      plt.subplot(2,1,1)      plt.hist(muons.ke.values, bins=np.logspace(3,7,100), histtype='step') @@ -443,6 +360,8 @@ if __name__ == '__main__':      plt.xlabel(r"$\cos(\theta)$")      plt.suptitle("Muons") +    # For the Michel energy plot, we only look at the single particle electron +    # fit      michel = michel[michel.id == 20]      plt.figure() | 
