<jupyter_start><jupyter_text>_Building Graphs: True Edges_<jupyter_code>import glob, os, sys, yaml
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import pprint
import seaborn as sns
import trackml.dataset
import torch
from torch_geometric.data import Data
import itertools
# append parent dir
# sys.path.append('..')

# local imports
from src import draw_event
from src import compose_event<jupyter_output><empty_output><jupyter_text>_(+) - Input Data_<jupyter_code># mu- data (old)
# input_dir = './data_sets/pandaml/data_3.0_7.0_GeV/'

# mu+mu- data (current)
input_dir = './data_sets/pandaml/data_0.1_1.5_GeV/'

# pbarp data (coming)
# input_dir = os.environ['HOME']+'/current/2_deepana/pandaml/data/'
# Find All Input Data Files (hits.csv, cells.csv, particles.csv, truth.csv)
all_files = os.listdir(input_dir)

# Extract File Prefixes (use e.g. xxx-hits.csv)
suffix = '-hits.csv'
file_prefixes = sorted(os.path.join(input_dir, f.replace(suffix, ''))
                       for f in all_files if f.endswith(suffix))
# file_prefixes[:10]
event_id = 1
event_prefix = file_prefixes[event_id]
# load an event
hits, tubes, particles, truth = trackml.dataset.load_event(event_prefix)

# memory usage
mem_bytes = (hits.memory_usage(index=True).sum() 
             + tubes.memory_usage(index=True).sum() 
             + particles.memory_usage(index=True).sum() 
             + truth.memory_usage(index=True).sum())

print('{} memory usage {:.2f} MB'.format(os.path.basename(event_prefix), mem_bytes / 2**20))
hits.head()
tubes.head()
particles.head()
truth.head()<jupyter_output><empty_output><jupyter_text>_(+) - Build Event_- functions from _event_utils.py_<jupyter_code>event = compose_event(event_prefix,skewed=False)
draw_event(event,figsize=(10, 10));<jupyter_output><empty_output><jupyter_text>_Build Graphs_  _(A) - True Edges (Layerwise)_**True Graph** is the ground truth for GNN. It is built from creating edges from _`hits`_ from the same particle but in adjacent layers. For this purpose one has _`true_edges, hits = get_layerwise_edges(event)`_ function in the _`event_util.py`_.<jupyter_code># true_edges, hits = get_layerwise_edges(event)
# EDA on get_layerwise_edges(event)
hits = event
hits = hits.assign(
        R=np.sqrt(
            (hits.x - hits.vx) ** 2 + (hits.y - hits.vy) ** 2 + (hits.z - hits.vz) ** 2
        )
    )
hits = hits.sort_values("R").reset_index(drop=True).reset_index(drop=False)
hits.loc[hits["particle_id"] == 0, "particle_id"] = np.nan
hit_list = (
        hits.groupby(["particle_id", "layer_id"], sort=False)["index"]
        .agg(lambda x: list(x))
        .groupby(level=0)
        .agg(lambda x: list(x))
    )
hit_list
# get first row of hit list
row = hit_list.values[0]
row
# get elements of array from 0 to n-1 i.e. skipping the last element
row[0:-1]
# get elements of array from 1 to n i.e. skipping the first elemnet
row[1:]
true_edges = []
for row in hit_list.values:
    for i, j in zip(row[0:-1], row[1:]): # row is list: we take 0 to n-1 elements as row[0:-1], and 1 to n as row[1:]
        true_edges.extend(list(itertools.product(i, j))) # extend() will add an iterable (list, set, etc) to the end of true_edges list, append() add one element to end of list.
true_edges = np.array(true_edges).T<jupyter_output><empty_output><jupyter_text>* Now we have `true_edges` and corresponding `hits` (changed due to R parameter.)<jupyter_code># lets see how to access true_edges, 2D ndarray
true_edges
true_edges[0].size
true_edges[1].size<jupyter_output><empty_output><jupyter_text>_(+) - Plotting True Edges_- I have hit pairs in two arrays- Extract each pair (w/ `hit_id`) to plot- How to plot hit pairs for one track?<jupyter_code># lets get unique pids with freq (~ hits).
sel_pids, sel_pids_fr = np.unique(hits.particle_id, return_counts=True)
print(sel_pids)
# check size of true_edges
size = true_edges.shape[1]
print(size)
# plotting true_edges
plt.close('all')
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)

p_ids = np.unique(event.particle_id.values)
det = pd.read_csv("src/stt.csv")
skw = det.query('skewed==0')
nkw = det.query('skewed==1') # one look for +ve/-ve polarity

# detector layout
ax.scatter(skw.x.values, skw.y.values, s=20, facecolors='none', edgecolors='lightgreen')
ax.scatter(nkw.x.values, nkw.y.values, s=20, facecolors='none', edgecolors='coral')

# particle tracks
for pid in sel_pids:
    idx = hits.particle_id == pid
    ax.scatter(hits[idx].x.values, hits[idx].y.values, label='particle_id: %d' %pid)
    
# true edges
for iedge in range(true_edges.shape[1]):
    pt1 = hits.iloc[true_edges[0][iedge]]
    pt2 = hits.iloc[true_edges[1][iedge]]
    ax.plot([pt1.x, pt2.x], [pt1.y, pt2.y], color='k', alpha=0.3, lw=1.5)

ax.set_title('Event ID # %d' % event_id)
ax.set_xlabel('x [cm]')
ax.set_ylabel('y [cm]')
ax.set_xlim(-40, 40)
ax.set_ylim(-40, 40)
ax.grid(False)
ax.legend(fontsize=10, loc='best')
fig.tight_layout()
# fig.savefig("true_edges.png")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1455595380326563, 'fraction_numerical': 0.016129032258064516, 'mean_word_length': 4.656531531531532, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '207099', 'license': 'MIT', 'n_tokens_mistral': 1953, 'n_tokens_neox': 1883, 'n_words': 452, 'path': 'eda/stt_eda2.ipynb', 'repo_name': 'a-akram/ctd2022', 'size': '5022'}