feat: add invariant mass analysis script for secondary vertexing DIS#261
feat: add invariant mass analysis script for secondary vertexing DIS#261
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new secondary vertexing benchmark for Deep Inelastic Scattering (DIS) events that analyzes invariant mass distributions from reconstructed secondary vertices. The benchmark reuses simulations from the existing tracking_performances_dis benchmark and adds a Python analysis script to calculate and visualize invariant mass spectra, focusing on kaon candidate identification.
Changes:
- Added a new Python analysis script for invariant mass analysis of secondary vertices
- Created configuration and Snakefile for the secondary_vertexing_dis benchmark
- Modified tracking_performances_dis reconstruction to include SecondaryVerticesHelix collection in output
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| benchmarks/secondary_vertexing_dis/analysis/invariant_mass.py | New Python script that loads secondary vertex data, calculates invariant masses, applies quality cuts, and generates visualization plots |
| benchmarks/secondary_vertexing_dis/Snakefile | Snakemake rule defining the workflow for running the invariant mass analysis |
| benchmarks/secondary_vertexing_dis/config.yml | CI/CD configuration for running the benchmark and collecting results |
| benchmarks/tracking_performances_dis/Snakefile | Updated to include SecondaryVerticesHelix in the output collections |
| Snakefile | Includes the new secondary_vertexing_dis Snakefile in the main workflow |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| print(f"Event {event_idx}, Vertex {vtx_idx}: {n_tracks} tracks, indices: {vertex_track_indices}") | ||
|
|
||
| # Calculate decay length for this vertex | ||
| decay_2d = np.sqrt(event_sec_x[vtx_idx]**2 + event_sec_y[vtx_idx]**2) | ||
| decay_3d = np.sqrt(event_sec_x[vtx_idx]**2 + event_sec_y[vtx_idx]**2 + event_sec_z[vtx_idx]**2) | ||
| chi2_ndf = event_chi2[vtx_idx] / (event_ndf[vtx_idx] + 1e-10) | ||
|
|
||
| # Focus on 2-track vertices (typical for kaon decays) | ||
| if n_tracks == 2: | ||
| two_track_vertices += 1 | ||
|
|
||
| idx1, idx2 = vertex_track_indices[0], vertex_track_indices[1] | ||
|
|
||
| # Check if indices are valid for this event | ||
| if idx1 < len(event_px) and idx2 < len(event_px): | ||
| valid_associations += 1 | ||
|
|
||
| # Calculate invariant mass | ||
| p1 = [event_px[idx1], event_py[idx1], event_pz[idx1], event_energy[idx1]] | ||
| p2 = [event_px[idx2], event_py[idx2], event_pz[idx2], event_energy[idx2]] | ||
|
|
||
| total_E = p1[3] + p2[3] | ||
| total_px = p1[0] + p2[0] | ||
| total_py = p1[1] + p2[1] | ||
| total_pz = p1[2] + p2[2] | ||
|
|
||
| inv_mass_sq = total_E**2 - (total_px**2 + total_py**2 + total_pz**2) | ||
|
|
||
| if inv_mass_sq > 0: | ||
| valid_invariant_masses += 1 | ||
| inv_mass = np.sqrt(inv_mass_sq) | ||
|
|
||
| # Apply kaon selection cuts | ||
| passes_vertex_quality = True or chi2_ndf < 3.0 # Good vertex fit | ||
| passes_decay_length = 0.05 < decay_2d < 2.0 # Reasonable decay length for kaons | ||
|
|
||
| # Only store candidates that pass quality cuts | ||
| if passes_vertex_quality and passes_decay_length: | ||
| passed_quality_cuts += 1 | ||
| invariant_masses.append(inv_mass) | ||
| decay_lengths_2d.append(decay_2d) | ||
| decay_lengths_3d.append(decay_3d) | ||
| vertex_quality.append(chi2_ndf) | ||
|
|
||
| # Check if it's a kaon candidate | ||
| if 0.4 <= inv_mass <= 0.6: | ||
| kaon_candidates += 1 | ||
| print(f" -> KAON CANDIDATE: mass={inv_mass:.4f} GeV, decay_length={decay_2d:.3f} mm, χ²/ndf={chi2_ndf:.2f}") | ||
| else: | ||
| print(f" -> Failed cuts: χ²/ndf={chi2_ndf:.2f} (cut<3.0), decay_length={decay_2d:.3f}mm (cut: 0.05-2.0mm)") | ||
| else: | ||
| print(f" -> Invalid mass² = {inv_mass_sq}") | ||
| else: | ||
| print(f" -> Invalid track indices: {idx1}, {idx2} (max: {len(event_px)-1})") | ||
| elif n_tracks > 0: | ||
| print(f" -> {n_tracks}-track vertex (not 2-track)") |
There was a problem hiding this comment.
The script outputs debug information for every event and vertex being processed, which will produce excessive output and may slow down execution. Consider adding a verbosity flag or reducing the logging to summary statistics only, or using a logging level system that can be controlled via command-line arguments.
e84800b to
74e7e48
Compare
|
@starsdong @Simple-Shyam this is adding a simple benchmark, but what we really need here is something more "real". |
Uh oh!
There was an error while loading. Please reload this page.