@@ -138,14 +138,10 @@ def _init_from_model_json(self, model_json_str: str) -> None:
138138 self ._dpmodel = BaseModel .deserialize (model_data )
139139 self ._is_spin = False
140140
141- self .rcut = self ._dpmodel .get_rcut ()
142- self .type_map = self ._dpmodel .get_type_map ()
143- # Hoist sel / mixed_types to plain attributes so the inference hot
144- # path (`_build_nlist_*`) does not need the dpmodel instance. This
145- # matches what `_init_from_metadata` sets and keeps both code paths
146- # numerically identical.
147- self .sel = list (self ._dpmodel .get_sel ())
148- self .mixed_types = bool (self ._dpmodel .mixed_types ())
141+ self ._rcut = self ._dpmodel .get_rcut ()
142+ self ._type_map = self ._dpmodel .get_type_map ()
143+ self ._sel = list (self ._dpmodel .get_sel ())
144+ self ._mixed_types = bool (self ._dpmodel .mixed_types ())
149145 if self ._is_spin :
150146 self ._model_output_def = ModelOutputDef (
151147 FittingOutputDef (
@@ -177,15 +173,15 @@ def _init_from_metadata(self) -> None:
177173 ``self._dpmodel`` is left as ``None`` to signal the metadata-only
178174 mode. Inference does not need it: it runs through
179175 ``aoti_load_package`` / the exported module and uses plain
180- attributes (``self.rcut ``, ``self.sel ``, ``self.mixed_types ``,
176+ attributes (``self._rcut ``, ``self._sel ``, ``self._mixed_types ``,
181177 ``self._model_output_def``) for all metadata-level queries.
182178 """
183179 self ._dpmodel = None
184180 self ._is_spin = bool (self .metadata .get ("is_spin" , False ))
185- self .rcut = float (self .metadata ["rcut" ])
186- self .type_map = list (self .metadata ["type_map" ])
187- self .sel = [int (s ) for s in self .metadata ["sel" ]]
188- self .mixed_types = bool (self .metadata ["mixed_types" ])
181+ self ._rcut = float (self .metadata ["rcut" ])
182+ self ._type_map = list (self .metadata ["type_map" ])
183+ self ._sel = [int (s ) for s in self .metadata ["sel" ]]
184+ self ._mixed_types = bool (self .metadata ["mixed_types" ])
189185
190186 fitting_defs = []
191187 for vdef in self .metadata ["fitting_output_defs" ]:
@@ -294,15 +290,15 @@ def _load_pt2(self, model_file: str) -> None:
294290
295291 def get_rcut (self ) -> float :
296292 """Get the cutoff radius of this model."""
297- return self .rcut
293+ return self ._rcut
298294
299295 def get_ntypes (self ) -> int :
300296 """Get the number of atom types of this model."""
301- return len (self .type_map )
297+ return len (self ._type_map )
302298
303299 def get_type_map (self ) -> list [str ]:
304300 """Get the type map (element name of the atom types) of this model."""
305- return self .type_map
301+ return self ._type_map
306302
307303 def get_dim_fparam (self ) -> int :
308304 """Get the number (dimension) of frame parameters of this DP."""
@@ -318,7 +314,7 @@ def get_dim_aparam(self) -> int:
318314
319315 @property
320316 def model_type (self ) -> type ["DeepEvalWrapper" ]:
321- """The the evaluator of the model type."""
317+ """The evaluator of the model type."""
322318 if self ._dpmodel is not None :
323319 model_output_type = self ._dpmodel .model_output_type ()
324320 else :
@@ -366,11 +362,11 @@ def get_has_efield(self) -> bool:
366362
367363 def get_has_spin (self ) -> bool :
368364 """Check if the model has spin atom types."""
369- return getattr ( self , " _is_spin" , False )
365+ return self . _is_spin
370366
371367 def get_use_spin (self ) -> list [bool ]:
372368 """Get the per-type spin usage of this model."""
373- if not getattr ( self , " _is_spin" , False ) :
369+ if not self . _is_spin :
374370 return []
375371 if self ._dpmodel is not None :
376372 return self ._dpmodel .spin .use_spin .tolist ()
@@ -528,12 +524,9 @@ def _build_nlist_native(
528524 """
529525 nframes = coords .shape [0 ]
530526 natoms = coords .shape [1 ]
531- rcut = self .rcut
532- # ``self.sel`` / ``self.mixed_types`` are populated in both
533- # :meth:`_init_from_model_json` and :meth:`_init_from_metadata`,
534- # so this works whether or not ``model.json`` was available.
535- sel = self .sel
536- mixed_types = self .mixed_types
527+ rcut = self ._rcut
528+ sel = self ._sel
529+ mixed_types = self ._mixed_types
537530
538531 if cells is not None :
539532 box_input = cells .reshape (nframes , 3 , 3 )
@@ -644,8 +637,8 @@ def _build_nlist_ase_single(
644637 nlist : np.ndarray, shape (nloc, nsel)
645638 mapping : np.ndarray, shape (nall,)
646639 """
647- sel = self .sel
648- mixed_types = self .mixed_types
640+ sel = self ._sel
641+ mixed_types = self ._mixed_types
649642 nsel = sum (sel )
650643
651644 natoms = positions .shape [0 ]
@@ -688,7 +681,7 @@ def _build_nlist_ase_single(
688681 ghost_remap [out_mask ] = np .arange (nloc , nloc + nghost , dtype = np .int64 )
689682
690683 # Build nlist: vectorized CSR-to-dense conversion
691- rcut = self .rcut
684+ rcut = self ._rcut
692685 counts = np .diff (first_neigh )
693686 max_nn = int (counts .max ()) if counts .size > 0 else 0
694687
0 commit comments