-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pythonised the sigma matrix function #307
Conversation
… vertical emittance
After offline discussion with @swhite2401, modified the handling of the linalg error. Now if the original 6x6 cholesky fails then it reverts to doing each 2x2 matrix individually, if this fails then it returns 0s. I also added the ability to specify a vertical emittance when providing a lattice object for the sigma matrix. This takes the uncoupled 2x2 matrix for the vertical plane and inserts it into the 6x6 sigma matrix from ohmi_envelope.
|
There are three cases that can occur,
Each one is doing something slightly different If the lattice object is provided with no other arguments, ohmi_envelope is used If the lattice object and emittances and longitudinal parameters are provided, then If the twiss_in is provided alongside the emittances and longitudinal parameters, then |
@lcarver : when calling
Better that using |
@lfarv : Thanks a lot. I think I implemented your suggestions correctly. For me I had the following possibilities in mind: ring with rad on, no emittances specified -> ohmi_envelope I hope its clear. I checked the longitudinal distributions of each method and I saw the same distribution each time, but there could be some missing subtleties. |
pyat/at/tracking/particles.py
Outdated
ring.radiation_off() | ||
mcf = ring.get_mcf() | ||
ring.radiation_on() | ||
envel = ring.envelope_parameters() | ||
|
||
if not radFlag: | ||
ring.radiation_off() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One cannot expect that calling sigma_matrix(ring,..
modifies the ring. So it should be:
mcf = ring.radiation_off(copy=True).get_mcf()
envelope = ring.radiation_on(copy=True).envelope_parameters()
or
mcf = get_mcf(ring.radiation_off(copy=True)
envelope = envelope_parameters(ring.radiation_on(copy=True))
as you prefer.
In addition, turning radiation off and then on does not ensure that you come back to the initial state (which multipoles did the user activate?). So it should be avoided.
A detail: when using |
Ok for me to merge after the latest changes proposed by @lfarv are implemented |
Not ready to merge just yet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok for me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK!
Re-wrote atbeam. Now it takes either a lattice object as input or you can give a twiss_in kwarg and specify emittances. I realised there was an issue before which was that if you gave at.beam a 2x2 or 4x4 matrix, the final particle output from at.beam only had 2 or 4 dimensions, i.e. not suitable for tracking. This issue is now avoided by always returning a 6xN sigma_matrix and therefore a 6xN array of particles.
A small issue that I observed was that if blength and espread are both 0, then the cholesky decomposition of the sigma_matrix (in at.beam) fails due to negative eigenvectors. That is why when neither blength or espread are specified I set them to very small positive values (with a warning).
Example usage below.