Skip to content

Fixing all Examples#42

Merged
eduardolneto merged 10 commits into
eg/analysisfrom
en/review_eg/examples_fix
Jul 16, 2026
Merged

Fixing all Examples#42
eduardolneto merged 10 commits into
eg/analysisfrom
en/review_eg/examples_fix

Conversation

@eduardolneto

Copy link
Copy Markdown
Contributor

This is a pull request to clean examples and make them work with PR #36 to PR #40. Due to the new changed requesting during pull request some of them stopped working. So I had to add some changes to coils and surface classes to make them work again. There is however, still a problem with examples using stochastic optimization and the classifier object.

@rogeriojorge rogeriojorge left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A couple of changes asked for

Comment thread tests/test_objective_functions.py Outdated
@patch('essos.objective_functions.BiotSavart', return_value=DummyField())
@patch('essos.objective_functions.perturb_curves', side_effect=lambda curves, sampler, key=None, perturbation_type=None: curves)
def test_perturbed_field_and_coils_from_dofs(self, pc, bs, coils, curves):
@patch('essos.objective_functions.perturb_curves_systematic')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this perturb_curves_systematic exist? I'm also checking in the objective_functions.py and it appears in line 206, but it is never imported. Doesn't this error out for you?

The same for perturb_curves_statistic, pertubred_field_from_dofs, field_from_dofs, and coils_from_dofs, as the current objective_functions.py only imports perturb_curves and has moved toward object-based losses

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.

Done

Comment on lines +64 to +82
class PytreeCoils:
def __init__(self, gamma, gamma_dash, gamma_dashdash, currents, quadpoints):
self.gamma = gamma
self.gamma_dash = gamma_dash
self.gamma_dashdash = gamma_dashdash
self.currents = currents
self.quadpoints = quadpoints

def __len__(self):
return self.gamma.shape[0]

def tree_flatten(self):
children = (self.gamma, self.gamma_dash, self.gamma_dashdash, self.currents, self.quadpoints)
return children, None

@classmethod
def tree_unflatten(cls, aux_data, children):
return cls(*children)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Doesn't this error out for you? Seems like PytreeCoils is missing attributes used by the tested losses. loss_coil_surface_distance() needs coils.stellsym and coils.nfp; loss_linkingnumber() and loss_lorentz_force_coils() need coils.curves.quadpoints. What about using a real Coils object in these tests or add a small .curves.quadpoints, .stellsym, and .nfp to the dummy object?

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.

Done


# Load coils and field
json_file = os.path.join(os.path.dirname(__file__), '../input_files', 'ESSOS_biot_savart_LandremanPaulQA.json')
json_file = os.path.join(os.path.dirname(__name__), 'input_files', 'ESSOS_biot_savart_LandremanPaulQA.json')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Didn't we see that this kind of change breaks for other users? Do you really need it?

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.

Done


# Load coils and field
wout_file = os.path.join(os.path.dirname(__file__), "../input_files", "wout_LandremanPaul2021_QA_reactorScale_lowres.nc")
wout_file = os.path.join(os.path.dirname(__name__), "input_files", "wout_LandremanPaul2021_QA_reactorScale_lowres.nc")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

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.

Done


#Load electric field
Er_file=os.path.join(os.path.dirname(__file__), '../input_files','Er.h5')
Er_file=os.path.join(os.path.dirname(__name__), 'input_files','Er.h5')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

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.

Done

R_axis=field.r_axis
Z_axis=field.z_axis
#Ideally here one would differentiate in time through diffrax !TODO
r_cross=jnp.sqrt(jnp.square(jnp.sqrt(jnp.square(xyz[:,0])+jnp.square(xyz[:,1]))-R_axis+1.e-12)+jnp.square(xyz[:,2]-Z_axis+1.e-12))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I thought xyz is (nparticles, ntimes, 3). Shouldn't this be xyz[:,:,0]?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Comment on lines +99 to +104






Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Many line breaks?

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.

Fixed

MAXTIME_TRACING = 1e-4
NUMBER_COILS_PER_HALF_FIELD_PERIOD = 3
NUMBER_OF_FIELD_PERIODS = 2
MODEL = 'GuidingCenterAdaptative'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this used later? Seems like it calls particles.to_full_orbit(field) inside the loss. What about importing/using the existing loss_particle_radial_drift() from objective_functions.py instead of redefining it locally?

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.

I kept the exmaples with independent functions on purpose, for people to see what the example is doing more clearly wihtout having to do to the code @rogeriojorge .

coils = copy_coils_from_field(field)
base_key = jax.random.key(key)
split_keys = jax.random.split(base_key, 2)
perturb_curves_systematic(coils, sampler, key=split_keys[0])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not assigned anywhere? so systematic perturbations are ignored? Should it be coils = perturb_curves_systematic(...) before applying the statistical perturbations?

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.

Done

@EstevaoMGomes EstevaoMGomes changed the title Slightly correcting bugs in modifications coils.py Fixing all examples Jul 10, 2026
@EstevaoMGomes EstevaoMGomes changed the title Fixing all examples Fixing all Examples Jul 10, 2026
@eduardolneto

eduardolneto commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

The only example not working is with from_simsopt method. but I dopnt have a solution for this yet. I would merge this and solve that after. The change fo PR #43 works also on older diffrax version. @rogeriojorge @EstevaoMGomes

@rogeriojorge rogeriojorge left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A couple of small things, and then it's ready to merge

Comment thread tests/test_objective_functions.py Outdated
Comment on lines +199 to +200
@patch("essos.objective_functions.perturb_curves_systematic", create=True)
@patch("essos.objective_functions.perturb_curves_statistic", create=True)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this is masking the fact that in objective_functions perturb_curves_systematic and perturb_curves_statistic are not imported but still used, which leads to error. Why not use the API already imported there, in objective_functions?

coils = perturb_curves(
coils,
sampler,
key=split_keys[0],
perturbation_type="systematic",
)
coils = perturb_curves(
coils,
sampler,
key=split_keys[1],
perturbation_type="statistical",
)

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.

Fixed.

Comment on lines +206 to 207
coils = perturb_curves_systematic(coils, sampler, key=split_keys[0])
coils = perturb_curves_statistic(coils, sampler, key=split_keys[1])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See previous comment:

coils = perturb_curves(
coils,
sampler,
key=split_keys[0],
perturbation_type="systematic",
)
coils = perturb_curves(
coils,
sampler,
key=split_keys[1],
perturbation_type="statistical",
)

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.

Fixed.

R_axis=field.r_axis
Z_axis=field.z_axis
#Ideally here one would differentiate in time through diffrax !TODO
r_cross=jnp.sqrt(jnp.square(jnp.sqrt(jnp.square(xyz[:,0])+jnp.square(xyz[:,1]))-R_axis+1.e-12)+jnp.square(xyz[:,2]-Z_axis+1.e-12))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ax3.plot(tracing.times, trajectory[:, 3]*SPEED_OF_LIGHT/jnp.sqrt(tracing.energy[i]/mass*2.), label=f'Particle {i+1}')
for i in subset_indices:
trajectory = trajectories[i]
ax1.plot(trajectory[:,0], trajectory[:,1], trajectory[:,2], label=f'Particle {i+1}')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think for this to work you need

ax1 = fig.add_subplot(221, projection="3d")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The same in the other collision examples

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.

Fixed.

@eduardolneto eduardolneto merged commit 074cf7f into eg/analysis Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants