Skip to content

Commit b82a897

Browse files
committed
WIP: Debugging Cython zero functionality
1 parent 526f7da commit b82a897

15 files changed

Lines changed: 160 additions & 176 deletions

py_ballisticcalc.exts/py_ballisticcalc_exts/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88

99
from .euler_engine import CythonizedEulerIntegrationEngine
1010
from .rk4_engine import CythonizedRK4IntegrationEngine
11-
from .trajectory_data import TrajectoryData
11+
# from .trajectory_data import TrajectoryDataT
1212

1313
__all__ = (
1414
'CythonizedEulerIntegrationEngine',
1515
'CythonizedRK4IntegrationEngine',
16-
'TrajectoryData',
16+
# 'TrajectoryDataT',
1717
)

py_ballisticcalc.exts/py_ballisticcalc_exts/base_engine.pxd

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ cdef class CythonizedBaseIntegrationEngine:
7171
# Python 'def' methods are not exposed in the C interface defined by a .pxd.
7272
# Only 'cdef' or 'cpdef' methods are declared here.
7373
cdef void _free_trajectory(CythonizedBaseIntegrationEngine self)
74-
cdef void _init_trajectory(CythonizedBaseIntegrationEngine self, object shot_info)
75-
cdef tuple _init_zero_calculation(CythonizedBaseIntegrationEngine self, object shot_info, object distance)
76-
cdef object _find_zero_angle(CythonizedBaseIntegrationEngine self, object shot_info, object distance, bint lofted)
77-
cdef object _zero_angle(CythonizedBaseIntegrationEngine self, object shot_info, object distance)
78-
cdef tuple _find_max_range(CythonizedBaseIntegrationEngine self, object shot_info, tuple angle_bracket_deg = *)
79-
cdef object _find_apex(CythonizedBaseIntegrationEngine self, object shot_info)
74+
cdef ShotProps_t* _init_trajectory(CythonizedBaseIntegrationEngine self, object shot_info)
75+
cdef tuple _init_zero_calculation(CythonizedBaseIntegrationEngine self, ShotProps_t *shot_props_ptr, double distance)
76+
cdef object _find_zero_angle(CythonizedBaseIntegrationEngine self, ShotProps_t *shot_props_ptr, double distance, bint lofted)
77+
cdef object _zero_angle(CythonizedBaseIntegrationEngine self, ShotProps_t *shot_props_ptr, double distance)
78+
cdef tuple _find_max_range(CythonizedBaseIntegrationEngine self, ShotProps_t *shot_props_ptr, tuple angle_bracket_deg = *)
79+
cdef object _find_apex(CythonizedBaseIntegrationEngine self, ShotProps_t *shot_props_ptr)
8080
# In contrast to Python engines, _integrate here returns (CBaseTrajSeq, Optional[error_str])
81-
cdef object _integrate(CythonizedBaseIntegrationEngine self,
81+
cdef object _integrate(CythonizedBaseIntegrationEngine self, ShotProps_t *shot_props_ptr,
8282
double range_limit_ft, double range_step_ft, double time_step, int filter_flags)
8383

8484

py_ballisticcalc.exts/py_ballisticcalc_exts/base_engine.pyx

Lines changed: 92 additions & 72 deletions
Large diffs are not rendered by default.

py_ballisticcalc.exts/py_ballisticcalc_exts/base_traj_seq.pxd

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,10 @@
11
"""
22
Header file for base_traj_seq.pyx - C Buffer Trajectory Sequence
3-
4-
Notes and conventions (keep in sync with base_traj_seq.pyx):
5-
- This .pxd is authoritative for C-level declarations shared across Cython
6-
modules. Avoid redeclaring enums, structs or function prototypes in the
7-
corresponding .pyx files; duplicating declarations can cause "redeclared"
8-
errors during editable installs or when Cython regenerates sources.
9-
- Nogil helpers are declared here with explicit exception sentinels so that
10-
callers know the sentinel value used when the function is invoked without
11-
the GIL. Conventions used in this module:
12-
* pointer-returning functions: use `except NULL nogil` (return NULL on error)
13-
* bint-returning try-style helpers: use `except False nogil` (return False on error)
14-
* append-style functions that cannot fail at the C level are marked `noexcept nogil`
15-
- The quadratic Lagrange interpolation used by the nogil core is currently
16-
inlined in the implementation to avoid cross-module nogil call-site
17-
diagnostics; a future refactor could move this math into a shared C
18-
header and declare a pure-C helper here.
193
"""
204

215
from libc.stddef cimport size_t
22-
# cimport BaseTrajDataT and interpolation helper
236
from py_ballisticcalc_exts.trajectory_data cimport BaseTrajDataT
247

25-
# Include BaseTrajC struct definition from header file
268
cdef extern from "include/basetraj_seq.h" nogil:
279
ctypedef struct BaseTrajC:
2810
double time
@@ -34,8 +16,6 @@ cdef extern from "include/basetraj_seq.h" nogil:
3416
double vz
3517
double mach
3618

37-
# Public enum for interpolation keys; exposed at module-level so .pyx can
38-
# reference it for nogil helpers.
3919
cdef class CBaseTrajSeq:
4020
cdef:
4121
BaseTrajC* _buffer

py_ballisticcalc.exts/py_ballisticcalc_exts/base_traj_seq.pyx

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This module provides:
55
- CBaseTrajSeq: a contiguous C buffer of BaseTrajC items with append/reserve access.
66
- Quadratic Lagrange interpolation on the raw buffer without allocating Python objects.
77
- Convenience methods to locate and interpolate a point by an independent variable
8-
(time, mach, position.{x,y,z}, velocity.{x,y,z}) and slant height.
8+
(time, mach, position.{x,y,z}, velocity.{x,y,z}) and slant_height.
99
1010
Design note: nogil helpers operate on a tiny C struct view of the sequence to avoid
1111
passing Python cdef-class instances into nogil code paths.
@@ -47,10 +47,29 @@ ctypedef struct _CBaseTrajSeq_cview:
4747

4848
__all__ = ['CBaseTrajSeq', 'BaseTrajC']
4949

50+
cdef inline double _key_val_from_kind_buf(BaseTrajC* p, int key_kind) noexcept nogil:
51+
if key_kind == <int>KEY_TIME:
52+
return p.time
53+
elif key_kind == <int>KEY_MACH:
54+
return p.mach
55+
elif key_kind == <int>KEY_POS_X:
56+
return p.px
57+
elif key_kind == <int>KEY_POS_Y:
58+
return p.py
59+
elif key_kind == <int>KEY_POS_Z:
60+
return p.pz
61+
elif key_kind == <int>KEY_VEL_X:
62+
return p.vx
63+
elif key_kind == <int>KEY_VEL_Y:
64+
return p.vy
65+
elif key_kind == <int>KEY_VEL_Z:
66+
return p.vz
67+
return <double>0.0
68+
5069

5170
# Interpolation helper (pure C math; safe to call with or without GIL)
52-
cdef int _interpolate_nogil_raw(_CBaseTrajSeq_cview* seq, Py_ssize_t idx, int key_kind, double key_value, BaseTrajC* out) noexcept:
53-
"""Interpolate at idx using points (idx-1, idx, idx+1) keyed by key_kind at key_value."""
71+
cdef int _interpolate_nogil_raw(_CBaseTrajSeq_cview* seq, Py_ssize_t idx, int key_kind, double key_value, BaseTrajC* out) noexcept nogil:
72+
"""Interpolate at idx using points (idx-1, idx, idx+1), computing new BaseTrajC where out.key_kind==key_value."""
5473
cdef BaseTrajC* buffer = seq._buffer
5574
cdef Py_ssize_t plength = <Py_ssize_t> seq._length
5675
cdef BaseTrajC *p0
@@ -124,29 +143,11 @@ cdef int _interpolate_nogil_raw(_CBaseTrajSeq_cview* seq, Py_ssize_t idx, int ke
124143
return 1
125144

126145

127-
cdef inline double _key_val_from_kind_buf(BaseTrajC* p, int key_kind) noexcept:
128-
if key_kind == <int>KEY_TIME:
129-
return p.time
130-
elif key_kind == <int>KEY_MACH:
131-
return p.mach
132-
elif key_kind == <int>KEY_POS_X:
133-
return p.px
134-
elif key_kind == <int>KEY_POS_Y:
135-
return p.py
136-
elif key_kind == <int>KEY_POS_Z:
137-
return p.pz
138-
elif key_kind == <int>KEY_VEL_X:
139-
return p.vx
140-
elif key_kind == <int>KEY_VEL_Y:
141-
return p.vy
142-
elif key_kind == <int>KEY_VEL_Z:
143-
return p.vz
144-
return <double>0.0
145-
146-
cdef inline double _slant_val_buf(BaseTrajC* p, double ca, double sa) noexcept:
146+
cdef inline double _slant_val_buf(BaseTrajC* p, double ca, double sa) noexcept nogil:
147+
"""Computes the slant_height of a trajectory point `p` given cosine `ca` and sine `sa` of look_angle."""
147148
return p.py * ca - p.px * sa
148149

149-
cdef Py_ssize_t _bisect_center_idx_buf(BaseTrajC* buf, size_t length, int key_kind, double key_value) noexcept:
150+
cdef Py_ssize_t _bisect_center_idx_buf(BaseTrajC* buf, size_t length, int key_kind, double key_value) noexcept nogil:
150151
cdef Py_ssize_t n = <Py_ssize_t>length
151152
if n < 3:
152153
return <Py_ssize_t>(-1)
@@ -176,7 +177,7 @@ cdef Py_ssize_t _bisect_center_idx_buf(BaseTrajC* buf, size_t length, int key_ki
176177
return n - 2
177178
return lo
178179

179-
cdef Py_ssize_t _bisect_center_idx_slant_buf(BaseTrajC* buf, size_t length, double ca, double sa, double value) noexcept:
180+
cdef Py_ssize_t _bisect_center_idx_slant_buf(BaseTrajC* buf, size_t length, double ca, double sa, double value) noexcept nogil:
180181
cdef Py_ssize_t n = <Py_ssize_t>length
181182
if n < 3:
182183
return <Py_ssize_t>(-1)
@@ -208,9 +209,9 @@ cdef Py_ssize_t _bisect_center_idx_slant_buf(BaseTrajC* buf, size_t length, doub
208209

209210

210211
cdef class CBaseTrajSeq:
211-
"""Contiguous C buffer of BaseTrajC with fast append and interpolation.
212+
"""Contiguous C buffer of BaseTrajC points with fast append and interpolation.
212213
213-
Python-facing access returns lightweight BaseTrajDataT objects; internal
214+
Python-facing access lazily creates lightweight BaseTrajDataT objects; internal
214215
nogil helpers work directly on the C buffer for speed.
215216
"""
216217
def __cinit__(self):
@@ -282,8 +283,8 @@ cdef class CBaseTrajSeq:
282283
"""Number of points in the sequence."""
283284
return <Py_ssize_t> self._length
284285

285-
def __getitem__(self, idx):
286-
"""Return BaseTrajDataT for the given index (supports negative indices)."""
286+
def __getitem__(self, idx: int) -> BaseTrajDataT:
287+
"""Return BaseTrajDataT for the given index. Supports negative indices."""
287288
cdef V3dT position
288289
cdef V3dT velocity
289290
cdef BaseTrajC* entry_ptr
@@ -350,12 +351,12 @@ cdef class CBaseTrajSeq:
350351
"""Interpolate using points (idx-1, idx, idx+1) keyed by key_attribute at key_value."""
351352
return self._interpolate_at_c(idx, key_attribute, key_value)
352353

353-
def get_at(self, str key_attribute, double key_value, start_from=None, start_from_time=None):
354-
"""Get BaseTrajDataT where key_attribute == key_value (quadratic interpolation).
354+
def get_at(self, str key_attribute, double key_value, start_from_time=None):
355+
"""Get BaseTrajDataT where key_attribute == key_value (via quadratic interpolation).
355356
356357
If start_from_time > 0, search is centered from the first point where time >= start_from_time,
357358
and proceeds forward or backward depending on local direction, mirroring
358-
trajectory_data.HitResult.get_at.
359+
trajectory_data.HitResult.get_at().
359360
"""
360361
cdef int key_kind
361362
cdef Py_ssize_t n
@@ -399,8 +400,6 @@ cdef class CBaseTrajSeq:
399400
sft = <double>0.0
400401
if start_from_time is not None:
401402
sft = <double>float(start_from_time)
402-
elif start_from is not None:
403-
sft = <double>float(start_from)
404403
if sft > <double>0.0 and key_kind != <int>KEY_TIME:
405404
buf = self._buffer
406405
start_idx = <Py_ssize_t>0

py_ballisticcalc.exts/py_ballisticcalc_exts/cy_bindings.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ cdef extern from "include/bclib.h" nogil:
7979
double calc_step
8080
double muzzle_velocity
8181
double stability_coefficient
82+
int filter_flags
8283
Atmosphere_t atmo
8384

8485
void ShotProps_t_free(ShotProps_t *shot_props_ptr)

py_ballisticcalc.exts/py_ballisticcalc_exts/euler_engine.pyx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from cython cimport final
22
from libc.math cimport fabs, sin, cos, tan, atan, atan2, fmin, fmax, pow
3-
from libc.stdlib cimport malloc, realloc, free
4-
from py_ballisticcalc_exts.trajectory_data cimport TrajFlag_t, BaseTrajDataT, TrajectoryData, BaseTrajDataT_create
53
from py_ballisticcalc_exts.cy_bindings cimport (
64
Config_t,
75
ShotProps_t,
@@ -10,16 +8,8 @@ from py_ballisticcalc_exts.cy_bindings cimport (
108
)
119
from py_ballisticcalc_exts.base_engine cimport (
1210
CythonizedBaseIntegrationEngine,
13-
TrajDataFilter_t,
14-
1511
WindSock_t_currentVector,
1612
WindSock_t_vectorForRange,
17-
18-
create_trajectory_row,
19-
20-
TrajDataFilter_t_create,
21-
TrajDataFilter_t_setup_seen_zero,
22-
TrajDataFilter_t_should_record,
2313
)
2414

2515
from py_ballisticcalc_exts.v3d cimport V3dT, add, sub, mag, mulS
@@ -46,7 +36,7 @@ cdef class CythonizedEulerIntegrationEngine(CythonizedBaseIntegrationEngine):
4636
"""Calculate time step based on current projectile speed."""
4737
return base_step / fmax(<double>1.0, velocity)
4838

49-
cdef object _integrate(CythonizedEulerIntegrationEngine self,
39+
cdef object _integrate(CythonizedEulerIntegrationEngine self, ShotProps_t *shot_props_ptr,
5040
double range_limit_ft, double range_step_ft,
5141
double time_step, int filter_flags):
5242
"""

py_ballisticcalc.exts/py_ballisticcalc_exts/include/bclib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ typedef struct {
8080
double calc_step;
8181
double muzzle_velocity;
8282
double stability_coefficient;
83+
int filter_flags;
8384
Atmosphere_t atmo;
8485
} ShotProps_t;
8586

py_ballisticcalc.exts/py_ballisticcalc_exts/rk4_engine.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ cdef class CythonizedRK4IntegrationEngine(CythonizedBaseIntegrationEngine):
5555
"""Calculate the step size for integration."""
5656
return self.DEFAULT_TIME_STEP * CythonizedBaseIntegrationEngine.get_calc_step(self)
5757

58-
cdef object _integrate(CythonizedRK4IntegrationEngine self,
58+
cdef object _integrate(CythonizedRK4IntegrationEngine self, ShotProps_t *shot_props_ptr,
5959
double range_limit_ft, double range_step_ft,
6060
double time_step, int filter_flags):
6161
"""

py_ballisticcalc.exts/py_ballisticcalc_exts/trajectory_data.pxd

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ cdef extern from "include/bclib.h":
2323
V3dT velocity
2424
double mach
2525

26-
# aliases
27-
# ctypedef BaseTrajDataT BaseTrajData # temporary undeclared
28-
2926
# Ensure signature places 'nogil' at the end to match Cython's recommendation
3027
cdef double lagrange_quadratic(double x, double x0, double y0, double x1, double y1, double x2, double y2) except -1.0 nogil
3128

@@ -36,7 +33,7 @@ cdef class BaseTrajDataT:
3633
readonly V3dT velocity
3734
readonly double mach
3835

39-
cdef class TrajectoryData:
36+
cdef class TrajectoryDataT:
4037
cdef:
4138
readonly double time
4239
readonly object distance
@@ -55,5 +52,8 @@ cdef class TrajectoryData:
5552
readonly object ogw
5653
readonly int flag
5754

55+
# @staticmethod
56+
# cdef from_BaseTrajDataT(BaseTrajDataT base_data)
57+
5858
# Factory helper exposed for use from other Cython modules
5959
cdef BaseTrajDataT BaseTrajDataT_create(double time, V3dT position, V3dT velocity, double mach)

0 commit comments

Comments
 (0)