diffpy.apps 0.1.1rc0__tar.gz → 0.2.0rc1__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 (52) hide show
  1. {diffpy_apps-0.1.1rc0/src/diffpy.apps.egg-info → diffpy_apps-0.2.0rc1}/PKG-INFO +5 -4
  2. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/README.rst +1 -0
  3. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/pyproject.toml +2 -3
  4. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/requirements/conda.txt +4 -0
  5. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy/__init__.py +1 -1
  6. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy/apps/app_agentify.py +22 -12
  7. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy/apps/pdfadapter.py +17 -18
  8. diffpy_apps-0.2.0rc1/src/diffpy/apps/refinebase/__init__.py +0 -0
  9. diffpy_apps-0.2.0rc1/src/diffpy/apps/refinebase/parametric_model.py +662 -0
  10. diffpy_apps-0.2.0rc1/src/diffpy/apps/refinebase/refinement_server.py +618 -0
  11. diffpy_apps-0.2.0rc1/src/diffpy/apps/refinebase/refinement_session.py +606 -0
  12. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1/src/diffpy.apps.egg-info}/PKG-INFO +5 -4
  13. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy.apps.egg-info/SOURCES.txt +19 -1
  14. diffpy_apps-0.2.0rc1/tests/conftest.py +43 -0
  15. diffpy_apps-0.2.0rc1/tests/data/C60.gr +1999 -0
  16. diffpy_apps-0.2.0rc1/tests/data/c60xyz.txt +60 -0
  17. diffpy_apps-0.2.0rc1/tests/data/make_c60.txt +22 -0
  18. diffpy_apps-0.2.0rc1/tests/data/ni-q27r100-neutron.gr +10052 -0
  19. diffpy_apps-0.2.0rc1/tests/data/ni-q27r60-xray.gr +6133 -0
  20. diffpy_apps-0.2.0rc1/tests/data/pb.cif +240 -0
  21. diffpy_apps-0.2.0rc1/tests/data/pb_100_qmin1.gr +3500 -0
  22. diffpy_apps-0.2.0rc1/tests/data/si-q27r60-xray.gr +6133 -0
  23. diffpy_apps-0.2.0rc1/tests/data/si.cif +224 -0
  24. diffpy_apps-0.2.0rc1/tests/data/si90ni10-q27r60-xray.gr +6134 -0
  25. diffpy_apps-0.2.0rc1/tests/data/sine.dat +400 -0
  26. diffpy_apps-0.2.0rc1/tests/helper.py +327 -0
  27. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/tests/test_agentify.py +9 -6
  28. diffpy_apps-0.2.0rc1/tests/test_parametric_model.py +143 -0
  29. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/tests/test_pdfadapter.py +4 -20
  30. diffpy_apps-0.2.0rc1/tests/test_refinement_server.py +451 -0
  31. diffpy_apps-0.2.0rc1/tests/test_refinement_session.py +455 -0
  32. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/tests/test_runmacro.py +3 -26
  33. diffpy_apps-0.1.1rc0/tests/conftest.py +0 -19
  34. diffpy_apps-0.1.1rc0/tests/helper.py +0 -100
  35. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/AUTHORS.rst +0 -0
  36. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/LICENSE.rst +0 -0
  37. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/MANIFEST.in +0 -0
  38. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/requirements/build.txt +0 -0
  39. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/requirements/docs.txt +0 -0
  40. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/requirements/pip.txt +0 -0
  41. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/requirements/tests.txt +0 -0
  42. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/setup.cfg +0 -0
  43. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy/apps/__init__.py +0 -0
  44. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy/apps/app_runmacro.py +0 -0
  45. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy/apps/apps.py +0 -0
  46. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy/apps/version.py +0 -0
  47. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy.apps.egg-info/dependency_links.txt +0 -0
  48. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy.apps.egg-info/entry_points.txt +0 -0
  49. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy.apps.egg-info/requires.txt +0 -0
  50. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/src/diffpy.apps.egg-info/top_level.txt +0 -0
  51. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/tests/data/Ni.cif +0 -0
  52. {diffpy_apps-0.1.1rc0 → diffpy_apps-0.2.0rc1}/tests/data/Ni.gr +0 -0
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diffpy.apps
3
- Version: 0.1.1rc0
3
+ Version: 0.2.0rc1
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
+ License-Expression: BSD-3-Clause
7
8
  Project-URL: Homepage, https://github.com/diffpy/diffpy.apps/
