xpart
Advanced tools
+1
-1
| Metadata-Version: 2.4 | ||
| Name: xpart | ||
| Version: 0.23.8 | ||
| Version: 0.23.9 | ||
| Summary: Generation of Particle Ensembles | ||
@@ -5,0 +5,0 @@ Home-page: https://xsuite.readthedocs.io/ |
+1
-1
@@ -8,5 +8,5 @@ [build-system] | ||
| [pytest] | ||
| [tool.pytest] | ||
| markers = [ | ||
| "context_dependent: marks test as one that depends on the execution context", | ||
| ] |
@@ -168,3 +168,3 @@ # copyright ############################### # | ||
| # Ensure there is a Marker between at_element and match_at_s (to test behave_likes_drift) | ||
| line.insert_element(element=xt.Marker(), name='test_marker', at_s=s_start + 0.3*(match_at_s-s_start)) | ||
| line.insert('test_marker', obj=xt.Marker(), at=s_start + 0.3*(match_at_s-s_start)) | ||
@@ -188,3 +188,3 @@ line.build_tracker(_context=test_context) | ||
| line.discard_tracker() | ||
| line.insert_element(element=xt.Marker(), name='match_at_s', at_s=match_at_s) | ||
| line.insert('match_at_s', obj=xt.Marker(), at=match_at_s) | ||
| line.build_tracker(_context=test_context) | ||
@@ -191,0 +191,0 @@ particles.move(_context=test_context) |
@@ -86,3 +86,5 @@ # copyright ############################### # | ||
| tw_at_s = line.twiss(at_s=at_s) | ||
| line.cut_at_s([at_s]) | ||
| tw = line.twiss() | ||
| tw_at_s = tw.rows[np.searchsorted(tw.s, at_s)] | ||
| norm_coords = tw_at_s.get_normalized_coordinates( | ||
@@ -89,0 +91,0 @@ particles, nemitt_x=nemitt_x, nemitt_y=nemitt_y, |
| Metadata-Version: 2.4 | ||
| Name: xpart | ||
| Version: 0.23.8 | ||
| Version: 0.23.9 | ||
| Summary: Generation of Particle Ensembles | ||
@@ -5,0 +5,0 @@ Home-page: https://xsuite.readthedocs.io/ |
@@ -1,1 +0,1 @@ | ||
| __version__ = '0.23.8' | ||
| __version__ = '0.23.9' |
+34
-31
@@ -41,23 +41,23 @@ # copyright ############################### # | ||
| def build_particles(_context=None, _buffer=None, _offset=None, _capacity=None, | ||
| mode=None, | ||
| particle_ref=None, | ||
| num_particles=None, | ||
| x=None, px=None, y=None, py=None, | ||
| zeta=None, delta=None, pzeta=None, ptau=None, | ||
| x_norm=None, px_norm=None, y_norm=None, py_norm=None, | ||
| zeta_norm=None, pzeta_norm=None, | ||
| tracker=None, | ||
| line=None, | ||
| at_element=None, | ||
| match_at_s=None, | ||
| particle_on_co=None, | ||
| R_matrix=None, | ||
| W_matrix=None, | ||
| method=None, | ||
| nemitt_x=None, nemitt_y=None,nemitt_zeta = None, | ||
| scale_with_transverse_norm_emitt=None, | ||
| weight=None, | ||
| s_tol=1e-6, | ||
| include_collective=False, | ||
| **kwargs, # They are passed to the twiss | ||
| mode=None, | ||
| particle_ref=None, | ||
| num_particles=None, | ||
| x=None, px=None, y=None, py=None, | ||
| zeta=None, delta=None, pzeta=None, ptau=None, | ||
| x_norm=None, px_norm=None, y_norm=None, py_norm=None, | ||
| zeta_norm=None, pzeta_norm=None, | ||
| tracker=None, | ||
| line=None, | ||
| at_element=None, | ||
| match_at_s=None, | ||
| particle_on_co=None, | ||
| R_matrix=None, | ||
| W_matrix=None, | ||
| method=None, | ||
| nemitt_x=None, nemitt_y=None,nemitt_zeta = None, | ||
| scale_with_transverse_norm_emitt=None, | ||
| weight=None, | ||
| s_tol=1e-6, | ||
| include_collective=False, | ||
| **kwargs, # They are passed to the twiss | ||
| ): | ||
@@ -201,11 +201,15 @@ | ||
| # Match at a position where there is no marker and backtrack to the previous marker | ||
| expected_at_element = np.where(np.array(s_elements)<=match_at_s)[0][-1] | ||
| assert at_element == expected_at_element or ( | ||
| at_element < expected_at_element and | ||
| all([xt._is_aperture(line.element_dict[nn], line) | ||
| or xt._behaves_like_drift(line.element_dict[nn], line) | ||
| for nn in line._element_names_unique[at_element:expected_at_element]])), ( | ||
| "`match_at_s` can only be placed in the drifts downstream of the " | ||
| "specified `at_element`. No active element can be present in between." | ||
| expected_at_element = np.searchsorted(s_elements, match_at_s) | ||
| names_between = line._element_names_unique[at_element:expected_at_element] | ||
| only_passives_between = all( | ||
| xt._is_aperture(line[nn], line) or xt._behaves_like_drift(line[nn], line) | ||
| for nn in names_between | ||
| ) | ||
| if at_element != expected_at_element and (at_element >= expected_at_element or not only_passives_between): | ||
| raise ValueError( | ||
| "`match_at_s` can only be placed in the drifts downstream of the " | ||
| "specified `at_element`. No active element can be present in between." | ||
| ) | ||
| (tracker_rmat, _ | ||
@@ -215,4 +219,3 @@ ) = xt.twiss._build_auxiliary_tracker_with_extra_markers( | ||
| marker_prefix='xpart_rmat_') | ||
| at_element_line_rmat = tracker_rmat.line._element_names_unique.index( | ||
| 'xpart_rmat_0') | ||
| at_element_line_rmat = tracker_rmat.line._element_names_unique.index('xpart_rmat_0') | ||
| line_rmat = tracker_rmat.line | ||
@@ -219,0 +222,0 @@ else: |
@@ -52,3 +52,3 @@ # copyright ############################### # | ||
| # analytical_tau_max = np.sqrt((5*tau_lim**3*rms_bunch_length**2 - 3*tau_lim**5)/(15*tau_lim*rms_bunch_length**2 - 5*tau_lim**3)) | ||
| func_to_solve = lambda new_tau_max: (scipy.integrate.quad(lambda x: (x**2 - rms_bunch_length**2)*lambda_dist(x, new_tau_max), -tau_lim, tau_lim))[0] | ||
| func_to_solve = lambda new_tau_max: (scipy.integrate.quad(lambda x: (x**2 - rms_bunch_length**2)*lambda_dist(x, new_tau_max[0]), -tau_lim, tau_lim))[0] | ||
| corrected_tau_max = scipy.optimize.fsolve(func_to_solve, x0=tau_max)[0] | ||
@@ -66,3 +66,3 @@ tau_max = corrected_tau_max | ||
| # correct bunch length (due to truncation at separatrix) | ||
| func_to_solve = lambda new_rms: (scipy.integrate.quad(lambda x: (x**2 - rms_bunch_length**2)*lambda_dist(x, new_rms), -tau_lim, tau_lim))[0] | ||
| func_to_solve = lambda new_rms: (scipy.integrate.quad(lambda x: (x**2 - rms_bunch_length**2)*lambda_dist(x, new_rms[0]), -tau_lim, tau_lim))[0] | ||
| corrected_rms = scipy.optimize.fsolve(func_to_solve, x0=rms_bunch_length)[0] | ||
@@ -81,4 +81,4 @@ | ||
| lambda_dist = lambda tau, beta: np.sqrt(beta) / self._Cq(q) * self._eq(-beta * tau**2, q) | ||
| func_to_solve = lambda new_beta: (scipy.integrate.quad(lambda x: (x**2 - rms_bunch_length**2)*lambda_dist(x, new_beta), -tau_lim, tau_lim))[0] | ||
| func_to_solve = lambda new_beta: (scipy.integrate.quad(lambda x: (x**2 - rms_bunch_length**2)*lambda_dist(x, new_beta[0]), -tau_lim, tau_lim))[0] | ||
| corrected_beta = scipy.optimize.fsolve(func_to_solve, x0=beta)[0] | ||
@@ -88,3 +88,3 @@ _print(f"SingleRFHarmonicMatcher: q-Gaussian parameter beta = {corrected_beta:.3f} for q={q:.3f} to achieve target RMS bunch length ({rms_bunch_length:.3f}m).") | ||
| self.tau_distr_y = lambda_dist(self.tau_distr_x, corrected_beta) | ||
| elif distribution == "binomial": | ||
@@ -94,3 +94,3 @@ # Binomial distribution adds tail to parabolic, see (Joho, 1980) at https://indico.psi.ch/event/3484/attachments/5948/7502/TM-11-14.pdf | ||
| tau_max = 1.0 # starting value, will be adjusted. Used as benchmarking value with RMS factor for parabola | ||
| lambda_dist = lambda tau, tau_max: (1 - (tau/tau_max)**2)**(m-0.5) | ||
| lambda_dist = lambda tau, tau_max: (1 - (tau/tau_max)**2)**(m-0.5) | ||
| binomial_2nd = lambda tau, tau_max: (1 - (tau/tau_max)**2)**(m-0.5)*tau**2 | ||
@@ -100,4 +100,4 @@ RMS_binomial = np.sqrt(integrate.quad(binomial_2nd, -1, 1, args=(tau_max))[0] / integrate.quad(lambda_dist, -1, 1, args=(tau_max))[0]) | ||
| _print(f"RMS factor for binimial is {factor_binomial:.3f}") | ||
| tau_max = factor_binomial*rms_bunch_length | ||
| func_to_solve = lambda new_tau_max: (scipy.integrate.quad(lambda x: (x**2 - rms_bunch_length**2)*lambda_dist(x, new_tau_max), -tau_lim, tau_lim))[0] | ||
| tau_max = factor_binomial*rms_bunch_length | ||
| func_to_solve = lambda new_tau_max: (scipy.integrate.quad(lambda x: (x**2 - rms_bunch_length**2)*lambda_dist(x, new_tau_max[0]), -tau_lim, tau_lim))[0] | ||
| corrected_tau_max = scipy.optimize.fsolve(func_to_solve, x0=tau_max)[0] | ||
@@ -233,9 +233,11 @@ tau_max = corrected_tau_max | ||
| return Cq | ||
| def _eq(self, x, q): | ||
| """ | ||
| """ | ||
| Q-exponential function | ||
| Available at https://link.springer.com/article/10.1007/s00032-008-0087-y | ||
| """ | ||
| isscalar = np.isscalar(x) | ||
| if isscalar: | ||
| x = np.array([x]) | ||
| eq = np.zeros(len(x)) | ||
@@ -249,2 +251,4 @@ for i, xx in enumerate(x): | ||
| eq[i] = 0 | ||
| if isscalar: | ||
| eq = eq[0] | ||
| return eq |
@@ -156,6 +156,3 @@ # copyright ############################### # | ||
| if twiss is None: | ||
| twiss = line.twiss(at_s=match_at_s, | ||
| at_elements=([at_element] if match_at_s is None else None), | ||
| **kwargs) | ||
| twiss = line.twiss(at_elements=([at_element] if match_at_s is None else None), at_s=match_at_s, **kwargs) | ||
| if side=='+': | ||
@@ -162,0 +159,0 @@ assert twiss[plane][0] < absolute_cut, 'The cut is on the wrong side' |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
281300
0.02%5833
0.1%