Source code for pidp_tools.pid

import numpy as np

[docs] def dEdx_CDC(particle_df): """ Identifies particles based on their ionization energy loss in the GlueX Central Drift Chamber (CDC). Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", and "CDC dEdx". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on CDC ionization energy loss cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) p = (particle['px']**2 + particle['py']**2 + particle['pz']**2)**0.5 isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & (particle['CDC dEdx'] *10**6> np.exp(-2.5*p+2.3)+1.4) isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & (particle['CDC dEdx'] *10**6> np.exp(-4.9*p+2.3)+1.45) & (particle['CDC dEdx'] *10**6< np.exp(-4.36*p+2.3)+2.3) isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & (particle['CDC dEdx'] *10**6> 1.59) & (particle['CDC dEdx'] *10**6< 2.49) isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & (particle['CDC dEdx'] *10**6> 2.25) & (particle['CDC dEdx'] *10**6< 3.14) particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions
[docs] def dEdx_FDC(particle_df): """ Identifies particles based on their ionization energy loss in the GlueX Forward Drift Chambers (FDC). Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", and "FDC dEdx". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on FDC ionization energy loss cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) p = (particle['px']**2 + particle['py']**2 + particle['pz']**2)**0.5 isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & (particle['FDC dEdx'] *10**6> np.exp(-3.55*p+3.7)+1.3) isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & (particle['FDC dEdx'] *10**6> np.exp(-4.4*p+2)+1.3) & (particle['FDC dEdx'] *10**6< np.exp(-4.4*p+2)+2.3) isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & (particle['FDC dEdx'] *10**6> 1.45) & (particle['FDC dEdx'] *10**6 < 2.6) isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & (particle['FDC dEdx'] *10**6> 2) & (particle['FDC dEdx'] *10**6 < 3) particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions
[docs] def dEdx_SC(particle_df): """ Identifies particles based on their ionization energy loss in the GlueX Start Counter (SC). Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", and "SC dEdx". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on SC ionization energy loss cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) p = (particle['px']**2 + particle['py']**2 + particle['pz']**2)**0.5 isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & (particle['SC dEdx'] *10**3> np.exp(-4*p+3.2)+1.6) isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & (particle['SC dEdx'] *10**3> np.exp(-4.4*p+2.7)+1.2) & (particle['SC dEdx'] *10**3< np.exp(-4.6*p+3.1)+2.2) isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & (particle['SC dEdx'] *10**3> 1.3) & (particle['SC dEdx'] *10**3< 2.3) isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & (particle['SC dEdx'] *10**3> 1.3) & (particle['SC dEdx'] *10**3< 2.3) particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions
[docs] def dEdx_TOF(particle_df): """ Identifies particles based on their ionization energy loss in the GlueX Time of Flight (TOF) detector. Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", and "TOF dEdx". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on TOF ionization energy loss cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) p = (particle['px']**2 + particle['py']**2 + particle['pz']**2)**0.5 isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & (particle['TOF dEdx'] *10**4> np.exp(-2.2*p+3.9)+8.2) isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & (particle['TOF dEdx'] *10**4> np.exp(-0.4*p+0.8)+7.6) & (particle['TOF dEdx'] *10**4< np.exp(-0.4*p+1.4)+10) isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & (particle['TOF dEdx'] *10**4> 8.6) & (particle['TOF dEdx'] *10**4< 11) isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & (particle['TOF dEdx'] *10**4> 8.1) & (particle['TOF dEdx'] *10**4< 11) particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions
[docs] def TOF_TOF(particle_df): """ Identifies particles based on their time of flight, as measured by the GlueX Time of Flight (TOF) detector. Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", "TOF Time of Flight", and "TOF Calculated Time of Flight". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on TOF TOF cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) particle['TOF TOF Diff'] = np.abs(particle['TOF Time of Flight']-particle['TOF Calculated Time of Flight']) isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & (particle['TOF TOF Diff'] <= 0.6) isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & (particle['TOF TOF Diff'] <= 0.3) isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & (particle['TOF TOF Diff'] <= 0.5) isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & (particle['TOF TOF Diff'] <= 0.5) particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions
[docs] def TOF_BCal(particle_df): """ Identifies particles based on their time of flight, as measured by the GlueX Barrel Calorimeter (BCal). Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", "tShower", and "BCal Calculated Time of Flight". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on BCal TOF cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) particle['BCal TOF Diff'] = np.abs(particle['tShower']-particle['BCal Calculated Time of Flight']) isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & ( particle['BCal TOF Diff'] <= 1) isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & (particle['BCal TOF Diff'] <= 0.75) isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & (particle['BCal TOF Diff'] <= 1) isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & (particle['BCal TOF Diff'] <= 1) particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions
[docs] def TOF_SC(particle_df): """ Identifies particles based on their time of flight, as measured by the GlueX Start Counter (SC). Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", "SC Time of Flight", and "SC Calculated Time of Flight". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on SC TOF cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) particle['SC TOF Diff'] = np.abs(particle['SC Time of Flight']-particle['SC Calculated Time of Flight']) isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & (particle['SC TOF Diff'] <= 2.5) isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & (particle['SC TOF Diff'] <= 2.5) isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & (particle['SC TOF Diff'] <= 2.5) isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & (particle['SC TOF Diff'] <= 2.5) particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions
[docs] def TOF_FCal(particle_df): """ Identifies particles based on their time of flight, as measured by the GlueX Forward Calorimeter (FCal). Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", "tShower", and "FCal Calculated Time of Flight". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on FCal TOF cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) particle['FCal TOF Diff'] = np.abs(particle['tShower']-particle['FCal Calculated Time of Flight']) isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & (particle['FCal TOF Diff'] <= 2) isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & (particle['FCal TOF Diff'] <= 2.5) isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & (particle['FCal TOF Diff'] <= 2) isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & (particle['FCal TOF Diff'] <= 2) particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions
[docs] def TOF(particle_df): """ Identifies particles based on their best-available time of flight, as measured by the GlueX Barrel Calorimeter (BCal), Time of Flight (TOF) detector, Forward Calorimeter (FCal), or the Start Counter (SC). Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", "tShower", "BCal Calculated Time of Flight", "TOF Time of Flight", "TOF Calculated Time of Flight", "FCal Calculated Time of Flight", "SC Time of Flight", and "SC Calculated Time of Flight". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on best-available TOF cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) particle['BCal TOF Diff'] = np.abs(particle['tShower']-particle['BCal Calculated Time of Flight']) particle['TOF TOF Diff'] = np.abs(particle['TOF Time of Flight']-particle['TOF Calculated Time of Flight']) particle['FCal TOF Diff'] = np.abs(particle['tShower']-particle['FCal Calculated Time of Flight']) particle['SC TOF Diff'] = np.abs(particle['SC Time of Flight']-particle['SC Calculated Time of Flight']) hasBCal = particle['BCal Calculated Time of Flight'].notna() hasTOF = particle['TOF Time of Flight'].notna() hasFCal = particle['FCal Calculated Time of Flight'].notna() hasSC = particle['SC Time of Flight'].notna() p = (particle['px']**2 + particle['py']**2 + particle['pz']**2)**0.5 isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & ((hasBCal & (particle['BCal TOF Diff'] <= 1)) | (~hasBCal & hasTOF & (particle['TOF TOF Diff'] <= 0.6)) | (~hasBCal & ~hasTOF & hasFCal & (particle['FCal TOF Diff'] <= 2)) | (~hasBCal & ~hasTOF & ~hasFCal & hasSC & (particle['SC TOF Diff'] <= 2.5))) isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & ((hasBCal & (particle['BCal TOF Diff'] <= 0.75)) | (~hasBCal & hasTOF & (particle['TOF TOF Diff'] <= 0.3)) | (~hasBCal & ~hasTOF & hasFCal & (particle['FCal TOF Diff'] <= 2.5)) | (~hasBCal & ~hasTOF & ~hasFCal & hasSC & (particle['SC TOF Diff'] <= 2.5))) isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & ((hasBCal & (particle['BCal TOF Diff'] <= 1)) | (~hasBCal & hasTOF & (particle['TOF TOF Diff'] <= 0.5)) | (~hasBCal & ~hasTOF & hasFCal & (particle['FCal TOF Diff'] <= 2)) | (~hasBCal & ~hasTOF & ~hasFCal & hasSC & (particle['SC TOF Diff'] <= 2.5))) isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & ((hasBCal & (particle['BCal TOF Diff'] <= 1)) | (~hasBCal & hasTOF & (particle['TOF TOF Diff'] <= 0.5)) | (~hasBCal & ~hasTOF & hasFCal & (particle['FCal TOF Diff'] <= 2)) | (~hasBCal & ~hasTOF & ~hasFCal & hasSC & (particle['SC TOF Diff'] <= 2.5))) particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions
[docs] def DIRC(particle_df): """ Identifies particles based on their likelihood values produced by the GlueX Detection of Internally Reflected Cherenkov Radiation (DIRC) detector. Parameters ---------- particle_df \: :external:class:`pandas.DataFrame` A dataframe containing particles to be identified. The supplied dataframe must have the following columns: "px","py","pz", "Hypothesis", "lp", "lk", "lpi", and "lele". Returns ------- predictions \: :external:class:`pandas.Series` The predictions based on DIRC likelihood cuts. """ particle = particle_df.copy() particle_list = ["Photon","KLong","Neutron","Proton","K+","Pi+","AntiMuon","Positron","AntiProton","K-","Pi-","Muon","Electron","No ID"] if not isinstance(particle['Hypothesis'][0], str): particle['Hypothesis'].apply(lambda x: particle_list[int(x)]) hasDIRC = particle['lp'].notna() maxLik = particle[['lp','lk','lpi','lele']].max() isProton = ((particle['Hypothesis'] == "Proton") | (particle['Hypothesis'] == "AntiProton")) & (maxLik == particle['lp']) & hasDIRC isK = ((particle['Hypothesis'] == "K+") | (particle['Hypothesis'] == "K-")) & (maxLik == particle['lk']) & hasDIRC isPi = ((particle['Hypothesis'] == "Pi+") | (particle['Hypothesis'] == "Pi-")) & (maxLik == particle['lpi']) & hasDIRC isElectron = ((particle['Hypothesis'] == "Electron") | (particle['Hypothesis'] == "Positron")) & (maxLik == particle['lele']) & hasDIRC particle['matches hypothesis'] = isProton | isK | isPi | isElectron def temp_match(row): if row['matches hypothesis']: return row['Hypothesis'] else: return "No ID" predictions = particle.apply(temp_match, axis=1) return predictions