8
9
  Project-URL: Issues, https://github.com/diffpy/diffpy.apps/issues/
9
10
  Keywords: diffraction,PDF,X-ray,neutron
@@ -11,7 +12,6 @@ Classifier: Development Status :: 5 - Production/Stable
11
12
  Classifier: Environment :: Console
12
13
  Classifier: Intended Audience :: Developers
13
14
  Classifier: Intended Audience :: Science/Research
14
- Classifier: License :: OSI Approved :: BSD License
15
15
  Classifier: Operating System :: MacOS :: MacOS X
16
16
  Classifier: Operating System :: Microsoft :: Windows
17
17
  Classifier: Operating System :: POSIX
@@ -71,6 +71,7 @@ contains
71
71
 
72
72
  - `runmacro`: A runner for DiffPy macro files.
73
73
  - `agentify`: A deployer for diffpy.cmi agentic skills.
74
+ - `Diffpy MCP server`: A local server for the DiffPy MCP instance.
74
75
 
75
76
  For more information about the diffpy.apps library, please consult our `online documentation <https://diffpy.github.io/diffpy.apps>`_.
76
77
 
@@ -41,6 +41,7 @@ contains
41
41
 
42
42
  - `runmacro`: A runner for DiffPy macro files.
43
43
  - `agentify`: A deployer for diffpy.cmi agentic skills.
44
+ - `Diffpy MCP server`: A local server for the DiffPy MCP instance.
44
45
 
45
46
  For more information about the diffpy.apps library, please consult our `online documentation <https://diffpy.github.io/diffpy.apps>`_.
46
47
 
@@ -6,11 +6,10 @@ 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"
@@ -22,7 +21,6 @@ classifiers = [
22
21
  'Environment :: Console',
23
22
  'Intended Audience :: Developers',
24
23
  'Intended Audience :: Science/Research',
25
- 'License :: OSI Approved :: BSD License',
26
24
  'Operating System :: MacOS :: MacOS X',
27
25
  'Operating System :: Microsoft :: Windows',
28
26
  'Operating System :: POSIX',
@@ -33,6 +31,7 @@ classifiers = [
33
31
  'Topic :: Scientific/Engineering :: Physics',
34
32
  'Topic :: Scientific/Engineering :: Chemistry',
35
33
  ]
34
+ license = "BSD-3-Clause"
36
35
 
37
36
  [project.urls]
38
37
  Homepage = "https://github.com/diffpy/diffpy.apps/"
@@ -6,3 +6,7 @@ pyyaml
6
6
  diffpy.srfit
7
7
  diffpy.srreal
8
8
  diffpy.structure
9
+ networkx
10
+ mcp[cli]
11
+ mp-api
12
+ pymatgen
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
  ##############################################################################
3
3
  #
4
- # (c) 2026 The Trustees of Columbia University in the City of New York.
4
+ # (c) 2026 diffpy.apps contributors.
5
5
  # All rights reserved.
6
6
  #
7
7
  # File coded by: Billinge Group members and community contributors.
@@ -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
+ )
@@ -65,8 +65,8 @@ class PDFAdapter:
65
65
  """
66
66
  profile = Profile()
67
67
  parser = PDFParser()
68
- parser.parseString(Path(profile_path).read_text())
69
- profile.loadParsedData(parser)
68
+ parser.parse_file(profile_path)
69
+ profile.load_parsed_data(parser)
70
70
  if q_range is not None:
71
71
  profile.meta["qmin"] = q_range[0]
72
72
  profile.meta["qmax"] = q_range[1]
@@ -77,7 +77,7 @@ class PDFAdapter:
77
77
  "xmax": calculation_range[1],
78
78
  "dx": calculation_range[2],
79
79
  }
80
- profile.setCalculationRange(**calculation_range)
80
+ profile.set_calculation_range(**calculation_range)
81
81
  self.profile = profile
82
82
 
83
83
  def initialize_structures(
@@ -185,10 +185,10 @@ class PDFAdapter:
185
185
  """
