diffpy.apps 0.2.0rc0__tar.gz → 0.2.0rc2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. {diffpy_apps-0.2.0rc0/src/diffpy.apps.egg-info → diffpy_apps-0.2.0rc2}/PKG-INFO +5 -5
  2. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/pyproject.toml +3 -4
  3. diffpy_apps-0.2.0rc2/src/diffpy/__init__.py +14 -0
  4. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy/apps/app_agentify.py +22 -12
  5. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy/apps/pdfadapter.py +7 -6
  6. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy/apps/refinebase/parametric_model.py +8 -9
  7. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy/apps/refinebase/refinement_server.py +22 -30
  8. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy/apps/refinebase/refinement_session.py +2 -2
  9. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2/src/diffpy.apps.egg-info}/PKG-INFO +5 -5
  10. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/conftest.py +1 -1
  11. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/helper.py +18 -18
  12. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/test_agentify.py +9 -6
  13. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/test_pdfadapter.py +3 -1
  14. diffpy_apps-0.2.0rc0/src/diffpy/apps/refinebase/__init__.py +0 -0
  15. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/AUTHORS.rst +0 -0
  16. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/LICENSE.rst +0 -0
  17. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/MANIFEST.in +0 -0
  18. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/README.rst +0 -0
  19. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/requirements/build.txt +0 -0
  20. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/requirements/conda.txt +0 -0
  21. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/requirements/docs.txt +0 -0
  22. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/requirements/pip.txt +0 -0
  23. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/requirements/tests.txt +0 -0
  24. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/setup.cfg +0 -0
  25. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy/apps/__init__.py +0 -0
  26. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy/apps/app_runmacro.py +0 -0
  27. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy/apps/apps.py +0 -0
  28. {diffpy_apps-0.2.0rc0/src/diffpy → diffpy_apps-0.2.0rc2/src/diffpy/apps/refinebase}/__init__.py +0 -0
  29. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy/apps/version.py +0 -0
  30. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy.apps.egg-info/SOURCES.txt +0 -0
  31. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy.apps.egg-info/dependency_links.txt +0 -0
  32. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy.apps.egg-info/entry_points.txt +0 -0
  33. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy.apps.egg-info/requires.txt +0 -0
  34. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/src/diffpy.apps.egg-info/top_level.txt +0 -0
  35. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/C60.gr +0 -0
  36. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/Ni.cif +0 -0
  37. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/Ni.gr +0 -0
  38. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/c60xyz.txt +0 -0
  39. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/make_c60.txt +0 -0
  40. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/ni-q27r100-neutron.gr +0 -0
  41. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/ni-q27r60-xray.gr +0 -0
  42. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/pb.cif +0 -0
  43. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/pb_100_qmin1.gr +0 -0
  44. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/si-q27r60-xray.gr +0 -0
  45. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/si.cif +0 -0
  46. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/si90ni10-q27r60-xray.gr +0 -0
  47. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/data/sine.dat +0 -0
  48. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/test_parametric_model.py +0 -0
  49. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/test_refinement_server.py +0 -0
  50. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/test_refinement_session.py +0 -0
  51. {diffpy_apps-0.2.0rc0 → diffpy_apps-0.2.0rc2}/tests/test_runmacro.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diffpy.apps
3
- Version: 0.2.0rc0
3
+ Version: 0.2.0rc2
4
4
  Summary: User applications to help with tasks using diffpy packages
5
- Author-email: Yuchen Xiao <yx2924@columbia.edu>, Simon Billinge <sbillinge@ucsb.edu>
6
- Maintainer-email: Yuchen Xiao <yx2924@columbia.edu>, Simon Billinge <sbillinge@ucsb.edu>
5
+ Author-email: Yuchen Xiao <xiaoyuch@msu.edu>, Simon Billinge <sbillinge@ucsb.edu>
6
+ Maintainer-email: Simon Billinge <sbillinge@ucsb.edu>
7
7
  License-Expression: BSD-3-Clause
8
8
  Project-URL: Homepage, https://github.com/diffpy/diffpy.apps/
9
9
  Project-URL: Issues, https://github.com/diffpy/diffpy.apps/issues/
@@ -16,12 +16,12 @@ Classifier: Operating System :: MacOS :: MacOS X
16
16
  Classifier: Operating System :: Microsoft :: Windows
17
17
  Classifier: Operating System :: POSIX
18
18
  Classifier: Operating System :: Unix
19
- Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
22
  Classifier: Topic :: Scientific/Engineering :: Physics
23
23
  Classifier: Topic :: Scientific/Engineering :: Chemistry
24
- Requires-Python: <3.14,>=3.11
24
+ Requires-Python: <3.15,>=3.12
25
25
  Description-Content-Type: text/x-rst
26
26
  License-File: LICENSE.rst
27
27
  License-File: AUTHORS.rst
@@ -6,17 +6,16 @@ build-backend = "setuptools.build_meta"
6
6
  name = "diffpy.apps"
7
7
  dynamic=['version', 'dependencies']
8
8
  authors = [
9
- {name='Yuchen Xiao', email='yx2924@columbia.edu'},
9
+ {name='Yuchen Xiao', email='xiaoyuch@msu.edu'},
10
10
  {name='Simon Billinge', email='sbillinge@ucsb.edu'},
11
11
  ]
12
12
  maintainers = [
13
- {name='Yuchen Xiao', email='yx2924@columbia.edu'},
14
13
  {name='Simon Billinge', email='sbillinge@ucsb.edu'},
15
14
  ]
16
15
  description = "User applications to help with tasks using diffpy packages"
17
16
  keywords = ['diffraction', 'PDF', 'X-ray', 'neutron']
18
17
  readme = "README.rst"
