From a77c2cd377982b68da6d85e9a1562d08264eba19 Mon Sep 17 00:00:00 2001 From: lzy <949777411@qq.com> Date: Wed, 2 Apr 2025 12:53:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9E=84=E5=BB=BAmars=5Ftoolkit,=E5=88=A0?= =?UTF-8?q?=E9=99=A4tools=5Ffor=5Fms?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- execute_tool_copy.py | 4 +- mars_toolkit.log | 1172 +++++++++++++++++ mars_toolkit/__init__.py | 46 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1520 bytes mars_toolkit/compute/__init__.py | 12 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 598 bytes .../__pycache__/material_gen.cpython-310.pyc | Bin 12358 -> 12656 bytes .../__pycache__/property_pred.cpython-310.pyc | Bin 0 -> 2152 bytes .../__pycache__/structure_opt.cpython-310.pyc | Bin 0 -> 5306 bytes .../compute/material_gen.py | 85 +- .../compute/property_pred.py | 13 +- mars_toolkit/compute/structure_opt.py | 192 +++ mars_toolkit/core/__init__.py | 13 + .../core/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 608 bytes .../__pycache__/cif_utils.cpython-310.pyc | Bin 0 -> 3465 bytes .../core/__pycache__/config.cpython-310.pyc | Bin 0 -> 2060 bytes .../error_handlers.cpython-310.pyc | Bin 1724 -> 1919 bytes .../__pycache__/llm_tools.cpython-310.pyc | Bin 5211 -> 5225 bytes .../core/__pycache__/utils.cpython-310.pyc | Bin 0 -> 2387 bytes mars_toolkit/core/cif_utils.py | 121 ++ mars_toolkit/core/config.py | 59 + .../core}/error_handlers.py | 6 + .../core}/llm_tools.py | 0 {tools_for_ms => mars_toolkit/core}/utils.py | 34 +- mars_toolkit/misc/__init__.py | 7 + .../misc/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 320 bytes .../__pycache__/general_tools.cpython-310.pyc | Bin 0 -> 1211 bytes .../__pycache__/misc_tools.cpython-310.pyc | Bin 0 -> 1207 bytes mars_toolkit/misc/misc_tools.py | 29 + mars_toolkit/query/__init__.py | 18 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 785 bytes .../__pycache__/dify_search.cpython-310.pyc | Bin 0 -> 1956 bytes .../__pycache__/mp_query.cpython-310.pyc | Bin 0 -> 13268 bytes .../__pycache__/oqmd_query.cpython-310.pyc | Bin 3008 -> 3199 bytes .../__pycache__/web_search.cpython-310.pyc | Bin 0 -> 2166 bytes .../query/dify_search.py | 38 +- .../query/mp_query.py | 299 +---- .../query/oqmd_query.py | 15 +- .../query/web_search.py | 64 +- mars_toolkit/visualization/__init__.py | 0 test_tools.py => test_mars_toolkit.py | 128 +- tools_for_ms/__init__.py | 16 - .../__pycache__/__init__.cpython-310.pyc | Bin 821 -> 0 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 916 -> 0 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 1005 -> 0 bytes .../__pycache__/api_key.cpython-310.pyc | Bin 278 -> 0 bytes .../__pycache__/basic_tools.cpython-310.pyc | Bin 2759 -> 0 bytes .../__pycache__/basic_tools.cpython-312.pyc | Bin 3976 -> 0 bytes .../__pycache__/llm_tools.cpython-311.pyc | Bin 7852 -> 0 bytes .../__pycache__/llm_tools.cpython-312.pyc | Bin 7572 -> 0 bytes .../__pycache__/utils.cpython-310.pyc | Bin 3215 -> 0 bytes .../__pycache__/utils.cpython-312.pyc | Bin 4683 -> 0 bytes tools_for_ms/services_tools/Configs.py | 23 - .../__pycache__/Configs.cpython-310.pyc | Bin 884 -> 0 bytes .../__pycache__/Configs.cpython-312.pyc | Bin 769 -> 0 bytes .../cif_visualization_tools.cpython-310.pyc | Bin 4012 -> 0 bytes .../error_handlers.cpython-312.pyc | Bin 2591 -> 0 bytes .../fairchem_service_tools.cpython-310.pyc | Bin 7305 -> 0 bytes ...airchem_service_tools_test.cpython-310.pyc | Bin 8247 -> 0 bytes .../fairchem_tools.cpython-310.pyc | Bin 7289 -> 0 bytes .../fairchem_tools.cpython-312.pyc | Bin 9541 -> 0 bytes .../mattergen_service.cpython-310.pyc | Bin 11094 -> 0 bytes .../mattergen_tools.cpython-312.pyc | Bin 15297 -> 0 bytes .../mattersim_tools.cpython-310.pyc | Bin 1958 -> 0 bytes .../mp_service_tools.cpython-310.pyc | Bin 22234 -> 0 bytes .../__pycache__/mp_tools.cpython-310.pyc | Bin 14774 -> 0 bytes .../__pycache__/mp_tools.cpython-312.pyc | Bin 26366 -> 0 bytes .../oqmd_service_tools.cpython-310.pyc | Bin 3016 -> 0 bytes .../__pycache__/oqmd_tools.cpython-312.pyc | Bin 5499 -> 0 bytes .../__pycache__/search_dify.cpython-310.pyc | Bin 1682 -> 0 bytes .../__pycache__/search_dify.cpython-312.pyc | Bin 2352 -> 0 bytes .../__pycache__/utils.cpython-310.pyc | Bin 3315 -> 0 bytes tools_for_ms/services_tools/fairchem_tools.py | 386 ------ 73 files changed, 1884 insertions(+), 896 deletions(-) create mode 100644 mars_toolkit.log create mode 100644 mars_toolkit/__init__.py create mode 100644 mars_toolkit/__pycache__/__init__.cpython-310.pyc create mode 100644 mars_toolkit/compute/__init__.py create mode 100644 mars_toolkit/compute/__pycache__/__init__.cpython-310.pyc rename tools_for_ms/services_tools/__pycache__/mattergen_tools.cpython-310.pyc => mars_toolkit/compute/__pycache__/material_gen.cpython-310.pyc (67%) create mode 100644 mars_toolkit/compute/__pycache__/property_pred.cpython-310.pyc create mode 100644 mars_toolkit/compute/__pycache__/structure_opt.cpython-310.pyc rename tools_for_ms/services_tools/mattergen_tools.py => mars_toolkit/compute/material_gen.py (91%) rename tools_for_ms/services_tools/mattersim_tools.py => mars_toolkit/compute/property_pred.py (90%) create mode 100644 mars_toolkit/compute/structure_opt.py create mode 100644 mars_toolkit/core/__init__.py create mode 100644 mars_toolkit/core/__pycache__/__init__.cpython-310.pyc create mode 100644 mars_toolkit/core/__pycache__/cif_utils.cpython-310.pyc create mode 100644 mars_toolkit/core/__pycache__/config.cpython-310.pyc rename {tools_for_ms/services_tools => mars_toolkit/core}/__pycache__/error_handlers.cpython-310.pyc (59%) rename {tools_for_ms => mars_toolkit/core}/__pycache__/llm_tools.cpython-310.pyc (90%) create mode 100644 mars_toolkit/core/__pycache__/utils.cpython-310.pyc create mode 100644 mars_toolkit/core/cif_utils.py create mode 100644 mars_toolkit/core/config.py rename {tools_for_ms/services_tools => mars_toolkit/core}/error_handlers.py (87%) rename {tools_for_ms => mars_toolkit/core}/llm_tools.py (100%) rename {tools_for_ms => mars_toolkit/core}/utils.py (69%) create mode 100644 mars_toolkit/misc/__init__.py create mode 100644 mars_toolkit/misc/__pycache__/__init__.cpython-310.pyc create mode 100644 mars_toolkit/misc/__pycache__/general_tools.cpython-310.pyc create mode 100644 mars_toolkit/misc/__pycache__/misc_tools.cpython-310.pyc create mode 100644 mars_toolkit/misc/misc_tools.py create mode 100644 mars_toolkit/query/__init__.py create mode 100644 mars_toolkit/query/__pycache__/__init__.cpython-310.pyc create mode 100644 mars_toolkit/query/__pycache__/dify_search.cpython-310.pyc create mode 100644 mars_toolkit/query/__pycache__/mp_query.cpython-310.pyc rename tools_for_ms/services_tools/__pycache__/oqmd_tools.cpython-310.pyc => mars_toolkit/query/__pycache__/oqmd_query.cpython-310.pyc (58%) create mode 100644 mars_toolkit/query/__pycache__/web_search.cpython-310.pyc rename tools_for_ms/services_tools/search_dify.py => mars_toolkit/query/dify_search.py (72%) rename tools_for_ms/services_tools/mp_tools.py => mars_toolkit/query/mp_query.py (58%) rename tools_for_ms/services_tools/oqmd_tools.py => mars_toolkit/query/oqmd_query.py (92%) rename tools_for_ms/basic_tools.py => mars_toolkit/query/web_search.py (51%) create mode 100644 mars_toolkit/visualization/__init__.py rename test_tools.py => test_mars_toolkit.py (56%) delete mode 100644 tools_for_ms/__init__.py delete mode 100644 tools_for_ms/__pycache__/__init__.cpython-310.pyc delete mode 100644 tools_for_ms/__pycache__/__init__.cpython-311.pyc delete mode 100644 tools_for_ms/__pycache__/__init__.cpython-312.pyc delete mode 100644 tools_for_ms/__pycache__/api_key.cpython-310.pyc delete mode 100644 tools_for_ms/__pycache__/basic_tools.cpython-310.pyc delete mode 100644 tools_for_ms/__pycache__/basic_tools.cpython-312.pyc delete mode 100644 tools_for_ms/__pycache__/llm_tools.cpython-311.pyc delete mode 100644 tools_for_ms/__pycache__/llm_tools.cpython-312.pyc delete mode 100644 tools_for_ms/__pycache__/utils.cpython-310.pyc delete mode 100644 tools_for_ms/__pycache__/utils.cpython-312.pyc delete mode 100644 tools_for_ms/services_tools/Configs.py delete mode 100644 tools_for_ms/services_tools/__pycache__/Configs.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/Configs.cpython-312.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/cif_visualization_tools.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/error_handlers.cpython-312.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/fairchem_service_tools.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/fairchem_service_tools_test.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/fairchem_tools.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/fairchem_tools.cpython-312.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/mattergen_service.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/mattergen_tools.cpython-312.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/mattersim_tools.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/mp_service_tools.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/mp_tools.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/mp_tools.cpython-312.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/oqmd_service_tools.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/oqmd_tools.cpython-312.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/search_dify.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/search_dify.cpython-312.pyc delete mode 100644 tools_for_ms/services_tools/__pycache__/utils.cpython-310.pyc delete mode 100644 tools_for_ms/services_tools/fairchem_tools.py diff --git a/execute_tool_copy.py b/execute_tool_copy.py index ed2a9ba..ac3f01a 100644 --- a/execute_tool_copy.py +++ b/execute_tool_copy.py @@ -190,7 +190,7 @@ def worker(data, output_file_path): # 将所有格式化后的结果连接起来 final_result = "\n\n\n".join(formatted_results) - data['obeservation']=final_result + data['observation']=final_result # print("#"*50,"start","#"*50) # print(data['obeservation']) # print("#"*50,'end',"#"*50) @@ -199,7 +199,7 @@ def worker(data, output_file_path): with file_lock: with jsonlines.open(output_file_path, mode='a') as writer: - writer.write(data) # obeservation . data + writer.write(data) # observation . data return f"Processed successfully" except Exception as e: diff --git a/mars_toolkit.log b/mars_toolkit.log new file mode 100644 index 0000000..4a0e17b --- /dev/null +++ b/mars_toolkit.log @@ -0,0 +1,1172 @@ +2025-04-02 11:35:20 - root - INFO - Project root: /home/ubuntu/50T/lzy/mars-mcp/.venv/lib/python3.10/site-packages/fairchem +2025-04-02 11:35:21 - root - INFO - amp: true +cmd: + checkpoint_dir: /home/ubuntu/50T/lzy/mars-mcp/checkpoints/2025-04-02-11-35-28 + commit: core:603304e,experimental:NA + identifier: '' + logs_dir: /home/ubuntu/50T/lzy/mars-mcp/logs/wandb/2025-04-02-11-35-28 + print_every: 100 + results_dir: /home/ubuntu/50T/lzy/mars-mcp/results/2025-04-02-11-35-28 + seed: null + timestamp_id: 2025-04-02-11-35-28 + version: 1.9.0 +dataset: + a2g_args: + r_energy: true + r_forces: true + r_stress: true + format: ase_db + transforms: + decompose_tensor: + decomposition: + stress_anisotropic: + irrep_dim: 2 + stress_isotropic: + irrep_dim: 0 + rank: 2 + tensor: stress + element_references: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/element_references.pt + normalizer: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/normalizers.pt +evaluation_metrics: + metrics: + energy: + - mae + - mae_density + forces: + - mae + - forcesx_mae + - forcesy_mae + - forcesz_mae + - cosine_similarity + stress: + - mae + - mae_density + stress_anisotropic: + - mae + stress_isotropic: + - mae + primary_metric: energy_mae +gp_gpus: null +gpus: 0 +logger: wandb +loss_functions: +- energy: + coefficient: 20 + fn: mae_density +- forces: + coefficient: 10 + fn: l2mae +- stress_isotropic: + coefficient: 1 + fn: mae +- stress_anisotropic: + coefficient: 1 + fn: mae + reduction: mean_all +model: + backbone: + alpha_drop: 0.1 + attn_activation: silu + attn_alpha_channels: 64 + attn_hidden_channels: 64 + attn_value_channels: 16 + avg_degree: 61.94676351484548 + avg_num_nodes: 31.16592360068011 + distance_function: gaussian + drop_path_rate: 0.1 + edge_channels: 128 + enforce_max_neighbors_strictly: false + ffn_activation: silu + ffn_hidden_channels: 128 + grid_resolution: 18 + lmax_list: + - 6 + max_neighbors: 20 + max_num_elements: 96 + max_radius: 12.0 + mmax_list: + - 4 + model: equiformer_v2_backbone + norm_type: layer_norm_sh + num_distance_basis: 512 + num_heads: 8 + num_layers: 10 + num_sphere_samples: 128 + otf_graph: true + proj_drop: 0.0 + share_atom_edge_embedding: false + sphere_channels: 128 + use_atom_edge_embedding: true + use_attn_renorm: true + use_gate_act: false + use_grid_mlp: true + use_m_share_rad: false + use_pbc: true + use_pbc_single: true + use_s2_act_attn: false + use_sep_s2_act: true + weight_init: uniform + heads: + energy: + module: equiformer_v2_energy_head + forces: + module: equiformer_v2_force_head + stress: + decompose: true + module: rank2_symmetric_head + output_name: stress + use_source_target_embedding: true + name: hydra + otf_graph: true + pass_through_head_outputs: true +optim: + batch_size: 8 + clip_grad_norm: 100 + ema_decay: 0.999 + eval_batch_size: 12 + eval_every: 3000 + load_balancing: atoms + lr_initial: 0.0002 + max_epochs: 16 + num_workers: 8 + optimizer: AdamW + optimizer_params: + weight_decay: 0.001 + scheduler: LambdaLR + scheduler_params: + epochs: 741904 + lambda_type: cosine + lr: 0.0002 + lr_min_factor: 0.01 + warmup_epochs: 463 + warmup_factor: 0.2 +outputs: + energy: + level: system + property: energy + forces: + eval_on_free_atoms: true + level: atom + property: forces + train_on_free_atoms: true + stress: + decomposition: + stress_anisotropic: + eval_on_free_atoms: true + irrep_dim: 2 + level: system + parent: stress + train_on_free_atoms: true + stress_isotropic: + eval_on_free_atoms: true + irrep_dim: 0 + level: system + parent: stress + train_on_free_atoms: true + level: system + property: stress +relax_dataset: {} +slurm: + account: ocp + cpus_per_task: 9 + folder: /fsx-ocp-med/lbluque/logs/omat-alex-mp/S2EFS/train/4460394 + gpus_per_node: 8 + job_id: '4460394' + job_name: eqV2_86M_ft_alexmptraj_e20_f10_s1_cos16 + mem: 480GB + nodes: 4 + ntasks_per_node: 8 + partition: learn + qos: ocp_high + time: 4320 +task: {} +test_dataset: {} +trainer: ocp +val_dataset: {} + +2025-04-02 11:35:21 - root - INFO - Loading model: hydra +2025-04-02 11:35:25 - root - WARNING - equiformerV2_energy_head (EquiformerV2EnergyHead) class is deprecated in favor of equiformerV2_scalar_head (EqV2ScalarHead) +2025-04-02 11:35:25 - root - WARNING - equiformerV2_force_head (EquiformerV2ForceHead) class is deprecated in favor of equiformerV2_rank1_head (EqV2Rank1Head) +2025-04-02 11:35:25 - root - INFO - Loaded HydraModel with 86589068 parameters. +2025-04-02 11:35:25 - root - INFO - Loading checkpoint in inference-only mode, not loading keys associated with trainer state! +2025-04-02 11:35:26 - root - WARNING - No seed has been set in modelcheckpoint or OCPCalculator! Results may not be reproducible on re-run +2025-04-02 11:35:26 - mars_toolkit.compute.structure_opt - INFO - FairChem model initialized successfully +2025-04-02 11:36:59 - root - INFO - Project root: /home/ubuntu/50T/lzy/mars-mcp/.venv/lib/python3.10/site-packages/fairchem +2025-04-02 11:37:01 - root - INFO - amp: true +cmd: + checkpoint_dir: /home/ubuntu/50T/lzy/mars-mcp/checkpoints/2025-04-02-11-37-36 + commit: core:603304e,experimental:NA + identifier: '' + logs_dir: /home/ubuntu/50T/lzy/mars-mcp/logs/wandb/2025-04-02-11-37-36 + print_every: 100 + results_dir: /home/ubuntu/50T/lzy/mars-mcp/results/2025-04-02-11-37-36 + seed: null + timestamp_id: 2025-04-02-11-37-36 + version: 1.9.0 +dataset: + a2g_args: + r_energy: true + r_forces: true + r_stress: true + format: ase_db + transforms: + decompose_tensor: + decomposition: + stress_anisotropic: + irrep_dim: 2 + stress_isotropic: + irrep_dim: 0 + rank: 2 + tensor: stress + element_references: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/element_references.pt + normalizer: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/normalizers.pt +evaluation_metrics: + metrics: + energy: + - mae + - mae_density + forces: + - mae + - forcesx_mae + - forcesy_mae + - forcesz_mae + - cosine_similarity + stress: + - mae + - mae_density + stress_anisotropic: + - mae + stress_isotropic: + - mae + primary_metric: energy_mae +gp_gpus: null +gpus: 0 +logger: wandb +loss_functions: +- energy: + coefficient: 20 + fn: mae_density +- forces: + coefficient: 10 + fn: l2mae +- stress_isotropic: + coefficient: 1 + fn: mae +- stress_anisotropic: + coefficient: 1 + fn: mae + reduction: mean_all +model: + backbone: + alpha_drop: 0.1 + attn_activation: silu + attn_alpha_channels: 64 + attn_hidden_channels: 64 + attn_value_channels: 16 + avg_degree: 61.94676351484548 + avg_num_nodes: 31.16592360068011 + distance_function: gaussian + drop_path_rate: 0.1 + edge_channels: 128 + enforce_max_neighbors_strictly: false + ffn_activation: silu + ffn_hidden_channels: 128 + grid_resolution: 18 + lmax_list: + - 6 + max_neighbors: 20 + max_num_elements: 96 + max_radius: 12.0 + mmax_list: + - 4 + model: equiformer_v2_backbone + norm_type: layer_norm_sh + num_distance_basis: 512 + num_heads: 8 + num_layers: 10 + num_sphere_samples: 128 + otf_graph: true + proj_drop: 0.0 + share_atom_edge_embedding: false + sphere_channels: 128 + use_atom_edge_embedding: true + use_attn_renorm: true + use_gate_act: false + use_grid_mlp: true + use_m_share_rad: false + use_pbc: true + use_pbc_single: true + use_s2_act_attn: false + use_sep_s2_act: true + weight_init: uniform + heads: + energy: + module: equiformer_v2_energy_head + forces: + module: equiformer_v2_force_head + stress: + decompose: true + module: rank2_symmetric_head + output_name: stress + use_source_target_embedding: true + name: hydra + otf_graph: true + pass_through_head_outputs: true +optim: + batch_size: 8 + clip_grad_norm: 100 + ema_decay: 0.999 + eval_batch_size: 12 + eval_every: 3000 + load_balancing: atoms + lr_initial: 0.0002 + max_epochs: 16 + num_workers: 8 + optimizer: AdamW + optimizer_params: + weight_decay: 0.001 + scheduler: LambdaLR + scheduler_params: + epochs: 741904 + lambda_type: cosine + lr: 0.0002 + lr_min_factor: 0.01 + warmup_epochs: 463 + warmup_factor: 0.2 +outputs: + energy: + level: system + property: energy + forces: + eval_on_free_atoms: true + level: atom + property: forces + train_on_free_atoms: true + stress: + decomposition: + stress_anisotropic: + eval_on_free_atoms: true + irrep_dim: 2 + level: system + parent: stress + train_on_free_atoms: true + stress_isotropic: + eval_on_free_atoms: true + irrep_dim: 0 + level: system + parent: stress + train_on_free_atoms: true + level: system + property: stress +relax_dataset: {} +slurm: + account: ocp + cpus_per_task: 9 + folder: /fsx-ocp-med/lbluque/logs/omat-alex-mp/S2EFS/train/4460394 + gpus_per_node: 8 + job_id: '4460394' + job_name: eqV2_86M_ft_alexmptraj_e20_f10_s1_cos16 + mem: 480GB + nodes: 4 + ntasks_per_node: 8 + partition: learn + qos: ocp_high + time: 4320 +task: {} +test_dataset: {} +trainer: ocp +val_dataset: {} + +2025-04-02 11:37:01 - root - INFO - Loading model: hydra +2025-04-02 11:37:04 - root - WARNING - equiformerV2_energy_head (EquiformerV2EnergyHead) class is deprecated in favor of equiformerV2_scalar_head (EqV2ScalarHead) +2025-04-02 11:37:04 - root - WARNING - equiformerV2_force_head (EquiformerV2ForceHead) class is deprecated in favor of equiformerV2_rank1_head (EqV2Rank1Head) +2025-04-02 11:37:05 - root - INFO - Loaded HydraModel with 86589068 parameters. +2025-04-02 11:37:05 - root - INFO - Loading checkpoint in inference-only mode, not loading keys associated with trainer state! +2025-04-02 11:37:05 - root - WARNING - No seed has been set in modelcheckpoint or OCPCalculator! Results may not be reproducible on re-run +2025-04-02 11:37:05 - mars_toolkit.compute.structure_opt - INFO - FairChem model initialized successfully +2025-04-02 12:32:21 - root - INFO - Project root: /home/ubuntu/50T/lzy/mars-mcp/.venv/lib/python3.10/site-packages/fairchem +2025-04-02 12:32:22 - root - INFO - amp: true +cmd: + checkpoint_dir: /home/ubuntu/50T/lzy/mars-mcp/checkpoints/2025-04-02-12-33-04 + commit: core:603304e,experimental:NA + identifier: '' + logs_dir: /home/ubuntu/50T/lzy/mars-mcp/logs/wandb/2025-04-02-12-33-04 + print_every: 100 + results_dir: /home/ubuntu/50T/lzy/mars-mcp/results/2025-04-02-12-33-04 + seed: null + timestamp_id: 2025-04-02-12-33-04 + version: 1.9.0 +dataset: + a2g_args: + r_energy: true + r_forces: true + r_stress: true + format: ase_db + transforms: + decompose_tensor: + decomposition: + stress_anisotropic: + irrep_dim: 2 + stress_isotropic: + irrep_dim: 0 + rank: 2 + tensor: stress + element_references: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/element_references.pt + normalizer: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/normalizers.pt +evaluation_metrics: + metrics: + energy: + - mae + - mae_density + forces: + - mae + - forcesx_mae + - forcesy_mae + - forcesz_mae + - cosine_similarity + stress: + - mae + - mae_density + stress_anisotropic: + - mae + stress_isotropic: + - mae + primary_metric: energy_mae +gp_gpus: null +gpus: 0 +logger: wandb +loss_functions: +- energy: + coefficient: 20 + fn: mae_density +- forces: + coefficient: 10 + fn: l2mae +- stress_isotropic: + coefficient: 1 + fn: mae +- stress_anisotropic: + coefficient: 1 + fn: mae + reduction: mean_all +model: + backbone: + alpha_drop: 0.1 + attn_activation: silu + attn_alpha_channels: 64 + attn_hidden_channels: 64 + attn_value_channels: 16 + avg_degree: 61.94676351484548 + avg_num_nodes: 31.16592360068011 + distance_function: gaussian + drop_path_rate: 0.1 + edge_channels: 128 + enforce_max_neighbors_strictly: false + ffn_activation: silu + ffn_hidden_channels: 128 + grid_resolution: 18 + lmax_list: + - 6 + max_neighbors: 20 + max_num_elements: 96 + max_radius: 12.0 + mmax_list: + - 4 + model: equiformer_v2_backbone + norm_type: layer_norm_sh + num_distance_basis: 512 + num_heads: 8 + num_layers: 10 + num_sphere_samples: 128 + otf_graph: true + proj_drop: 0.0 + share_atom_edge_embedding: false + sphere_channels: 128 + use_atom_edge_embedding: true + use_attn_renorm: true + use_gate_act: false + use_grid_mlp: true + use_m_share_rad: false + use_pbc: true + use_pbc_single: true + use_s2_act_attn: false + use_sep_s2_act: true + weight_init: uniform + heads: + energy: + module: equiformer_v2_energy_head + forces: + module: equiformer_v2_force_head + stress: + decompose: true + module: rank2_symmetric_head + output_name: stress + use_source_target_embedding: true + name: hydra + otf_graph: true + pass_through_head_outputs: true +optim: + batch_size: 8 + clip_grad_norm: 100 + ema_decay: 0.999 + eval_batch_size: 12 + eval_every: 3000 + load_balancing: atoms + lr_initial: 0.0002 + max_epochs: 16 + num_workers: 8 + optimizer: AdamW + optimizer_params: + weight_decay: 0.001 + scheduler: LambdaLR + scheduler_params: + epochs: 741904 + lambda_type: cosine + lr: 0.0002 + lr_min_factor: 0.01 + warmup_epochs: 463 + warmup_factor: 0.2 +outputs: + energy: + level: system + property: energy + forces: + eval_on_free_atoms: true + level: atom + property: forces + train_on_free_atoms: true + stress: + decomposition: + stress_anisotropic: + eval_on_free_atoms: true + irrep_dim: 2 + level: system + parent: stress + train_on_free_atoms: true + stress_isotropic: + eval_on_free_atoms: true + irrep_dim: 0 + level: system + parent: stress + train_on_free_atoms: true + level: system + property: stress +relax_dataset: {} +slurm: + account: ocp + cpus_per_task: 9 + folder: /fsx-ocp-med/lbluque/logs/omat-alex-mp/S2EFS/train/4460394 + gpus_per_node: 8 + job_id: '4460394' + job_name: eqV2_86M_ft_alexmptraj_e20_f10_s1_cos16 + mem: 480GB + nodes: 4 + ntasks_per_node: 8 + partition: learn + qos: ocp_high + time: 4320 +task: {} +test_dataset: {} +trainer: ocp +val_dataset: {} + +2025-04-02 12:32:22 - root - INFO - Loading model: hydra +2025-04-02 12:32:25 - root - WARNING - equiformerV2_energy_head (EquiformerV2EnergyHead) class is deprecated in favor of equiformerV2_scalar_head (EqV2ScalarHead) +2025-04-02 12:32:25 - root - WARNING - equiformerV2_force_head (EquiformerV2ForceHead) class is deprecated in favor of equiformerV2_rank1_head (EqV2Rank1Head) +2025-04-02 12:32:26 - root - INFO - Loaded HydraModel with 86589068 parameters. +2025-04-02 12:32:26 - root - INFO - Loading checkpoint in inference-only mode, not loading keys associated with trainer state! +2025-04-02 12:32:26 - root - WARNING - No seed has been set in modelcheckpoint or OCPCalculator! Results may not be reproducible on re-run +2025-04-02 12:32:26 - mars_toolkit.compute.structure_opt - INFO - FairChem model initialized successfully +2025-04-02 12:41:48 - root - INFO - Project root: /home/ubuntu/50T/lzy/mars-mcp/.venv/lib/python3.10/site-packages/fairchem +2025-04-02 12:41:49 - root - INFO - amp: true +cmd: + checkpoint_dir: /home/ubuntu/50T/lzy/mars-mcp/checkpoints/2025-04-02-12-41-36 + commit: core:603304e,experimental:NA + identifier: '' + logs_dir: /home/ubuntu/50T/lzy/mars-mcp/logs/wandb/2025-04-02-12-41-36 + print_every: 100 + results_dir: /home/ubuntu/50T/lzy/mars-mcp/results/2025-04-02-12-41-36 + seed: null + timestamp_id: 2025-04-02-12-41-36 + version: 1.9.0 +dataset: + a2g_args: + r_energy: true + r_forces: true + r_stress: true + format: ase_db + transforms: + decompose_tensor: + decomposition: + stress_anisotropic: + irrep_dim: 2 + stress_isotropic: + irrep_dim: 0 + rank: 2 + tensor: stress + element_references: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/element_references.pt + normalizer: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/normalizers.pt +evaluation_metrics: + metrics: + energy: + - mae + - mae_density + forces: + - mae + - forcesx_mae + - forcesy_mae + - forcesz_mae + - cosine_similarity + stress: + - mae + - mae_density + stress_anisotropic: + - mae + stress_isotropic: + - mae + primary_metric: energy_mae +gp_gpus: null +gpus: 0 +logger: wandb +loss_functions: +- energy: + coefficient: 20 + fn: mae_density +- forces: + coefficient: 10 + fn: l2mae +- stress_isotropic: + coefficient: 1 + fn: mae +- stress_anisotropic: + coefficient: 1 + fn: mae + reduction: mean_all +model: + backbone: + alpha_drop: 0.1 + attn_activation: silu + attn_alpha_channels: 64 + attn_hidden_channels: 64 + attn_value_channels: 16 + avg_degree: 61.94676351484548 + avg_num_nodes: 31.16592360068011 + distance_function: gaussian + drop_path_rate: 0.1 + edge_channels: 128 + enforce_max_neighbors_strictly: false + ffn_activation: silu + ffn_hidden_channels: 128 + grid_resolution: 18 + lmax_list: + - 6 + max_neighbors: 20 + max_num_elements: 96 + max_radius: 12.0 + mmax_list: + - 4 + model: equiformer_v2_backbone + norm_type: layer_norm_sh + num_distance_basis: 512 + num_heads: 8 + num_layers: 10 + num_sphere_samples: 128 + otf_graph: true + proj_drop: 0.0 + share_atom_edge_embedding: false + sphere_channels: 128 + use_atom_edge_embedding: true + use_attn_renorm: true + use_gate_act: false + use_grid_mlp: true + use_m_share_rad: false + use_pbc: true + use_pbc_single: true + use_s2_act_attn: false + use_sep_s2_act: true + weight_init: uniform + heads: + energy: + module: equiformer_v2_energy_head + forces: + module: equiformer_v2_force_head + stress: + decompose: true + module: rank2_symmetric_head + output_name: stress + use_source_target_embedding: true + name: hydra + otf_graph: true + pass_through_head_outputs: true +optim: + batch_size: 8 + clip_grad_norm: 100 + ema_decay: 0.999 + eval_batch_size: 12 + eval_every: 3000 + load_balancing: atoms + lr_initial: 0.0002 + max_epochs: 16 + num_workers: 8 + optimizer: AdamW + optimizer_params: + weight_decay: 0.001 + scheduler: LambdaLR + scheduler_params: + epochs: 741904 + lambda_type: cosine + lr: 0.0002 + lr_min_factor: 0.01 + warmup_epochs: 463 + warmup_factor: 0.2 +outputs: + energy: + level: system + property: energy + forces: + eval_on_free_atoms: true + level: atom + property: forces + train_on_free_atoms: true + stress: + decomposition: + stress_anisotropic: + eval_on_free_atoms: true + irrep_dim: 2 + level: system + parent: stress + train_on_free_atoms: true + stress_isotropic: + eval_on_free_atoms: true + irrep_dim: 0 + level: system + parent: stress + train_on_free_atoms: true + level: system + property: stress +relax_dataset: {} +slurm: + account: ocp + cpus_per_task: 9 + folder: /fsx-ocp-med/lbluque/logs/omat-alex-mp/S2EFS/train/4460394 + gpus_per_node: 8 + job_id: '4460394' + job_name: eqV2_86M_ft_alexmptraj_e20_f10_s1_cos16 + mem: 480GB + nodes: 4 + ntasks_per_node: 8 + partition: learn + qos: ocp_high + time: 4320 +task: {} +test_dataset: {} +trainer: ocp +val_dataset: {} + +2025-04-02 12:41:49 - root - INFO - Loading model: hydra +2025-04-02 12:41:52 - root - WARNING - equiformerV2_energy_head (EquiformerV2EnergyHead) class is deprecated in favor of equiformerV2_scalar_head (EqV2ScalarHead) +2025-04-02 12:41:52 - root - WARNING - equiformerV2_force_head (EquiformerV2ForceHead) class is deprecated in favor of equiformerV2_rank1_head (EqV2Rank1Head) +2025-04-02 12:41:52 - root - INFO - Loaded HydraModel with 86589068 parameters. +2025-04-02 12:41:52 - root - INFO - Loading checkpoint in inference-only mode, not loading keys associated with trainer state! +2025-04-02 12:41:53 - root - WARNING - No seed has been set in modelcheckpoint or OCPCalculator! Results may not be reproducible on re-run +2025-04-02 12:41:53 - mars_toolkit.compute.structure_opt - INFO - FairChem model initialized successfully +2025-04-02 12:44:38 - root - INFO - Project root: /home/ubuntu/50T/lzy/mars-mcp/.venv/lib/python3.10/site-packages/fairchem +2025-04-02 12:44:39 - root - INFO - amp: true +cmd: + checkpoint_dir: /home/ubuntu/50T/lzy/mars-mcp/checkpoints/2025-04-02-12-43-44 + commit: core:603304e,experimental:NA + identifier: '' + logs_dir: /home/ubuntu/50T/lzy/mars-mcp/logs/wandb/2025-04-02-12-43-44 + print_every: 100 + results_dir: /home/ubuntu/50T/lzy/mars-mcp/results/2025-04-02-12-43-44 + seed: null + timestamp_id: 2025-04-02-12-43-44 + version: 1.9.0 +dataset: + a2g_args: + r_energy: true + r_forces: true + r_stress: true + format: ase_db + transforms: + decompose_tensor: + decomposition: + stress_anisotropic: + irrep_dim: 2 + stress_isotropic: + irrep_dim: 0 + rank: 2 + tensor: stress + element_references: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/element_references.pt + normalizer: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/normalizers.pt +evaluation_metrics: + metrics: + energy: + - mae + - mae_density + forces: + - mae + - forcesx_mae + - forcesy_mae + - forcesz_mae + - cosine_similarity + stress: + - mae + - mae_density + stress_anisotropic: + - mae + stress_isotropic: + - mae + primary_metric: energy_mae +gp_gpus: null +gpus: 0 +logger: wandb +loss_functions: +- energy: + coefficient: 20 + fn: mae_density +- forces: + coefficient: 10 + fn: l2mae +- stress_isotropic: + coefficient: 1 + fn: mae +- stress_anisotropic: + coefficient: 1 + fn: mae + reduction: mean_all +model: + backbone: + alpha_drop: 0.1 + attn_activation: silu + attn_alpha_channels: 64 + attn_hidden_channels: 64 + attn_value_channels: 16 + avg_degree: 61.94676351484548 + avg_num_nodes: 31.16592360068011 + distance_function: gaussian + drop_path_rate: 0.1 + edge_channels: 128 + enforce_max_neighbors_strictly: false + ffn_activation: silu + ffn_hidden_channels: 128 + grid_resolution: 18 + lmax_list: + - 6 + max_neighbors: 20 + max_num_elements: 96 + max_radius: 12.0 + mmax_list: + - 4 + model: equiformer_v2_backbone + norm_type: layer_norm_sh + num_distance_basis: 512 + num_heads: 8 + num_layers: 10 + num_sphere_samples: 128 + otf_graph: true + proj_drop: 0.0 + share_atom_edge_embedding: false + sphere_channels: 128 + use_atom_edge_embedding: true + use_attn_renorm: true + use_gate_act: false + use_grid_mlp: true + use_m_share_rad: false + use_pbc: true + use_pbc_single: true + use_s2_act_attn: false + use_sep_s2_act: true + weight_init: uniform + heads: + energy: + module: equiformer_v2_energy_head + forces: + module: equiformer_v2_force_head + stress: + decompose: true + module: rank2_symmetric_head + output_name: stress + use_source_target_embedding: true + name: hydra + otf_graph: true + pass_through_head_outputs: true +optim: + batch_size: 8 + clip_grad_norm: 100 + ema_decay: 0.999 + eval_batch_size: 12 + eval_every: 3000 + load_balancing: atoms + lr_initial: 0.0002 + max_epochs: 16 + num_workers: 8 + optimizer: AdamW + optimizer_params: + weight_decay: 0.001 + scheduler: LambdaLR + scheduler_params: + epochs: 741904 + lambda_type: cosine + lr: 0.0002 + lr_min_factor: 0.01 + warmup_epochs: 463 + warmup_factor: 0.2 +outputs: + energy: + level: system + property: energy + forces: + eval_on_free_atoms: true + level: atom + property: forces + train_on_free_atoms: true + stress: + decomposition: + stress_anisotropic: + eval_on_free_atoms: true + irrep_dim: 2 + level: system + parent: stress + train_on_free_atoms: true + stress_isotropic: + eval_on_free_atoms: true + irrep_dim: 0 + level: system + parent: stress + train_on_free_atoms: true + level: system + property: stress +relax_dataset: {} +slurm: + account: ocp + cpus_per_task: 9 + folder: /fsx-ocp-med/lbluque/logs/omat-alex-mp/S2EFS/train/4460394 + gpus_per_node: 8 + job_id: '4460394' + job_name: eqV2_86M_ft_alexmptraj_e20_f10_s1_cos16 + mem: 480GB + nodes: 4 + ntasks_per_node: 8 + partition: learn + qos: ocp_high + time: 4320 +task: {} +test_dataset: {} +trainer: ocp +val_dataset: {} + +2025-04-02 12:44:39 - root - INFO - Loading model: hydra +2025-04-02 12:44:43 - root - WARNING - equiformerV2_energy_head (EquiformerV2EnergyHead) class is deprecated in favor of equiformerV2_scalar_head (EqV2ScalarHead) +2025-04-02 12:44:43 - root - WARNING - equiformerV2_force_head (EquiformerV2ForceHead) class is deprecated in favor of equiformerV2_rank1_head (EqV2Rank1Head) +2025-04-02 12:44:43 - root - INFO - Loaded HydraModel with 86589068 parameters. +2025-04-02 12:44:43 - root - INFO - Loading checkpoint in inference-only mode, not loading keys associated with trainer state! +2025-04-02 12:44:43 - root - WARNING - No seed has been set in modelcheckpoint or OCPCalculator! Results may not be reproducible on re-run +2025-04-02 12:44:43 - mars_toolkit.compute.structure_opt - INFO - FairChem model initialized successfully +2025-04-02 12:45:04 - mars_toolkit.compute.structure_opt - ERROR - Failed to optimize structure: 'str' object has no attribute 'site_properties' +2025-04-02 12:45:04 - mars_toolkit.core.error_handlers - ERROR - Unexpected error: 'str' object has no attribute 'site_properties' +2025-04-02 12:47:19 - root - INFO - Project root: /home/ubuntu/50T/lzy/mars-mcp/.venv/lib/python3.10/site-packages/fairchem +2025-04-02 12:47:20 - root - INFO - amp: true +cmd: + checkpoint_dir: /home/ubuntu/50T/lzy/mars-mcp/checkpoints/2025-04-02-12-48-00 + commit: core:603304e,experimental:NA + identifier: '' + logs_dir: /home/ubuntu/50T/lzy/mars-mcp/logs/wandb/2025-04-02-12-48-00 + print_every: 100 + results_dir: /home/ubuntu/50T/lzy/mars-mcp/results/2025-04-02-12-48-00 + seed: null + timestamp_id: 2025-04-02-12-48-00 + version: 1.9.0 +dataset: + a2g_args: + r_energy: true + r_forces: true + r_stress: true + format: ase_db + transforms: + decompose_tensor: + decomposition: + stress_anisotropic: + irrep_dim: 2 + stress_isotropic: + irrep_dim: 0 + rank: 2 + tensor: stress + element_references: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/element_references.pt + normalizer: + file: /fsx-ocp-med/shared/alex-10M/alex-mp-norms-refs/normalizers.pt +evaluation_metrics: + metrics: + energy: + - mae + - mae_density + forces: + - mae + - forcesx_mae + - forcesy_mae + - forcesz_mae + - cosine_similarity + stress: + - mae + - mae_density + stress_anisotropic: + - mae + stress_isotropic: + - mae + primary_metric: energy_mae +gp_gpus: null +gpus: 0 +logger: wandb +loss_functions: +- energy: + coefficient: 20 + fn: mae_density +- forces: + coefficient: 10 + fn: l2mae +- stress_isotropic: + coefficient: 1 + fn: mae +- stress_anisotropic: + coefficient: 1 + fn: mae + reduction: mean_all +model: + backbone: + alpha_drop: 0.1 + attn_activation: silu + attn_alpha_channels: 64 + attn_hidden_channels: 64 + attn_value_channels: 16 + avg_degree: 61.94676351484548 + avg_num_nodes: 31.16592360068011 + distance_function: gaussian + drop_path_rate: 0.1 + edge_channels: 128 + enforce_max_neighbors_strictly: false + ffn_activation: silu + ffn_hidden_channels: 128 + grid_resolution: 18 + lmax_list: + - 6 + max_neighbors: 20 + max_num_elements: 96 + max_radius: 12.0 + mmax_list: + - 4 + model: equiformer_v2_backbone + norm_type: layer_norm_sh + num_distance_basis: 512 + num_heads: 8 + num_layers: 10 + num_sphere_samples: 128 + otf_graph: true + proj_drop: 0.0 + share_atom_edge_embedding: false + sphere_channels: 128 + use_atom_edge_embedding: true + use_attn_renorm: true + use_gate_act: false + use_grid_mlp: true + use_m_share_rad: false + use_pbc: true + use_pbc_single: true + use_s2_act_attn: false + use_sep_s2_act: true + weight_init: uniform + heads: + energy: + module: equiformer_v2_energy_head + forces: + module: equiformer_v2_force_head + stress: + decompose: true + module: rank2_symmetric_head + output_name: stress + use_source_target_embedding: true + name: hydra + otf_graph: true + pass_through_head_outputs: true +optim: + batch_size: 8 + clip_grad_norm: 100 + ema_decay: 0.999 + eval_batch_size: 12 + eval_every: 3000 + load_balancing: atoms + lr_initial: 0.0002 + max_epochs: 16 + num_workers: 8 + optimizer: AdamW + optimizer_params: + weight_decay: 0.001 + scheduler: LambdaLR + scheduler_params: + epochs: 741904 + lambda_type: cosine + lr: 0.0002 + lr_min_factor: 0.01 + warmup_epochs: 463 + warmup_factor: 0.2 +outputs: + energy: + level: system + property: energy + forces: + eval_on_free_atoms: true + level: atom + property: forces + train_on_free_atoms: true + stress: + decomposition: + stress_anisotropic: + eval_on_free_atoms: true + irrep_dim: 2 + level: system + parent: stress + train_on_free_atoms: true + stress_isotropic: + eval_on_free_atoms: true + irrep_dim: 0 + level: system + parent: stress + train_on_free_atoms: true + level: system + property: stress +relax_dataset: {} +slurm: + account: ocp + cpus_per_task: 9 + folder: /fsx-ocp-med/lbluque/logs/omat-alex-mp/S2EFS/train/4460394 + gpus_per_node: 8 + job_id: '4460394' + job_name: eqV2_86M_ft_alexmptraj_e20_f10_s1_cos16 + mem: 480GB + nodes: 4 + ntasks_per_node: 8 + partition: learn + qos: ocp_high + time: 4320 +task: {} +test_dataset: {} +trainer: ocp +val_dataset: {} + +2025-04-02 12:47:20 - root - INFO - Loading model: hydra +2025-04-02 12:47:24 - root - WARNING - equiformerV2_energy_head (EquiformerV2EnergyHead) class is deprecated in favor of equiformerV2_scalar_head (EqV2ScalarHead) +2025-04-02 12:47:24 - root - WARNING - equiformerV2_force_head (EquiformerV2ForceHead) class is deprecated in favor of equiformerV2_rank1_head (EqV2Rank1Head) +2025-04-02 12:47:24 - root - INFO - Loaded HydraModel with 86589068 parameters. +2025-04-02 12:47:24 - root - INFO - Loading checkpoint in inference-only mode, not loading keys associated with trainer state! +2025-04-02 12:47:24 - root - WARNING - No seed has been set in modelcheckpoint or OCPCalculator! Results may not be reproducible on re-run +2025-04-02 12:47:24 - mars_toolkit.compute.structure_opt - INFO - FairChem model initialized successfully diff --git a/mars_toolkit/__init__.py b/mars_toolkit/__init__.py new file mode 100644 index 0000000..fba5167 --- /dev/null +++ b/mars_toolkit/__init__.py @@ -0,0 +1,46 @@ +""" +Mars Toolkit + +A comprehensive toolkit for materials science research, providing tools for: +- Material generation and property prediction +- Structure optimization +- Database queries (Materials Project, OQMD) +- Knowledge base retrieval +- Web search + +Author: Yutang LI +Institution: SIAT-MIC +Contact: yt.li2@siat.ac.cn +""" + +# Core modules +from mars_toolkit.core.config import config +from mars_toolkit.core.utils import setup_logging + +# Basic tools +from mars_toolkit.misc.misc_tools import get_current_time + +# Compute modules +from mars_toolkit.compute.material_gen import generate_material +from mars_toolkit.compute.property_pred import predict_properties +from mars_toolkit.compute.structure_opt import optimize_crystal_structure, convert_structure + +# Query modules +from mars_toolkit.query.mp_query import ( + search_material_property_from_material_project, + get_crystal_structures_from_materials_project, + get_mpid_from_formula +) +from mars_toolkit.query.oqmd_query import fetch_chemical_composition_from_OQMD +from mars_toolkit.query.dify_search import retrieval_from_knowledge_base +from mars_toolkit.query.web_search import search_online + +from mars_toolkit.core.llm_tools import llm_tool, get_tools, get_tool_schemas + + + +# Initialize logging +setup_logging() + +__version__ = "0.1.0" +__all__ = ["llm_tool", "get_tools", "get_tool_schemas"] diff --git a/mars_toolkit/__pycache__/__init__.cpython-310.pyc b/mars_toolkit/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27f48c35e03ace427dc21d269fbbb2ea20558f91 GIT binary patch literal 1520 zcmZ`(%WfMt6rIt_@_1xRiCrglY%oC=6%db{0?on*3J1x?Xx#^FpeQ#4&7mYFd7?kE3# z8ZbG9zx@SSahkid@Ed%yhKc^nc-7jSaHpfTP&cl zHb_y&jiAyZ%LFeNM}}KY4VykiGo!CXE{aLmVLksOIYQ^lEoj0EZm1KwK(xp`ea4NO z1K_z}J`U^)XG-Qu!;zjjp~Owt01L0FqgT{&^sa;oxJ94Ui7ooh=r^3Xr|8@7&tDIL z{8gdfOP)_S3R?_!u;rRcSo(oqp+&`T)6z|$Nc3arD3ty6S#nlbCtT@^IYAd^FE5YI z&t4_3bm1s-Cur_6DLy~7g1U^dj1|crV0<);s}9q}SWE!*EO+IMNIjW=77*x9xFf7I zh8K>&ojAk>OEEa96@}ovr4nQ*4cv0rsP>jZaKg;oIx2~+HL3=1>NSY?PiWYzvc>go zGuP?nWNfrr347J5qfp;}bK6z6^;rUa$J5nJ40tV&6t{7=W+u_<9wt^|WJeHUpf zyp{`Ua3`(~ZtYlv-_~XkZx$p11${>mT}V-IxKUS1MSL4p>;7<$>_S!#iS}H6WU4;JQ!^5P zS@$&m{W2S#dvFI=zf<{=oqEpU9h_W@=ValC>3uBGdwx}OHa%yxu%LVGp*35;FnvD^ zJa>Z-=wa*Igm~wul!W{o8RQv$`0M#-sudrVS7qVK(HF;;BY86)`C5+@n*~sNJR(FC u!V!|q=2iEF(s?QQm++B`>>&)TDD9_l+Js-+kGGp?8)or#qtk9R()e%ab@XZg literal 0 HcmV?d00001 diff --git a/mars_toolkit/compute/__init__.py b/mars_toolkit/compute/__init__.py new file mode 100644 index 0000000..0b3fb73 --- /dev/null +++ b/mars_toolkit/compute/__init__.py @@ -0,0 +1,12 @@ +""" +Compute Module + +This module provides computational tools for materials science, including: +- Material generation +- Property prediction +- Structure optimization +""" + +from mars_toolkit.compute.material_gen import generate_material +from mars_toolkit.compute.property_pred import predict_properties +from mars_toolkit.compute.structure_opt import optimize_crystal_structure, convert_structure diff --git a/mars_toolkit/compute/__pycache__/__init__.cpython-310.pyc b/mars_toolkit/compute/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51e5a03457c17d8162baeb13ce3f543030112390 GIT binary patch literal 598 zcmZ`%Jx{|h5Ovb@g9ru?6O&=9L>m?sgb)&Q5fV&UtY9Clg&jw>gOvUP{sA)^{H3f+ zNc;jOE@=u3U@512=a+ZyY@4mEnBaPP`ItWjguFH2_X-i5 z&lL5>C`a#%r8@IqWroOc2|0&DDs!$%A@li3JfX90pUxo%+y0N$D{Bg{zCwKvk~gYY zz4o@`zO+D1;iZ<#75yCtBjcdn?j(S%n__XNQ()+{k(A)ZVZGN00OPiDK2yxCwd-we z@&{!8lrG1kddQeCoUwXeXV$T1zzuRe zo;@zIHKzvFAcSzRb+`woy8+S%(h4vS5rS5&5J>a|Rfq>mJXFOdLJ{=6QpYW1D8hgzyy-Q%p=+?Vok%DBXy2`p|dMf*XG8O0jV(b-T zAM3AD2v?;ltxCc%Vr0w#eSi`+Ff*tRVkJ@ICUZz1652ZBfH|xW3mh{Jnj`wiw#?+p zA$GV*^-+jJ{SwiSKm#Ot5sX128;2x|v2k{k9h;I<1X8RHrRbEDB2zwSg61VfzuDcO zyBEh{4;umLIDvNb^5zb93_7vzWfN>1eLb#=g`qn|*fGRCY)EkXcI@}#-1{TjK6V`X z*->GWK|FxETX6Mb-s;=&rrKZ-Zdy|HTNha;48Z{yUY3GVuqD_UJP4yO!s0A~E-@@% z{00)~dnI5=JHf6c>n)gK<5LIFq+ClSOlO&Spq%=bFVu`)B7jv@s)JvOVq5lk0E$FHm~GJsEuJ-nln$87+<9 z<~vVs{_*8+E?xZk@_Sc4y0o=?;p@vEAhY?@Wlb1NSkt9Zfjo1_*|}`Vwnoz@PTh0z zx~DrBYMi+8hc~v)uWYWI{pPi$try?fTK?1bA3nEv@yV_8ukWbdeD})xZ*4yF>XpB| zuzBwM=Got04jT<*3U${16+WxcglnbVr1fqt6Za`*E?;=t z9ca3`_>xS>6VxU%)KP4S6I(7zR(ip2D;1TKDs{*Mq!3Yvt<3o5@osv}_5{;bgWwPaK>}!**aMSkW+E4M}ZF_J9_F(wfb*UYt_;slRrFtR7d8|rTs8w%2*vMnhS(cs;I}N;{lB^P5 z2YbixXMwB`g_LDV3c*3LLQ9dyFg36J8awxcaz?@sZP4W;pxbFIbRicP+{DfN zS1?pi;Q*Jhyx}!(JZPuzfYeoR9T=%fc2n7lGk1fTX~x@s7)F<+g5Q>R_@OEuk}~cm z9N~>Pj;+-?$%TDCDQDFVR9d{!cD69i<9CWW*MuVeBSpR7F9{wo#e#YA)Xs>fv~`8f ze@2OuqGTcB{h{?|+y1K3Q|otiTu^;&R@{3YzVG=bZTpXRPd@kV$>Y9OO_pd_H0gf< zMUkWKcl#&&Q8^^Xq^Nta_aeRB{i^pK)#^Y8x3}-h@n-KKx%PhaPZllKf9*voSuwQQ zNdCXY_B&<8-T(HTz^nL+{=Kxpo$c?!%lS%wPjjQ^7My1GUB&5XW^Dwr*+R}_*{t<| z+n&ju_%rGi63_zl=Pg7#Xh;gt5RGCNO%Bn39H8AO`2-WCnu^RwcT5^^KhGrHt;{1o E0Oid*c>n+a delta 1794 zcmY*ZO>7%Q6rP#gwby^^zc`M6;xzwB)7Wm(v`I-qe-WxGT4<%JL%}qeNt$%mPVEg< zqFn+ca3cL-xuB|&T_FS<$q^1cwGt=9p@-bKA^)@3#Q^HsEw2`41BTKU)_UY|Lj^>2#*E@^@^nmaK zdgq$aMY}{m^lsV>B8aX~g?BIZ)O#7`3e0`N_6s|}2OF3L8>E37MC66^gT@dY!iWzo z9-@a}2TdO~@-#12!+OCe(xUJq`e9>)j_kx-s*my`jS{9~kP_98UUp9)rXMrL>3CBR zp+pFppc5?4S~d_p&JwH@<~LZ9PqH>1<&%7hPtQpy#8Ny0QFxA|(42>*S!P3~Z#vI# z=h`Ie;v7K%S8Kz@>{7uc)=G1gYRRY-YP|aK z!Yr?e^cs*%lUL_?c_+>(0f@KWld+gg(P2vSkxn$Rz8e z+Og_2rMhgP2DZ@^R1V9?lopj0=xKMD9tO+@=pk9hpX1xeLQ7o>$cDK#YI+ydy3h18 z(jd0NB-_Je+shPNEq?=i20DX22wx+%&-R-*=seCQ;uB`bLhG1$Zj$P4Qv+Jq z`77IxBTl5fdoAk54Oq9sR+yK~R=#_Ry=-1K4ubw_vjmdv_f^VnY04N-hA>Vc?5L@_JY!1r)9 zVzyc_7U*3kcQrdE8+*{5`xy;6Df)dZ@pzrAJlK2mV|R(9x5oO=OnUHcsj`BZNAO9X3Tke8|~ zOPZ4zKIzq@pcEsTGduh}KI{1N7n~3C&z$ALTR7(YTIln{-J8+rM2bo0Wg!5!Cr})m zNw}bIo}1?@^YgsAt(HpV>jp2Cs#n~V?$FMd2*-bVcjDc8Y6*3_^BP1d$A-FC^112oV#={(JI$brho%F|0 zRlP7{4=5YZOAelcki7`G`?q-Lt0%#`8bN)pdS>i7OZj!$Mvmjj2dVu2AzDwA~{t$OqkNL zh;$)^>ia)Kh~##UR`$nxAxvj(g<1=FH%@oMBr1|n=Ms*+BuN9E=LxJ&M|pM#R)dwD zYGd)A!HYkfeY)_TiA>1x^fLMu33Zu;8Alg{`WL6z{ZI+cAn4tjH&8Rq#yzWYvM?1@ z8{&;*JV8*Zb`*~S@J5SFSFRKgQx;K-Xz^Gu+c1t`sPiDcqFSq$PBnQ-OL|Oi z5^jG&0DWinqtD>ErvzI8!F0aF^nb_F_l>99eTxLcJG6 zwy_p9ePBJckBQvib_UfAcsV8IjmNYkL8By3-D5JhU~a-}m*j!RUEX|5=Z27Us+xNHFevT~t$k2ve6rc6B+3Y-=FHV5bY)9uQz8U~OQ+#jtua0JC zLFtBJnR&O9je$Mpy+l^bwiw%7DnNl4Fk-1RLo09>;zCwl#8v<{uNift5asD4&wysw zNAMmPMpa;*%H@fx;L^_LSMc_w|9so;btLxOssYU=I*=V)cVZQUhhdyxawU=&vIH%u zdTlIpFv*egahL>kcd2|ltvgJ;t{trGL}U`%Kz$DiA&tQds;1E0dVbXc%^G~UhI;P8 zqPwu>)s}>+T3L|>2$ibVYo!2kVNR;GrB)yggYZh#S?$M@uyP^W=|n%H623R&8F{`t zILK2mDDD@TE(Y(tyFW-~(?JULyOl;0voP)UVXOy;eWAr*(Oaj`WCia}rq!A(GP9|_ z5pRNNbrpnfdDNjBcE|Q?k9H_Z2Zm+4)cMP5IDc5K``m3hzx$r^o8R(&bvm<4ueR|1 zwIm0u)b;*9|L8V!<7TL)Srq40OXq<;kRs$g%S0#N1{dT76mOx}MB#!s1w-M&`m(cr zs@GeunnA$xC`sDtmT24D=KS=pp&0dxCB7HhRgAg~rbO)5_NCN-m2B)qPSbBNp$ zus+aQ^p_tjB^|VT;Ux_NX@8aaAfM>E25mSq?$#lgIE=tJD(_nT?Y)kCQg488i066~ SVTPa8p_XM)i#mV4?)(ivR*NkF literal 0 HcmV?d00001 diff --git a/mars_toolkit/compute/__pycache__/structure_opt.cpython-310.pyc b/mars_toolkit/compute/__pycache__/structure_opt.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6732e2021997a213ebe2625308cb3a096a82e02 GIT binary patch literal 5306 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 c>bOkQFJu+c&txKhA Optional[Atoms]: + """ + 将输入内容转换为Atoms对象 + + Args: + input_format: 输入格式 (cif, xyz, vasp等) + content: 结构内容字符串 + + Returns: + ASE Atoms对象,如果转换失败则返回None + """ + try: + with tempfile.NamedTemporaryFile(suffix=f".{input_format}", mode="w", delete=False) as tmp_file: + tmp_file.write(content) + tmp_path = tmp_file.name + + atoms = read(tmp_path) + os.unlink(tmp_path) + return atoms + except Exception as e: + logger.error(f"Failed to convert structure: {str(e)}") + return None + +def generate_symmetry_cif(structure: Structure) -> str: + """ + 生成对称性CIF + + Args: + structure: Pymatgen Structure对象 + + Returns: + CIF格式的字符串 + """ + analyzer = SpacegroupAnalyzer(structure) + structure_refined = analyzer.get_refined_structure() + + with tempfile.NamedTemporaryFile(suffix=".cif", mode="w+", delete=False) as tmp_file: + cif_writer = CifWriter(structure_refined, symprec=0.1, refine_struct=True) + cif_writer.write_file(tmp_file.name) + tmp_file.seek(0) + content = tmp_file.read() + os.unlink(tmp_file.name) + return content + +def optimize_structure(atoms: Atoms, output_format: str) -> str: + """ + 优化晶体结构 + + Args: + atoms: ASE Atoms对象 + output_format: 输出格式 (cif, xyz, vasp等) + + Returns: + 包含优化结果的格式化字符串 + """ + atoms.calc = calc + + try: + # 捕获优化过程的输出 + temp_output = StringIO() + original_stdout = sys.stdout + sys.stdout = temp_output + + # 执行优化 + dyn = FIRE(FrechetCellFilter(atoms)) + dyn.run(fmax=config.FMAX) + + # 恢复标准输出并获取日志 + sys.stdout = original_stdout + optimization_log = temp_output.getvalue() + temp_output.close() + + # 获取总能量 + total_energy = atoms.get_potential_energy() + + # 处理优化后的结构 + if output_format == "cif": + optimized_structure = Structure.from_ase_atoms(atoms) + content = generate_symmetry_cif(optimized_structure) + content = remove_symmetry_equiv_xyz(content) + + else: + with tempfile.NamedTemporaryFile(suffix=f".{output_format}", mode="w+", delete=False) as tmp_file: + write(tmp_file.name, atoms) + tmp_file.seek(0) + content = tmp_file.read() + + os.unlink(tmp_file.name) + + # 格式化返回结果 + format_result = f""" +The following is the optimized crystal structure information: +### Optimization Results (using FIRE(eqV2_86M) algorithm): +**Total Energy: {total_energy} eV** + +#### Optimizing Log: +```text +{optimization_log} +``` +### Optimized {output_format.upper()} Content: +``` +{content} +``` +""" + return format_result + except Exception as e: + logger.error(f"Failed to optimize structure: {str(e)}") + raise e + +@llm_tool(name="optimize_crystal_structure", + description="Optimize crystal structure using FairChem model") +async def optimize_crystal_structure( + content: str, + input_format: str = "cif", + output_format: str = "cif" +) -> str: + """ + Optimize crystal structure using FairChem model. + + Args: + content: Crystal structure content string + input_format: Input format (cif, xyz, vasp) + output_format: Output format (cif, xyz, vasp) + + Returns: + Optimized structure with energy and optimization log + """ + # 确保模型已初始化 + if calc is None: + init_model() + + # 使用asyncio.to_thread异步执行可能阻塞的操作 + def run_optimization(): + # 转换结构 + atoms = convert_structure(input_format, content) + if atoms is None: + raise ValueError(f"无法转换输入的{input_format}格式内容,请检查格式是否正确") + + # 优化结构 + return optimize_structure(atoms, output_format) + + try: + # 直接返回结果或抛出异常 + return await asyncio.to_thread(run_optimization) + except Exception as e: + return handle_general_error(e) diff --git a/mars_toolkit/core/__init__.py b/mars_toolkit/core/__init__.py new file mode 100644 index 0000000..771eee2 --- /dev/null +++ b/mars_toolkit/core/__init__.py @@ -0,0 +1,13 @@ +""" +Core Module + +This module provides core functionality for the Mars Toolkit. +""" + +from mars_toolkit.core.config import config +from mars_toolkit.core.utils import settings, setup_logging +from mars_toolkit.core.error_handlers import ( + handle_minio_error, handle_http_error, + handle_validation_error, handle_general_error +) +from mars_toolkit.core.llm_tools import llm_tool diff --git a/mars_toolkit/core/__pycache__/__init__.cpython-310.pyc b/mars_toolkit/core/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8aa07d2c4b150b27d735c5ab4fd300a3811f3dec GIT binary patch literal 608 zcmZWnv2NQi5T#^Ul2sc`ivkJIMXQEJT{5L80%YmXcBv;WgeuVzQBo90Du9zO>JQ{M zvUAN8AYYKFcd`N$FabT>y?aN#qo_BVjKF%he{SyrLLM>se}#}-!Dqh#G=!2SXhIpN zkcI)q3%O7cjntAZr#zCeN@$`|nyM9Dsf=b5zm#v(nyw*^e~}`&{hnQG!}A}y870rM zZ6|E5rX(MXz7Y+#d5wzQ*w;?zzLLW2^PM)i>!7bPHs5M3{|I-UJ%Kk;1U{~HzY}c{ z`qXmgMBiG!foL3<)NKoS5&8FB)i;teC3>M5H%1%(Zst1YhM78@sT(-BsnEe(_%Ih* z-g8sQ0}F?zQYz-a($8Y!6UG`{Gv?0}IGt#8iW32#NrN}*Pmjx^6VjRmR854E{8%!X zW(Oa}nk8yugajeQu8+rEul}rAf#NSQZ&8i#a#?m-@pAk<_HHaMK5t8TyDxEzPpTfK m;B|%)XDAti+jESa4||_}IsCY<@P3HJ=M<53d=i`mC(%C{ce>I5 literal 0 HcmV?d00001 diff --git a/mars_toolkit/core/__pycache__/cif_utils.cpython-310.pyc b/mars_toolkit/core/__pycache__/cif_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7c6fcbfbedd8b0741862e2b7239dad6df8c3893 GIT binary patch literal 3465 zcmai%&u<*J701b$+1=UEN|qHgvHK$>a;PKJUZn+s7J}=>m2FgpBNvv_zygBlXvp22 zXm(~zawM%VTez@$4EhHIEu`Msd;7-_z4a8Jx88b4`XzU@Ub!|p!g4s|Bl+Ir z@^VD*-2L0X`j0LV@=yD*_yqX)2tRcP1t)uiQ|{$-kGi+F=LzrB7r`0bYjB?jFUVe# zH$;m!Mc4~?i-#|Qy*6+22t5(^cFFouvO)=owzluFPjr@NIunY0T=FUxQS^9_DK>N; zY$VIWjH7cuQCZ4*RgvnfEEMaNk`0oA=ULHbcAodQ&&$3{Mgs_M7Z4gIR-WC< za^O({-5A zvPyM@j&2m)uJoXko9s!Y6UaQ+jGhNx$H`(s??Z-Dh-rkC~%0efp-ehCl&9fhW zq_RYJleC)_(N}OT*-7D-`QxKzw`L1JRiilhz9zMEKli`z|FArvH9e(gEF|8fZBeLE)`Fq6hJQ4|KdLW$JtxFm9fk^>h6fDyUUM)171-Dr7+p@1VUCn-3 z`FND*!6y3^N~X&TQ%#3Fa&s+=+SSszemXHLdlv>V#KKNl2$uDr3KLSIp-j_CDz~no z@}yDe-i@EGQxjrWOODxgPTsofBqi*zvpZ8xyiK;=FhMyIg$ZnzY2Q6g#mH`?X(GD% zLYjtKW8F9HxjlyV3>AMNvV(p4&&`cNITRb!epTpdj#)0-F*+#$`3NKovP5S;fE8g35g@(_(ujLAw zO<;X$mU@}Uxr&QqC{hpY=g$%oz1`kb74b+b>-JR3Jpzo&h~X7jm+xNPa*v{ARt z=p;nswaz262oaY*UyRF)Oxkq=vqqDs4l!TE!!xgL*U?S#^p|xTuxKZz78W*o?jCE2 zCRWMHlIHaapVxz z&MpOg(!AoB&4KZJzU%CoD1_{fW08wg%d*JQg}$KxAmd@uw!)nuldx4TWiOVOz$S^y(bq@yxW5ka42Rp}9P3NcPJ^5f7?7H|^O7} zzN*P7NCZw$kjLZR#IJpgTkSbLAo5Q&t^KQ@%o&*kb-;ZP=?h0Fq!}Pmvu@61??bjZ zl|A)&IvBDIc;ID)wF0`{C>@tOPrqK-aeyX zWRx77GxCub;yAGLvjt)Z>B1E`4T9ZfLk^dgYVOLrcwM{f3kg`+L#*1os8{9eXn^`r zDGw|Tk22ib=c6r&SSq9jE7@VDswAJC4zR7vrx!4;V>d&uOemNV%EI z3V5G!VL|uT^4s2!GwnC$8l9&fHbKK$Z=l;&E|LNSvv$m;m<^cP_Zk(D;#kjehdV=~ z=}~XwWjTt!a>t&=7lPfMe4D~4`@4eTcL?{-S`*4iO%KVhk(NF6xZOU_d^@Wr|<3z>Bye#EqX6V^FNj z3LtxFVP8xG89K<`!M=_v9Z$b#2H2t9M9_QQ__=A%KVP-+>KkqOg|>MYJ3^5_M?k z2VO|u1%pt2z1HY>tJI^b-kRsp$oD|1&cD59tE($MYX69SARl7*`jTnI7KL#ve~53> zvdNxhe;b^BFirfz*Z~qEEr?80FCT8P=HO*{=O$ZF-{ynTVKlrs{jcVh4Hjk7wt$37 NA&tDyTf5w0{{@9U{6zo& literal 0 HcmV?d00001 diff --git a/mars_toolkit/core/__pycache__/config.cpython-310.pyc b/mars_toolkit/core/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b7804551bbe407bd0b41fbe393bc7c8013e885c GIT binary patch literal 2060 zcmb7F&2JM&6yKfQtc?>V0YghENZYE1x&^NtAPESiScyZd#2>OZ5LQL2VP|45S$j7# zV<4*_RZ9MYp4t-}df?bg|Cqh@gw(%)1MQo2C`nY1I?}v(vor5we(z($d_JeZc<{$x zz26N*`BQF=4-GbVVe+d$h~g+jB`8n_$Uy_m(NyK0LNuZuDnvg(j!yLh#hD-zU8QKm zzvY(0;kMr!F)aLWXf{GJ3TQ58_kC^-(v2Ch@TpHIH@y>AITgYm_PDtnGE?-a*}#mO zb{Gabz9{AD!t{q;Fp`4RcHP{ed;F?Nha?L9p#V0*q7Mrm5;FvGc1nGO86HqU887AD zz{8XxO7s=q6Ny$G?s@Xd@i76LyD<3>2vr;vfIvibGy+d18a!Bc3^L(lh~Z>mo*@}0 zN3zZ&Ipa)`oRcS$&NP{FW=P(dCDYDXdXCJ{0zFSJY@;ufZA50t*+cz6bv}cWbEI&n z0RK5T4=`Rxj4_JwHz(2b0?fzw9LFXx+l^|s+MByM|9G)-WA}OscRLU0eQ%+${`|%u zSg*%l^@WJ|ZOg)uUm9RQ!N&oIKs=$ID21$Ny^&Fmzqk6~fLf!+qoEjC9P_fZ@zAy+ z98u;HEHDJg8bq$=Z(H#tsT6cpZq1b{^NZtod#+qrsKgIWD7sm;tsvgB1`yF}123{7 zMg_zEkP;V?f(G2$#y<1Hw<@JdxpI5HyjYGe<0!gTUw2ry(%G%=jaa)IcNVS> z;`yy^HNNr@(HrIR^*JkE__UAVNJJy>0MK-w`h0`~KTgXgF#w+t8+s}P<^7Pn4AL@8 zejbP{%R^;fd7`{jUnwh)Kae|GTFFVq)kUwsK3;g!mfQ1{URtoyM3jCK*2Rukm9P*piDFcbWlFZxN=12^#F zfEKj`mCA_*Wt&Vq#leWaR@gMCe|ziGAjzC@#kdPtUdSjA*8kN}{PnnoN|?LycIi$Kf>V5{^g$S$&bsNT>n0PvpaTxC(Y%1C zE{@3zC{Hp+TE3I!pm{2WmX$`PPZ~Las1Da8qU%yd_Ed?Y4A`R?Koz~v080hXM64i? z4sreMSJ zl1SW-J<1rR2Ik-^m%oNtEvHVY=qLSMoIiTk_(rpMQ35rDMhZaXTv@!(-hrQT-CfAv zqmvAP8G7)fj~$49B6OQ%29x|=YtEp78 tXt2v5nHXX(g5P9ncWhEBO^k6>{Fl`vduJS{CD}rF7KpCQW~NcD@(=Q{LLvYF literal 0 HcmV?d00001 diff --git a/tools_for_ms/services_tools/__pycache__/error_handlers.cpython-310.pyc b/mars_toolkit/core/__pycache__/error_handlers.cpython-310.pyc similarity index 59% rename from tools_for_ms/services_tools/__pycache__/error_handlers.cpython-310.pyc rename to mars_toolkit/core/__pycache__/error_handlers.cpython-310.pyc index 7843a782afd6ad57c0353c2bfb181fe931003333..288a63f11dcffc0b295f350a61e373b728772029 100644 GIT binary patch delta 351 zcmXYtu};G<5Qgj0M!_Oc5n`YNG9v>q3@mI6g)(HzUYW#gERtO0*p*x&)! z8F>IkMjoK=0FKK|ce?++yZ=6d-!OzAz&#r`ubV~Wt-`M-HblK1o=6FjOj(r`Ts94`F4k`bEZhiS^{aRCC;?$HmWU}K+Pp{xCp=htkLwE z=1_8~?{%d#y*y87@z~PRo^w{FwM%CI!!!lSsk1V3R;=x)Zso3h&Y}72KcfQ^?`+VK lxf;Bn6Z1V-qf?`XD|BHz?`?l?gnWeiqyE?%`(yvu{{uIVb}Rq@ delta 122 zcmey*w}+Q6pO=@50SIQXze>+#oyd2Asmf*Z62{q#j82msm_?;a^7C_wv2Jd1 g0hkeAlAoWGomrxvoL`i>S(|-1Gvlqzm$^DP0f%TES^xk5 delta 67 zcmaE WzbHPpc(Wz@a%RR~n;&v@Z~_43ffsrJ diff --git a/mars_toolkit/core/__pycache__/utils.cpython-310.pyc b/mars_toolkit/core/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..09f7375e43e40774134238bb1a1aae4be963bdd3 GIT binary patch literal 2387 zcmZWrNpIUm6efp@C~C31+s)<{Q4<|3w@nMAfzj4hlk`Cm$6S-@rExfnW*Cp43j>a$6Q_)JEd1h&S?7Uu$bJ*HJv(&$KgwS3See zwzINC&{LD-j^uX!nuIm1Ka#LcvJaJZ0cWuBNNN{J;i1$X!*WxqWRGE2sZo)cu@zD` z=-D3d+L}u|3`~C2j!BbH>h`*^!&Of{qtKUSNg@&tw~cN}M8PsfSb2=vD$$5OFOdvZ zmlIqQxG}%^R^SsOd@jZ31wJ{#KM?pSd|KdBBmB&=1Zg>o&p}$wJw)wk zk%k3k3~#x?%*}0UWqZTAUcU_~P)P4CGyTxAL)Y3T2P_BTdgJQ$)<&bnav&f*90qQW z9xIR>mH}~VYx_FOfQSa+J~P)_t!-<2XY1B&X6{iMT45C214kThrh*(7#HnO*ZDnJp zwqD<~Hn**~$g^?Hlt6OX%nXP?mj)jCvo(xy|u z3~L?BZ3RP>V+C4C9gGcgSgi%Uj@uomRY=}I>(kESt930bxo^ zBQ|DPcCQyun@^0`vLZg>qJoe^3ZpT;9Oq<`lW8u{I$mJYXqE%>oSfq13@7I};k&;( zUBZ3LF%3u#zVT@wrZk7^wxSjI-E;b?#8Xd0e8SI>Wa`QnFxR;?~o ztAi5H-Y{uZFX$fgvRh+DOzj@FBRu%Le9?{_>iVP-FDx#UFY>BMS&!T$qKeYB51nCm zK{^;O-(D>Hi)Fk}UcXY_yi#sf5YszBup=u7V63Xm2= zXbg82o>>;gTxfUUbkKU4yCjOCTGvLgZ@yIRFw$RYR4m>j*!i71&Ozb)|X*xKB8QKx)Q40)N z0k%lYxXTmu&r6>bVnX|&2oT(z2Po!eJ&TI6j*tu=LDhfITV(LH`UdF&=Q3G+t-eMj zJ>lP=xA|AmCYV=B(JJ?@?FKZs6s>c-h3 z&miLe1X#99=nZj~Vumn1xjxaBVq>V|p}}a3y=!!4EGHxJD_->R3=l&yU@#eSUVKbc JLdLv#;a~A?k7WP= literal 0 HcmV?d00001 diff --git a/mars_toolkit/core/cif_utils.py b/mars_toolkit/core/cif_utils.py new file mode 100644 index 0000000..7fa40ae --- /dev/null +++ b/mars_toolkit/core/cif_utils.py @@ -0,0 +1,121 @@ +""" +CIF Utilities Module + +This module provides basic functions for handling CIF (Crystallographic Information File) files, +which are commonly used in materials science for representing crystal structures. + +Author: Yutang LI +Institution: SIAT-MIC +Contact: yt.li2@siat.ac.cn +""" + +import json +import logging + +logger = logging.getLogger(__name__) + +def read_cif_txt_file(file_path): + """ + Read the CIF file and return its content. + + Args: + file_path: Path to the CIF file + + Returns: + String content of the CIF file or None if an error occurs + """ + try: + with open(file_path, 'r', encoding='utf-8') as f: + return f.read() + except Exception as e: + logger.error(f"Error reading file {file_path}: {e}") + return None + +def extract_cif_info(path: str, fields_name: list): + """ + Extract specific fields from the CIF description JSON file. + + Args: + path: Path to the JSON file containing CIF information + fields_name: List of field categories to extract. Use 'all_fields' to extract all fields. + Other options include 'basic_fields', 'energy_electronic_fields', 'metal_magentic_fields' + + Returns: + Dictionary containing the extracted fields + """ + basic_fields = ['formula_pretty', 'chemsys', 'composition', 'elements', 'symmetry', 'nsites', 'volume', 'density'] + energy_electronic_fields = ['formation_energy_per_atom', 'energy_above_hull', 'is_stable', 'efermi', 'cbm', 'vbm', 'band_gap', 'is_gap_direct'] + metal_magentic_fields = ['is_metal', 'is_magnetic', "ordering", 'total_magnetization', 'num_magnetic_sites'] + + selected_fields = [] + if fields_name[0] == 'all_fields': + selected_fields = basic_fields + energy_electronic_fields + metal_magentic_fields + else: + for field in fields_name: + selected_fields.extend(locals().get(field, [])) + + with open(path, 'r') as f: + docs = json.load(f) + + new_docs = {} + for field_name in selected_fields: + new_docs[field_name] = docs.get(field_name, '') + + return new_docs + +def remove_symmetry_equiv_xyz(cif_content): + """ + Remove symmetry operations section from CIF file content. + + This is often useful when working with CIF files in certain visualization tools + or when focusing on the basic structure without symmetry operations. + + Args: + cif_content: CIF file content string + + Returns: + Cleaned CIF content string with symmetry operations removed + """ + lines = cif_content.split('\n') + output_lines = [] + + i = 0 + while i < len(lines): + line = lines[i].strip() + + # 检测循环开始 + if line == 'loop_': + # 查看下一行,检查是否是对称性循环 + next_lines = [] + j = i + 1 + while j < len(lines) and lines[j].strip().startswith('_'): + next_lines.append(lines[j].strip()) + j += 1 + + # 检查是否包含对称性操作标签 + if any('_symmetry_equiv_pos_as_xyz' in tag for tag in next_lines): + # 跳过整个循环块 + while i < len(lines): + if i + 1 >= len(lines): + break + + next_line = lines[i + 1].strip() + # 检查是否到达下一个循环或数据块 + if next_line == 'loop_' or next_line.startswith('data_'): + break + + # 检查是否到达原子位置部分 + if next_line.startswith('_atom_site_'): + break + + i += 1 + else: + # 不是对称性循环,保留loop_行 + output_lines.append(lines[i]) + else: + # 非循环开始行,直接保留 + output_lines.append(lines[i]) + + i += 1 + + return '\n'.join(output_lines) diff --git a/mars_toolkit/core/config.py b/mars_toolkit/core/config.py new file mode 100644 index 0000000..29cd4ef --- /dev/null +++ b/mars_toolkit/core/config.py @@ -0,0 +1,59 @@ +""" +Configuration Module + +This module provides configuration settings for the Mars Toolkit. +It includes API keys, endpoints, paths, and other configuration parameters. +""" + +from typing import Dict, Any + +class Config: + """Configuration class for Mars Toolkit""" + + # Materials Project + MP_API_KEY = 'PMASAg256b814q3OaSRWeVc7MKx4mlKI' + MP_ENDPOINT = 'https://api.materialsproject.org/' + MP_TOPK = 3 + + LOCAL_MP_ROOT = '/home/ubuntu/sas0/LYT/paper_dataset/mp_cif/' + + # Proxy + HTTP_PROXY = 'http://192.168.168.1:20171' + HTTPS_PROXY = 'http://192.168.168.1:20171' + + # FairChem + FAIRCHEM_MODEL_PATH = '/home/ubuntu/50T/lzy/mars-mcp/pretrained_models/fairchem_ckpt/eqV2_86M_omat_mp_salex.pt' + FMAX = 0.05 + + # MatterGen + MATTERGENMODEL_ROOT = '/home/ubuntu/50T/lzy/mars-mcp/pretrained_models/mattergen_ckpt' + MATTERGENMODEL_RESULT_PATH = 'results/' + + # Dify + DIFY_ROOT_URL = 'http://192.168.191.101:6080' + DIFY_API_KEY = 'app-IKZrS1RqIyurPSzR73mz6XSA' + + # Searxng + SEARXNG_HOST="http://192.168.191.101:40032/" + + # Visualization + VIZ_CIF_OUTPUT_ROOT = '/home/ubuntu/50T/lzy/mars-mcp/outputs/cif_visualization' + + @classmethod + def as_dict(cls) -> Dict[str, Any]: + """Return all configuration settings as a dictionary""" + return { + key: value for key, value in cls.__dict__.items() + if not key.startswith('__') and not callable(value) + } + + @classmethod + def update(cls, **kwargs): + """Update configuration settings""" + for key, value in kwargs.items(): + if hasattr(cls, key): + setattr(cls, key, value) + + +# Create a global instance for easy access +config = Config() diff --git a/tools_for_ms/services_tools/error_handlers.py b/mars_toolkit/core/error_handlers.py similarity index 87% rename from tools_for_ms/services_tools/error_handlers.py rename to mars_toolkit/core/error_handlers.py index 9669eb6..64e6484 100644 --- a/tools_for_ms/services_tools/error_handlers.py +++ b/mars_toolkit/core/error_handlers.py @@ -1,4 +1,10 @@ """ +Error Handlers Module + +This module provides error handling utilities for the Mars Toolkit. +It includes functions for handling various types of errors that may occur +during toolkit operations. + Author: Yutang LI Institution: SIAT-MIC Contact: yt.li2@siat.ac.cn diff --git a/tools_for_ms/llm_tools.py b/mars_toolkit/core/llm_tools.py similarity index 100% rename from tools_for_ms/llm_tools.py rename to mars_toolkit/core/llm_tools.py diff --git a/tools_for_ms/utils.py b/mars_toolkit/core/utils.py similarity index 69% rename from tools_for_ms/utils.py rename to mars_toolkit/core/utils.py index 955f409..1a96f9b 100644 --- a/tools_for_ms/utils.py +++ b/mars_toolkit/core/utils.py @@ -1,8 +1,7 @@ - - import os import boto3 import logging +import logging.config from typing import Optional from pydantic import Field from pydantic_settings import BaseSettings @@ -34,36 +33,11 @@ class Settings(BaseSettings): env_file = ".env" env_file_encoding = "utf-8" -def get_minio_client(settings: Settings): - """获取MinIO客户端""" - return boto3.client( - 's3', - endpoint_url=settings.internal_minio_endpoint or settings.minio_endpoint, - aws_access_key_id=settings.minio_access_key, - aws_secret_access_key=settings.minio_secret_key - ) - -def handle_minio_upload(file_path: str, file_name: str) -> str: - """统一处理MinIO上传""" - try: - client = get_minio_client(settings) - client.upload_file(file_path, settings.minio_bucket, file_name, ExtraArgs={"ACL": "private"}) - - # 生成预签名 URL - url = client.generate_presigned_url( - 'get_object', - Params={'Bucket': settings.minio_bucket, 'Key': file_name}, - ExpiresIn=3600 - ) - return url.replace(settings.internal_minio_endpoint or "", settings.minio_endpoint) - except Exception as e: - from tools_for_ms.services_tools.error_handlers import handle_minio_error - return handle_minio_error(e) - def setup_logging(): - parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) - log_file_path = os.path.join(parent_dir, 'mars_toolkit.log') """配置日志记录""" + parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')) + log_file_path = os.path.join(parent_dir, 'mars_toolkit.log') + logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': False, diff --git a/mars_toolkit/misc/__init__.py b/mars_toolkit/misc/__init__.py new file mode 100644 index 0000000..cf3e9f5 --- /dev/null +++ b/mars_toolkit/misc/__init__.py @@ -0,0 +1,7 @@ +""" +Basic Module + +This module provides basic utility functions for the Mars Toolkit. +""" + +from mars_toolkit.misc.misc_tools import get_current_time diff --git a/mars_toolkit/misc/__pycache__/__init__.cpython-310.pyc b/mars_toolkit/misc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8314c2d2073f36f27bcbc87a48f09499fe72ecf2 GIT binary patch literal 320 zcmYjMy-vh13{HFHN0m;xfsr9=2O1V85JK$70G)2J?vmWqqG_tcLFzpRFTu{6uytiZ z;t7~Y3rJY_ewOC!07?oT2pwqhz#X_J_Al_pHh9$1m> z@AKQWN6D8~g+}LjRio!-BD{0<36=JIGqnW52C3)U&`LtvdcL)eQ?2=O?L4onZ61-z z{3C8-MKUaQnm`8UbW1>J^j$F(#H&O>)LI3~& literal 0 HcmV?d00001 diff --git a/mars_toolkit/misc/__pycache__/general_tools.cpython-310.pyc b/mars_toolkit/misc/__pycache__/general_tools.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58adfaf8631c5d07df3695016c6f720de65e6fee GIT binary patch literal 1211 zcmZ`&PmA0(6qjU=$LpO9OBzB+FS-mH!>*l6E<-5YmNvO0l)KPHpP-la$umo)g~~ix?>*_g_j`Yuy}bm%`u(Rr=f4H; z_ssT+fcXr_d#1>%^K3KtmuK}Bj(5WJQJMF6s}3hO~J=w*W{s)xl8BQfL=AM*GO z;d?w0G2a#OS;$8`dOi3N7dxDsp!7z!Odbj)G^^;eX(~e>H@vMxl1vxU(7I>nQa3Lp z7luA(MwYa-vXXX1&stSl*(gKpf?3M6psKOdEJZ2L;GS)0&8*Opfn8Hdp-Pb@e*h-* zB*iY~ptQ0UaNapq@DzCN6;)NwEJWk>=fcj)R%@Z`%wO&Dhr-g0gn9#%DNenLN_Fj8 ztR-EeL`qz!SS{Qx#9wN;^Z~oz+4Kt+_XgpPi?pz2ntTm_dHPK1NxE#l;oT!lP%kKdwq;Wy|6g~*~8gBQ{2E=K<2VSjJ%E{M=6 z=r2$jb-zCCJ^Kub|A*z3o2+g@%aVk`I@WVD=}(@!#x$W*pDsX0J$!msWb^Eh0`5b4 zY$VH17EH|-Oafa&iAt6~5f`)5MxUo^yPL>9nEtBKP);b(fAVgumTKNd(2b^BIJ#t0 z7&D>Wt?}v6xIP+lI({@6Kc0+F=(y-^K2ztaxlmhicb{kU>q;;qXbZ&XOIFDb1*N7f z7nB)#09XzV>A}CyfI!$XONTC8u571wpm3VN<^pizVupqY2t>n8E?wj%ng}YsZusQ zBE1V*7unSkvafx+x=+0KYo}S+XpvoylF^~R5kLZZw>^ff?IW*^AFK!dQ$GlOP$7z= O5svW)k4Qr9;C}#OpI|%y literal 0 HcmV?d00001 diff --git a/mars_toolkit/misc/__pycache__/misc_tools.cpython-310.pyc b/mars_toolkit/misc/__pycache__/misc_tools.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70641404595070ed4e1022499b186e78492ac1ec GIT binary patch literal 1207 zcmZ`&L5tir6qaO<$LpO9OBzaPF1idG!>-*+FGEtY4Q+Z!DA@^RO<_XbGT>A?`U<0}Icl2I**0rZXe?c$plXsR(3zgBc-h0w}-}j!>?Cc~6#_u2goc|WU z-z%FV0_84D^CJk33dAud6)rIRgNoFoAo$W26am=6Dy#>^ptlXGs2&zWjKq*fe8}UU z2;bp}i21gNPeMN8(VM|*Tx@Z2gwku>GPy65(5#}ncv#w_l2cv3-tjgQ=EDimFgfao@${aH`+%^=MOxTas}g%?>j8a1G0b0JnnxgB;qFt5 zF7P>ek6&O*E`oCmE5gC@7IAV;E$8XWQ@CS5+LS)g?!P97U3nTyWu-`X$7ewe7 z{AVbQx?dmlnSBMt|I_l$byYX0Wl2I|9O}85^eeAjahlMnFBh<*o<6-LvU#>of%iT= zG?L{<3#R4^CPA&CMJ3B0inG~qqfgVzxNBq|Lx0<7XeYGjKXo@&OEvEibff78k1km^ z#!P5;V|;utt`EkXj=!6XA56wabX;`TAFETXljwSPg-T${L3$E(r3HBneLNXLuJr@^^~0zk6xohO-%O%Gt~fnOUh)Ha#1? z4PF=7)e str: + """Returns the current date and time in the specified timezone. + + Args: + timezone: Timezone name (e.g., UTC, Asia/Shanghai, America/New_York) + + Returns: + Formatted date and time string + """ + try: + tz = pytz.timezone(timezone) + current_time = datetime.now(tz) + return f"The current {timezone} time is: {current_time.strftime('%Y-%m-%d %H:%M:%S %Z')}" + except pytz.exceptions.UnknownTimeZoneError: + return f"Unknown timezone: {timezone}. Please use a valid timezone such as 'UTC', 'Asia/Shanghai', etc." diff --git a/mars_toolkit/query/__init__.py b/mars_toolkit/query/__init__.py new file mode 100644 index 0000000..81a0e13 --- /dev/null +++ b/mars_toolkit/query/__init__.py @@ -0,0 +1,18 @@ +""" +Query Module + +This module provides query tools for materials science, including: +- Materials Project database queries +- OQMD database queries +- Dify knowledge base retrieval +- Web search +""" + +from mars_toolkit.query.mp_query import ( + search_material_property_from_material_project, + get_crystal_structures_from_materials_project, + get_mpid_from_formula +) +from mars_toolkit.query.oqmd_query import fetch_chemical_composition_from_OQMD +from mars_toolkit.query.dify_search import retrieval_from_knowledge_base +from mars_toolkit.query.web_search import search_online diff --git a/mars_toolkit/query/__pycache__/__init__.cpython-310.pyc b/mars_toolkit/query/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5003b27b953c9757efc59b6ca28f978ec8c6e94 GIT binary patch literal 785 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 literal 0 HcmV?d00001 diff --git a/tools_for_ms/services_tools/__pycache__/oqmd_tools.cpython-310.pyc b/mars_toolkit/query/__pycache__/oqmd_query.cpython-310.pyc similarity index 58% rename from tools_for_ms/services_tools/__pycache__/oqmd_tools.cpython-310.pyc rename to mars_toolkit/query/__pycache__/oqmd_query.cpython-310.pyc index 74c4847b7cb083955e0a7032e6156bd194999e45..2f44dafacfa753eb9330c00805e58d925d8d1f42 100644 GIT binary patch delta 654 zcmYjOL2DC16yBL8+1<$|jfz@PWRNQ6kliA92~rx`OCX_?=Ae67raO~l>FiEAJ1eA@ z6!aj7hmw=vK~LgM(W~IWi)U~98~g=5SZB8soCoiHAM@V#-n{v7^L(u-8VzLV^Y-JP z$*a}V=AFffX4LQv3Mk~j2W5mlEaQq_(Q$=WffO;sTC_ffw+!mA*0@3&)O=Za0sO@k3ipk6^Y}B`-5c)U zy^P5@9txUqhR|plr8q7Lo=NdMqAbPZED2R45{-n!M@2!DOt6|VygOrwmLQ4BVmu^@ z$%yb2?+`@}NXqcTqDR|BsF$g!kX`(&n<=7;2Yu8}QWdGJQ10UWes9zn_P5ctNE8WG z7tfW;qeok5M3hTHH%!p!w+*Kaa*OjgP(tu8XTPez{Q9%jgy7opw>1Ff65H>9z5H$; zKE1B@oI^U!0sCagEzQn0y{U+qmmOq!Uhnb7$m7RzFD5eW#Nn(2rSM^-yz-fzIErad zLU%ToH7#;ud4gWwyPBIpKt&h?xyi+3qW2-!iiWirNhnF>gXMaCeQ~?czLa!BA(?wQ zd@8F&zCB@Tpaq!BtsqE9%z{96^o_hM QB8ch`0tDbWgss2-0Nl*F<^TWy delta 442 zcmY*TyH3L}6!mowY(sTifNa-Gwvw1k0g37N$&-?FI_ZRS5jFP zr5>&!;mL9@FML5pZvF;%MZg|vmXib6TKdBFpeCe5DIJ_fk+K{%#!v8306IQ$d<=`p z1?>P$-svN_NtYd$t2UEj(Mv(TBGXPLtlrA9anOrQpyO67&3XS&#RDxR*d2&&Y}S)cw{c1TPKr%2b7?3~J9b@~lmx+`t7QGQ?jiiai-)BSQW2YAcz2g()?or3^R;@0iI%9`S}HQQEfN? diff --git a/mars_toolkit/query/__pycache__/web_search.cpython-310.pyc b/mars_toolkit/query/__pycache__/web_search.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f99194497ce05195783a1a1da0b4d822f6f59d6 GIT binary patch literal 2166 zcma)7-EZ7P5Z_(;k2r0|lUY-OZOcUTz?q>RnFzLHt z0`u5cOD;TOz}zjivE&@W5z$)9l(p3)Nrf*MmFD#@5YkvpM$)_$W}=1Vyt4hUbl?v6 zheO6eYDZD*i8PIXw}Le3g?-s9ZF*@Eg$XM@Ex&QIAY_RMdtq?Q6}8Lt6Y6p%a-P7D z<&nr-A09Uo9Gq_vX(oQmWF1Zz@NlS3aaaMzW#xX(_^7B)tO&+qSx@rVo2V%k*YbFS zaX0NvHD7-B%6nH^(kcxGL`7h7smv>E?7*Ad!U+9<3rnC~w1fB19h5XpB(NYoGFre$ z-4x_^QG&N%4<(z3pQB_CB^Jz#O_N`w#vT%eFz;2U*~cKQJTdl&u=cA5Xq$}5zD=#i z=rMjwdWOQsBm01Sfv9y8Z5w^GZH|rW=(}^B8&~!nTBFVZ(OiAXHKtrsadhSv z^8jOX{}Vd9i+@IRPSnTdj^a){t!!JOF*YgLA)xvFZ^?EQv|Dt3T!ryoF3z{2t~xQcib!qp`-+GP!5|}OFP3GfWkwF7&=@4BC9%1 z0c#o3QAPI98>E?#P5?#QPkG2Pi8t2**!rJK)yYYCGo@sg+(WynkC8r67=2uy2XFj-fLYP%9UMXi&^aI#U`Ev#E$4o1794FX3Tr`423 zmiM^-TbPvE~|bvN`f$zGkqpJ_5dL1 zMQJ*evpi3{F!9(!7UTl7S*raeR2r~R8WCi!#sIX80}fiY&W_F#L_>XF=l<4FJCrA; zMKcvaA5Ycn;f`{B4^Sj3y?AsVKId z+qN2Ku=B#S)QWR-|8>fqCv$i~->0xiT3BPeH7Bc{N7KObcnj1^ON@rl_qhTBHxw}y z(H;N1!e=n>AtFH<$9WQp(NZqLC=^fuI=u3%Lf#SJmV%VCrK3Mp#;eN0;;TE#|5uqB z1A@TcRyNhS%UCF&mz)X+K(_q#uBZad-T-1E+gij80ylOD#N&kn@d54yG3K8C11T|O AVgLXD literal 0 HcmV?d00001 diff --git a/tools_for_ms/services_tools/search_dify.py b/mars_toolkit/query/dify_search.py similarity index 72% rename from tools_for_ms/services_tools/search_dify.py rename to mars_toolkit/query/dify_search.py index 13028f9..82c8672 100644 --- a/tools_for_ms/services_tools/search_dify.py +++ b/mars_toolkit/query/dify_search.py @@ -1,9 +1,22 @@ +""" +Dify Search Module + +This module provides functions for retrieving information from local materials science +literature knowledge base using Dify API. + +Author: Yutang LI +Institution: SIAT-MIC +Contact: yt.li2@siat.ac.cn +""" + import asyncio import json -from .Configs import DIFY_API_KEY import requests import codecs -from ..llm_tools import llm_tool +from typing import Dict, Any + +from mars_toolkit.core.llm_tools import llm_tool +from mars_toolkit.core.config import config @llm_tool( name="retrieval_from_knowledge_base", @@ -13,19 +26,19 @@ async def retrieval_from_knowledge_base(query: str, topk: int = 3) -> str: """ 检索本地材料科学文献知识库中的相关信息 - 输入: + Args: query: 查询字符串,如材料名称"CsPbBr3" topk: 返回结果数量,默认3条 - 输出: + Returns: 包含文档ID、标题和相关性分数的字典 """ # 设置Dify API的URL端点 - url = 'http://192.168.191.101:6080/v1/chat-messages' + url = f'{config.DIFY_ROOT_URL}/v1/chat-messages' # 配置请求头,包含API密钥和内容类型 headers = { - 'Authorization': f'Bearer {DIFY_API_KEY}', # 使用配置文件中的API密钥 + 'Authorization': f'Bearer {config.DIFY_API_KEY}', 'Content-Type': 'application/json' } @@ -45,11 +58,9 @@ async def retrieval_from_knowledge_base(query: str, topk: int = 3) -> str: # 获取响应文本 response_text = response.text - useful_results = [] # 初始化结果列表(当前未使用) # 解码响应文本中的Unicode转义序列 response_text = codecs.decode(response_text, 'unicode_escape') - print(response_text) # 打印完整响应用于调试 # 将响应文本解析为JSON对象 result_json = json.loads(response_text) @@ -61,20 +72,13 @@ async def retrieval_from_knowledge_base(query: str, topk: int = 3) -> str: useful_info = { "id": metadata.get("document_id"), # 文档ID "title": result_json.get("title"), # 文档标题 - "content": None, # 内容字段设为空,注意:原字典使用'answer'字段存储内容 - "metadata": None, # 元数据字段设为空 - "embedding": None, # 嵌入向量字段设为空 + "content": result_json.get("answer", ""), # 内容字段,使用'answer'字段存储内容 "score": metadata.get("score") # 相关性分数 } # 返回提取的有用信息 - return useful_info + return json.dumps(useful_info, ensure_ascii=False, indent=2) except Exception as e: # 捕获并处理所有可能的异常,返回错误信息 return f"错误: {str(e)}" - -# 当脚本直接运行时的测试代码 -if __name__ == "__main__": - # 使用示例查询"CsPbBr3"测试函数 - print(asyncio.run(retrieval_from_knowledge_base('CsPbBr3'))) diff --git a/tools_for_ms/services_tools/mp_tools.py b/mars_toolkit/query/mp_query.py similarity index 58% rename from tools_for_ms/services_tools/mp_tools.py rename to mars_toolkit/query/mp_query.py index 5fcc6d1..3ac2d44 100644 --- a/tools_for_ms/services_tools/mp_tools.py +++ b/mars_toolkit/query/mp_query.py @@ -1,9 +1,8 @@ """ -Materials Project API Service Tools +Materials Project Query Module This module provides functions for querying the Materials Project database, -processing search results, and formatting responses. It includes a LLM tool -for integration with large language models. +processing search results, and formatting responses. Author: Yutang LI Institution: SIAT-MIC @@ -23,97 +22,11 @@ from mp_api.client import MPRester from pymatgen.core import Structure from pymatgen.symmetry.analyzer import SpacegroupAnalyzer from pymatgen.io.cif import CifWriter -from ..services_tools import Configs -from ..utils import settings, handle_minio_upload -from .error_handlers import handle_general_error -from ..llm_tools import llm_tool -def read_cif_txt_file(file_path): - """Read the markdown file and return its content.""" - try: - with open(file_path, 'r', encoding='utf-8') as f: - return f.read() - except Exception as e: - print(f"Error reading file {file_path}: {e}") - return None -def get_extra_cif_info(path: str, fields_name: list): - """Extract specific fields from the CIF description.""" - basic_fields = ['formula_pretty', 'chemsys', 'composition', 'elements', 'symmetry', 'nsites', 'volume', 'density'] - energy_electronic_fields = ['formation_energy_per_atom', 'energy_above_hull', 'is_stable', 'efermi', 'cbm', 'vbm', 'band_gap', 'is_gap_direct'] - metal_magentic_fields = ['is_metal', 'is_magnetic', "ordering", 'total_magnetization', 'num_magnetic_sites'] - # metal_magentic_fields = ['is_metal', 'is_magnetic', "ordering", 'total_magnetization', 'total_magnetization_normalized_vol', 'total_magnetization_normalized_formula_units', 'num_magnetic_sites', 'num_unique_magnetic_sites', 'types_of_magnetic_species', "decomposes_to"] - - selected_fields = [] - if fields_name[0] == 'all_fields': - selected_fields = basic_fields + energy_electronic_fields + metal_magentic_fields - # selected_fields = energy_electronic_fields + metal_magentic_fields - else: - for field in fields_name: - selected_fields.extend(locals().get(field, [])) - - with open(path, 'r') as f: - docs = json.load(f) - - new_docs = {} - for field_name in selected_fields: - new_docs[field_name] = docs.get(field_name, '') - - # new_docs['structure'] = {"lattice": docs['structure']['lattice']} - return new_docs - -def remove_symmetry_equiv_xyz(cif_content): - """ - Remove symmetry operations section from CIF file content - - Args: - cif_content: CIF file content string - - Returns: - Cleaned CIF content string - """ - lines = cif_content.split('\n') - output_lines = [] - - i = 0 - while i < len(lines): - line = lines[i].strip() - - # 检测循环开始 - if line == 'loop_': - # 查看下一行,检查是否是对称性循环 - next_lines = [] - j = i + 1 - while j < len(lines) and lines[j].strip().startswith('_'): - next_lines.append(lines[j].strip()) - j += 1 - - # 检查是否包含对称性操作标签 - if any('_symmetry_equiv_pos_as_xyz' in tag for tag in next_lines): - # 跳过整个循环块 - while i < len(lines): - if i + 1 >= len(lines): - break - - next_line = lines[i + 1].strip() - # 检查是否到达下一个循环或数据块 - if next_line == 'loop_' or next_line.startswith('data_'): - break - - # 检查是否到达原子位置部分 - if next_line.startswith('_atom_site_'): - break - - i += 1 - else: - # 不是对称性循环,保留loop_行 - output_lines.append(lines[i]) - else: - # 非循环开始行,直接保留 - output_lines.append(lines[i]) - - i += 1 - - return '\n'.join(output_lines) +from mars_toolkit.core.llm_tools import llm_tool +from mars_toolkit.core.config import config +from mars_toolkit.core.error_handlers import handle_general_error +from mars_toolkit.core.cif_utils import read_cif_txt_file, extract_cif_info, remove_symmetry_equiv_xyz logger = logging.getLogger(__name__) @@ -218,17 +131,14 @@ def process_search_results(docs: List[Dict[str, Any]]) -> List[Dict[str, Any]] | new_docs[field_name] = doc.get(field_name, '') res.append(new_docs) except Exception as e: - # logger.warning(f"Error processing document: {str(e)}") + logger.warning(f"Error processing document: {str(e)}") continue return res except Exception as e: error_msg = f"Error in process_search_results: {str(e)}" - # logger.error(error_msg) - import traceback - # logger.error(traceback.format_exc()) + logger.error(error_msg) return error_msg - def _search_worker(queue, api_key, **kwargs): """ Worker function for executing Materials Project API searches. @@ -243,24 +153,15 @@ def _search_worker(queue, api_key, **kwargs): try: import os import traceback - os.environ['HTTP_PROXY'] = Configs.HTTP_PROXY or '' - os.environ['HTTPS_PROXY'] = Configs.HTTPS_PROXY or '' - + os.environ['HTTP_PROXY'] = config.HTTP_PROXY or '' + os.environ['HTTPS_PROXY'] = config.HTTPS_PROXY or '' # 初始化 MPRester 客户端 with MPRester(api_key) as mpr: - # print(f"MPRester initialized with endpoint:") - - - # print("Executing search...") result = mpr.materials.summary.search(**kwargs) - # print(f"Search completed, result type: {type(result)}") # 检查结果 if result: - # print(f"Number of results: {len(result)}") - # print(f"First result type: {type(result[0])}") - # 尝试使用更安全的方式处理结果 processed_results = [] for doc in result: @@ -285,17 +186,12 @@ def _search_worker(queue, api_key, **kwargs): # 最后的尝试,直接使用 doc processed_results.append(doc) - # print(f"Processed {len(processed_results)} results") queue.put(processed_results) else: - # print("No results found") queue.put([]) except Exception as e: - # print(f"Error in _search_worker: {str(e)}") - # print(traceback.format_exc()) queue.put(e) - async def execute_search(search_args: Dict[str, Any], timeout: int = 120) -> List[Dict[str, Any]] | str: """ Execute a search against the Materials Project API. @@ -309,78 +205,44 @@ async def execute_search(search_args: Dict[str, Any], timeout: int = 120) -> Lis Returns: List of document dictionaries from the search results or error message string if an exception occurs """ - # print(f"Starting execute_search with args: {search_args}") - # 确保 formula 参数是列表类型 if 'formula' in search_args and isinstance(search_args['formula'], str): search_args['formula'] = [search_args['formula']] - # print(f"Converted formula to list in execute_search: {search_args['formula']}") manager = Manager() queue = manager.Queue() try: - p = Process(target=_search_worker, args=(queue, Configs.MP_API_KEY), kwargs=search_args) - + p = Process(target=_search_worker, args=(queue, config.MP_API_KEY), kwargs=search_args) p.start() - - # logger.info(f"Started worker process with PID: {p.pid}") - # print(f"Waiting for process {p.pid} to complete (timeout: {timeout}s)...") p.join(timeout=timeout) if p.is_alive(): - # logger.warning(f"Terminating worker process {p.pid} due to timeout") - # print(f"Process {p.pid} timed out, terminating...") + logger.warning(f"Terminating worker process {p.pid} due to timeout") p.terminate() p.join() error_msg = f"Request timed out after {timeout} seconds" return error_msg - # print("Process completed, retrieving results from queue...") try: - if queue.empty(): - # logger.warning("Queue is empty after process completion") - # print("Warning: Queue is empty after process completion") - pass - else: - # logger.info("Queue contains data, retrieving...") - # print("Queue contains data, retrieving...") - pass - result = queue.get(timeout=timeout) - # print(f"Result type: {type(result)}") if isinstance(result, Exception): - # logger.error(f"Error in search worker: {str(result)}") - # print(f"Error in search worker: {str(result)}") - # 尝试获取更详细的错误信息 + logger.error(f"Error in search worker: {str(result)}") if hasattr(result, "__traceback__"): import traceback tb_str = ''.join(traceback.format_exception(None, result, result.__traceback__)) - # print(f"Error traceback: {tb_str}") return f"Error in search worker: {str(result)}" - if isinstance(result, list): - # print(f"Successfully retrieved {len(result)} documents") - # logger.info(f"Successfully retrieved {len(result)} documents") - pass - else: - # print(f"Result is not a list, but {type(result)}") - pass - return result except queue.Empty: error_msg = "Failed to retrieve data from queue (timeout)" - # logger.error(error_msg) - # print(error_msg) + logger.error(error_msg) return error_msg except Exception as e: error_msg = f"Error in execute_search: {str(e)}" - # logger.error(error_msg) - # print(error_msg) - import traceback - # print(traceback.format_exc()) + logger.error(error_msg) return error_msg @llm_tool(name="search_material_property_from_material_project", description="Search materials in Materials Project database by formula and properties") @@ -403,8 +265,6 @@ async def search_material_property_from_material_project( Returns: JSON formatted material properties data """ - # print(f"search_material_property_from_material_project called with formula: {formula}, type: {type(formula)}") - # 验证晶系参数 VALID_CRYSTAL_SYSTEMS = ['Triclinic', 'Monoclinic', 'Orthorhombic', 'Tetragonal', 'Trigonal', 'Hexagonal', 'Cubic'] @@ -421,9 +281,6 @@ async def search_material_property_from_material_project( # 确保 formula 是列表类型 if isinstance(formula, str): formula = [formula] - # print(f"Converted formula to list: {formula}") - - params = { "chemsys": chemsys, @@ -432,37 +289,25 @@ async def search_material_property_from_material_project( "is_gap_direct": is_gap_direct, "is_stable": is_stable, "chunk_size": 5, - } # Filter out None values params = {k: v for k, v in params.items() if v is not None} - # print("Parameters after filtering:", params) mp_id_list = await get_mpid_from_formula(formula=formula) try: res=[] - # Execute search against Materials Project API - #docs = await execute_search(params) - # for mp_id in id_list: for mp_id in mp_id_list: - crystal_props = get_extra_cif_info(Configs.LOCAL_MP_PROPERTY_ROOT+f"{mp_id}.json", ['all_fields']) + crystal_props = extract_cif_info(config.LOCAL_MP_ROOT+f"/Props/{mp_id}.json", ['all_fields']) res.append(crystal_props) - - - #res = process_search_results(docs) - # print(f"Processed {len(res)} results") - if len(res) == 0: - # print("No results found") return "No results found, please try again." # Format response with top results - # print(f"Formatting top {Configs.MP_TOPK} results") try: # 创建包含索引的JSON结果 formatted_results = [] - for i, item in enumerate(res[:Configs.MP_TOPK], 1): + for i, item in enumerate(res[:config.MP_TOPK], 1): formatted_result = f"[property {i} begin]\n" formatted_result += json.dumps(item, indent=2) formatted_result += f"\n[property {i} end]\n\n" @@ -472,25 +317,19 @@ async def search_material_property_from_material_project( res_chunk = "\n\n".join(formatted_results) res_template = f""" Here are the search results from the Materials Project database: -Due to length limitations, only the top {Configs.MP_TOPK} results are shown below:\n +Due to length limitations, only the top {config.MP_TOPK} results are shown below:\n {res_chunk} If you need more results, please modify your search criteria or try different query parameters. """ - # print("Successfully formatted results") return res_template except Exception as format_error: - # print(f"Error formatting results: {str(format_error)}") - import traceback - # print(traceback.format_exc()) + logger.error(f"Error formatting results: {str(format_error)}") return str(format_error) except Exception as e: - # print(f"Error in search_material_property_from_material_project: {str(e)}") - import traceback - # print(traceback.format_exc()) + logger.error(f"Error in search_material_property_from_material_project: {str(e)}") return str(e) - @llm_tool(name="get_crystal_structures_from_materials_project", description="Get symmetrized crystal structures CIF data from Materials Project database by chemical formula") async def get_crystal_structures_from_materials_project( formulas: list[str], @@ -508,46 +347,11 @@ async def get_crystal_structures_from_materials_project( Returns: Formatted text containing symmetrized CIF data """ - # 确保 formulas 是列表类型 - # if isinstance(formulas, str): - # formulas = [formulas] - - # try: - # # 构建搜索参数 - # search_args = { - # "formula": formulas, - # "fields": ["material_id",] - # } - - # # 使用execute_search函数查询晶体结构信息 - # docs = await execute_search(search_args, timeout=60) - - # if isinstance(docs, str): - # # 如果返回的是字符串,说明发生了错误 - # return f"获取晶体结构时出错: {docs}" - - # if not docs: - # return "未找到指定化学式的晶体结构数据。" - - # 处理结果 - # result = {} - # for i, doc in enumerate(docs): - # try: - # # 获取材料ID和结构 - # material_id = doc.get('material_id') - # structure_data = doc.get('structure') - - # if not structure_data: - # continue - - # # 将结构数据转换为pymatgen Structure对象 result={} mp_id_list=await get_mpid_from_formula(formula=formulas) - for i,mp_id in enumerate(mp_id_list): - cif_file = glob.glob(f"/home/ubuntu/sas0/LYT/paper_dataset/mp_cif/MPDatasets/{mp_id}.cif")[0] - #print('111',cif_file) + cif_file = glob.glob(config.LOCAL_MP_ROOT+f"/MPDatasets/{mp_id}.cif")[0] structure = Structure.from_file(cif_file) # 如果需要常规单元格 if conventional_unit_cell: @@ -570,28 +374,24 @@ async def get_crystal_structures_from_materials_project( result[key] = cif_data - # 只保留前Configs.MP_TOPK个结果 - if len(result) >= Configs.MP_TOPK: + # 只保留前config.MP_TOPK个结果 + if len(result) >= config.MP_TOPK: break - # except Exception as e: - # continue - - # 格式化响应 try: - prompt = f""" + prompt = f""" # Materials Project Symmetrized Crystal Structure Data Below are symmetrized crystal structure data for {len(result)} materials from the Materials Project database, in CIF (Crystallographic Information File) format. These structures have been analyzed and optimized for symmetry using SpacegroupAnalyzer with precision parameter symprec={symprec}.\n """ - for i, (key, cif_data) in enumerate(result.items(), 1): - prompt += f"[cif {i} begin]\n" - prompt += cif_data - prompt += f"\n[cif {i} end]\n\n" + for i, (key, cif_data) in enumerate(result.items(), 1): + prompt += f"[cif {i} begin]\n" + prompt += cif_data + prompt += f"\n[cif {i} end]\n\n" - prompt += """ + prompt += """ ## Usage Instructions 1. You can copy the above CIF data and save it as .cif files @@ -601,15 +401,14 @@ These structures have been analyzed and optimized for symmetry using SpacegroupA CIF files contain complete structural information of crystals, including cell parameters, atomic coordinates, symmetry, etc. Symmetrization helps identify and optimize crystal symmetry, making the structure more standardized and accurate. """ - return prompt + return prompt except Exception as format_error: - import traceback + logger.error(f"Error formatting crystal structures: {str(format_error)}") return str(format_error) - @llm_tool(name="get_mpid_from_formula", description="Get material IDs (mpid) from Materials Project database by chemical formula") -async def get_mpid_from_formula(formula: str) -> str: +async def get_mpid_from_formula(formula: str) -> List[str]: """ Get material IDs (mpid) from Materials Project database by chemical formula. Returns mpids for the lowest energy structures. @@ -618,27 +417,17 @@ async def get_mpid_from_formula(formula: str) -> str: formula: Chemical formula (e.g., "Fe2O3") Returns: - Formatted text containing material IDs + List of material IDs """ - # 确保 formula 是列表类型,因为 _search_by_formula_worker 需要列表输入 - - os.environ['HTTP_PROXY'] = Configs.HTTP_PROXY or '' - os.environ['HTTPS_PROXY'] = Configs.HTTPS_PROXY or '' + os.environ['HTTP_PROXY'] = config.HTTP_PROXY or '' + os.environ['HTTPS_PROXY'] = config.HTTPS_PROXY or '' id_list = [] - with MPRester(Configs.MP_API_KEY) as mpr: - docs = mpr.materials.summary.search(formula=formula)#这里设定搜索条件id list =[]for doc in docs:#获取材料索引号id list.append(doc.material id) - for doc in docs: - id_list.append(doc.material_id) - return id_list - # cif_description_list= [] - # cif_information_list=[] - # crystal_props_list=[] - # #print("mp_id",id_list) - # for mp_id in id_list: - # cif_description = read_cif_txt_file('/home/ubuntu/sas0/LYT/paper_dataset/mp_cif/Text-bond/{}.txt'.format(mp_id)) - # cif_information = read_cif_txt_file('/home/ubuntu/sas0/LYT/paper_dataset/mp_cif/Symmetry_MPDatasets/{}_symmetrized.cif'.format(mp_id)) - # cif_information = cif_information.replace('# generated using pymatgen\n', '') - - # crystal_props = get_extra_cif_info("/home/ubuntu/sas0/LYT/paper_dataset/mp_cif/Props/{}.json".format(mp_id), ['all_fields']) - # cif_description_list.append(cif_description) - # cif_information_list.append(cif_information) + try: + with MPRester(config.MP_API_KEY) as mpr: + docs = mpr.materials.summary.search(formula=formula) + for doc in docs: + id_list.append(doc.material_id) + return id_list + except Exception as e: + logger.error(f"Error getting mpid from formula: {str(e)}") + return [] diff --git a/tools_for_ms/services_tools/oqmd_tools.py b/mars_toolkit/query/oqmd_query.py similarity index 92% rename from tools_for_ms/services_tools/oqmd_tools.py rename to mars_toolkit/query/oqmd_query.py index 7b13ce1..d4ed1ea 100644 --- a/tools_for_ms/services_tools/oqmd_tools.py +++ b/mars_toolkit/query/oqmd_query.py @@ -1,3 +1,13 @@ +""" +OQMD Query Module + +This module provides functions for querying the Open Quantum Materials Database (OQMD). + +Author: Yutang LI +Institution: SIAT-MIC +Contact: yt.li2@siat.ac.cn +""" + import logging import httpx import pandas as pd @@ -5,13 +15,12 @@ from bs4 import BeautifulSoup from io import StringIO from typing import Annotated -from ..llm_tools import llm_tool -from ..llm_tools import * +from mars_toolkit.core.llm_tools import llm_tool logger = logging.getLogger(__name__) @llm_tool(name="fetch_chemical_composition_from_OQMD", description="Fetch material data for a chemical composition from OQMD database") -async def fetch_chemical_composition_from_OQMD ( +async def fetch_chemical_composition_from_OQMD( composition: Annotated[str, "Chemical formula (e.g., Fe2O3, LiFePO4)"] ) -> str: """ diff --git a/tools_for_ms/basic_tools.py b/mars_toolkit/query/web_search.py similarity index 51% rename from tools_for_ms/basic_tools.py rename to mars_toolkit/query/web_search.py index cf9e48b..1aa6ab2 100644 --- a/tools_for_ms/basic_tools.py +++ b/mars_toolkit/query/web_search.py @@ -1,48 +1,16 @@ +""" +Web Search Module + +This module provides functions for searching information on the web. +""" import asyncio -from datetime import datetime -from typing import Annotated, Dict, Any -import pytz +from typing import Annotated, Dict, Any, List from langchain_community.utilities import SearxSearchWrapper -from .llm_tools import llm_tool - -# Json Schema 将函数转化为大模型能够理解的格式(因为大模型训练时,调用函数相关的数据使用Json Schema的格式) -#1. 使用@tool装饰器装饰函数。 -#2. 使用Annotated为参数添加描述。 -#3. 完善函数的docstring以明确工具的功能。 让模型在调用函数时能清楚每个模块的功能 - -# @tool -# def online_search( -# query: Annotated[str, "The search term to find scientific content in English"] -# ) -> str: -# """Searches scientific information on the Internet and returns results in English.""" -# search = SearxSearchWrapper( -# searx_host="http://192.168.191.101:40032/", -# categories=["science"], -# k=20 -# ) - -# return search.run(query, language='es', num_results=2) - - -@llm_tool(name="get_current_time", description="Get current date and time in specified timezone") -async def get_current_time(timezone: str = "UTC") -> str: - """Returns the current date and time in the specified timezone. - - Args: - timezone: Timezone name (e.g., UTC, Asia/Shanghai, America/New_York) - - Returns: - Formatted date and time string - """ - try: - tz = pytz.timezone(timezone) - current_time = datetime.now(tz) - return f"The current {timezone} time is: {current_time.strftime('%Y-%m-%d %H:%M:%S %Z')}" - except pytz.exceptions.UnknownTimeZoneError: - return f"Unknown timezone: {timezone}. Please use a valid timezone such as 'UTC', 'Asia/Shanghai', etc." +from mars_toolkit.core.llm_tools import llm_tool +from mars_toolkit.core.config import config @llm_tool(name="search_online", description="Search scientific information online and return results as a string") async def search_online( @@ -73,7 +41,7 @@ async def search_online( # Initialize search wrapper search = SearxSearchWrapper( - searx_host="http://192.168.191.101:40032/", + searx_host=config.SEARXNG_HOST, categories=["science",], k=num_results ) @@ -107,17 +75,3 @@ async def search_online( result_str += f"Source: {result['source']}\n\n" return result_str - - -# 让大模型可以根据函数名,直接调用函数 -# tool_map = { -# "online_search": online_search, -# "get_current_time": get_current_time, -# } - - - - -#####要用时得加修饰符@tool;为了实现异步,不用@tool -#tools = [online_search,get_current_time] -#tools_json_shcema = [convert_to_openai_function_format(tool.args_schema.model_json_schema()) for tool in tools] diff --git a/mars_toolkit/visualization/__init__.py b/mars_toolkit/visualization/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test_tools.py b/test_mars_toolkit.py similarity index 56% rename from test_tools.py rename to test_mars_toolkit.py index c57688b..0c2b8a9 100644 --- a/test_tools.py +++ b/test_mars_toolkit.py @@ -1,6 +1,8 @@ - import asyncio +import json +from rich.console import Console +console = Console() async def test_tool(tool_name: str) -> str: """ @@ -16,27 +18,27 @@ async def test_tool(tool_name: str) -> str: print(f"开始测试工具: {tool_name}") if tool_name == "get_current_time": - from tools_for_ms.basic_tools import get_current_time + from mars_toolkit.misc.misc_tools import get_current_time result = await get_current_time(timezone="Asia/Shanghai") elif tool_name == "search_online": - from tools_for_ms.basic_tools import search_online - #from tools_for_ms.basic_tools import search_online + from mars_toolkit.query.web_search import search_online result = await search_online(query="material science", num_results=2) elif tool_name == "search_material_property_from_material_project": - from tools_for_ms.services_tools.mp_tools import search_material_property_from_material_project + from mars_toolkit.query.mp_query import search_material_property_from_material_project result = await search_material_property_from_material_project(formula="Fe2O3") elif tool_name == "get_crystal_structures_from_materials_project": - from tools_for_ms.services_tools.mp_tools import get_crystal_structures_from_materials_project - result = await get_crystal_structures_from_materials_project( - formulas=["Fe2O3"]) + from mars_toolkit.query.mp_query import get_crystal_structures_from_materials_project + result = await get_crystal_structures_from_materials_project(formulas=["Fe2O3"]) + elif tool_name == "get_mpid_from_formula": - from tools_for_ms.query_tools.mp_tools import get_mpid_from_formula - result = await get_mpid_from_formula(['Fe2O3']) + from mars_toolkit.query.mp_query import get_mpid_from_formula + result = await get_mpid_from_formula(formula=["Fe2O3"]) + elif tool_name == "optimize_crystal_structure": - from tools_for_ms.services_tools.fairchem_tools import optimize_crystal_structure + from mars_toolkit.compute.structure_opt import optimize_crystal_structure # 使用一个简单的CIF字符串作为测试输入 simple_cif = """ data_simple @@ -58,21 +60,21 @@ async def test_tool(tool_name: str) -> str: result = await optimize_crystal_structure(content=simple_cif, input_format="cif") elif tool_name == "generate_material": - from tools_for_ms.services_tools.mattergen_tools import generate_material + from mars_toolkit.compute.material_gen import generate_material # 使用简单的属性约束进行测试 result = await generate_material(properties={'dft_mag_density': 0.15}, batch_size=2, num_batches=1) elif tool_name == "fetch_chemical_composition_from_OQMD": - from tools_for_ms.services_tools.oqmd_tools import fetch_chemical_composition_from_OQMD + from mars_toolkit.query.oqmd_query import fetch_chemical_composition_from_OQMD result = await fetch_chemical_composition_from_OQMD(composition="Fe2O3") elif tool_name == "retrieval_from_knowledge_base": - from tools_for_ms.query_tools.search_dify import retrieval_from_knowledge_base + from mars_toolkit.query.dify_search import retrieval_from_knowledge_base result = await retrieval_from_knowledge_base(query="CsPbBr3", topk=3) elif tool_name == "predict_properties": - from tools_for_ms.services_tools.mattersim_tools import predict_properties - # 使用一个简单的硅钻石结构CIF字符串作为测试输入 + from mars_toolkit.compute.property_pred import predict_properties + # 使用一个简单的CsPbBr3结构CIF字符串作为测试输入 _cif = """ # generated using pymatgen data_CsPbBr3 @@ -120,52 +122,14 @@ loop_ Br Br17 1 0.79480800 0.20538600 0.47431200 1 Br Br18 1 0.95175500 0.49370800 0.75000000 1 Br Br19 1 0.45175500 0.00629200 0.25000000 1 - """ result = await predict_properties(cif_content=_cif) -# elif tool_name == "visualize_cif": -# from tools_for_ms.services_tools.cif_visualization_tools import visualize_cif -# # 使用一个简单的CIF字符串作为测试输入 -# simple_cif = """ -# data_CdEu2NEu -# _chemical_formula_structural CdEu2NEu -# _chemical_formula_sum "Cd1 Eu3 N1" -# _cell_length_a 5.114863465543178 -# _cell_length_b 5.110721509244114 -# _cell_length_c 5.113552093505859 -# _cell_angle_alpha 90.02261043268513 -# _cell_angle_beta 90.00946914658029 -# _cell_angle_gamma 89.99314499504335 - -# _space_group_name_H-M_alt "P 1" -# _space_group_IT_number 1 - -# loop_ -# _space_group_symop_operation_xyz -# 'x, y, z' - -# loop_ -# _atom_site_type_symbol -# _atom_site_label -# _atom_site_symmetry_multiplicity -# _atom_site_fract_x -# _atom_site_fract_y -# _atom_site_fract_z -# _atom_site_occupancy -# Cd Cd1 1.0 0.6641489863395691 0.6804293394088744 0.3527604341506958 1.0000 -# Eu Eu1 1.0 0.1641521006822586 0.18045939505100247 0.35262206196784973 1.0000 -# Eu Eu2 1.0 0.16385404765605927 0.6803322434425354 0.8526210784912109 1.0000 -# N N1 1.0 0.16389326751232147 0.1804375052452087 0.8527467250823975 1.0000 -# Eu Eu3 1.0 0.664197564125061 0.1803932040929794 0.8526203036308289 1.0000 -# """ -# result = await visualize_cif(cif_content=simple_cif) - -# else: -# return f"未知工具: {tool_name}" + else: + return f"未知工具: {tool_name}" print(f"工具 {tool_name} 测试完成") - return f"工具 {tool_name} 测试成功,返回结果类型: {type(result)},返回的结果{result}" + return f"工具 {tool_name} 测试成功,返回结果类型: {type(result)}, 返回的结果: {result}" except Exception as e: import traceback @@ -173,18 +137,44 @@ loop_ return f"工具 {tool_name} 测试失败: {str(e)}\n{error_details}" -if __name__ == "__main__": +def print_tool_schemas(): + """打印所有注册的工具函数的JSON模式""" + import mars_toolkit + schemas = mars_toolkit.get_tool_schemas() + console.print("[bold green]已注册的工具函数列表:[/bold green]") + for i, schema in enumerate(schemas, 1): + console.print(f"[bold cyan]工具 {i}:[/bold cyan] {schema['function']['name']}") + console.print(f"[bold yellow]描述:[/bold yellow] {schema['function']['description']}") + console.print("[bold magenta]参数:[/bold magenta]") + for param_name, param_info in schema['function']['parameters']['properties'].items(): + required = "必需" if param_name in schema['function']['parameters'].get('required', []) else "可选" + console.print(f" - [bold]{param_name}[/bold] ({required}): {param_info.get('description', '无描述')}") + console.print("") - # 查询工具 - # search_material_property_from_material_project 在material project中通过化学式查询材料性质 ✅ - # get_crystal_structures_from_materials_project 在material project中通过化学式查询晶体性质✅ - # fetch_chemical_composition_from_OQMD 在OQMD中通过化学式查询获取化学组成✅ - # search_online - # 生成内容的工具 - # optimize_crystal_structure 使用fairchem 优化晶体结构✅ - # predict_properties 使用mattersim 预测晶体性质 ✅ - # generate_material 使用matter 预测晶体性质✅ - # 测试 MatterSim 工具 - tool_name ='search_material_property_from_material_project' + +if __name__ == "__main__": + # 打印所有工具函数的模式 + #print_tool_schemas() + + # 测试工具函数列表 + tools_to_test = [ + "get_current_time", # 基础工具 + "search_online", # 网络搜索工具 + "search_material_property_from_material_project", # 材料项目查询工具 + "get_crystal_structures_from_materials_project", # 晶体结构查询工具 + "get_mpid_from_formula", # 材料ID查询工具 + "optimize_crystal_structure", # 晶体结构优化工具 + "generate_material", # 材料生成工具 + "fetch_chemical_composition_from_OQMD", # OQMD查询工具 + "retrieval_from_knowledge_base", # 知识库检索工具 + "predict_properties" # 属性预测工具 + ] + + # 选择要测试的工具 + tool_name = tools_to_test[5] # 测试 search_online 工具 + + # 运行测试 result = asyncio.run(test_tool(tool_name)) print(result) + console.print(f"[bold blue]测试结果:[/bold blue]") + console.print(result) diff --git a/tools_for_ms/__init__.py b/tools_for_ms/__init__.py deleted file mode 100644 index 301e67b..0000000 --- a/tools_for_ms/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -Tools package for LLM function calling. - -This package provides utilities for defining, registering, and managing LLM tools. -""" - -from .llm_tools import llm_tool, get_tools, get_tool_schemas -from .basic_tools import * -from .services_tools.oqmd_tools import fetch_chemical_composition_from_OQMD -from .services_tools.mp_tools import search_material_property_from_material_project,get_crystal_structures_from_materials_project -from .services_tools.search_dify import retrieval_from_knowledge_base -from .services_tools.fairchem_tools import optimize_crystal_structure -#from .services_tools.mattergen_tools import generate_material -#from .services_tools.mattersim_tools import predict_properties - -__all__ = ["llm_tool", "get_tools", "get_tool_schemas"] diff --git a/tools_for_ms/__pycache__/__init__.cpython-310.pyc b/tools_for_ms/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 9e43ae5043200f827c9a99450244f91da5f1997c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 821 zcmZXSL2uJA6vv%3Ym=-Ul|VvFnv?^VBGzz$(}Xy1+(3w)axtFmq-J)U*-occ;zMxb z%#E*o*?woi|J28qQzdS$x^8EM9)00VxV0`}av-%Yx^xZG+4v3*wFzp903>An4 zER=x?i%<=Ufr^SK@UekBSon7&hiX)e`q+VtRZ=7>Ez*8Hl!t0ujC+41C+es;3Q&bu z_%$f*vG_fjC7Vy_LThQWhR`cg@vPJ)J3qh3%C@FX=sKfBN>NwyG+ivkU#>BFB^b9^ z>x2|efagDDyc9LyPcy?SVI4R9g48Tiq$U-t`t;5pI!}KDaLd`Ci=|Z9$GW8AuJ>#= zy>+prORk8W1zqq2%;S2pu37ZvfQi$1xefb>1)Ndt{Hmx z;oiP#cDo~=FZRgs9@!jinLsww@4Vn8svp2tAFDE JUC4kUcDjBY3I0?OsF=;z>beSCK6q<`QNn=`?OKsY#~N1;PKq zvtGpirWc`%N4@NAU~hZ!W!mDlAeec)Pw{AB;u}s7qVNsMkLG7z~vXCY;2{X`Hffq;z8-o8ADp`id$pn^ge1;av{PoQ zlPRvRkHjQnCS!As9U2$-E~q;rW|J{-e>iX?iINj#fQib;NGnNRzd3r^^NPM-wnSZZzhj9l_T8Px8#> zg9iu0fjFBDt`;*O1mH+SALwQ#{Qv*} diff --git a/tools_for_ms/__pycache__/__init__.cpython-312.pyc b/tools_for_ms/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index aa1c0177b1eaef1e000a77842ccee1534fc8882a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1005 zcmZ{izi-qq6vyq{mAlK`m9`+Ewkl*`IYcikz|t}x5Cbg;sZ$m!b)1~39S7Sfx|10A zE7;i>_)C~rBRVm`1gcP_PCV!C_;Cm;a^8FXgg!fGzQC{7 z=>%SHP=X?q;KUPHdXXm^QA0MPCU&ugSbFc(R#RM%t*BMoOQJ11QAhfbU;7tCSN5V_ zZMQ^UE=S9?-4+++O0-hj9kD9cqBV>%lz4A(bZP7lx|3J_fl|T*MNE(4j0LIE!QS3} zkd`^MT;&0ch2VKM^!wG-z_AmcpF zz^l_+S9Iuq!SMfsM%5NV5*MpF8MC!zs+GA(3>`5Un*pxy4cM-y%+e8YK@RN^s$`)I zG@){mY9-0jXZsHZUNtl<)&R=b^#LF>T`+COQ|iy~b4G2o?Fv#oHWpZ8bxCchnfaSG zE{nsVkuA-v=Ij{oy6#b~UJ90Ej2y;>0kEM8%O#(%f78P0YQ}P=p}AijLU6OtEaBA7 zn+0X3$th2t3@%qKLJ~y@sXBAbjBbF6y6Lth*s3m6=X9pxx?%d5Q^+#aT)mLV)YL5p zUs*Vp#q6~0@^u`tv4G5EO?W!iZpN#v1t5(%=+35BYIN5zR~HyiA8rK{n3e1OA2NKN zsqY|A0A`Yqcjy#cbbcosDapd}u*_{4-oAAZipe;Xu{PV17GeF{1csAH6A}XBX$ct? zrL@prF@n`b?QcR!+?PiW%=JwEdgzVDr&hxN02f*w`= L-PbL>4&VF){=7{# diff --git a/tools_for_ms/__pycache__/api_key.cpython-310.pyc b/tools_for_ms/__pycache__/api_key.cpython-310.pyc deleted file mode 100644 index ef305242431d62e8266e1716e51f6cc1624e1876..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 278 zcmd1j<>g`kf=G!Y>3KlLsX`H>mM z5k(p47WpobM(N=OM#+|DW@*NT&K4#nCYFvV7G`di&MB5DZf34#CW#g)RT3E`B?ZM+ z`ub&=1$v1EnU$G($@#hZWrlv5Oi_IP0j_?Ip7D+Wp7GwUktqDoAfJ^CMIiTpiC@n8 zp~b01#rip!RT+tSm8FS!`r-LS*#$X?$*KAQMfq8&$tC&)l_eSZc~G8_eo20QPO(1F g*7)qyO1*;0TO2mI`6;D2sdgZ9i&=mK3j+ru0B5pFIRF3v diff --git a/tools_for_ms/__pycache__/basic_tools.cpython-310.pyc b/tools_for_ms/__pycache__/basic_tools.cpython-310.pyc deleted file mode 100644 index eb27a78d83050821ce680b4cf973319fb3576c30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2759 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 T>0fg;2)x$K7cD<6qwe)Tna8q0 diff --git a/tools_for_ms/__pycache__/llm_tools.cpython-312.pyc b/tools_for_ms/__pycache__/llm_tools.cpython-312.pyc deleted file mode 100644 index ddcebe5e7ef24c498f95199f84d7af140ca3fba2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7572 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 Wy-cmWi|LxP*9cVe_QzOJW&Afd6IP1= diff --git a/tools_for_ms/__pycache__/utils.cpython-310.pyc b/tools_for_ms/__pycache__/utils.cpython-310.pyc deleted file mode 100644 index 99addb5ade06e021c6d178b8e9a6ab819e6fd99d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3215 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 TDbu523fankaq=xrJCgqZyjqcG diff --git a/tools_for_ms/services_tools/Configs.py b/tools_for_ms/services_tools/Configs.py deleted file mode 100644 index 84e986a..0000000 --- a/tools_for_ms/services_tools/Configs.py +++ /dev/null @@ -1,23 +0,0 @@ -MP_API_KEY='PMASAg256b814q3OaSRWeVc7MKx4mlKI' -MP_ENDPOINT='https://api.materialsproject.org/' -MP_TOPK = 3 -LOCAL_MP_PROPERTY_ROOT='/home/ubuntu/sas0/LYT/paper_dataset/mp_cif/Props/' - - - -# Proxy -HTTP_PROXY='http://192.168.168.1:20171' #'http://127.0.0.1:7897' #192.168.191.101:20171 -HTTPS_PROXY='http://192.168.168.1:20171'#'http://127.0.0.1:7897' - - -FAIRCHEM_MODEL_PATH='/home/ubuntu/50T/lzy/mars-mcp/pretrained_models/fairchem_ckpt/eqV2_86M_omat_mp_salex.pt' -FMAX=0.05 - - -MATTERGENMODEL_ROOT='/home/ubuntu/50T/lzy/mars-mcp/pretrained_models/mattergen_ckpt' -MATTERGENMODEL_RESULT_PATH='results/' - -DIFY_ROOT_URL='http://192.168.191.101:6080' -DIFY_API_KEY='app-IKZrS1RqIyurPSzR73mz6XSA' - -VIZ_CIF_OUTPUT_ROOT='/home/ubuntu/50T/lzy/mars-mcp/outputs/cif_visualization' diff --git a/tools_for_ms/services_tools/__pycache__/Configs.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/Configs.cpython-310.pyc deleted file mode 100644 index 1663d1cfffa763ad6dca15ab6e8ba49c99764164..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 884 zcmb7D-EPw`6i$D(b=@i1$*Su9J1RK{jB8RNyArgjG_7TVxAvlWkXdRm)!3rsit% z)X=;^d$4sZ9vU}&T-ui}`ABLFb-8zGJ<_i-Q?kKWU1+=%!bd@IQs zQWac9AqB~0vWOEPuxNtOg$EdBlp}&;ENBcuhNk`u*gRqaq&rJ$$*dl>8fv?{@}pK$ z?WpP5KXeC84+QBQ2r(DC;gkW!Y0R;|pag{xp@9H1?DOdr4bk)iivhhpZJ}=4M3F2R zNm+pddfQ;}{L{y!-M>kX|5rgW$?oTLkxQf%PDK*LvX5sE`#4k^YEwOGH@nUBIc99v z7((u<&b4uuaNA9t&R&?d&s{C;JYGbU#4M2#^3c$YFA^O1DUSVUF_w2%HEpEX1{&%Y z*_NE^h5IZt+v(r#$cs~CeA3^&f%YW z>!$`pJ!62ZiDyr|ysUeLKanpf4?p{lA50uYfk3l}qfh`r`HerN0_9oIixx9~E*k7E gtGt%4BMIp7@_!LKGL)5aAs=fpmVSG&T&NU(0eF2B9smFU diff --git a/tools_for_ms/services_tools/__pycache__/Configs.cpython-312.pyc b/tools_for_ms/services_tools/__pycache__/Configs.cpython-312.pyc deleted file mode 100644 index 0a648e7bdf338e3e4a47f39479c134293c3dad7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 769 zcmaJ<&rjPh6i#TNC2gl^)h@8Zc9_J3sFOlVLDQy)2FThpQ4)Sdnyk>6kdZXOPA8gO zy1!!D{saD&T{u=bP1`Au2&wl>i^LzeYsc;OnPwsE`{S3qW%*bD3 z@4*dE!57A1EXH9i)|s(poSc=TBk$y`S!dRobLOmqQ?QCo(VBPWEpEiUDy7dgMKnaW z-e?}TgthZk)i(44wBKJ>Iu~n!-;t9Sr*RySO#tl3s|9w9uxI-u!r=$hk82@z!LJ;R zoh)R2)J@o^*Mw&4Zfw?hVO>Z%;4};n7#c5XI>0~ z&_O;x=lgZoYAP_KF<}rvV*BW#7RBzjubExGP2T;Z+Tcy#C!?v>O3;r$gi(xbZ-5*) zl_c~irs=zA0Q+ZA4Em>tuAw)GNm9g!4E>mZWbxrUHiVkM3!6>8#V60~C|Z#_7B&R^ zTpkUvW+eLhYLGM!4Y5b-$tfBXH5qoKqqIb^)N5<1+%wYxC8nx%Qf}8YHK^(8A@#_x zaZjq-qO5Q2N(xlew$z21Xzr%@ZACmxtBPovlD;GL?v8X-HPeNMo075DHSexf+Vb`h z%-rCf-c8F>dY{)NbCZ3V+xGvmswP)l?q_i^TCS@=#O}Nsya6QMAm$Hqeaf#xm$LtkToy^XU^BJ?J XZ1Lq4v+(25^0+doEPpQJ$5iVNYP#;< diff --git a/tools_for_ms/services_tools/__pycache__/cif_visualization_tools.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/cif_visualization_tools.cpython-310.pyc deleted file mode 100644 index 8936a5decc55ba757a8bc322b35148c7cc068c0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4012 zcmbssTZ|OPae8KUcXn@gZ|{8^U>0LrUJ33X7$-Ve4hV7%i3BK|jakPT&27)^%`vmH z^vrO#tJw&f$B~%hkWC;C;Os?;4T>?yQVgeZw*d1NsZVNF(bW5MwiVl> zJ2_$$UBfO6rfV}dmp(dOJ9}~W-l5u!ON$?WIDhBU#owH)-Tr;;)a`%XJxgp?W28%; z++V!+$^4zqU)V9Z`Gp-N_{uOne{XK_!Zk~Ci>B?G#>o8K)!L0;16l3z{l#BQ#g;)e zVP6JOWj~jwnSh6fjJ!v5z+|Fp7}^+Hu4=ArInaw9bcvU91Cr=&WAuPV9G$>S>n=y% z#i({+t?1fhSp@blu9&8!y0&dDqhO%pwY^yt_N4BAb@;%m!|G4=?;oa#V}|2trcu__ zoH6RX2BeSN{}XRJBT~7bSvqaOtH!1+AXLr4!RQ5-hKUXvEaaHJ^+yJT`Rxh#oC1Ki z(3CLBee$GILFH~&s3ITDqP+r^ekfE#Ec+r3tr0E@I1E^XW6IUgA>p7P3$9pt5eXFu z3FQQix{@!QK$nH9;vpd{90m>*>F3hHm39J62$`7oZ>B*Sp4zR`%^uM(6P)b!J&Rww zxA4KqC$`d;$KQ?x!e-uH_|>gJjx*s+b^?FiJG4-}Te~|0Ub*o8XY=>o3&c0PHQ=!{ zccFIqgH;~2v!`n3|IpBzueril%*-s!-KxENHgM3T+c#_XPjbmQ*n8ti0TzW1f`{N- zlmx*Q#`!^D3Cq*cOsXRILRCB?%pwHXxKu%hAdtxLo&bXvlx>2ub^_+udla-rV?8u@b2$e%O!rA>6)3=oEScUje+M3GWQ> zN)#j}{V49j-MHt9cn;(o9mc)D=SSa)PmIaK9X$f>>=ynHxh=4_RzJq{^II6qi_ilN zp$CxnKu72S%!_!sPQ2{L~88i8pY6>l*KNdvF?WWWMNjjrUg9 zxIKP+R;(nT*X<|jbBrT?`l?t-22_5+PXbk|8>;rrg71UBuk~B;Cj1QN6soTCB`&Mg zkK<>rKtST_*0a!d9+A6lSM@1|BM4&$AD;Wm>fD3?A?vw)Ww{^X1w|7>8Ht7+Z*aLyRL}2Xer&4SgzZ5AqMO$Mqabbjw>983b@xdyL9j z*|4rlqy+|7LAj+V3+A`;=da&~MM^zg(h$+GVJt)B5HbodU~zsG)Hyar>l9oL8?6s; z3O1T)R)USz2bw7wc%bWshEUFz1vH9|kZ!hGq@kQ`+Jqt}Ba%&w@)-bS@yM2X|5;8K z%st2EI(Czi<7#HQk)Q|DUKnOxPrvb}Q*Uzg@G6?+=rGIA`lR8ws(qxKRGoTq?=Kee z#%53%2qauInEebZuNF0T3{J@=mS<|24ODS;t2kW4dMJG*ewsl13Rj*Kk3f7(*vbZA3Q%ywrr3 z16%~YilrUVu|XUXXR>9!YkAx@3N-E-`7u{DwUX_*pn!HvhwZ?5nYII7&28z>uvdWE z?novD2C|AOHxS1-rw}iusKgeE8vGG_UtyaVd60k%ipFWE2-3h-yxF$WeuuChfVQk` zO$8NcoE-}jz=|5O8RoAe!cydQ;lINJW45Iacq3lH^#*oq9Ud^tr2z{nwk=k!IKYZB zhuKNBoB=4}ju|=K;iZ~0!18>(B;!S9Fy3D*(Kg~09-i9>;+zox?P3fmXx&$`tcYe68jP%9AuawcDRAoH<|n?aH;mG(SeKi>cqxAMOFQ8y`Zg1=Gw6yz)cS zOc3WcKR3JZ*3H#*Thg^Nre_I5l75=bYnL!TUC;4lLT0L&y#9{}-q zJT4wciJ}ya$o~mPWB*FF^&#cB_#m^MMpPBsIaMWZuyy?m>;ynV1cw=HO`X6Ix&5r;8 diff --git a/tools_for_ms/services_tools/__pycache__/error_handlers.cpython-312.pyc b/tools_for_ms/services_tools/__pycache__/error_handlers.cpython-312.pyc deleted file mode 100644 index e097feb4427c1295061d588c191675708907a17b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2591 zcmd5-?QaxC7@vK)y_epVyH=nekp(LDB)#KB2q|D_3d+TTm{x*k!e-r_yB^uwJ7(ud zuU1n`l{S&c2MBK(&(IHhTtkoeL5zQbi8*48x{^pD(AH0FijnZincY2FvGSSy@XXBf zduDc?-#qi1??a&gAm3&0pXsazfIsM<{t0ep{s+>z0923!Dx%q}&_Z8@aYji$3tk7RXBemgWGkHO4X9q&p!%Q(24OJ8t|IOf zulk4iWN1kwK#;~Ikp_Y+TM`KpBwXa9p@DsY&I0bsp$_q#0+#i(*qsO@bOUE_0cUc0 zhuD+o>}@}o=n8b@bSx{lLoDK$mf5=3$jCS*D=|e6%+Rez87p+4xA*Y=eg)>~+$d{t zoqEyY_hl4(NO970EaBMx=3}HeO<08>$q;5)l}U1{M`aC>mL-MfDI?zf}FJ9F;R^u)x}jqj`m1IxHzNJ>tHmY_l` zXEep7*#0#=Ryv+PM$CEU0>HMLno({LoFQ8rWCq!BrouV^12A6?Iqt3Z7Fv}ZWUc^} z8)UD5FZlW)GoT2f{Glj|d?Xb4i5X}hI~DB&I>Z4^Y!{=vJ1TyH2 z+KVDIik^&ZLKJv`n1{pQSAOjr%X;>dx@G}ss?C4XW{w)vRG(lmq*4&X1*9wP6(tY= zk1Hib28-+D_~Lr9LjjQkTrX}g2U*HYc8NJsF*3brVv1BZR69gO1*gnff>Zq#ugX|1bBJdQ%XEui%zrkTcVCuRuT^}T zUK;1j&Wcd#uZ1^1du+9kEF8A(pRe9ObA9I8r_&RsT)vu*$XbR})qkq)DQvBD**f`n zs>|6%@}~_;aJF&GFt=PiS?a4r;*YVAa z)%3Ow`}0u2P!;V<l8Hj(Gl(jfCE#K{qo*B}rRrsQ>ElCOmOl+~xBUHqt zkKcJDQiQ4nqL%>CQ$=*cW#EV_)#XRN-Hy_~isEEQ_0{;2m|2ctm^qeb_`iaHS^qm& z^BZWq<6k|p@@N0*TmID-cmC*a9TFb!JhNxyg9m^#vq6CoE=FeoX-wYisctZjmK*2k za5hY#RW?+@W>>Y@Jn+?ri=d)2tGBwLYE;|G#}+{e2WlmcR+rgdjy<3Y+6nvv)5>sN diff --git a/tools_for_ms/services_tools/__pycache__/fairchem_service_tools.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/fairchem_service_tools.cpython-310.pyc deleted file mode 100644 index fc519c6671579f0027d49f4e3e22c4cb5d3fee83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7305 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 BLk<7{ diff --git a/tools_for_ms/services_tools/__pycache__/fairchem_service_tools_test.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/fairchem_service_tools_test.cpython-310.pyc deleted file mode 100644 index cf0efedc7b135cf08e17ba9c3404ed38796105b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8247 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 BK)nC} diff --git a/tools_for_ms/services_tools/__pycache__/fairchem_tools.cpython-312.pyc b/tools_for_ms/services_tools/__pycache__/fairchem_tools.cpython-312.pyc deleted file mode 100644 index 5806247002d8a2ce470534fdd4cc498d4bd55807..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9541 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 diff --git a/tools_for_ms/services_tools/__pycache__/mattergen_service.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/mattergen_service.cpython-310.pyc deleted file mode 100644 index 8d6391bba435bfc1c4fe3809f929354730125603..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11094 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 diff --git a/tools_for_ms/services_tools/__pycache__/mp_service_tools.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/mp_service_tools.cpython-310.pyc deleted file mode 100644 index 3ba2bfe266efe713c50caeb9b50221cbfd3fd607..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22234 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 Z05krX?~jxoK_T#2>pl51Ihg$I{{pzYzfJ%E diff --git a/tools_for_ms/services_tools/__pycache__/mp_tools.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/mp_tools.cpython-310.pyc deleted file mode 100644 index 020fb00e267756e5bcd0050e8057464a352be898..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14774 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 diff --git a/tools_for_ms/services_tools/__pycache__/mp_tools.cpython-312.pyc b/tools_for_ms/services_tools/__pycache__/mp_tools.cpython-312.pyc deleted file mode 100644 index 8fc112d31354b6d03156ed75e86f4b70c5e12e4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26366 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 KOix7FRQ|tSA;BB~ diff --git a/tools_for_ms/services_tools/__pycache__/oqmd_service_tools.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/oqmd_service_tools.cpython-310.pyc deleted file mode 100644 index 5f2d4b701e229c8b5923f1a55faef413f8e4ee01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3016 zcmbtW&2JmW6`vU{m%Gak$+B!oPNHmLCo$VttXrokgrbd`M2UgKQY*EBw=jqmXGpEQ zAN1_dlordv4RbYM6zHXa0Sf4)|3U9P_tN7uw;l@L+GBHY`(~D^=)?jFbQkmW=Dpwh zn3*?|)awp{Z}Tr-_Ws&H=x=H;`;}qv9+dQRs3@X1L|)Ni59=}UO3;$fh{|3WtGQBW zMisB3`$lL*wr4}XOwG`Vs$Nz1E1|Q47@E{r{TO=ZE;j-o z9{8b4ec`*^guA|bBI(XZx=PYjlA3eRPg#>lBlaUEtCXc39`uz4S)CEe-gR0YrVC%-3|8L&F{VKeiCf3t<4)vX>uk8Jnmo>g6TI0Z57I&prpKn(62GYIr;)U zAtU@4XA1%yU`lA|5x#+LA!>Y#e)q2t$;pJ|_!t+IQ7JD?O2-JJymVmjrYNg+jA{8E z;@5;p%`yHAE855qmE53}F&UM6Xk_N)iAAkrJgVds{!wmD?7VVdOq^qMj4_HWMWJ?K zkD>s7l{&}x19W$5WaSqBJ*|%H+&ZWM<;NpO)N_Z{#)OY^=b%CB_n=1`(4TvNpf?Az zjTN+nMmV?WJkYhSFAzPKW2hINl;1@o`~F>xa~^PhliMd;ba4q4v$-umc8rysGgM{0 zePa9l9k8sb{ks7E)$$tuXLd!Ln=FX)AYB{dF~pBvTtTCHUY{(|DsZXZ1#yusjWN{A zW88xseM}VnV2Q5KOONoVx{Kmf1BvCMe_%9fU<7NlGPy)w0@TJBym&%Xr0C0v^A4=o zsPU^tTrS!n9wPe6KPA8H0t3AJRIzCg62`ImP4&{wgDUI^x>G({PWkC7kb0}|}N@zVWEG!?JA689zIHo!^jd&WLz-E8qi=6!{KnUT9!GtzXWp&Xakm1XS}>_ZSQ zf$N!Z4eAXrwH(Bh9cC9k-7v-ES+EY;ecrcTs;A# z(S?PTrr+-~Xv--)7W$s0h;2U%r8V7wsjTe#DV!2s?5(ourm_V5lJu!(bLP{w+L!9K zMV{FW!Z7w_g|mL>cbF`9!^9U}RV3}m=l5tbjHUhIVTTo0zZoXI9^ZMrmizB$L$r7ueZ9!j%Qgv2^IOwv&1c}5EFBF}+WNYH7k zmy74@UvIOJMJj-1@fz{!aAfy_n9;UA8kOn1=ja2X<@g1qi_osb><@^)3!|?#TKh@F zT7$hoEC#K2zO&N`v!j-JU!{6IqO=8P_Ce5LseW~(EtM_WQ(8e<>mP9o!0J%a&!8d? zorZxg;(2W0#gc{1l7kIZ@B*GE4Prpg!K=6i#legCB57dqu;3sd=ip_KZNLm5JS5MY zvH`q=eE-i2?=0d=K${016VOgZ&$r}R^PH@x1%e~bm%$>>>_aZ}Q~rh;l=jja#bzQw zqL*Kq;;65f4Vahq$s04}rXIs4{iIlKtKC-5z;>HAVTNB(mGWIjbEf)%lCypoC3Fxn exQ-z*t58|Uf|%5bpIF!-4k6$R`8Of+&;A2wZC@4u diff --git a/tools_for_ms/services_tools/__pycache__/oqmd_tools.cpython-312.pyc b/tools_for_ms/services_tools/__pycache__/oqmd_tools.cpython-312.pyc deleted file mode 100644 index 38158d15d8e40068f85fd2b8fdc7d2d2780c2adc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5499 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 diff --git a/tools_for_ms/services_tools/__pycache__/search_dify.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/search_dify.cpython-310.pyc deleted file mode 100644 index 860f10a69b3696eb0674083be1c1d30be1b29c03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1682 zcma)6-EUMy6u)!7_p20C5>b-|W6UPf?b1k~QIszeLPAI&A?(Y|?VZ`}rT1f!iI}|FOqhHMUvvrtmN4?9QvZ)i2+LUUWM3&MsIOB?YO+TwX;{UY zr~5|9KoT*qjty*{lkp%<6BB1h3TKH~)^QH&XS5kqN|Ov8n3U^s(z`%2UEe2ayl$KRoZQI|~Fo>iuy zZ%qc_36J0kvBvF)#P7rY&durWuS=bUyX}Pso$Kd2m#%d0eBHixyK`x-JAc3X{jJsI zv+ai$@-kNg+b2AON#szs%G@yMDPVwWpT~sOxXQxnB-g=XOan(idC{^k5DfnTU-T!4 z(+H!cjAbTWldc1QSY42t3f3CPMGdLX6HYB?O|`zAq2qExZYT{Er*Y<-+SD4_aiytO zq^7~tMXjOZY)fwHOmFCdDP}C14ZVe$X2V=e;hZbMYO0Zf@jweDx^*oCF@TE!t8?-$y$x5kpOFqbepHq;SOSZd$yMNCpt8~n~rY&@1zLE*wE_Zi|uPSx{oe&ZY*@ZebAfx z3eNT(U0%Ka!)WJv>!s7VhcBJB=V#mJe}edTS~vIaeKLKzvpCmVy4?O|z7M!FeW(59 zSuh7z08H)KmBefPg9*l}V}(L-$JXKEw(Y~k9mV0|NO5f2$o7%KRI%Vp*ldeWqR6h0 zsBY{gHYIeZK4@2~p6l2mp$f;NFo0Cc?TXn%NZop(t!MXy0V4t1a->!zNunL#=C~I+ zlWtJqQr)n}oh`+!qj`<%ZcvR`L`A;w93@dT3?gFrAtrpC69!X+Mu}0&#axXeLfxY( zJSBx26U4@_%2fe^8_e}d7&AT)2d)FhEy#Nt+?zgOHny1!Pa$+-A8-j<8grRP4stDW zLQ3*Fmt9QX5-1FCE6~$7#Vkeqae^@br*FeN7R9A^@yhD*^4L&5OOqF6QUZ~W7+|S} z5rZ3(lZ@*Eg%fcdq_~b&r7l?AD6DE;Xyb@06~cIG-${og?~^MLqhM5!L7}oqT#2bi z-w-1;xdM3VGxQ2qiL(KqrW|_~tj8Vz$@B-7;HH0(%<~;?P!2gFKT32f*nRd%VIuTN zAs&wd78gDoIa2WIwSuTdkyQ?<0P7w06 zI%ujg(${oDM*Xh;Bbyr(T~Se1F;Q9pshZE%Or$^4(*yD**_@WwxM^9w?FN>`jpr{U zk7x?)<_EZ8N43Cl!#;rqq*&RlL`eYX5Nx6Eg5aqawKSrdQ09eF5xfhW!hxuYmPOx7 v7HAwKG`u24lYJjS2F4!QDe8740&hwt$|4hb7Rj=>nYy+~HFs~6)wO>Cm>(~S diff --git a/tools_for_ms/services_tools/__pycache__/search_dify.cpython-312.pyc b/tools_for_ms/services_tools/__pycache__/search_dify.cpython-312.pyc deleted file mode 100644 index 4f8933c3ccc84492ff5ebbb5a25d368ff7c78a70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2352 zcma(SZEO@pboTakZ}0Z5J#2wqKhn}R;1Sy6K#Xlvgcg-FQ4>uJjmc)aGi~?Sk8^gH z(&o<859CZRQc+r@Xh8)`L5TXJQKKgOG4T&tO)iTj8o9gHKOW)_qyBK_u1k&4#M$h; zH}Ac9@6G#|`63bt0Ww|-{4~-d0`MbUctco0ZhkLh8=!cxf>w&=l1AG7lAP)l^2IkNOCOvm&R!_Y zUM`+GT0DNDbZ)9}@oe$<;nIUWH4T@0(m{CK z_1k88zsnP24mOmPkPzJf(11Tn{+nMBhX(*dgU)1q&}UO_Wt;@3NZ6r&)|X`=mtj;U z188ue0E4q!)*l2m>&d449<~ZIz6_i3!_WnBeubOmGF*yZmGH1EKLWA=JLs)bl|u1W zRhS{E^OBn7?TE+C@Loa~VAp!oRMf*(;i_a-$Ox&rRgQXK^>z|%3K7A=v*}nA2vBIIZ zdn-6qSE;PtwjwRSGlh%Or3+`TFTD5j$43fhpQ+Yq;pmH{bC=uutVf1+EmBPu_OCKF8zCK%g_44xJm&o4bk7kzMeQSI1)ag~Dhd*33S~zm3aCDxOe)061 zd;5Q!e7ZPyc=^ms;pHP$hl`Wv3c2TrI&uW!Q{m7;#p=YCQQJ=UCKAb>ZQaQ`@9IwW zB)gMalf8Fty=!aYKr*3>%66BIEK43i)K8Ny_850O@rrqlb7?I3dHt{8GS~fW`I%vB*^+K^+p3L+(TpFuH zE3I0W(@Ys!E<1v3H@N4Zf~r>&YuT76rNO}D82~QpU=6RMn7?uaVyPOTzs0IztcHYU z*wG}ycQoRNSVbfno9aQt6$#ZCHeCi;VWO4RtT%ptFfnTCDB%n_hV3MFY<(=DO^hdW z8CzYtl1|XO*^-7$Ea_H)n~d^C1LvLDb^OYM`sV3-rtX=mJ3q3}|9R)vbr0u+G7n-K-iVxtpFYOZB*T_Puvt@W+bJEwNe^`6Izb=!zC0n{~3Z<*RM zlU=;6E5EjFTAGsP9$#GBm0#bKZ)ncPTJmdKrk|L4Vs6vo+RZm2f%PGxryfL`t_qF6 zT^H+r0Y0wd`!%uIjv4vn#+inzwe8;s?SGUxLjKd*LBjD&tZx%DyL)3F3$FMWf?r{S zeVy!;aHOx5y%J+6-pEmUD@XB8mf)@+NxG~WlH>+fu8ugfOkbFIjT?}yaYIqfYGnmT z?+vRXR;4oW1|otx$>avT_tnDmmBE`Sk);Jm6GaWsmr|1O#tH*F#yj99K>^-Qrr(9T zNlQ8!x)<*xOOjDwVKS9jhGDLOnrlG(4s5svYOjIFccASDCYTT2o{#qY%CSD*4PhtK zao#Ee0v0+d;4|eHy1E%8>@sDS`+dM4&P{y9#(v<%+(7Pumj+%K__ATgWp%OPzQypa PZ}{D14)`1Ky~ONalSQ~D diff --git a/tools_for_ms/services_tools/__pycache__/utils.cpython-310.pyc b/tools_for_ms/services_tools/__pycache__/utils.cpython-310.pyc deleted file mode 100644 index afac9a32ffe20cef2d652369fc7dca0b2ec0aadc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3315 zcmZWrTW=f372Z3SOH!gFOP15b7Lckn(~2r`0b0XoEzwlO*rEiBhNFF1tae7!%FA7L zc4%9KR2Z;P1O?pYsXz;%k&3J~p#h(&Ub6_TU*N4i@gHZARFBu|{jhC4Ci;R(RK+B{|CLSy91T8&M+)1KsDwWCpb!Vx^cN2DHZmY-rxIK5X;WXluhrGwb zB)&4Y*;r~VtTk#*Es41w@GEosyc&h?UQ0utSN)(G#Lf#io6@YP!d~y(o7z^S(YX1FPF zdxTpO&kP{M-nC>#70-xJWJm0WLk#+-ahM zG3SIm)N)feYa8CuM#H;N-vSfpG`=UCPS^9hp?8<=y9H>jH?ME3H<~R`fCd_qZW6}) zg$}lGbI{yc-?$-i(8QDOUE!>@S{vTRt@V$$gtNgTw`Tz>0@E+bo>YI z*jl66Sbx3Au}&C=$!MSMdDwaVR&(j5cc$ZcI0a?ELGR3na@KLFR;zDrqGCij>){6h zO;f3tL7&Zf?N+^Yx=%_2MmhHB7dt*n7kH9HcSG(LvsssK*KX8XqL|IN-3#tg{(oEt zhG$$q2ZbTmi3-jSEGIhH(CCj3ZCC||+X>r!qYB3Bn?1g>@bhNH6t?HZeusLVa6Hsv zFT!%s^M2j)qd|)eL%f|ZqGDoL0?h>p0T=vSVQ<3nQoQ`d;%?HRi@oh$%zKL;{H(PY z_4gO?Y^k@CFt3v?rj*?aK|#O+Ko=n_L}|6VFRW~T^DtM6QO;Hj)mGU>C{||Jd0b)^ z#RU||DrTe5KnOkMOpJS;AIAyzF=V8k$MV=-knLbY2H{j;<0#4~Ca}TWi4vc)Nd%@) zpeETgiWwBR`s?FmrMD0>LEtngp50MqwOJKj{nUqbbyAZ(g`E!L720h0U>T2EgD=IU zxUvU<{6N{$x;981J_A0JXip5VrryKtee?S-pZ(#FYhm12fA+;+|MSV0&;R}pp{4It zbWt3-o!4WLnDFnX-fJ>?AraFE4Y>EZrD6$lJK@QD!V030g07@4q*g`>si^F2SpAeX zP!Xcs1{!B9&Bj&$O^YB5O;a7!fYfy7$J%0Y_Z>1%ke)YSj|2%f}rP@uA>$32k&uK+<^YsUu`Ae*w3I`RHZ12&4 zS2STQOP3b<4Z0te$AII2ZTQUZqyh$YLq^j^EEI+ufrvY~>&FC?muZ?Zmat}}Ak`|( z;ud;cpfZtOD!D6W+BBvN_5lHureQm#MA9P1XgBf$`r632VnAi874MvO*6R12wJO*3 zvaPU`eSmwj*iYcceu@HZFLdOdN@eR=woHBR7}=KJg+bDdG|dK=F?6JjrdqFN%rUj7 zo>T3I+PCZ~^a|h`JxCXHX-ScXP(bH7)}+*>G`M*J6gkmO)WfV59ExZs+M$|PxV4u% zh6GOxVj@+DeWU@EfCx}89Op;DHWRVG=)FhcA=h}ELnkF+xI`lt(1Z%*p z3Mf^XZT7WlwO__~E~6X7^J{3-=DwirvVQ;w35y(%*|g$KNu7v zdXLJmJE(UcmH2IF?N7{aEzEZo=E>ar>XrGmEAyMk8HlPKpNkv;L+^CBFdEI3_5L(0 z+lJs=-QE;G4mAufBR2XQZ`d7}pfV+Lo=1`Zl3f$(>@tcL2x0O4F07TMN4vXE{FsM< z%$s6jScOcG-J%)ZnnfNW)J>^FnQn!ZsZD0EEYe)U`El!V`Lp=|Qz4T{!M>VZBz}p^ bPu~DxD7IxoJ}=7G(aPG`g_*oP;r!@-Um<+0 diff --git a/tools_for_ms/services_tools/fairchem_tools.py b/tools_for_ms/services_tools/fairchem_tools.py deleted file mode 100644 index 423ab2a..0000000 --- a/tools_for_ms/services_tools/fairchem_tools.py +++ /dev/null @@ -1,386 +0,0 @@ -# 输入content-> 转换content生成atom(ase能处理的格式)->用matgen生成优化后的结构-再生成对称性cif。 - -from io import StringIO -import sys -import tempfile -from ase.io import read, write -from ase.optimize import FIRE -from ase.filters import FrechetCellFilter -import os - -from .. import llm_tool -os.environ["PYTHONWARNINGS"] = "ignore" - -# 或者更精细的控制 -os.environ["PYTHONWARNINGS"] = "ignore::DeprecationWarning" - -from typing import Optional -import logging -from pymatgen.core.structure import Structure -from .error_handlers import handle_general_error -from pymatgen.symmetry.analyzer import SpacegroupAnalyzer -logger = logging.getLogger(__name__) -from pymatgen.io.cif import CifWriter -from ase.atoms import Atoms -from .Configs import* -calc = None - -# def init_model(): -# """初始化FairChem模型""" -# global calc -# try: -# from fairchem.core import OCPCalculator -# calc = OCPCalculator(checkpoint_path= FAIRCHEM_MODEL_PATH) -# logger.info("FairChem model initialized successfully") -# except Exception as e: -# logger.error(f"Failed to initialize FairChem model: {str(e)}") -# raise -# init_model() -# # 格式转化 -# def convert_structure(input_format: str, content: str) -> Optional[Atoms]: - -# '''example: -# input_format = "xyz" cif vasp 等等 -# content = """5 -# H2O molecule with an extra oxygen and hydrogen -# O 0.0 0.0 0.0 -# H 0.0 0.0 0.9 -# H 0.0 0.9 0.0 -# O 1.0 0.0 0.0 -# H 1.0 0.0 0.9 -# return Atoms(symbols='OH2OH', pbc=False) -# """ -# ''' - -# """将输入内容转换为Atoms对象""" -# try: -# with tempfile.NamedTemporaryFile(suffix=f".{input_format}", mode="w", delete=False) as tmp_file: -# tmp_file.write(content) -# tmp_path = tmp_file.name - -# atoms = read(tmp_path) -# os.unlink(tmp_path) -# return atoms -# except Exception as e: -# logger.error(f"Failed to convert structure: {str(e)}") -# return None - -# def generate_symmetry_cif(structure: Structure) -> str: -# """生成对称性CIF""" -# analyzer = SpacegroupAnalyzer(structure) -# structure = analyzer.get_refined_structure() - -# with tempfile.NamedTemporaryFile(suffix=".cif", mode="w+", delete=False) as tmp_file: -# cif_writer = CifWriter(structure, symprec=0.1, refine_struct=True) -# cif_writer.write_file(tmp_file.name) -# tmp_file.seek(0) -# return tmp_file.read() - - -# def optimize_structure(atoms: Atoms, output_format: str): -# """优化晶体结构""" -# atoms.calc = calc -# try: -# import io -# # from contextlib import redirect_stdout - -# # # 创建StringIO对象捕获输出 -# # f = io.StringIO() -# # dyn = FIRE(FrechetCellFilter(atoms)) - -# # # 同时捕获并输出到控制台 -# # with redirect_stdout(f): -# # dyn.run(fmax=FMAX) -# # # 获取捕获的日志 -# # optimization_log = f.getvalue() - -# temp_output = StringIO() -# # 保存原始的stdout -# original_stdout = sys.stdout -# # 重定向stdout到StringIO对象 -# sys.stdout = temp_output -# dyn = FIRE(FrechetCellFilter(atoms)) -# dyn.run(fmax=FMAX) -# sys.stdout = original_stdout -# output_string = temp_output.getvalue() - -# temp_output.close() -# optimization_log = output_string - - - - - - - -# # 同时输出到控制台 - -# total_energy = atoms.get_potential_energy() - -# except Exception as e: -# return handle_general_error(e) - -# #atoms.get_potential_energy() 函数解析 -# # atoms.get_potential_energy() 是 ASE (Atomic Simulation Environment) 中 Atoms 对象的一个方法,用于获取原子系统的势能(或总能量)。 - -# # 功能与用途 -# # 获取能量 :返回原子系统的计算总能量,通常以电子伏特 (eV) 为单位。 -# # 用途 : -# # 评估结构稳定性(能量越低的结构通常越稳定) -# # 计算反应能垒和反应能 -# # 分析能量随结构变化的趋势 -# # 作为结构优化的目标函数 -# # 计算分子或材料的吸附能、形成能等 -# # 工作原理 -# # 计算引擎依赖 : -# # 该方法不会自行计算能量,而是从附加到 Atoms 对象的计算器 (calculator) 获取能量 -# # 需要先给 Atoms 对象设置一个计算器(如 VASP、Quantum ESPRESSO、GPAW 等) -# # 执行机制 : -# # 如果能量已计算过且原子结构未改变,则返回缓存值 -# # 否则会触发计算器执行能量计算 - -# # 处理对称性 -# if output_format == "cif": -# optimized_structure = Structure.from_ase_atoms(atoms) -# content = generate_symmetry_cif(optimized_structure) -# #print('xxx',content) -# #print('yyy',total_energy) -# # 格式化返回结果 -# format_result = f""" -# The following is the optimized crystal structure information: -# ### Optimization Results (using FIRE(eqV2_86M) algorithm): -# **Total Energy: {total_energy} eV** - -# #### Optimizing Log: -# ```text -# {optimization_log} -# ``` -# ### Optimized {output_format.upper()} Content: -# ```{content} -# {optimized_structure[:300]} -# ``` -# """ -# print("output_log",format_result) - -input_format = "cif" # generated using pymatgen -content = """ -data_H2O -_symmetry_space_group_name_H-M 'P 1' -_cell_length_a 7.60356659 -_cell_length_b 7.60356659 -_cell_length_c 7.14296200 -_cell_angle_alpha 90.00000000 -_cell_angle_beta 90.00000000 -_cell_angle_gamma 120.00000516 -_symmetry_Int_Tables_number 1 -_chemical_formula_structural H2O -_chemical_formula_sum 'H24 O12' -_cell_volume 357.63799926 -_cell_formula_units_Z 12 -loop_ - _symmetry_equiv_pos_site_id - _symmetry_equiv_pos_as_xyz - 1 'x, y, z' -loop_ - _atom_site_type_symbol - _atom_site_label - _atom_site_symmetry_multiplicity - _atom_site_fract_x - _atom_site_fract_y - _atom_site_fract_z - _atom_site_occupancy - H H0 1 0.33082300 0.33082300 0.69642800 1 - H H1 1 0.66917700 0.00000000 0.69642800 1 - H H2 1 0.00000000 0.66917700 0.69642800 1 - H H3 1 0.66917700 0.66917700 0.19642800 1 - H H4 1 0.33082300 0.00000000 0.19642800 1 - H H5 1 0.00000000 0.33082300 0.19642800 1 - H H6 1 0.45234700 0.45234700 0.51064600 1 - H H7 1 0.54765300 0.00000000 0.51064600 1 - H H8 1 0.00000000 0.54765300 0.51064600 1 - H H9 1 0.54765300 0.54765300 0.01064600 1 - H H10 1 0.45234700 0.00000000 0.01064600 1 - H H11 1 0.00000000 0.45234700 0.01064600 1 - H H12 1 0.78617100 0.66371600 0.47884700 1 - H H13 1 0.33628400 0.12245500 0.47884700 1 - H H14 1 0.87754500 0.21382900 0.47884700 1 - H H15 1 0.66371600 0.78617100 0.47884700 1 - H H16 1 0.12245500 0.33628400 0.47884700 1 - H H17 1 0.21382900 0.87754500 0.47884700 1 - H H18 1 0.21382900 0.33628400 0.97884700 1 - H H19 1 0.66371600 0.87754500 0.97884700 1 - H H20 1 0.12245500 0.78617100 0.97884700 1 - H H21 1 0.33628400 0.21382900 0.97884700 1 - H H22 1 0.87754500 0.66371600 0.97884700 1 - H H23 1 0.78617100 0.12245500 0.97884700 1 - O O24 1 0.32664200 0.32664200 0.55565800 1 - O O25 1 0.67335800 0.00000000 0.55565800 1 - O O26 1 0.00000000 0.67335800 0.55565800 1 - O O27 1 0.67335800 0.67335800 0.05565800 1 - O O28 1 0.32664200 0.00000000 0.05565800 1 - O O29 1 0.00000000 0.32664200 0.05565800 1 - O O30 1 0.66060500 0.66060500 0.42957500 1 - O O31 1 0.33939500 0.00000000 0.42957500 1 - O O32 1 0.00000000 0.33939500 0.42957500 1 - O O33 1 0.33939500 0.33939500 0.92957500 1 - O O34 1 0.66060500 0.00000000 0.92957500 1 - O O35 1 0.00000000 0.66060500 0.92957500 1 -""" -# atoms=convert_structure(input_format=input_format,content=content) -# optimize_structure(atoms=atoms,output_format='cif') - -# 添加新的异步LLM工具,包装optimize_structure功能 -import asyncio -from io import StringIO -import sys -import tempfile -from ase.io import read, write -from ase.optimize import FIRE -from ase.filters import FrechetCellFilter -import os -from typing import Optional, Dict, Any -from ase.atoms import Atoms -from pymatgen.core.structure import Structure -from pymatgen.symmetry.analyzer import SpacegroupAnalyzer -from pymatgen.io.cif import CifWriter -import logging - -logger = logging.getLogger(__name__) - -# 初始化FairChem模型 -calc = None - -def init_model(): - """初始化FairChem模型""" - global calc - if calc is not None: - return - - try: - from fairchem.core import OCPCalculator - from tools_for_ms.services_tools.Configs import FAIRCHEM_MODEL_PATH - calc = OCPCalculator(checkpoint_path=FAIRCHEM_MODEL_PATH) - logger.info("FairChem model initialized successfully") - except Exception as e: - logger.error(f"Failed to initialize FairChem model: {str(e)}") - raise - -def convert_structure(input_format: str, content: str) -> Optional[Atoms]: - """将输入内容转换为Atoms对象""" - try: - with tempfile.NamedTemporaryFile(suffix=f".{input_format}", mode="w", delete=False) as tmp_file: - tmp_file.write(content) - tmp_path = tmp_file.name - - atoms = read(tmp_path) - os.unlink(tmp_path) - return atoms - except Exception as e: - logger.error(f"Failed to convert structure: {str(e)}") - return None - -def generate_symmetry_cif(structure: Structure) -> str: - """生成对称性CIF""" - analyzer = SpacegroupAnalyzer(structure) - structure_refined = analyzer.get_refined_structure() - - with tempfile.NamedTemporaryFile(suffix=".cif", mode="w+", delete=False) as tmp_file: - cif_writer = CifWriter(structure_refined, symprec=0.1, refine_struct=True) - cif_writer.write_file(tmp_file.name) - tmp_file.seek(0) - return tmp_file.read() - -def optimize_structure(atoms: Atoms, output_format: str) -> Dict[str, Any]: - """优化晶体结构""" - atoms.calc = calc - - try: - # 捕获优化过程的输出 - temp_output = StringIO() - original_stdout = sys.stdout - sys.stdout = temp_output - - # 执行优化 - from tools_for_ms.services_tools.Configs import FMAX - dyn = FIRE(FrechetCellFilter(atoms)) - dyn.run(fmax=FMAX) - - # 恢复标准输出并获取日志 - sys.stdout = original_stdout - optimization_log = temp_output.getvalue() - temp_output.close() - - # 获取总能量 - total_energy = atoms.get_potential_energy() - - # 处理优化后的结构 - if output_format == "cif": - optimized_structure = Structure.from_ase_atoms(atoms) - content = generate_symmetry_cif(optimized_structure) - else: - with tempfile.NamedTemporaryFile(suffix=f".{output_format}", mode="w+", delete=False) as tmp_file: - write(tmp_file.name, atoms) - tmp_file.seek(0) - content = tmp_file.read() - - # 格式化返回结果 - format_result = f""" -The following is the optimized crystal structure information: -### Optimization Results (using FIRE(eqV2_86M) algorithm): -**Total Energy: {total_energy} eV** - -#### Optimizing Log: -```text -{optimization_log} -``` -### Optimized {output_format.upper()} Content: -``` -{content[:300]} -``` -""" - - # return { - # "total_energy": total_energy, - # "optimization_log": optimization_log, - # "content": content, - # "formatted_result": format_result - # } - return format_result - except Exception as e: - logger.error(f"Failed to optimize structure: {str(e)}") - raise e - -@llm_tool(name="optimize_crystal_structure", - description="Optimize crystal structure using FairChem model") -async def optimize_crystal_structure( - content: str, - input_format: str = "cif", - output_format: str = "cif" -) -> Dict[str, Any]: - """ - Optimize crystal structure using FairChem model. - - Args: - content: Crystal structure content string - input_format: Input format (cif, xyz, vasp) - output_format: Output format (cif, xyz, vasp) - - Returns: - Optimized structure with energy and optimization log - """ - # 确保模型已初始化 - if calc is None: - init_model() - - # 使用asyncio.to_thread异步执行可能阻塞的操作 - def run_optimization(): - # 转换结构 - atoms = convert_structure(input_format, content) - if atoms is None: - raise ValueError(f"无法转换输入的{input_format}格式内容,请检查格式是否正确") - - # 优化结构 - return optimize_structure(atoms, output_format) - - # 直接返回结果或抛出异常 - return await asyncio.to_thread(run_optimization)