ion-CSP 2.0.4__py3-none-any.whl → 2.0.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import csv
2
3
  import shutil
3
4
  import logging
4
5
  import subprocess
@@ -76,15 +77,30 @@ class ReadMlpDensity:
76
77
  os.makedirs(backup_dir, exist_ok=True)
77
78
  for item in os.listdir(self.max_density_dir):
78
79
  shutil.move(os.path.join(self.max_density_dir, item), os.path.join(backup_dir, item))
79
-
80
+ numbers, mlp_densities, mlp_energies = [], [], []
80
81
  os.makedirs(self.max_density_dir, exist_ok=True)
81
82
  for density, CONTCAR_filename in sorted_filename[:n_screen]:
82
83
  # 生成新的包含密度值的文件名,并重命名文件
83
84
  # 密度转换为字符串,保留4位小数
84
85
  density_str = f'{density:.4f}'
86
+ mlp_densities.append(density_str)
85
87
  # 保留 CONTCAR 的序数信息,方便回推检查
86
88
  number = CONTCAR_filename.split("_")[1]
89
+ numbers.append(number)
87
90
  OUTCAR_filename = f'OUTCAR_{number}'
91
+ try:
92
+ with open(f"{self.folder_dir}/OUTCAR_{number}") as mlp_out:
93
+ lines = mlp_out.readlines()
94
+ for line in lines:
95
+ if "TOTEN" in line:
96
+ values = line.split()
97
+ mlp_energy = round(float(values[-2]), 2)
98
+ except FileNotFoundError:
99
+ logging.error(
100
+ f" No avalible MLP OUTCAR_{number} found"
101
+ )
102
+ mlp_energy = False
103
+ mlp_energies.append(mlp_energy)
88
104
  new_CONTCAR_filename = f'CONTCAR_{density_str}_{number}'
89
105
  new_OUTCAR_filename = f'OUTCAR_{density_str}_{number}'
90
106
  shutil.copy(f'{self.folder_dir}/{CONTCAR_filename}', f'{self.max_density_dir}/{new_CONTCAR_filename}')
@@ -92,6 +108,30 @@ class ReadMlpDensity:
92
108
  print(f'New CONTCAR and OUTCAR of {density_str}_{number} are renamed and saved')
93
109
  logging.info(f'New CONTCAR and OUTCAR of {density_str}_{number} are renamed and saved')
94
110
 
111
+ with open(
112
+ f"{self.max_density_dir}/mlp_density_energy.csv",
113
+ "w",
114
+ newline="",
115
+ encoding="utf-8",
116
+ ) as csv_file:
117
+ writer = csv.writer(csv_file)
118
+ header = [
119
+ "Number",
120
+ "MLP_E",
121
+ "MLP_Density",
122
+ ]
123
+ datas = list(
124
+ zip(
125
+ numbers,
126
+ mlp_energies,
127
+ mlp_densities,
128
+ )
129
+ )
130
+ datas.sort(key=lambda x: -float(x[-1]))
131
+ writer.writerow(header)
132
+ for data in datas:
133
+ writer.writerow(data)
134
+
95
135
  def phonopy_processing_max_density(self, specific_directory :str = None):