19
- requires-python = ">=3.11, <3.14"
18
+ requires-python = ">=3.12, <3.15"
20
19
  classifiers = [
21
20
  'Development Status :: 5 - Production/Stable',
22
21
  'Environment :: Console',
@@ -26,9 +25,9 @@ classifiers = [
26
25
  'Operating System :: Microsoft :: Windows',
27
26
  'Operating System :: POSIX',
28
27
  'Operating System :: Unix',
29
- 'Programming Language :: Python :: 3.11',
30
28
  'Programming Language :: Python :: 3.12',
31
29
  'Programming Language :: Python :: 3.13',
30
+ 'Programming Language :: Python :: 3.14',
32
31
  'Topic :: Scientific/Engineering :: Physics',
33
32
  'Topic :: Scientific/Engineering :: Chemistry',
34
33
  ]
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env python
2
+ ##############################################################################
3
+ #
4
+ # (c) 2026 diffpy.apps contributors.
5
+ # All rights reserved.
6
+ #
7
+ # File coded by: Billinge Group members and community contributors.
8
+ #
9
+ # See GitHub contributions for a more detailed list of contributors.
10
+ # https://github.com/diffpy/diffpy.apps/graphs/contributors
11
+ #
12
+ # See LICENSE.rst for license information.
13
+ #
14
+ ##############################################################################
@@ -2,10 +2,10 @@ import shutil
2
2
  import socket
3
3
  import subprocess
4
4
  import tempfile
5
+ import warnings
5
6
  from pathlib import Path
6
7
 
7
8
  REPO_URL = "https://github.com/diffpy/cmi-agent-skills"
8
- DIR_NAME = "cmi-skill"
9
9
 
10
10
 
11
11
  def ensure_setup():
@@ -35,21 +35,31 @@ def agentify(args):
35
35
  elif agent == "codex":
36
36
  skills_dir = ".codex/skills"
37
37
  if system_flag:
38
- destination = Path().home() / skills_dir / DIR_NAME
38
+ dest_dir = Path().home() / skills_dir
39
39
  else:
40
- destination = Path().cwd() / skills_dir / DIR_NAME
41
- if destination.exists() and not args.update:
42
- raise FileExistsError(
43
- f"Agentic skill {DIR_NAME} already exists at {destination}. "
44
- "To overwrite, pass '--update' flag to update the skill"
45
- )
40
+ dest_dir = Path().cwd() / skills_dir
46
41
  with tempfile.TemporaryDirectory() as tmp:
47
42
  tmp_path = Path(tmp)
48
43
  subprocess.run(
49
44
  ["git", "clone", REPO_URL, str(tmp_path)],
50
45
  check=True,
51
46
  )
52
- if destination.exists():
53
- shutil.rmtree(destination)
54
- shutil.copytree(tmp_path / DIR_NAME, destination, dirs_exist_ok=True)
55
- print(f"Agentic skill {DIR_NAME} has been deployed to {destination}")
47
+ for item in tmp_path.iterdir():
48
+ if item.is_dir():
49
+ destination = dest_dir / item.name
50
+ if destination.exists():
51
+ if args.update:
52
+ shutil.rmtree(destination)
53
+ shutil.copytree(item, destination, dirs_exist_ok=True)
54
+ print(f"Updated existing skill at {destination}")
55
+ else:
56
+ warnings.warn(
57
+ f"Skill at {destination} already exists. "
58
+ "Use '--update' flag to overwrite."
59
+ )
60
+ continue
61
+ else:
62
+ shutil.copytree(item, destination, dirs_exist_ok=True)
63
+ print(
64
+ f"Skill {item.name} has been deployed to {destination}"
65
+ )
@@ -12,8 +12,8 @@ from diffpy.srfit.fitbase import (
12
12
  Profile,
13
13
  )
14
14
  from diffpy.srfit.pdf import PDFGenerator, PDFParser
15
- from diffpy.srfit.structure import constrainAsSpaceGroup
16
- from diffpy.structure.parsers import getParser
15
+ from diffpy.srfit.structure import constrain_as_space_group
16
+ from diffpy.structure.parsers import get_parser
17
17
 
18
18
 
19
19
  class PDFAdapter:
@@ -147,7 +147,7 @@ class PDFAdapter:
147
147
  run_parallel = False
148
148
  for i, structure_path in enumerate(structure_paths):
149
149
  name = names[i] if names and i < len(names) else f"G{i+1}"
150
- stru_parser = getParser("cif")
150
+ stru_parser = get_parser("cif")
151
151
  structure = stru_parser.parse(Path(structure_path).read_text())
152
152
  sg = getattr(stru_parser, "spacegroup", None)
153
153
  spacegroup = sg.short_name if sg is not None else "P1"
@@ -176,7 +176,7 @@ class PDFAdapter:
176
176
  ----------
177
177
  equation : list of str, optional
178
178
  The list of a single equation passed to
179
- FitContribution.setEquation.
179
+ FitContribution.set_equation
180
180
 
181
181
  Returns
182
182
  -------
@@ -202,7 +202,6 @@ class PDFAdapter:
202
202
  delta1 and delta2 variables, and structure parameters
203
203
  constrained by the space group.
204
204
  """
205
-
206
205
  recipe = FitRecipe()
207
206
  recipe.add_contribution(self.contribution)
208
207
  qdamp = recipe.create_new_variable("qdamp", fixed=False, value=0.04)
@@ -221,7 +220,9 @@ class PDFAdapter:
221
220
  recipe.add_constraint(pdfgenerator.qdamp, qdamp)
222
221
  recipe.add_constraint(pdfgenerator.qbroad, qbroad)
223
222
  stru_parset = pdfgenerator.phase
224
- spacegroupparams = constrainAsSpaceGroup(stru_parset, spacegroup)
223
+ spacegroupparams = constrain_as_space_group(
224
+ stru_parset, spacegroup
225
+ )
225
226
  for par in spacegroupparams.xyzpars:
226
227
  recipe.add_variable(
227
228
  par, name=f"{pdfgenerator.name}_{par.name}", fixed=False
@@ -199,8 +199,7 @@ class ParametricModelEquation(ParametricModel):
199
199
 
200
200
  class ParametricModelFunction(ParametricModel):
201
201
  def __init__(self, name, function, argnames=None):
202
- """
203
- Initialize a ParametricModelFunction instance.
202
+ """Initialize a ParametricModelFunction instance.
204
203
 
205
204
  function can be either a callable or a string representing
206
205
  the pre-defined function.
@@ -254,8 +253,7 @@ class ParametricModelPDF(ParametricModel):
254
253
  finite=False,
255
254
  run_parallel=True,
256
255
  ):
257
- """
258
- Create a ParametricModelPDF instance from a structure object.
256
+ """Create a ParametricModelPDF instance from a structure object.
259
257
 
260
258
  structure can be a raw diffpy.structure/pyobjcryst structure, or
261
259
  an existing DiffpyStructureParSet/ObjCrystCrystalParSet phase
@@ -615,10 +613,11 @@ def create_pdf_model_from_code(
615
613
  finite=False,
616
614
  run_parallel=True,
617
615
  ):
618
- """Create a ParametricModelPDF by executing code that builds a structure.
616
+ """Create a ParametricModelPDF by executing code that builds a
617
+ structure.
619
618
 
620
- The code must assign the structure/crystal object to a variable named
621
- structure_name (default "structure") in its local namespace.
619
+ The code must assign the structure/crystal object to a variable
620
+ named structure_name (default "structure") in its local namespace.
622
621
  """
623
622
  local_namespace = {}
624
623
  exec(code, global_namespace, local_namespace)
@@ -645,8 +644,8 @@ def create_pdf_model_from_code(
645
644
  if hasattr(structure, "GetCrystal")
646
645
  else structure
647
646
  )
648
- if hasattr(crystal, "GetSpaceGroup"):
649
- spacegroup_symbol = crystal.GetSpaceGroup().GetName()
647
+ if hasattr(crystal, "get_space_group"):
648
+ spacegroup_symbol = crystal.get_space_group().get_name()
650
649
  else:
651
650
  logging.warning(
652
651
  "Could not determine a space group for the structure named "
@@ -102,7 +102,8 @@ async def set_profile_calculation_range(
102
102
  xmax: Annotated[float, "End of the calculation range"] = None,
103
103
  dx: Annotated[float, "Step size for the calculation range"] = None,
104
104
  ) -> str:
105
- """Set the calculation range for a profile in the refinement session."""
105
+ """Set the calculation range for a profile in the refinement
106
+ session."""
106
107
  session.set_profile_calculation_range(
107
108
  profile_name, xmin=xmin, xmax=xmax, dx=dx
108
109
  )
@@ -191,8 +192,8 @@ async def add_pdf_model(
191
192
  bool, "Whether to run the PDF model in parallel"
192
193
  ] = True,
193
194
  ) -> str:
194
- """
195
- Add a structure-file-based parametric model to the refinement session.
195
+ """Add a structure-file-based parametric model to the refinement
196
+ session.
196
197
 
197
198
  Parameters
198
199
  ----------
@@ -247,8 +248,7 @@ async def add_function_model(
247
248
  list[str] | None, "Argument names for the function"
248
249
  ] = None,
249
250
  ) -> str:
