pxmeter 0.0.1__tar.gz → 0.1.1__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 (39) hide show
  1. pxmeter-0.1.1/PKG-INFO +32 -0
  2. {pxmeter-0.0.1 → pxmeter-0.1.1}/README.md +24 -13
  3. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/cli.py +61 -55
  4. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/configs/data_config.py +1 -1
  5. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/data/ccd.py +1 -1
  6. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/data/utils.py +13 -2
  7. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/mapping.py +1 -1
  8. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/utils.py +3 -15
  9. pxmeter-0.1.1/pxmeter.egg-info/PKG-INFO +32 -0
  10. pxmeter-0.1.1/pxmeter.egg-info/entry_points.txt +2 -0
  11. {pxmeter-0.0.1 → pxmeter-0.1.1}/setup.py +4 -3
  12. pxmeter-0.0.1/PKG-INFO +0 -10
  13. pxmeter-0.0.1/pxmeter.egg-info/PKG-INFO +0 -10
  14. pxmeter-0.0.1/pxmeter.egg-info/entry_points.txt +0 -2
  15. {pxmeter-0.0.1 → pxmeter-0.1.1}/LICENSE +0 -0
  16. {pxmeter-0.0.1 → pxmeter-0.1.1}/MANIFEST.in +0 -0
  17. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/__init__.py +0 -0
  18. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/calc_metric.py +0 -0
  19. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/configs/__init__.py +0 -0
  20. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/configs/run_config.py +0 -0
  21. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/constants.py +0 -0
  22. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/data/__init__.py +0 -0
  23. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/data/parser.py +0 -0
  24. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/data/struct.py +0 -0
  25. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/data/writer.py +0 -0
  26. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/eval.py +0 -0
  27. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/metrics/__init__.py +0 -0
  28. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/metrics/lddt_metrics.py +0 -0
  29. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/metrics/rmsd.py +0 -0
  30. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/metrics/rmsd_metrics.py +0 -0
  31. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/permutation/__init__.py +0 -0
  32. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/permutation/atom.py +0 -0
  33. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter/permutation/chain.py +0 -0
  34. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter.egg-info/SOURCES.txt +0 -0
  35. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter.egg-info/dependency_links.txt +0 -0
  36. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter.egg-info/requires.txt +0 -0
  37. {pxmeter-0.0.1 → pxmeter-0.1.1}/pxmeter.egg-info/top_level.txt +0 -0
  38. {pxmeter-0.0.1 → pxmeter-0.1.1}/requirements.txt +0 -0
  39. {pxmeter-0.0.1 → pxmeter-0.1.1}/setup.cfg +0 -0
pxmeter-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,32 @@
1
+ Metadata-Version: 2.4
2
+ Name: pxmeter
3
+ Version: 0.1.1
4
+ Summary: PXMeter is a comprehensive toolkit for evaluating the quality of structures generated by biomolecular structure prediction models.
5
+ Author: Bytedance Inc.
6
+ Author-email: ai4s-bio@bytedance.com
7
+ License: Apache 2.0 License
8
+ Platform: manylinux1
9
+ Requires-Python: >=3.11
10
+ License-File: LICENSE
11
+ Requires-Dist: biotite>=1.2.0
12
+ Requires-Dist: dockq==2.1.3
13
+ Requires-Dist: gemmi==0.7.0
14
+ Requires-Dist: joblib
15
+ Requires-Dist: ml_collections
16
+ Requires-Dist: numpy
17
+ Requires-Dist: pandas
18
+ Requires-Dist: pdbeccdutils==0.8.5
19
+ Requires-Dist: posebusters==0.3.1
20
+ Requires-Dist: rdkit>=2024.09.6
21
+ Requires-Dist: scipy
22
+ Requires-Dist: tabulate
23
+ Requires-Dist: tqdm
24
+ Requires-Dist: click
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: license
28
+ Dynamic: license-file
29
+ Dynamic: platform
30
+ Dynamic: requires-dist
31
+ Dynamic: requires-python
32
+ Dynamic: summary
@@ -4,8 +4,8 @@
4
4
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
5
5
 
6
6
  <div align="left" style="margin: 20px 0;">
7
- <span style="margin: 0 10px;">📄 <a href="URL">From Dataset Diagnostics to Evaluation: Revisiting
8
- Structure Prediction Benchmarks with PXMeter</a></span>
7
+ <span style="margin: 0 10px;">📄 <a href="https://www.biorxiv.org/content/10.1101/2025.07.17.664878v1">From Dataset Curation to Unified Evaluation: Revisiting
8
+ Structure Prediction Benchmarks with PXMeter</a></span>
9
9
  </div>
10
10
 
11
11
  PXMeter is a comprehensive toolkit for evaluating the quality of structures generated by biomolecular structure prediction models, with support for proteins, nucleic acids, and small molecules.
@@ -86,7 +86,12 @@ Refer to [benchmark/README.md](./benchmark/README.md) for evaluation protocols o
86
86
  - PoseBusters V2
87
87
 
88
88
  The benchmark data is released under the CC0 license.
89
- We include code in the `benchmark` directory that evaluates various models using PXMeter and aggregates their metrics. This serves as an example of best practices for using the tool. For more details, please refer to the [Technical Report URL].
89
+ We include code in the `benchmark` directory that evaluates various models using PXMeter and aggregates their metrics.
90
+ This serves as an example of best practices for using the tool. For more details, please refer to our paper:
91
+
92
+ 📄 <a href="https://www.biorxiv.org/content/10.1101/2025.07.17.664878v1">From Dataset Curation to Unified Evaluation: Revisiting
93
+ Structure Prediction Benchmarks with PXMeter</a>
94
+
90
95
 
91
96
 
92
97
  ## 💪 Contributing to PXMeter
@@ -102,21 +107,27 @@ pre-commit install
102
107
  ```
103
108
 
104
109
 
105
- ## 🚧 Limitations
106
- - PXMeter supports chain/atom permutations but not residue-level permutations. As a result, the accuracy of evaluation for branched chains, such as glycans, cannot be fully guaranteed.
107
- - It is recommended to use CIF files from the RCSB PDB as references, as they ensure content accuracy. All development and testing were conducted exclusively on CIF files from this source.
108
-
109
-
110
110
  ## ✍️ Citing PXMeter
111
+ If you use PXMeter in your research, please cite the following:
111
112
  ```bibtex
112
- @software{pxmeter,
113
- title = {PXMeter: Biomolecular Structure Quality Assessment Toolkit},
114
- author = {Bytedance AI for Science Team},
115
- year = {2024},
116
- url = {https://github.com/your-org/pxmeter},
113
+ @article {Ma2025.07.17.664878,
114
+ author = {Ma, Wenzhi and Liu, Zhenyu and Yang, Jincai and Lu, Chan and Zhang, Hanyu and Xiao, Wenzhi},
115
+ title = {From Dataset Curation to Unified Evaluation: Revisiting Structure Prediction Benchmarks with PXMeter},
116
+ year = {2025},
117
+ doi = {10.1101/2025.07.17.664878},
118
+ publisher = {Cold Spring Harbor Laboratory},
119
+ URL = {https://www.biorxiv.org/content/early/2025/07/22/2025.07.17.664878},
120
+ eprint = {https://www.biorxiv.org/content/early/2025/07/22/2025.07.17.664878.full.pdf},
121
+ journal = {bioRxiv}
117
122
  }
118
123
  ```
119
124
 
125
+
126
+ ## 🚧 Limitations
127
+ - PXMeter supports chain/atom permutations but not residue-level permutations. As a result, the accuracy of evaluation for branched chains, such as glycans, cannot be fully guaranteed.
128
+ - It is recommended to use CIF files from the RCSB PDB as references, as they ensure content accuracy. All development and testing were conducted exclusively on CIF files from this source.
129
+
130
+
120
131
  ## 🛡️ Security
121
132
  If you discover a potential security issue in this project, or think you may
122
133
  have discovered a security issue, we ask that you notify Bytedance Security via our [security center](https://security.bytedance.com/src) or [vulnerability reporting email](sec@bytedance.com).
@@ -12,13 +12,19 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import sys
15
16
  from pathlib import Path
16
17
 
17
18
  import click
18
19
 
19
- from pxmeter.configs.data_config import COMPONENTS_FILE, download_ccd_cif
20
+ from pxmeter.configs.data_config import (
21
+ COMPONENTS_FILE,
22
+ download_ccd_cif,
23
+ make_one_letter_code_json_from_ccd,
24
+ ONE_LETTER_CODE_JSON,
25
+ )
20
26
  from pxmeter.eval import evaluate, MetricResult
21
- from pxmeter.utils import none_or_str, read_chain_id_to_mol_from_json
27
+ from pxmeter.utils import read_chain_id_to_mol_from_json
22
28
 
23
29
 
24
30
  def run_eval_cif(
@@ -29,14 +35,14 @@ def run_eval_cif(
29
35
  ref_assembly_id: str | None = None,
30
36
  ref_altloc: str = "first",
31
37
  interested_lig_label_asym_id: str | None = None,
32
- chain_id_to_mol_json: str | None = None,
38
+ chain_id_to_mol_json: Path | None = None,
33
39
  output_mapped_cif: bool = False,
34
40
  ) -> MetricResult:
35
41
  """
36
- Evaluate the performance of a model CIF file against a reference CIF file.
37
- And save the result to a JSON file.
42
+ Evaluate the performance of a model CIF file by comparing it to a reference CIF file,
43
+ and save the results in a JSON file.
38
44
  """
39
- if chain_id_to_mol_json:
45
+ if chain_id_to_mol_json is not None:
40
46
  chain_id_to_mol = read_chain_id_to_mol_from_json(chain_id_to_mol_json)
41
47
  else:
42
48
  chain_id_to_mol = None
@@ -68,37 +74,9 @@ def run_eval_cif(
68
74
  return metric_result
69
75
 
70
76
 
71
- @click.group()
72
- def ccd_cli():
73
- """
74
- CCD Options.
75
- """
76
- return
77
-
78
-
79
- @ccd_cli.command(name="update")
80
- def update():
81
- """
82
- Update the CCD database.
83
- """
84
- download_ccd_cif(output_path=COMPONENTS_FILE.parent)
85
-
86
-
87
- @click.group()
88
- def eval_cif():
89
- """
90
- Evaluate the performance of a model CIF file against a reference CIF file.
91
- """
92
- return
93
-
94
-
95
77
  @click.group(invoke_without_command=True)
96
- @click.option(
97
- "-r", "--ref_cif", type=Path, required=True, help="Path to the reference CIF file."
98
- )
99
- @click.option(
100
- "-m", "--model_cif", type=Path, required=True, help="Path to the model CIF file."
101
- )
78
+ @click.option("-r", "--ref_cif", type=Path, help="Path to the reference CIF file.")
79
+ @click.option("-m", "--model_cif", type=Path, help="Path to the model CIF file.")
102
80
  @click.option(
103
81
  "-o",
104
82
  "--output_json",
@@ -114,7 +92,7 @@ def eval_cif():
114
92
  )
115
93
  @click.option(
116
94
  "--ref_assembly_id",
117
- type=none_or_str,
95
+ type=str,
118
96
  default=None,
119
97
  help="Assembly ID in the reference CIF file. Defaults to None.",
120
98
  )
@@ -127,15 +105,15 @@ def eval_cif():
127
105
  @click.option(
128
106
  "-l",
129
107
  "--interested_lig_label_asym_id",
130
- type=none_or_str,
108
+ type=str,
131
109
  default=None,
132
110
  help="The label_asym_id of the ligand of interest in the reference structure (for ligand RMSD metrics). \
133
- If multiple ligands are present, separate them by comma. Defaults to None.",
111
+ If multiple ligands are present, separate them by comma. Defaults to None.",
134
112
  )
135
113
  @click.option(
136
114
  "-c",
137
115
  "--chain_id_to_mol_json",
138
- type=none_or_str,
116
+ type=Path,
139
117
  default=None,
140
118
  help="Path to a JSON file containing a mapping of chain IDs to molecular input (SMILES). \
141
119
  E.g. {'B': 'c1ccccc1', 'D':'CCCC'}",
@@ -145,7 +123,9 @@ def eval_cif():
145
123
  is_flag=True,
146
124
  help="Whether to output the mapped CIF file. Defaults to False.",
147
125
  )
148
- def run_eval_cif_cli(
126
+ @click.pass_context
127
+ def cli(
128
+ ctx,
149
129
  ref_cif: Path,
150
130
  model_cif: Path,
151
131
  output_json: Path,
@@ -153,21 +133,47 @@ def run_eval_cif_cli(
153
133
  ref_assembly_id: str | None = None,
154
134
  ref_altloc: str = "first",
155
135
  interested_lig_label_asym_id: str | None = None,
156
- chain_id_to_mol_json: str | None = None,
136
+ chain_id_to_mol_json: Path | None = None,
157
137
  output_mapped_cif: bool = False,
158
138
  ):
159
139
  """
160
- Evaluate the performance of a model CIF file against a reference CIF file.
161
- And save the result to a JSON file.
140
+ Evaluate the performance of a model CIF file by comparing it to a reference CIF file,
141
+ and save the results in a JSON file.
162
142
  """
163
- run_eval_cif(
164
- ref_cif,
165
- model_cif,
166
- output_json,
167
- ref_model,
168
- ref_assembly_id,
169
- ref_altloc,
170
- interested_lig_label_asym_id,
171
- chain_id_to_mol_json,
172
- output_mapped_cif,
173
- )
143
+ if ctx.invoked_subcommand is None:
144
+ if len(sys.argv) == 1:
145
+ click.echo(ctx.get_help())
146
+ ctx.exit()
147
+
148
+ if ref_cif is None or model_cif is None:
149
+ click.echo("Error: --ref_cif and --model_cif are required.")
150
+ ctx.exit()
151
+
152
+ run_eval_cif(
153
+ ref_cif,
154
+ model_cif,
155
+ output_json,
156
+ ref_model,
157
+ ref_assembly_id,
158
+ ref_altloc,
159
+ interested_lig_label_asym_id,
160
+ chain_id_to_mol_json,
161
+ output_mapped_cif,
162
+ )
163
+
164
+
165
+ @cli.group(name="ccd")
166
+ def ccd_cli():
167
+ """
168
+ CCD Options.
169
+ """
170
+ return
171
+
172
+
173
+ @ccd_cli.command(name="update")
174
+ def update():
175
+ """
176
+ Update the CCD database.
177
+ """
178
+ download_ccd_cif(output_path=COMPONENTS_FILE.parent)
179
+ make_one_letter_code_json_from_ccd(COMPONENTS_FILE, ONE_LETTER_CODE_JSON)
@@ -52,7 +52,7 @@ def download_ccd_cif(output_path: Path):
52
52
 
53
53
  sp.run(f"gunzip -d {output_cif_gz}", shell=True, check=True)
54
54
 
55
- logging.info("Download CCD CIF file successfully.")
55
+ logging.info("Download CCD CIF file successfully: %s", output_cif)
56
56
 
57
57
 
58
58
  def make_one_letter_code_json_from_ccd(components_file: Path, output_json: Path):
@@ -232,7 +232,7 @@ def get_ccd_perm_info(ccd_code: str) -> dict[str, Any]:
232
232
  for node in removed_nodes:
233
233
  mol_graph.remove_node(node)
234
234
 
235
- matches = get_mol_graph_matches(mol_graph, mol_graph)[:1000]
235
+ matches = get_mol_graph_matches(mol_graph, mol_graph, max_matches=1000)
236
236
 
237
237
  # re-index after removing H
238
238
  reverted_old_atom_map = {v: k for k, v in mol.atom_map.items()}
@@ -234,13 +234,16 @@ def rdkit_mol_to_nx_graph(mol: Chem.Mol) -> nx.Graph:
234
234
  return G
235
235
 
236
236
 
237
- def get_mol_graph_matches(mol_graph1: nx.Graph, mol_graph2: nx.Graph) -> list[dict]:
237
+ def get_mol_graph_matches(
238
+ mol_graph1: nx.Graph, mol_graph2: nx.Graph, max_matches: int = 1000
239
+ ) -> list[dict]:
238
240
  """
239
241
  Find all isomorphisms between subgraph of mol_graph1 and mol_graph2.
240
242
 
241
243
  Args:
242
244
  mol_graph1 (nx.Graph): Source molecular graph (typically larger subgraph)
243
245
  mol_graph2 (nx.Graph): Target molecular graph (typically smaller supergraph)
246
+ max_matches (int): Maximum number of matches to return. Default is 1000.
244
247
 
245
248
  Returns:
246
249
  list[dict]: List of node mapping dictionaries where each dictionary represents
@@ -254,4 +257,12 @@ def get_mol_graph_matches(mol_graph1: nx.Graph, mol_graph2: nx.Graph) -> list[di
254
257
  mol_graph2,
255
258
  node_match=lambda x, y: x["atomic_num"] == y["atomic_num"],
256
259
  )
257
- return list(isomatcher.subgraph_isomorphisms_iter())
260
+
261
+ matches = []
262
+ num = 0
263
+ for i in isomatcher.subgraph_isomorphisms_iter():
264
+ matches.append(i)
265
+ num += 1
266
+ if num >= max_matches:
267
+ break
268
+ return matches
@@ -584,7 +584,7 @@ class MappingCIF:
584
584
  ref_graph = rdkit_mol_to_nx_graph(ref_mol)
585
585
  model_graph = rdkit_mol_to_nx_graph(model_mol)
586
586
  try:
587
- matches = get_mol_graph_matches(model_graph, ref_graph)
587
+ matches = get_mol_graph_matches(model_graph, ref_graph, max_matches=1)
588
588
  assert len(matches) > 0
589
589
  match = matches[0]
590
590
 
@@ -13,30 +13,18 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import json
16
+ from pathlib import Path
16
17
 
17
18
  from rdkit import Chem
18
19
 
19
20
 
20
- def none_or_str(value: str | None) -> str | None:
21
- """
22
- Converts the string "None" to a NoneType, otherwise returns the input string.
23
- Args:
24
- value (str, optional): The input string which may be "None".
25
- Returns:
26
- str or None: None if the input is the string "None", otherwise the input string.
27
- """
28
- if value == "None":
29
- return None
30
- return value
31
-
32
-
33
- def read_chain_id_to_mol_from_json(json_f: str) -> dict[str, Chem.Mol]:
21
+ def read_chain_id_to_mol_from_json(json_f: Path | str) -> dict[str, Chem.Mol]:
34
22
  """
35
23
  Reads a JSON file containing chain IDs and their corresponding SMILES representations,
36
24
  and returns a dictionary mapping chain IDs to RDKit Mol objects.
37
25
 
38
26
  Args:
39
- json_f (str): The path to the JSON file.
27
+ json_f (Path | str): The path to the JSON file.
40
28
 
41
29
  Returns:
42
30
  dict[str, Chem.Mol]: A dictionary mapping chain IDs to RDKit Mol objects.
@@ -0,0 +1,32 @@
1
+ Metadata-Version: 2.4
2
+ Name: pxmeter
3
+ Version: 0.1.1
4
+ Summary: PXMeter is a comprehensive toolkit for evaluating the quality of structures generated by biomolecular structure prediction models.
5
+ Author: Bytedance Inc.
6
+ Author-email: ai4s-bio@bytedance.com
7
+ License: Apache 2.0 License
8
+ Platform: manylinux1
9
+ Requires-Python: >=3.11
10
+ License-File: LICENSE
11
+ Requires-Dist: biotite>=1.2.0
12
+ Requires-Dist: dockq==2.1.3
13
+ Requires-Dist: gemmi==0.7.0
14
+ Requires-Dist: joblib
15
+ Requires-Dist: ml_collections
16
+ Requires-Dist: numpy
17
+ Requires-Dist: pandas
18
+ Requires-Dist: pdbeccdutils==0.8.5
19
+ Requires-Dist: posebusters==0.3.1
20
+ Requires-Dist: rdkit>=2024.09.6
21
+ Requires-Dist: scipy
22
+ Requires-Dist: tabulate
23
+ Requires-Dist: tqdm
24
+ Requires-Dist: click
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: license
28
+ Dynamic: license-file
29
+ Dynamic: platform
30
+ Dynamic: requires-dist
31
+ Dynamic: requires-python
32
+ Dynamic: summary
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pxm = pxmeter.cli:cli
@@ -20,8 +20,9 @@ with open("requirements.txt") as f:
20
20
  setup(
21
21
  name="pxmeter",
22
22
  python_requires=">=3.11",
23
- version="0.0.1",
24
- description="PXMeter is a tool crafted to assess the structural quality derived from Biomolecular Folding Models",
23
+ version="0.1.1",
24
+ description="PXMeter is a comprehensive toolkit for evaluating the quality of \
25
+ structures generated by biomolecular structure prediction models.",
25
26
  author="Bytedance Inc.",
26
27
  author_email="ai4s-bio@bytedance.com",
27
28
  packages=find_packages(
@@ -41,7 +42,7 @@ setup(
41
42
  platforms="manylinux1",
42
43
  entry_points={
43
44
  "console_scripts": [
44
- "pxm = pxmeter.cli:run_eval_cif_cli",
45
+ "pxm = pxmeter.cli:cli",
45
46
  ],
46
47
  },
47
48
  )
pxmeter-0.0.1/PKG-INFO DELETED
@@ -1,10 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: pxmeter
3
- Version: 0.0.1
4
- Summary: PXMeter is a tool crafted to assess the structural quality derived from Biomolecular Folding Models
5
- Author: Bytedance Inc.
6
- Author-email: ai4s-bio@bytedance.com
7
- License: Apache 2.0 License
8
- Platform: manylinux1
9
- Requires-Python: >=3.11
10
- License-File: LICENSE
@@ -1,10 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: pxmeter
3
- Version: 0.0.1
4
- Summary: PXMeter is a tool crafted to assess the structural quality derived from Biomolecular Folding Models
5
- Author: Bytedance Inc.
6
- Author-email: ai4s-bio@bytedance.com
7
- License: Apache 2.0 License
8
- Platform: manylinux1
9
- Requires-Python: >=3.11
10
- License-File: LICENSE
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- pxm = pxmeter.cli:run_eval_cif_cli
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes