yu-mcal 0.1.4__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.
@@ -0,0 +1,91 @@
1
+ """Gaussian log file reader (2025/06/21)"""
2
+ import os
3
+ from pathlib import Path
4
+
5
+
6
+ def check_normal_termination(log_file: str) -> bool:
7
+ """Check if the calculation terminated normally.
8
+
9
+ Parameters
10
+ ----------
11
+ log_file : str
12
+ Path to the log file
13
+
14
+ Returns
15
+ -------
16
+ bool
17
+ True if the calculation terminated normally, False otherwise
18
+ """
19
+ if not Path(log_file).exists():
20
+ return False
21
+
22
+ with FileReader(log_file) as f:
23
+ line = f.reversed_readline()
24
+ if 'Normal termination' in line:
25
+ return True
26
+ else:
27
+ return False
28
+
29
+
30
+ class FileReader:
31
+ """File reader that reads line by line from the end.
32
+
33
+ Examples
34
+ --------
35
+ >>> with FileReader('sample.txt') as f:
36
+ ... while True:
37
+ ... line = f.reversed_readline()
38
+ ... if not line:
39
+ ... break
40
+ ... print(line)
41
+ """
42
+ def __init__(self, file_path, buffer_size=8192):
43
+ self.buffer_size = buffer_size
44
+ self.file = open(file_path, 'rb')
45
+ # ファイルポインタをファイルの末尾に移動
46
+ self.file.seek(0, os.SEEK_END)
47
+ self.file_size = self.file.tell()
48
+ # 最後のブロックの終了位置をファイルサイズに設定
49
+ self.reversed_block_end = self.file_size
50
+ # 最後のブロックの開始位置を計算(ファイル末尾からバッファサイズ分前、またはファイル先頭)
51
+ self.reversed_block_start = max(0, self.reversed_block_end - self.buffer_size)
52
+ self.lines = []
53
+
54
+ def __enter__(self):
55
+ return self
56
+
57
+ def __exit__(self, exc_type, exc_value, traceback):
58
+ self.close()
59
+
60
+ def close(self):
61
+ self.file.close()
62
+
63
+ def reversed_readline(self):
64
+ if not self.lines and self.reversed_block_end - self.reversed_block_start != 0:
65
+ # ファイルポインタを現在のブロックの開始位置に設定
66
+ self.file.seek(self.reversed_block_start)
67
+
68
+ block = self.file.read(self.reversed_block_end - self.reversed_block_start)
69
+ lines = block.splitlines(keepends=True)
70
+
71
+ # 現在のブロックがファイルの最初のブロックの場合
72
+ if self.reversed_block_start == 0:
73
+ # ブロックの終了位置を開始位置に設定して次の読み取りを防ぐ
74
+ self.reversed_block_end = self.reversed_block_start
75
+ else:
76
+ # 次のブロックの終了位置を更新(現在のブロックの最初の行の長さを加算)
77
+ self.reversed_block_end = max(0, self.reversed_block_start + len(lines[0]))
78
+
79
+ self.reversed_block_start = max(0, self.reversed_block_end - self.buffer_size)
80
+
81
+ # 末尾のブロックの場合、全行を読み取る
82
+ if self.reversed_block_end == 0:
83
+ self.lines = lines
84
+ else:
85
+ self.lines = lines[1:]
86
+
87
+ return self.lines.pop().decode('utf-8')
88
+ elif self.lines:
89
+ return self.lines.pop().decode('utf-8')
90
+ else:
91
+ return None
@@ -0,0 +1,267 @@
1
+ """ GjfMaker beta (2025/08/18)"""
2
+ import os
3
+ import warnings
4
+ from pathlib import Path
5
+ from typing import List, Optional, Tuple
6
+
7
+ import pandas as pd
8
+
9
+
10
+ class GjfMaker:
11
+ parent_dir = Path(os.path.abspath(__file__)).parent.parent
12
+ ELEMENT_PROP = pd.read_csv(f'{parent_dir}/constants/element_properties.csv')
13
+ ELEMENTS_NUM = ELEMENT_PROP[['symbol', 'number']].set_index('symbol').to_dict()['number']
14
+
15
+ def __init__(self, remove_radical_flag: bool = False) -> None:
16
+ """Initialize the GjfMaker class.
17
+
18
+ Parameters
19
+ ----------
20
+ remove_radical_flag : bool
21
+ If True, the radical is removed, by default False.
22
+ Not recommended to use this flag.
23
+ """
24
+ self.remove_radical_flag = remove_radical_flag
25
+
26
+ self._link_dict = {}
27
+ self._link_num = 0
28
+ self._cpu_num = '%NProcShared=9\n'
29
+ self._mem_num = '%Mem=40GB\n'
30
+ self._is_chk_file = False
31
+ self._is_rwf_file = False
32
+ self.is_detail = False
33
+ self._function = '# B3LYP/6-31G(d,p)\n'
34
+ self._root = []
35
+ self._title = '\nDefalut Title\n'
36
+ self._symbols = []
37
+ self._charge_spin = ''
38
+ self._coordinates = []
39
+
40
+ self._root_space = ' '
41
+
42
+ def add_link(self) -> None:
43
+ """Add the link of the gjf file."""
44
+ self.create_chk_file()
45
+ self._link_dict[self._link_num] = [self._cpu_num, self._mem_num, self._function, self._root]
46
+ self._link_num += 1
47
+ self._root = ['Geom=AllCheck\n', 'Guess=Read\n']
48
+
49
+ def add_root(self, root: str) -> None:
50
+ """Add the root of the gjf file."""
51
+ if root[0] == '#':
52
+ root = root[1:]
53
+ self._root.append(root + '\n')
54
+
55
+ def create_chk_file(self) -> None:
56
+ """Create the chk file."""
57
+ self._is_chk_file = True
58
+
59
+ def create_rwf_file(self) -> None:
60
+ """Create the rwf file."""
61
+ self._is_rwf_file = True
62
+
63
+ def export_gjf(
64
+ self,
65
+ file_name: str,
66
+ save_dir: str = '.',
67
+ chk_rwf_name: Optional[str] = None
68
+ ) -> None:
69
+ """Export the gjf file.
70
+
71
+ Parameters
72
+ ----------
73
+ file_name : str
74
+ Name of the gjf file.
75
+ save_dir : str
76
+ Directory to save the gjf file.
77
+ chk_rwf_name : Optional[str]
78
+ Name of the chk or rwf file.
79
+ """
80
+ if self.remove_radical_flag and self._check_radical():
81
+ print('This molecule is radical')
82
+ return
83
+
84
+ os.makedirs(save_dir, exist_ok=True)
85
+
86
+ self._link_dict[self._link_num] = [self._cpu_num, self._mem_num, self._function, self._root]
87
+
88
+ if self._is_chk_file:
89
+ if chk_rwf_name:
90
+ self._chk_file = f'%Chk={chk_rwf_name}.chk\n'
91
+ else:
92
+ self._chk_file = f'%Chk={save_dir}/{file_name}.chk\n'
93
+ else:
94
+ self._chk_file = ''
95
+
96
+ if self._is_rwf_file:
97
+ if chk_rwf_name:
98
+ self._rwf_file = f'%RWF={chk_rwf_name}.rwf\n'
99
+ else:
100
+ self._rwf_file = f'%RWF={save_dir}/{file_name}.rwf\n'
101
+ else:
102
+ self._rwf_file = ''
103
+
104
+ with open(f'{save_dir}/{file_name}.gjf', 'w') as f:
105
+ for i in range(self._link_num+1):
106
+ _cpn_num, _mem_num, _function, _root = self._link_dict[i]
107
+ if i > 0:
108
+ f.write(f'\n--Link{i}--\n')
109
+ f.write(_cpn_num)
110
+ f.write(_mem_num)
111
+ f.write(self._chk_file)
112
+ f.write(self._rwf_file)
113
+ f.write(_function)
114
+ for r in _root:
115
+ f.write(f'#{self._root_space}{r}')
116
+
117
+ if i == 0:
118
+ f.write(self._title)
119
+
120
+ if not self._charge_spin:
121
+ self._check_charge_spin()
122
+ f.write(self._charge_spin)
123
+
124
+ for sym, (x, y, z) in zip(self._symbols, self._coordinates):
125
+ x = f'{x:.8f}'.rjust(14, ' ')
126
+ y = f'{y:.8f}'.rjust(14, ' ')
127
+ z = f'{z:.8f}'.rjust(14, ' ')
128
+ f.write(f' {sym} {x} {y} {z}\n')
129
+ f.write('\n')
130
+
131
+ def opt(self, tight: bool = True) -> None:
132
+ """Set the optimization option of the gjf file.
133
+
134
+ Parameters
135
+ ----------
136
+ tight : bool
137
+ If True, the optimization is tight, by default True.
138
+ """
139
+ opt = 'Opt'
140
+ if tight:
141
+ opt = 'Opt=Tight'
142
+ self.add_root(opt)
143
+
144
+ def output_detail(self) -> None:
145
+ """Output the detail to log file."""
146
+ self.is_detail = True
147
+ _, function = self._function.split()
148
+ self._function = f'#P {function}\n'
149
+ self._root_space = ' '
150
+
151
+ def reset_variable(self) -> None:
152
+ """Reset the variables of the gjf file."""
153
+ self._root = []
154
+ self._symbols = []
155
+ self._coordinates = []
156
+ self._link_dict = {}
157
+ self._link_num = 0
158
+
159
+ def set_charge_spin(self, charge: int, spin: int) -> None:
160
+ """Set the charge and spin of the molecule.
161
+
162
+ Parameters
163
+ ----------
164
+ charge : int
165
+ Charge of the molecule.
166
+ spin : int
167
+ Spin of the molecule.
168
+ """
169
+ self._charge_spin = f'\n{charge} {spin}\n'
170
+
171
+ def set_coordinates(self, coordinates: List[Tuple[float, float, float]]) -> None:
172
+ """Set the coordinates of the molecule.
173
+
174
+ Parameters
175
+ ----------
176
+ coordinates : List[Tuple[float, float, float]]
177
+ Coordinates of the molecule.
178
+ """
179
+ self._coordinates.extend(coordinates)
180
+
181
+ def set_function(self, function: str) -> None:
182
+ """Set the function of the gjf file.
183
+
184
+ Parameters
185
+ ----------
186
+ function : str
187
+ Function of the gjf file.
188
+ """
189
+ detail = ''
190
+ if self.is_detail:
191
+ detail = 'P'
192
+
193
+ self._function = f'#{detail} {function}\n'
194
+
195
+ def set_resource(self, cpu_num: int, mem_num: int, mem_unit: str = 'GB') -> None:
196
+ """Set the number of cpu and memory.
197
+
198
+ Parameters
199
+ ----------
200
+ cpu_num : int
201
+ Number of cpu.
202
+ mem_num : int
203
+ Number of memory.
204
+ mem_unit : str
205
+ Unit of memory, by default 'GB'.
206
+ """
207
+ self._cpu_num = f'%NProcShared={cpu_num}\n'
208
+ self._mem_num = f'%Mem={mem_num}{mem_unit}\n'
209
+
210
+ def set_symbols(self, symbols: List[str]) -> None:
211
+ """Set the symbols of the molecule.
212
+
213
+ Parameters
214
+ ----------
215
+ symbols : List[str]
216
+ Symbols of the molecule.
217
+ """
218
+ self._symbols.extend(symbols)
219
+
220
+ def set_title(self, title: str) -> None:
221
+ """Set the title of the gjf file.
222
+
223
+ Parameters
224
+ ----------
225
+ title : str
226
+ Title of the gjf file.
227
+ """
228
+ self._title = f'\n{title}\n'
229
+
230
+ def _check_charge_spin(self) -> None:
231
+ """Check the charge and spin of the molecule."""
232
+ elements = 0
233
+
234
+ if not self._symbols:
235
+ self._charge_spin = ''
236
+ return
237
+
238
+ for symbol in self._symbols:
239
+ elements += self.ELEMENTS_NUM[symbol]
240
+
241
+ if elements % 2 == 0:
242
+ self._charge_spin = '\n0 1\n'
243
+ else:
244
+ self._charge_spin = '\n0 2\n'
245
+
246
+ def _check_radical(self) -> bool:
247
+ """Check if the molecule is radical.
248
+
249
+ Returns
250
+ -------
251
+ bool
252
+ True if the molecule is radical, False otherwise.
253
+
254
+ Warnings
255
+ --------
256
+ This radical check is incomplete. If the number of unpaired electrons is even, it is not considered a radical.
257
+ """
258
+ # FIXME: This radical check is incomplete. If the number of unpaired electrons is even, it is not considered a radical.
259
+ warnings.warn('This radical check is incomplete. If the number of unpaired electrons is even, it is not considered a radical.')
260
+ elements = 0
261
+ for symbol in self._symbols:
262
+ elements += self.ELEMENTS_NUM[symbol]
263
+
264
+ if elements % 2 == 0:
265
+ return False
266
+ else:
267
+ return True
@@ -0,0 +1,263 @@
1
+ Metadata-Version: 2.4
2
+ Name: yu-mcal
3
+ Version: 0.1.4
4
+ Summary: Program for the calculation of mobility tensor for organic semiconductor crystals
5
+ Author: Koki Ozawa
6
+ Author-email: Hiroyuki Matsui <h-matsui@yz.yamagata-u.ac.jp>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2025 Hiroyuki Matsui
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+ License-File: LICENSE
29
+ Keywords: mobility,mobility tensor,organic semiconductor,reorganization energy,transfer integral
30
+ Classifier: Development Status :: 4 - Beta
31
+ Classifier: Intended Audience :: Education
32
+ Classifier: Intended Audience :: Science/Research
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Programming Language :: Python :: 3.9
35
+ Classifier: Programming Language :: Python :: 3.10
36
+ Classifier: Programming Language :: Python :: 3.11
37
+ Classifier: Programming Language :: Python :: 3.12
38
+ Classifier: Programming Language :: Python :: 3.13
39
+ Classifier: Topic :: Scientific/Engineering
40
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
41
+ Classifier: Topic :: Scientific/Engineering :: Physics
42
+ Requires-Python: >=3.9
43
+ Requires-Dist: numpy>=2.0.2
44
+ Requires-Dist: pandas>=2.3.3
45
+ Requires-Dist: yu-tcal==3.1.0
46
+ Description-Content-Type: text/markdown
47
+
48
+ # mcal: Program for the calculation of mobility tensor for organic semiconductor crystals
49
+ [![Python](https://img.shields.io/badge/python-3.9%20or%20newer-blue)](https://www.python.org)
50
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
51
+ [![docs](https://img.shields.io/badge/docs-here-11419572)](https://matsui-lab-yamagata.github.io/mcal/)
52
+
53
+ # Overview
54
+ `mcal.py` is a tool for calculating mobility tensors of organic semiconductors. It calculates transfer integrals and reorganization energy from crystal structures, and determines mobility tensors considering anisotropy and path continuity.
55
+
56
+ # Requirements
57
+ * Python 3.9 or newer
58
+ * NumPy
59
+ * Pandas
60
+ * yu-tcal==3.1.0
61
+ * Gaussian 09 or 16
62
+
63
+ # Important notice
64
+ * The path of the Gaussian must be set.
65
+
66
+ # Installation
67
+ ```bash
68
+ pip install yu-mcal
69
+ ```
70
+
71
+
72
+ ## Verify Installation
73
+
74
+ After installation, you can verify by running:
75
+
76
+ ```bash
77
+ mcal --help
78
+ ```
79
+
80
+ # mcal Usage Manual
81
+
82
+ ## Basic Usage
83
+
84
+ ```bash
85
+ mcal <cif_filename or pkl_filenname> <osc_type> [options]
86
+ ```
87
+
88
+ ### Required Arguments
89
+
90
+ - `cif_filename`: Path to the CIF file
91
+ - `pkl_filename`: Path to the pickle file
92
+ - `osc_type`: Organic semiconductor type
93
+ - `p`: p-type semiconductor (uses HOMO level)
94
+ - `n`: n-type semiconductor (uses LUMO level)
95
+
96
+ ### Basic Examples
97
+
98
+ ```bash
99
+ # Calculate as p-type semiconductor
100
+ mcal xxx.cif p
101
+
102
+ # Calculate as n-type semiconductor
103
+ mcal xxx.cif n
104
+ ```
105
+
106
+ ## Options
107
+
108
+ ### Calculation Settings
109
+
110
+ #### `-M, --method <method>`
111
+ Specify the calculation method used in Gaussian calculations.
112
+ - **Default**: `B3LYP/6-31G(d,p)`
113
+ - **Example**: `mcal xxx.cif p -M "B3LYP/6-31G(d)"`
114
+
115
+ #### `-c, --cpu <number>`
116
+ Specify the number of CPUs to use.
117
+ - **Default**: `4`
118
+ - **Example**: `mcal xxx.cif p -c 8`
119
+
120
+ #### `-m, --mem <memory>`
121
+ Specify the amount of memory in GB.
122
+ - **Default**: `10`
123
+ - **Example**: `mcal xxx.cif p -m 16`
124
+
125
+ #### `-g, --g09`
126
+ Use Gaussian 09 (default is Gaussian 16).
127
+ - **Example**: `mcal xxx.cif p -g`
128
+
129
+ ### Calculation Control
130
+
131
+ #### `-r, --read`
132
+ Read results from existing log files without executing Gaussian.
133
+ - **Example**: `mcal xxx.cif p -r`
134
+
135
+ #### `-rp, --read_pickle`
136
+ Read results from existing pickle file without executing calculations.
137
+ - **Example**: `mcal xxx_result.pkl p -rp`
138
+
139
+ #### `--resume`
140
+ Resume calculation using existing results if log files terminated normally.
141
+ - **Example**: `mcal xxx.cif p --resume`
142
+
143
+ #### `--fullcal`
144
+ Disable speedup processing using moment of inertia and distance between centers of weight, and calculate transfer integrals for all pairs.
145
+ - **Example**: `mcal xxx.cif p --fullcal`
146
+
147
+ #### `--cellsize <number>`
148
+ Specify the number of unit cells to expand in each direction around the central unit cell for transfer integral calculations.
149
+ - **Default**: `2` (creates 5×5×5 supercell)
150
+ - **Examples**:
151
+ - `mcal xxx.cif p --cellsize 1` (creates 3×3×3 supercell)
152
+ - `mcal xxx.cif p --cellsize 3` (creates 7×7×7 supercell)
153
+
154
+ ### Output Settings
155
+
156
+ #### `-p, --pickle`
157
+ Save calculation results to a pickle file.
158
+ - **Example**: `mcal xxx.cif p -p`
159
+
160
+ ### Diffusion Coefficient Calculation Methods
161
+
162
+ #### `--mc`
163
+ Calculate diffusion coefficient tensor using kinetic Monte Carlo method.
164
+ - **Example**: `mcal xxx.cif p --mc`
165
+
166
+ #### `--ode`
167
+ Calculate diffusion coefficient tensor using Ordinary Differential Equation method.
168
+ - **Example**: `mcal xxx.cif p --ode`
169
+
170
+ ## Practical Usage Examples
171
+
172
+ ### Basic Calculations
173
+ ```bash
174
+ # Calculate mobility of p-type xxx
175
+ mcal xxx.cif p
176
+
177
+ # Use 8 CPUs and 16GB memory
178
+ mcal xxx.cif p -c 8 -m 16
179
+ ```
180
+
181
+ ### High-Precision Calculations
182
+ ```bash
183
+ # Calculate transfer integrals for all pairs (high precision, time-consuming)
184
+ mcal xxx.cif p --fullcal
185
+
186
+ # Use larger supercell to widen transfer integral calculation range
187
+ mcal xxx.cif p --cellsize 3
188
+
189
+ # Use different basis set
190
+ mcal xxx.cif p -M "B3LYP/6-311G(d,p)"
191
+ ```
192
+
193
+ ### Reusing Results
194
+ ```bash
195
+ # Read from existing calculation results
196
+ mcal xxx.cif p -r
197
+
198
+ # Read from existing pickle file
199
+ mcal xxx_result.pkl p -rp
200
+
201
+ # Resume interrupted calculation
202
+ mcal xxx.cif p --resume
203
+
204
+ # Save results to pickle file
205
+ mcal xxx.cif p -p
206
+ ```
207
+
208
+ ### Comparing Diffusion Coefficients
209
+ ```bash
210
+ # Compare with normal calculation + kinetic Monte Carlo + ODE methods
211
+ mcal xxx.cif p --mc --ode
212
+ ```
213
+
214
+ ## Output
215
+
216
+ ### Standard Output
217
+ - Reorganization energy
218
+ - Transfer integrals for each pair
219
+ - Diffusion coefficient tensor
220
+ - Mobility tensor
221
+ - Eigenvalues and eigenvectors of mobility
222
+
223
+ ## Notes
224
+
225
+ 1. **Calculation Time**: Calculation time varies significantly depending on the number of molecules and cell size
226
+ 2. **Memory Usage**: Ensure sufficient memory for large systems
227
+ 3. **Gaussian Installation**: Gaussian 09 or Gaussian 16 is required
228
+ 4. **Dependencies**: Make sure all required Python libraries are installed
229
+
230
+ ## Troubleshooting
231
+
232
+ ### If calculation stops midway
233
+ ```bash
234
+ # Resume with --resume option
235
+ mcal xxx.cif p --resume
236
+ ```
237
+
238
+ ### Memory shortage error
239
+ ```bash
240
+ # Increase memory amount
241
+ mcal xxx.cif p -m 32
242
+ ```
243
+
244
+ ### To reduce calculation time
245
+ ```bash
246
+ # Enable speedup processing (default)
247
+ mcal xxx.cif p
248
+
249
+ # Use smaller supercell for faster calculation
250
+ mcal xxx.cif p --cellsize 1
251
+
252
+ # Increase number of CPUs
253
+ mcal xxx.cif p -c 16
254
+ ```
255
+
256
+ # Authors
257
+ [Matsui Laboratory, Research Center for Organic Electronics (ROEL), Yamagata University](https://matsui-lab.yz.yamagata-u.ac.jp/index-e.html)
258
+ Hiroyuki Matsui, Koki Ozawa
259
+ Email: h-matsui[at]yz.yamagata-u.ac.jp
260
+ Please replace [at] with @
261
+
262
+ # Acknowledgements
263
+ This work was supported by JSPS Grant-in-Aid for JSPS Fellows Grant Number JP25KJ0647.
@@ -0,0 +1,15 @@
1
+ mcal/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
2
+ mcal/mcal.py,sha256=dUw4CrbtrSDrez47MwwnpX-OFv3OcnArVOuaHlLixrk,29264
3
+ mcal/calculations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ mcal/calculations/hopping_mobility_model.py,sha256=eD9doesa1yVDQxzBYW0N41OyjikZb77S69I_mIMbL2g,13180
5
+ mcal/calculations/rcal.py,sha256=CH3iV18KTM8xU7M7zKR3e1m67GbJLH8zi0j50TsUXLE,13500
6
+ mcal/constants/element_properties.csv,sha256=_Yanl713VZQaAqPYoLNn-hXDdg01ZfkYsCLQ1SQSX8w,4073
7
+ mcal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ mcal/utils/cif_reader.py,sha256=nhvk7y8ix4yKhyKjDaw2Luotw6YFMGbGCaeBVP6Qd5E,22901
9
+ mcal/utils/gaus_log_reader.py,sha256=nNIgBae9hRUgpmNF7eIC5LOENSo6NQmuckMM4A3HAa8,3159
10
+ mcal/utils/gjf_maker.py,sha256=Kkh_gNcifFfhTikZar6SzoNJ7AyEBiCBXJTQkHxHX-0,8193
11
+ yu_mcal-0.1.4.dist-info/METADATA,sha256=y_vQTgF-UcwXOuyV3BpWh9WfCAvtn5Z3bv1KmmL91k4,7890
12
+ yu_mcal-0.1.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
+ yu_mcal-0.1.4.dist-info/entry_points.txt,sha256=_0xZR3t9qvFSd9L6Iot03NixVLxXioEY19L6w3Fs1Ew,40
14
+ yu_mcal-0.1.4.dist-info/licenses/LICENSE,sha256=JP8vm7gYE73jLgnMFTOLNo_RnH88RrB4Goyh7H_muto,1072
15
+ yu_mcal-0.1.4.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mcal = mcal.mcal:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Hiroyuki Matsui
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.