@@ -59,7 +59,7 @@ class _CoilObjective(_Objective):
5959 "Coil" if the objective returns a single scalar per coil, and "Node"
6060 if it returns a scalar at every grid point. To be compatible with
6161 masking, compute function should apply the mask
62- self._coilset_tree["coilset_mask "] before returning data.
62+ self._coilset_tree["objective_mask "] before returning data.
6363 """
6464
6565 __doc__ = __doc__ .rstrip () + collect_docs (coil = True )
@@ -133,7 +133,9 @@ def _build_coilset_tree():
133133 params_tree["coils"] contains a nested list of 0s representing
134134 individual coils and the coilsets to which they belong. Similarly,
135135 params_tree["nodes"] lists the grid nodes associated with each coil.
136- params_tree["coilset_mask"] contains the indices in [0,self._dim_f-1]
136+ params_tree["coil_mask"] contains the indices in [0,self._num_coils]
137+ for which the corresponding weight is positive. Similarly,
138+ params_tree["objective_mask"] contains the indices in [0,self._dim_f-1]
137139 for which the corresponding weight is positive. If all weights are
138140 positive (i.e. no masking needed), contains default slice(None).
139141 """
@@ -166,12 +168,16 @@ def expand(t, idx=0):
166168 self ._coilset_tree = {
167169 "coils" : tree [0 ],
168170 "nodes" : tree [1 ],
169- "coilset_mask" : slice (None ),
171+ "coil_mask" : np .arange (self ._num_coils ),
172+ "objective_mask" : slice (None ),
170173 }
171174 if np .any ([w == 0 for w in tree_leaves (self ._weight )]):
172- mask = self ._coilset_broadcast (self ._weight )
173- mask = np .nonzero (mask )[0 ]
174- self ._coilset_tree ["coilset_mask" ] = mask
175+ coil_mask = self ._coilset_broadcast (self ._weight )
176+ objective_mask = self ._coilset_broadcast (
177+ self ._weight , self ._broadcast_input
178+ )
179+ self ._coilset_tree ["coil_mask" ] = np .nonzero (coil_mask )[0 ]
180+ self ._coilset_tree ["objective_mask" ] = np .nonzero (objective_mask )[0 ]
175181
176182 coil = self .things [0 ]
177183 grid = self ._grid
@@ -211,33 +217,31 @@ def expand(t, idx=0):
211217
212218 _build_coilset_tree ()
213219 quad_weights = np .concatenate ([g .spacing [:, 2 ] for g in grid ])[
214- self ._coilset_tree ["coilset_mask " ]
220+ self ._coilset_tree ["objective_mask " ]
215221 ]
216222
217223 if self ._broadcast_input == "Node" :
218224 grid_nodes_unmasked = [
219- g .num_nodes for g in grid [ self ._coilset_tree ["coilset_mask" ] ]
225+ grid [ i ] .num_nodes for i in self ._coilset_tree ["coil_mask" ]
220226 ]
221227 self ._dim_f = np .sum (grid_nodes_unmasked )
222228 else :
223- coils_unmasked = np .ones (self ._num_coils )[
224- self ._coilset_tree ["coilset_mask" ]
225- ]
229+ coils_unmasked = np .ones (self ._num_coils )[self ._coilset_tree ["coil_mask" ]]
226230 self ._dim_f = len (coils_unmasked )
227231
228232 # map grid to the same structure as coil and then remove unnecessary members
229233 grid = tree_unflatten (structure , grid )
230234 grid = _prune_coilset_tree (grid )
231235 coil = _prune_coilset_tree (coil )
232236
233- self ._weight = self ._coilset_broadcast (self ._weight )
237+ self ._weight = self ._coilset_broadcast (self ._weight , self . _broadcast_input )
234238 if self ._bounds :
235239 self ._bounds = (
236- self ._coilset_broadcast (self ._bounds [0 ]),
237- self ._coilset_broadcast (self ._bounds [1 ]),
240+ self ._coilset_broadcast (self ._bounds [0 ], self . _broadcast_input ),
241+ self ._coilset_broadcast (self ._bounds [1 ], self . _broadcast_input ),
238242 )
239243 elif self ._target :
240- self ._target = self ._coilset_broadcast (self ._target )
244+ self ._target = self ._coilset_broadcast (self ._target , self . _broadcast_input )
241245
242246 timer = Timer ()
243247 if verbose > 0 :
@@ -294,14 +298,18 @@ def bounds(self, bounds):
294298 assert (bounds is None ) or (isinstance (bounds , tuple ) and len (bounds ) == 2 )
295299 if bounds :
296300 self ._bounds = (
297- self ._coilset_broadcast (bounds [0 ]),
298- self ._coilset_broadcast (bounds [1 ]),
301+ self ._coilset_broadcast (bounds [0 ], self . _broadcast_input ),
302+ self ._coilset_broadcast (bounds [1 ], self . _broadcast_input ),
299303 )
300304 self ._check_dimensions ()
301305
302306 @_Objective .target .setter
303307 def target (self , target ):
304- self ._target = self ._coilset_broadcast (target ) if target is not None else target
308+ self ._target = (
309+ self ._coilset_broadcast (target , self ._broadcast_input )
310+ if target is not None
311+ else target
312+ )
305313 self ._check_dimensions ()
306314
307315 @_Objective .weight .setter
@@ -311,13 +319,15 @@ def weight(self, weight):
311319 # objective should be rebuilt to account for masking
312320 self ._built = False
313321
314- def _coilset_broadcast (self , x ):
315- """Expand an array in accordance with the attribute _broadcast_input .
322+ def _coilset_broadcast (self , x , target = "Coil" ):
323+ """Broadcast an array to dimensions consistent with "target" .
316324
317325 Parameters
318326 ----------
319327 x : float or list[float]
320328 Must be broadcastable to the structure of self._things[0].
329+ target: str, optional
330+ Optional string taking values "Coil" or "Node". Defaults to "Coil".
321331
322332 Returns
323333 -------
@@ -331,10 +341,10 @@ def _coilset_broadcast(self, x):
331341 return np .atleast_1d (arr_flat [0 ])
332342
333343 arr = jax_tree_broadcast (x , self ._coilset_tree ["coils" ])
334- if self . _broadcast_input == "Node" :
344+ if target == "Node" :
335345 arr = tree_map (lambda a , b : [a ] * b , arr , self ._coilset_tree ["nodes" ])
336346 arr , _ = tree_flatten (arr )
337- return np .asarray (arr )[self ._coilset_tree ["coilset_mask " ]]
347+ return np .asarray (arr )[self ._coilset_tree ["objective_mask " ]]
338348
339349
340350class CoilLength (_CoilObjective ):
@@ -433,7 +443,7 @@ def compute(self, params, constants=None):
433443 data = super ().compute (params , constants = constants )
434444 data = tree_leaves (data , is_leaf = lambda x : isinstance (x , dict ))
435445 out = jnp .array ([dat ["length" ] for dat in data ])
436- return out [self ._coilset_tree ["coilset_mask " ]]
446+ return out [self ._coilset_tree ["objective_mask " ]]
437447
438448
439449class CoilCurvature (_CoilObjective ):
@@ -535,7 +545,7 @@ def compute(self, params, constants=None):
535545 data = super ().compute (params , constants = constants )
536546 data = tree_leaves (data , is_leaf = lambda x : isinstance (x , dict ))
537547 out = jnp .concatenate ([dat ["curvature" ] for dat in data ])
538- return out [self ._coilset_tree ["coilset_mask " ]]
548+ return out [self ._coilset_tree ["objective_mask " ]]
539549
540550
541551class CoilTorsion (_CoilObjective ):
@@ -635,7 +645,7 @@ def compute(self, params, constants=None):
635645 data = super ().compute (params , constants = constants )
636646 data = tree_leaves (data , is_leaf = lambda x : isinstance (x , dict ))
637647 out = jnp .concatenate ([dat ["torsion" ] for dat in data ])
638- return out [self ._coilset_tree ["coilset_mask " ]]
648+ return out [self ._coilset_tree ["objective_mask " ]]
639649
640650
641651class CoilCurrentLength (CoilLength ):
@@ -741,7 +751,7 @@ def compute(self, params, constants=None):
741751 lengths = super ().compute (params , constants = constants )
742752 params = tree_leaves (params , is_leaf = lambda x : isinstance (x , dict ))
743753 currents = jnp .concatenate ([param ["current" ] for param in params ])
744- out = jnp .atleast_1d (lengths * currents [self ._coilset_tree ["coilset_mask " ]])
754+ out = jnp .atleast_1d (lengths * currents [self ._coilset_tree ["objective_mask " ]])
745755 return out
746756
747757
@@ -848,7 +858,7 @@ def compute(self, params, constants=None):
848858 for dat in data
849859 ]
850860 )
851- return out [self ._coilset_tree ["coilset_mask " ]]
861+ return out [self ._coilset_tree ["objective_mask " ]]
852862
853863
854864class CoilSetMinDistance (_Objective ):
@@ -1566,7 +1576,7 @@ def compute(self, params, constants=None):
15661576 constants = self ._get_deprecated_constants (constants )
15671577 data = tree_leaves (data , is_leaf = lambda x : isinstance (x , dict ))
15681578 out = jnp .array ([jnp .var (jnp .linalg .norm (dat ["x_s" ], axis = 1 )) for dat in data ])
1569- return (out * constants ["mask" ])[self ._coilset_tree ["coilset_mask " ]]
1579+ return (out * constants ["mask" ])[self ._coilset_tree ["objective_mask " ]]
15701580
15711581
15721582class QuadraticFlux (_Objective ):
0 commit comments