Skip to content

Fix computeBunchMoments bugs, BunchTwissAnalysis refactor, bump to C++17#132

Draft
woodtp wants to merge 7 commits into
PyORBIT-Collaboration:mainfrom
woodtp:bugfix/computeBunchMoments
Draft

Fix computeBunchMoments bugs, BunchTwissAnalysis refactor, bump to C++17#132
woodtp wants to merge 7 commits into
PyORBIT-Collaboration:mainfrom
woodtp:bugfix/computeBunchMoments

Conversation

@woodtp

@woodtp woodtp commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #121.

Based on #122.

The moment calculation bugs are corrected, and an additional normalize flag is added to computeBunchMoments to prevent normalization of x-y moments by powers of either $\sqrt{\beta_{x,y}}$ or $\sqrt{\beta_{x,y}\varepsilon_{x,y}}$ unless explicitly requested.

The class has been reworked to expedite calculation of moments up to 2nd order, which is the most common use case. Previously, calling computeBunchMoments would scale as $O(N^2)$ due to a double loop over the
Bunch. Now, the double loop is triggered only if moment orders $\geq3$ are requested. Maybe there's a clever way to get around doing the loop twice, but my impression is that these terms are not needed very often anyway.

I've also unified computeBunchMoments and analyzeBunch and marked the analyzeBunch method with [[deprecated]]. The choice is sort-of arbitrary, but I think we should favor computeBunchMoments as the entry point, because the name is more descriptive. Previously, both methods calculated moments; the difference was that analyzeBunch was calculating up to 2nd order moments, while computeBunchMoments itself called analyzeBunch before calculating x-y moments up to the requested order. analyzeBunch will still work until removed, but will now emit a warning message (only at first invocation) that computeBunchMoments should be used instead before forwarding arguments to computeBunchMoments.

Bumping the c++ standard allows us to more easily compose specialized implementations of the moments calculation based on whether the dispersion correction is enabled or the macrosize bunch attribute is
defined. When these two conditions are false, the compiler should be able to optimize-out the extra instructions within the Bunch loop(s) that these scenarios require.

Questions

  1. Should the normalization and/or dispersion correction apply universally? If dispersion or normalization are enabled, they are only applied to the x-y moments returned by getBunchMoment(i, j) and not getCorrelation(i, j).
  2. Should BunchTwissAnalysis be able to compute higher order moments between all combinations of $x, x', y, y', z, dE$ as opposed to just $\langle x^i y^j \rangle$?

woodtp added 3 commits June 15, 2026 17:17
- tabs -> 2 spaces per style guide
- foreach loop for the extension modules
- clean up cpp_args
  - migrate c++ standard specification to project()
  - global project argument for `-DUSE_MPI`
  - Removed `-fPIC`. Meson handles this for us.
- set default buildtype to 'release' in project()
  - can be overridden with `meson setup ... -Dbuildtype=debug`
- Add `-march=native` global project argument, conditionally.
  - Since we don't distribute binaries and expect users to compile pyo3 for themselves, I don't see a reason not to include this flag as it can only help performance. At worst, it does nothing.
…unchTwissAnalysis::analyzeBunch. Bump to c++17.

The moment calculation bugs are corrected, and an additional
`normalization` flag is added to computeBunchMoments to prevent
normalization of x-y moments by sqrt(beta) or sqrt(beta*emitt) unless
explicitly requested.

The class has been reworked to expedite calculation of moments up to 2nd
order, which is the most common usecase. Previously, calling
computeBunchMoments would scale as O(N^2) due to a double loop over the
Bunch. Now, the double loop is triggered only if moment orders >=3 are
requested.

Bumping the c++ std version allows us to more easily compose specialized
implementations of the moments calculation based on whether the
dispersion correction is enabled or the 'macrosize' bunch attribute is
defined. When these two conditions are `false`, the compiler will be
able to optimize-out the extra instructions within in the Bunch loop(s)
that these scenarios require.
@woodtp
woodtp requested review from austin-hoover and azukov July 23, 2026 15:54
@woodtp woodtp self-assigned this Jul 23, 2026
@woodtp woodtp added the bug Something isn't working label Jul 23, 2026
Comment on lines +65 to +77
int order = 2;
int normalize = 0;
int emitnormterm = 0;
int dispterm = 0;
if (!PyArg_ParseTuple(
args,
"O|ippp:computeBunchMoments",
&pyBunch,
&order,
&normalize,
&emitnormterm,
&dispterm
)) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that these lines are the only true changes to wrap_bunch_twiss_analysis.cc. Everything else is just formatting via clang-format.

@woodtp

woodtp commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

CI checks for every build except apple-silicon are failing. Based on the errors, I think it's because g++ has a different opinion about the included header paths compared to clang; I'll need to poke around a bit to figure out what's going on.

Converting to draft.

@woodtp
woodtp marked this pull request as draft July 23, 2026 16:21
@shishlo

shishlo commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Quote: “I've also unified computeBunchMoments and analyzeBunch and marked the analyzeBunch method with [[deprecated]]. The choice is sort-of arbitrary, but I think we should favor computeBunchMoments as the entry point, because the name is more descriptive.”

I asked Google:
In statistics, is there difference between moments of values and correlations?

Answer:
Yes, there is a clear difference, but they are also connected because a Pearson correlation coefficient is actually a specific type of standardized product moment.

So, I am not sure that computeBunchMoments is the same as analyzeBunch. I seems to me that analyzeBunch is more appropriate name.

@austin-hoover

austin-hoover commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@shishlo The function analyzeBunch calculates the first and second moments; it fills avg_arr which is the mean $\mu = \langle {z} \rangle$ and corr_arr which is the moment matrix $\langle {z} {z}^T \rangle$. The function getCorrelation(i, j) returns the i, j element of the covariance matrix $\Sigma = \langle ({z} - \mu) ({z} - \mu)^T \rangle$, not the correlation matrix. So getCorrelation should be called getCovariance.

@austin-hoover

Copy link
Copy Markdown
Contributor

And corr_arr should be called moment_arr or something else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BunchTwissAnalysis::computeBunchMoments doesn't calculate central moments correctly

3 participants