66import glob
77import shutil
88import json
9+ import csv
10+ import unittest
911from typing import List , Dict , Optional , Any
10-
1112from pathlib import Path
1213
1314import numpy as np
14- import unittest
15+ from pymatgen . core . periodic_table import Element
1516
1617from abacustest .lib_prepare .abacus import ReadInput , WriteInput , AbacusStru
1718from abacustest .lib_model .comm import check_abacus_inputs
@@ -204,7 +205,14 @@ def calculate_bader_charge_from_cube(
204205 fcube (list|str): List of cube files or a single cube file path.
205206
206207 Returns:
207- list: A list of Bader charges.
208+ dict: A dictionary containing:
209+ - atom_labels: List of atom labels.
210+ - net_bader_charges: List of net charge for each atom. Core charge is included.
211+ - number_of_electrons: List of number of electrons around each atom. Core charge is not included.
212+ - core_charge: List of core charge for each atom.
213+ - work_path: Absolute path to the work directory.
214+ - cube_file: Absolute path to the cube file used in this tool.
215+ - charge_results_json: Absolute path to the JSON file containing detailed Bader charge results
208216 """
209217 if not isinstance (fcube , (list , tuple )):
210218 fcube = [fcube ]
@@ -231,19 +239,22 @@ def calculate_bader_charge_from_cube(
231239 bader_charges = read_bader_acf (Path (work_path ) / 'ACF.dat' )
232240 cube_data = read_gaussian_cube (merged_cube_file )
233241 net_bader_charges = (np .array (cube_data ["chg" ]) - np .array (bader_charges )).tolist ()
242+ atom_labels = [Element .from_Z (i ).symbol for i in cube_data ['atomz' ]]
234243
235244 bader_charge_json = Path ("./bader_charge_results.json" ).absolute ()
236245 with open (bader_charge_json , "w" ) as fout :
237246 json .dump ({
238247 "number_of_electrons" : bader_charges ,
239248 "core_charge" : cube_data ["chg" ],
240- "net_charges" : net_bader_charges
249+ "net_bader_charges" : net_bader_charges ,
250+ "atom_labels" : atom_labels
241251 }, fout )
242252
243253 return {
254+ "atom_labels" : atom_labels ,
255+ "net_bader_charges" : net_bader_charges ,
244256 "number_of_electrons" : bader_charges ,
245257 "core_charge" : cube_data ["chg" ],
246- "net_charges" : net_bader_charges ,
247258 "work_path" : Path (work_path ).absolute (),
248259 "cube_file" : Path (merged_cube_file ).absolute (),
249260 "charge_results_json" : bader_charge_json .absolute (),
@@ -264,11 +275,12 @@ def abacus_badercharge_run(
264275 Returns:
265276 dict: A dictionary containing:
266277 - net_bader_charges: List of net Bader charge for each atom. Core charge is included.
267- - bader_charges : List of Bader charge for each atom. The value represents the number of valence electrons for each atom, and core charge is not included.
268- - atom_core_charges : List of core charge for each atom.
278+ - number_of_electrons : List of number of electrons around each atom. Core charge is not included.
279+ - core_charges : List of core charge for each atom.
269280 - atom_labels: Labels of atoms in the structure.
270281 - abacus_workpath: Absolute path to the ABACUS work directory.
271282 - badercharge_run_workpath: Absolute path to the Bader analysis work directory.
283+ - bader_result_csv: Absolute path to the CSV file containing detailed Bader charge results
272284 """
273285 try :
274286 is_valid , msg = check_abacus_inputs (abacus_inputs_dir )
@@ -289,13 +301,23 @@ def abacus_badercharge_run(
289301 # Postprocess the charge density to obtain Bader charges
290302 bader_results = calculate_bader_charge_from_cube (fcube )
291303
304+ # Write necessary results to csv file
305+ bader_result_csv = Path ("./bader_charge_results.csv" ).absolute ()
306+
307+ with open (bader_result_csv , "w" ) as fout :
308+ writer = csv .writer (fout )
309+ writer .writerow (['atom_label' , 'net_bader_charge' ])
310+ for label , charge in zip (bader_results ["atom_labels" ], bader_results ["net_bader_charges" ]):
311+ writer .writerow ([label , f"{ charge : .6f} " ])
312+
292313 return {
293- "net_charges " : bader_results ["net_charges " ],
314+ "net_bader_charges " : bader_results ["net_bader_charges " ],
294315 "number_of_electrons" : bader_results ["number_of_electrons" ],
295316 "core_charges" : bader_results ["core_charge" ],
296- "atom_labels" : atom_labels ,
317+ "atom_labels" : atom_labels , # Use atom labels from ABACUS STRU file, not from cube file
297318 "abacus_workpath" : Path (abacus_jobpath ).absolute (),
298319 "badercharge_run_workpath" : Path (bader_results ["work_path" ]).absolute (),
320+ "bader_result_csv" : Path (bader_result_csv ).absolute ()
299321 }
300322 except Exception as e :
301323 return {"message" : f"Calculating Bader charge failed: { e } " }
0 commit comments