250
- """
251
- Add a function model to the refinement session.
251
+ """Add a function model to the refinement session.
252
252
 
253
253
  function can be either a callable or a string representing
254
254
  the pre-defined function.
@@ -282,7 +282,8 @@ async def set_model_equation(
282
282
  model_name: Annotated[str, "Name of the parametric model"],
283
283
  equation: Annotated[str, "New equation for the parametric model"],
284
284
  ) -> str:
285
- """Set the equation for an existing parametric model in the session."""
285
+ """Set the equation for an existing parametric model in the
286
+ session."""
286
287
  session.set_model_equation(model_name=model_name, equation=equation)
287
288
  return f"Equation for model {model_name} set successfully."
288
289
 
@@ -339,7 +340,8 @@ async def set_model_profile(
339
340
  model_name: Annotated[str, "Name of the parametric model"],
340
341
  profile_name: Annotated[str, "Name of the profile to set on the model"],
341
342
  ) -> str:
342
- """Set the profile for a parametric model in the refinement session."""
343
+ """Set the profile for a parametric model in the refinement
344
+ session."""
343
345
  session.set_model_profile(model_name, profile_name)
344
346
  return f"Profile {profile_name} set for model {model_name} successfully."
345
347
 
@@ -365,7 +367,8 @@ async def get_profile_data(
365
367
  profile_name: Annotated[str, "Name of the profile to retrieve"],
366
368
  data_path: Annotated[str, "Path to the data to retrieve"],
367
369
  ) -> str:
368
- """Get the details of a specific profile in the refinement session."""
370
+ """Get the details of a specific profile in the refinement
371
+ session."""
369
372
  profile = session.profiles_dict[profile_name]
370
373
  data = {"xobs": profile.xobs.tolist(), "yobs": profile.yobs.tolist()}
371
374
  with open(data_path, "w") as f:
@@ -395,8 +398,8 @@ async def constrain_pdf_model_space_group_symmetry(
395
398
  ) -> str:
396
399
  """Constrain a parametric model to a specific space group symmetry.
397
400
 
398
- If no space group is provided, the model will be constrained to
399
- its current space group parsed from its structure.
401
+ If no space group is provided, the model will be constrained to its
402
+ current space group parsed from its structure.
400
403
  """
401
404
  session.constrain_pdf_model_space_group_symmetry(model_name, space_group)
402
405
  return (
@@ -428,9 +431,8 @@ async def combine_models(
428
431
  list[str], "Names of the child parametric models"
429
432
  ],
430
433
  ) -> str:
431
- """
432
- Combine two parametric models by registering the child to the parent model.
433
- """
434
+ """Combine two parametric models by registering the child to the
435
+ parent model."""
434
436
  session.combine_models(parent_model_name, child_model_names)
435
437
  return (
436
438
  f"Models {parent_model_name} and "
@@ -445,9 +447,7 @@ async def set_variables_value(
445
447
  dict, "Mapping of variable names to the values to set them to"
446
448
  ],
447
449
  ) -> str:
448
- """
449
- Set the value of a specific variable in a parametric model.
450
- """
450
+ """Set the value of a specific variable in a parametric model."""
451
451
  session.set_variables_value(name_value_dict)
452
452
 
453
453
  return f"Variables '{name_value_dict}' are set."
@@ -458,9 +458,7 @@ async def set_variables_value(
458
458
  async def get_variable(
459
459
  variable_name: Annotated[str, "Name of the variable"],
460
460
  ) -> str:
461
- """
462
- Get the value of a specific variable in a parametric model.
463
- """
461
+ """Get the value of a specific variable in a parametric model."""
464
462
  variable = session.get_variable(variable_name)
465
463
  return f"Variable '{variable_name}': {variable['value']}"
466
464
 
@@ -473,9 +471,7 @@ async def list_model_parameters(
473
471
  bool, "Whether to list only independent parameters"
474
472
  ] = True,
475
473
  ) -> str:
476
- """
477
- List all parameters of a specific parametric model.
478
- """
474
+ """List all parameters of a specific parametric model."""
479
475
  if model_name not in session.models_dict:
480
476
  raise ValueError(f"Model with ID {model_name} does not exist.")
481
477
 
@@ -495,9 +491,7 @@ async def list_model_parameters(
495
491
  @mcp.tool()
496
492
  @tool_errors
497
493
  async def clear() -> str:
498
- """
499
- Clear the current refinement session.
500
- """
494
+ """Clear the current refinement session."""
501
495
  session.clear()
502
496
  return "Refinement session cleared successfully."
503
497
 
@@ -507,9 +501,7 @@ async def clear() -> str:
507
501
  async def list_recipe_parameters(
508
502
  recipe_name: Annotated[str, "Name of the recipe"],
509
503
  ) -> str:
510
- """
511
- List all parameters of a specific recipe.
512
- """
504
+ """List all parameters of a specific recipe."""
513
505
  if recipe_name not in session.recipes_dict:
514
506
  raise ValueError(f"Recipe with ID {recipe_name} does not exist.")
515
507
 
@@ -552,8 +544,8 @@ async def solve(
552
544
  bool, "Whether to also include sgpars from the models automatically"
553
545
  ] = False,
554
546
  ) -> str:
555
- """
556
- Initiate a refinement using the specified profiles, models, and variables.
547
+ """Initiate a refinement using the specified profiles, models, and
548
+ variables.
557
549
 
558
550
  Parameters
559
551
  ----------
@@ -67,7 +67,7 @@ class RefinementSession:
67
67
  if profile_name is None:
68
68
  profile_name = str(uuid.uuid4())
69
69
  profile = Profile()
70
- profile.setObservedProfile(xobs=xarray, yobs=yarray, dyobs=dy)
70
+ profile.set_observed_profile(xobs=xarray, yobs=yarray, dyobs=dy)
71
71
  profile.xpar.name = xname
72
72
  profile._xname = xname
73
73
  profile.ypar.name = yname
@@ -531,7 +531,7 @@ class RefinementSession:
531
531
  par = self.get_variable(eq_or_var_name)["obj"]
532
532
  par.bound_range(lb, ub)
533
533
  recipe.free("all")
534
- leastsq(recipe.residual, recipe.getValues())
534
+ leastsq(recipe.residual, recipe.get_values())
535
535
  # NOTE: non-scalar value will raise error in `get_results_string`
536
536
  try:
537
537
  result_string = FitResults(recipe).get_results_string()
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diffpy.apps
3
- Version: 0.2.0rc0
3
+ Version: 0.2.0rc2
4
4
  Summary: User applications to help with tasks using diffpy packages
5
- Author-email: Yuchen Xiao <yx2924@columbia.edu>, Simon Billinge <sbillinge@ucsb.edu>
6
- Maintainer-email: Yuchen Xiao <yx2924@columbia.edu>, Simon Billinge <sbillinge@ucsb.edu>
5
+ Author-email: Yuchen Xiao <xiaoyuch@msu.edu>, Simon Billinge <sbillinge@ucsb.edu>
6
+ Maintainer-email: Simon Billinge <sbillinge@ucsb.edu>
7
7
  License-Expression: BSD-3-Clause
8
8
  Project-URL: Homepage, https://github.com/diffpy/diffpy.apps/
9
9
  Project-URL: Issues, https://github.com/diffpy/diffpy.apps/issues/
@@ -16,12 +16,12 @@ Classifier: Operating System :: MacOS :: MacOS X
16
16
  Classifier: Operating System :: Microsoft :: Windows
17
17
  Classifier: Operating System :: POSIX
18
18
  Classifier: Operating System :: Unix
19
- Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
22
  Classifier: Topic :: Scientific/Engineering :: Physics
23
23
  Classifier: Topic :: Scientific/Engineering :: Chemistry
24
- Requires-Python: <3.14,>=3.11
24
+ Requires-Python: <3.15,>=3.12
25
25
  Description-Content-Type: text/x-rst
26
26
  License-File: LICENSE.rst
27
27
  License-File: AUTHORS.rst
@@ -39,5 +39,5 @@ def sine_profile():
39
39
  xobs = numpy.linspace(-numpy.pi, numpy.pi, 100)
40
40
  yobs = numpy.sin(xobs) + 1e-3 * numpy.random.normal(size=xobs.shape)
41
41
  sine_profile = Profile()
42
- sine_profile.setObservedProfile(xobs, yobs)
42
+ sine_profile.set_observed_profile(xobs, yobs)
43
43
  return sine_profile
@@ -10,8 +10,8 @@ from diffpy.srfit.fitbase import (
10
10
  Profile,
11
11
  )
12
12
  from diffpy.srfit.pdf import DebyePDFGenerator, PDFGenerator, PDFParser
13
- from diffpy.srfit.structure import constrainAsSpaceGroup
14
- from diffpy.structure.parsers import getParser
13
+ from diffpy.srfit.structure import constrain_as_space_group
14
+ from diffpy.structure.parsers import get_parser
15
15
 
16
16
  _DATA_DIR = Path(__file__).parent / "data"
17
17
 
@@ -49,21 +49,21 @@ def run_ni_example():
49
49
  QBROAD_I = 0.02
50
50
  RUN_PARALLEL = True
51
51
 
52
- p_cif = getParser("cif")
53
- stru1 = p_cif.parseFile(structure_path)
52
+ p_cif = get_parser("cif")
53
+ stru1 = p_cif.parse_file(structure_path)
54
54
  sg = p_cif.spacegroup.short_name
55
55
  profile = Profile()
56
56
  parser = PDFParser()
57
- parser.parseFile(profile_path)
58
- profile.loadParsedData(parser)
59
- profile.setCalculationRange(xmin=PDF_RMIN, xmax=PDF_RMAX, dx=PDF_RSTEP)
57
+ parser.parse_file(profile_path)
58
+ profile.load_parsed_data(parser)
59
+ profile.set_calculation_range(xmin=PDF_RMIN, xmax=PDF_RMAX, dx=PDF_RSTEP)
60
60
  generator_crystal1 = PDFGenerator("G1")
61
61
  generator_crystal1.setStructure(stru1, periodic=True)
62
62
  generator_crystal1.setQmax(QMAX)
63
63
  generator_crystal1.setQmin(QMIN)
64
64
  generator_crystal1.delta2.value = DELTA2_I
65
65
  contribution = FitContribution("crystal")
66
- contribution.addProfileGenerator(generator_crystal1)
66
+ contribution.add_profile_generator(generator_crystal1)
67
67
  if RUN_PARALLEL:
68
68
  try:
69
69
  import multiprocessing
@@ -82,28 +82,28 @@ def run_ni_example():
82
82
  "\nYou don't appear to have the necessary packages for "
83
83
  "parallelization"
84
84
  )
85
- contribution.setProfile(profile, xname="r")
86
- contribution.setEquation("s0*G1")
85
+ contribution.set_profile(profile, xname="r")
86
+ contribution.set_equation("s0*G1")
87
87
  recipe = FitRecipe()
88
- recipe.addContribution(contribution)
88
+ recipe.add_contribution(contribution)
89
89
  recipe.crystal.G1.qdamp.value = QDAMP_I
90
90
  recipe.crystal.G1.qbroad.value = QBROAD_I
91
91
  recipe.crystal.G1.setQmax(QMAX)
92
92
  recipe.crystal.G1.setQmin(QMIN)
93
- recipe.addVar(contribution.s0, SCALE_I, name="s0")
94
- spacegroupparams = constrainAsSpaceGroup(generator_crystal1.phase, sg)
93
+ recipe.add_variable(contribution.s0, SCALE_I, name="s0")
94
+ spacegroupparams = constrain_as_space_group(generator_crystal1.phase, sg)
95
95
  for par in spacegroupparams.latpars:
96
- recipe.addVar(par, value=CUBICLAT_I, fixed=False, name="G1_a")
96
+ recipe.add_variable(par, value=CUBICLAT_I, fixed=False, name="G1_a")
97
97
  for par in spacegroupparams.adppars:
98
- recipe.addVar(par, value=UISO_I, fixed=False, name="G1_Uiso_0")
99
- recipe.addVar(generator_crystal1.delta2, name="G1_delta2")
100
- recipe.addVar(
98
+ recipe.add_variable(par, value=UISO_I, fixed=False, name="G1_Uiso_0")
99
+ recipe.add_variable(generator_crystal1.delta2, name="G1_delta2")
100
+ recipe.add_variable(
101
101
  generator_crystal1.qdamp,
102
102
  fixed=False,
103
103
  name="qdamp",
104
104
  value=QDAMP_I,
105
105
  )
106
- recipe.addVar(
106
+ recipe.add_variable(
107
107
  generator_crystal1.qbroad,
108
108
  fixed=False,
109
109
  name="qbroad",
@@ -28,7 +28,7 @@ pytestmark = pytest.mark.skipif(
28
28
  update=False,
29
29
  ),
30
30
  "cwd",
31
- ".claude/skills/cmi-skill",
31
+ ".claude/skills/diffpy-playbook",
32
32
  ),
33
33
  # C2: diffpy.apps agentify --system
34
34
  # Deploys system claude skill.
@@ -40,7 +40,7 @@ pytestmark = pytest.mark.skipif(
40
40
  update=False,
41
41
  ),
42
42
  "home",
43
- ".claude/skills/cmi-skill",
43
+ ".claude/skills/diffpy-playbook",
44
44
  ),
45
45
  # C3: diffpy.apps agentify --agent codex
46
46
  # Deploys workspace codex skill.
@@ -52,7 +52,7 @@ pytestmark = pytest.mark.skipif(
52
52
  update=False,
53
53
  ),
54
54
  "cwd",
55
- ".codex/skills/cmi-skill",
55
+ ".codex/skills/diffpy-playbook",
56
56
  ),
57
57
  # C4: diffpy.apps agentify --agent codex --system
58
58
  # Deploys system codex skill.
@@ -64,7 +64,7 @@ pytestmark = pytest.mark.skipif(
64
64
  update=False,
65
65
  ),
66
66
  "home",
67
- ".codex/skills/cmi-skill",
67
+ ".codex/skills/diffpy-playbook",
68
68
  ),
69
69
  ],
70
70
  )
@@ -94,14 +94,17 @@ def test_agentify_update():
94
94
  update=False,
95
95
  )
96
96
  agentify(args)
97
- skill_path = Path(tmp) / "cwd" / ".claude" / "skills" / "cmi-skill"
97
+ skill_path = (
98
+ Path(tmp) / "cwd" / ".claude" / "skills" / "diffpy-playbook"
99
+ )
98
100
  assert skill_path.exists()
99
101
  args.update = True
100
102
  agentify(args)
101
103
  pytest.raises(
102
104
  FileExistsError,
103
105
  match=re.escape(
104
- f"Agentic skill cmi-skill already exists at {skill_path}. "
106
+ "Agentic skill diffpy-playbook already exists at "
107
+ f"{skill_path}. "
105
108
  "To overwrite, pass '--update' flag to update the skill"
106
109
  ),
107
110
  )
@@ -37,7 +37,9 @@ def test_pdfadapter():
37
37
  adapter.initialize_structures([str(structure_path)])
38
38
  adapter.initialize_contribution(equation=["s0*G1"])
39
39
  adapter.initialize_recipe()
40
- adapter.recipe.addVar(list(adapter.recipe._contributions.values())[0].s0)
40
+ adapter.recipe.add_variable(
41
+ list(adapter.recipe._contributions.values())[0].s0
42
+ )
41
43
  adapter.set_initial_variable_values(initial_pv_dict)
42
44
  adapter.recipe.fix("all")
43
45
  for var in variables_to_refine:
File without changes