186
186
  equation = equation[0] if equation is not None else None
187
187
  contribution = FitContribution("pdfcontribution")
188
- contribution.setProfile(self.profile)
188
+ contribution.set_profile(self.profile)
189
189
  for pdfgenerator in self.pdfgenerators:
190
- contribution.addProfileGenerator(pdfgenerator)
191
- contribution.setEquation(equation)
190
+ contribution.add_profile_generator(pdfgenerator)
191
+ contribution.set_equation(equation)
192
192
  self.contribution = contribution
193
193
  return self.contribution
194
194
 
@@ -202,11 +202,10 @@ 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
- recipe.addContribution(self.contribution)
208
- qdamp = recipe.newVar("qdamp", fixed=False, value=0.04)
209
- qbroad = recipe.newVar("qbroad", fixed=False, value=0.02)
206
+ recipe.add_contribution(self.contribution)
207
+ qdamp = recipe.create_new_variable("qdamp", fixed=False, value=0.04)
208
+ qbroad = recipe.create_new_variable("qbroad", fixed=False, value=0.02)
210
209
  for i, (pdfgenerator, spacegroup) in enumerate(
211
210
  zip(self.pdfgenerators, self.spacegroups)
212
211
  ):
@@ -215,23 +214,23 @@ class PDFAdapter:
215
214
  "delta2",
216
215
  ]:
217
216
  par = getattr(pdfgenerator, pname)
218
- recipe.addVar(
217
+ recipe.add_variable(
219
218
  par, name=f"{pdfgenerator.name}_{pname}", fixed=False
220
219
  )
221
- recipe.constrain(pdfgenerator.qdamp, qdamp)
222
- recipe.constrain(pdfgenerator.qbroad, qbroad)
220
+ recipe.add_constraint(pdfgenerator.qdamp, qdamp)
221
+ recipe.add_constraint(pdfgenerator.qbroad, qbroad)
223
222
  stru_parset = pdfgenerator.phase
224
223
  spacegroupparams = constrainAsSpaceGroup(stru_parset, spacegroup)
225
224
  for par in spacegroupparams.xyzpars:
226
- recipe.addVar(
225
+ recipe.add_variable(
227
226
  par, name=f"{pdfgenerator.name}_{par.name}", fixed=False
228
227
  )
229
228
  for par in spacegroupparams.latpars:
230
- recipe.addVar(
229
+ recipe.add_variable(
231
230
  par, name=f"{pdfgenerator.name}_{par.name}", fixed=False
232
231
  )
233
232
  for par in spacegroupparams.adppars:
234
- recipe.addVar(
233
+ recipe.add_variable(
235
234
  par, name=f"{pdfgenerator.name}_{par.name}", fixed=False
236
235
  )
237
236
  recipe.fithooks[0].verbose = 0
@@ -247,7 +246,7 @@ class PDFAdapter:
247
246
  e.g. 's0' for scale factor.
248
247
  """
249
248
  for var_name in variable_names:
250
- self.recipe.addVar(
249
+ self.recipe.add_variable(
251
250
  getattr(self.contribution, var_name),
252
251
  name=var_name,
253
252
  fixed=False,
@@ -275,7 +274,7 @@ class PDFAdapter:
275
274
  Mapping from recipe variable names to new values.
276
275
  """
277
276
  for vname, vvalue in variable_name_to_value.items():
278
- self.recipe._parameters[vname].setValue(vvalue)
277
+ self.recipe._parameters[vname].set_value(vvalue)
279
278
 
280
279
  def get_results(self):
281
280
  """Return the current fit results as a JSON-compatible