96
136
  """
97
137
  Use phonopy to check and generate symmetric primitive cells, reducing the complexity of subsequent optimization calculations, and preventing pyxtal.from_random from generating double proportioned supercells.
@@ -127,14 +167,18 @@ class ReadMlpDensity:
127
167
  # 复制对应的OUTCAR文件到primitive_cell目录下
128
168
  density_number = new_CONTCAR_filename.split("CONTCAR_")[1]
129
169
  new_OUTCAR_filename = f'OUTCAR_{density_number}'
130
- shutil.copy(f'{self.max_density_dir}/{new_OUTCAR_filename}', f'{self.primitive_cell_dir}/{new_OUTCAR_filename}')
170
+ shutil.copy(f'{self.phonopy_dir}/{new_OUTCAR_filename}', f'{self.primitive_cell_dir}/{new_OUTCAR_filename}')
171
+ shutil.copy(
172
+ f"{self.phonopy_dir}/mlp_density_energy.csv",
173
+ f"{self.primitive_cell_dir}/mlp_density_energy.csv",
174
+ )
131
175
  for_vasp_opt_dir = os.path.join(self.base_dir, '3_for_vasp_opt')
132
176
  if os.path.exists(for_vasp_opt_dir):
133
177
  shutil.rmtree(for_vasp_opt_dir)
134
178
  shutil.copytree(self.primitive_cell_dir, for_vasp_opt_dir)
135
179
  logging.info('The phonopy processing has been completed!!\nThe symmetrized primitive cells have been saved in POSCAR format to the primitive_cell folder.\nThe output content of phonopy has been saved to the phonopy.log file in the same directory.')
136
180
  # 在 phonopy 成功进行对称化处理后,删除 2_mlp_optimized/max_density 文件夹以节省空间
137
- shutil.rmtree(self.max_density_dir)
181
+ shutil.rmtree(self.phonopy_dir)
138
182
  except FileNotFoundError:
139
183
  logging.error(
140
184
  "There are no CONTCAR structure files after screening.\nPlease check if the ions correspond to the crystals and adjust the screening criteria"
ion_CSP/task_manager.py CHANGED
@@ -125,7 +125,7 @@ class TaskManager:
125
125
  def _display_tasks(self, tasks, total, current_page, total_pages, function):
126
126
  """标准化任务显示 - Standardized tasks display"""
127
127
  display = "logs" if function == "view" else "tasks"
128
- print(f"\033cPage {current_page}/{total_pages} ({total} {display})")
128
+ print(f"\033cPage {current_page}/{total_pages} ({total} {display})\n")
129
129
  if function == "kill":
130
130
  for i, task in enumerate(tasks, 1):
131
131
  print(
@@ -138,11 +138,11 @@ class TaskManager:
138
138
  )
139
139
  else:
140
140
  raise ValueError(f"Not supported function {function}. Available function: 'view' and 'kill' ")
141
- print("\nPage {} of {}".format(current_page, total_pages))
142
141
  # 分页控制
143
142
  print("\nOptions:")
144
143
  if function == "view":
145
144
  print("n) Next page | p) Previous page | f) Filter | q) Quit")
145
+ print("Enter number to view log in detail")
146
146
  elif function == "kill":
147
147
  print("n) Next page | p) Previous page | f) Filter | k) Kill | q) Quit")
148
148
  else:
@@ -171,10 +171,11 @@ class TaskManager:
171
171
  elif function == "kill" and choice == "K":
172
172
  try:
173
173
  task_num = input("Enter task number to kill: ").strip()
174
- if not task_num.isdigit():
174
+ if task_num.isdigit() and 1 <= int(task_num) <= 10:
175
+ # 计算全局任务索引
176
+ global_index = current_page * 10 + (int(task_num) - 1)
177
+ else:
175
178
  raise ValueError
176
- # 计算全局任务索引
177
- global_index = current_page * 10 + (int(task_num) - 1)
178
179
  if 0 <= global_index < len(tasks):
179
180
  selected_index = global_index
180
181
  confirm = input(
@@ -189,10 +190,10 @@ class TaskManager:
189
190
  else:
190
191
  print("Invalid task number")
191
192
  input("\nPress Enter to continue...")
192
- except ValueError:
193
+ except (ValueError, TypeError):
193
194
  print("Please enter a valid number")
194
195
  input("\nPress Enter to continue...")
195
- elif function == "view" and choice.isdigit():
196
+ elif function == "view" and choice.isdigit() and 1<= int(choice) <=10:
196
197
  # 计算全局任务索引
197
198
  global_index = current_page * 10 + (int(choice) - 1)
198
199
  if 0 <= global_index < len(tasks):
@@ -255,6 +256,8 @@ class TaskManager:
255
256
  os.remove(std_log)
256
257
  std_log.symlink_to(output_log)
257
258
 
259
+ print('Starting task ......')
260
+ time.sleep(6)
258
261
  logging.info(f"Started {module} module (PID: {process.pid})")
259
262
  print(f"Task started (PID: {process.pid})")
260
263
  print(f"Normalized log file: {std_log}")
@@ -366,7 +369,7 @@ class TaskManager:
366
369
  print("q) Exit")
367
370
  print("=" * 50)
368
371
 
369
- choice = input("Please enter operation: ").strip().lower()
372
+ choice = input("Please select an operation: ").strip().lower()
370
373
  if choice == "1":
371
374
  work_dir = input("Enter EE working directory: ").strip()
372
375
  self.task_runner("EE", work_dir)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ion_CSP
3
- Version: 2.0.4
3
+ Version: 2.0.8
4
4
  Summary: Crystal Structure Design Software Based on Molecular/Ionic Configuration.
5
5
  Home-page: https://github.com/bagabaga007/ion_CSP
6
6
  Author: Ze Yang
@@ -67,7 +67,7 @@ Dynamic: requires-python
67
67
  | paramiko | 3.5.1 |
68
68
  | pyxtal | 1.0.4 |
69
69
  | phonopy | 2.28.0 |
70
- | rdkit | 2023.03.3|
70
+ | rdkit | 2024.03.3|
71
71
 
72
72
  ### 安装步骤
73
73
  ```bash
@@ -172,7 +172,7 @@ This software enables efficient crystal structure screening from molecular/ion c
172
172
  | paramiko | 3.5.1 |
173
173
  | pyxtal | 1.0.4 |
174
174
  | phonopy | 2.28.0 |
175
- | rdkit | 2023.03.3|
175
+ | rdkit | 2024.03.3|
176
176
 
177
177
  ### Installation Steps
178
178
  ```bash
@@ -6,14 +6,14 @@ ion_CSP/gen_opt.py,sha256=aVZmf2RqePCwZShgpNvzqfntNAW0I0yctWHGXoe3mgw,19463
6
6
  ion_CSP/identify_molecules.py,sha256=hFKXS0Jjd7LyMsYGc9RmnoRPu1ibXF9fYO_9lR3wTfo,4634
7
7
  ion_CSP/log_and_time.py,sha256=6RKegXF8Gc1HqzAbE-PT9ejX3Ncyuz3v3FivujJt8to,9072
8
8
  ion_CSP/mlp_opt.py,sha256=ox4Qxg4D6WzrB8dxVnUWmAngnOA_wdcInP5UhBWsH4c,5535
9
- ion_CSP/read_mlp_density.py,sha256=ktGNHYWLi4VrdJK_Hg2ac2-JM2QlVt9iymLxdixkLb8,9663
9
+ ion_CSP/read_mlp_density.py,sha256=TinsFGJPF0TPVZKMCzPyxuHBGrdeqw7yOnGh-78qbqo,11209
10
10
  ion_CSP/steps_opt_monitor.sh,sha256=1klPjnK0gqkDbvI9PtjdK5qidJ5G0Mo8q1SfrlLW5xM,3330
11
- ion_CSP/task_manager.py,sha256=PGtlvlJb7uzb1YcJyhP7cURQqOO4nNM-VacyZwVXixs,16088
11
+ ion_CSP/task_manager.py,sha256=S0QK7EJhKrQL1hzMqkR6a6y3Du027Ppyz-zHenWrFQ4,16241
12
12
  ion_CSP/upload_download.py,sha256=Hiz5jKOy9x26hJJdcpt-owQdVUbzzGuGOelro6JozY8,23801
13
13
  ion_CSP/vasp_processing.py,sha256=eQTMKIPBzi1X4HHTqWkHE1Lt8dvCCV-MXPCR3RtKYZ0,13977
14
- ion_csp-2.0.4.dist-info/licenses/LICENSE,sha256=2J6A8GT2iIf2LhuWO1_0ilgx7ijzzpQ2BXU7rHKe8Cc,1068
15
- ion_csp-2.0.4.dist-info/METADATA,sha256=r9ijfq_Yo5mTqMnCzNT9vYVF-FDSxN9bkHtU99FDdUw,6380
16
- ion_csp-2.0.4.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
17
- ion_csp-2.0.4.dist-info/entry_points.txt,sha256=NexQJDs9f69kJA2DgoU6tsA3V8a66nadJRem1U_c_6g,54
18
- ion_csp-2.0.4.dist-info/top_level.txt,sha256=aYZa43dDebjLpWPN6bDIlBb6BVwA8gk4ajEjDDK9b9I,8
19
- ion_csp-2.0.4.dist-info/RECORD,,
14
+ ion_csp-2.0.8.dist-info/licenses/LICENSE,sha256=2J6A8GT2iIf2LhuWO1_0ilgx7ijzzpQ2BXU7rHKe8Cc,1068
15
+ ion_csp-2.0.8.dist-info/METADATA,sha256=pZg7XM0CD5Du6rQJvijc_VOyfvtFVlnmWAZiwBPmeIU,6380
16
+ ion_csp-2.0.8.dist-info/WHEEL,sha256=QZxptf4Y1BKFRCEDxD4h2V0mBFQOVFLFEpvxHmIs52A,91
17
+ ion_csp-2.0.8.dist-info/entry_points.txt,sha256=NexQJDs9f69kJA2DgoU6tsA3V8a66nadJRem1U_c_6g,54
18
+ ion_csp-2.0.8.dist-info/top_level.txt,sha256=aYZa43dDebjLpWPN6bDIlBb6BVwA8gk4ajEjDDK9b9I,8
19
+ ion_csp-2.0.8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5