66
77
88class Format (ABC ):
9+ """The abstract base class for all formats.
10+
11+ To add a new format, one should create a new class inherited from this class, and then
12+
13+ - implement several methods, such as :meth:`from_system`;
14+ - register the format with a key;
15+ - add documentation in the class docstring;
16+
17+ The new format can be either insider or outside the package.
18+ """
19+
920 __FormatPlugin = Plugin ()
1021 __FromPlugin = Plugin ()
1122 __ToPlugin = Plugin ()
1223
1324 @staticmethod
1425 def register (key ):
26+ """Register a format plugin.
27+
28+ By default, after a format plugin is registered, the following methods
29+ will be registered as well for :meth:`System`, :meth:`LabeledSystem`, :meth:`MultiSystems`, and
30+ :meth:`BondOrderSystem`:
31+
32+ - from_{key.replace('/', '_')}
33+ - to_{key.replace('/', '_')}
34+ - from({key}, ...)
35+ - to({key}, ...)
36+
37+ The decorator should be explicitly executed before :mod:`dpdata.system`
38+ is imported. A module will be imported automatically if it
39+
40+ - is a submodule of :mod:`dpdata.plugins`;
41+ - is registered at the `dpdata.plugins` entry point
42+
43+ Parameters
44+ ----------
45+ key : str
46+ The key to register the plugin.
47+
48+ Returns
49+ -------
50+ function
51+ The decorator function.
52+
53+ Examples
54+ --------
55+ Register a format plugin:
56+
57+ >>> @Format.register('test')
58+ ... @Format.register('test2')
59+ ... class TestFormat(Format):
60+ ... pass
61+ """
1562 return Format .__FormatPlugin .register (key )
1663
1764 @staticmethod
1865 def register_from (key ):
66+ """Register a from method if the target method name is not default.
67+
68+ Parameters
69+ ----------
70+ key : str
71+ The key to register the plugin.
72+
73+ Returns
74+ -------
75+ function
76+ The decorator function.
77+
78+ Examples
79+ --------
80+ Register a from method:
81+
82+ >>> @Format.register_from('from_test_haha')
83+ ... @Format.register('test)
84+ ... class TestFormat(Format):
85+ ... pass
86+
87+ This will register a from method named from_test_haha, although the
88+ format name is test.
89+ """
1990 return Format .__FromPlugin .register (key )
2091
2192 @staticmethod
2293 def register_to (key ):
94+ """Register a to method if the target method name is not default.
95+
96+ Parameters
97+ ----------
98+ key : str
99+ The key to register the plugin.
100+
101+ Returns
102+ -------
103+ function
104+ The decorator function.
105+
106+ Examples
107+ --------
108+ Register a to method:
109+
110+ >>> @Format.register_to('to_test_haha')
111+ ... @Format.register('test')
112+ ... class TestFormat(Format):
113+ ... pass
114+
115+ This will register a to method named to_test_haha, although the
116+ format name is test.
117+ """
23118 return Format .__ToPlugin .register (key )
24119
25120 @staticmethod
26121 def get_formats ():
122+ """Get all registered formats."""
27123 return Format .__FormatPlugin .plugins
28124
29125 @staticmethod
30126 def get_from_methods ():
127+ """Get all registered from methods."""
31128 return Format .__FromPlugin .plugins
32129
33130 @staticmethod
34131 def get_to_methods ():
132+ """Get all registered to methods."""
35133 return Format .__ToPlugin .plugins
36134
37135 @staticmethod
38136 def post (func_name ):
137+ """Register a post function for from method.
138+
139+ Such function will be called after the "from" method is called.
140+
141+ Parameters
142+ ----------
143+ func_name : str or list of str
144+ The name of the post function.
145+
146+ Returns
147+ -------
148+ function
149+ The decorator function.
150+
151+ Examples
152+ --------
153+ Register a post function:
154+
155+ >>> @Format.post('remove_pbc')
156+ ... @Format.register('test')
157+ ... class TestFormat(Format):
158+ ... pass
159+ """
160+
39161 def decorator (object ):
40162 if not isinstance (func_name , (list , tuple , set )):
41163 object .post_func = (func_name ,)
@@ -46,60 +168,119 @@ def decorator(object):
46168 return decorator
47169
48170 def from_system (self , file_name , ** kwargs ):
49- """System.from.
171+ """Implement System.from that converts from this format to System .
50172
51173 Parameters
52174 ----------
53175 file_name : str
54- file name
176+ file name, i.e. the first argument
55177 **kwargs : dict
56- other parameters
178+ keyword arguments that will be passed from the method
57179
58180 Returns
59181 -------
60- data: dict
61- system data
182+ data : dict
183+ system data, whose keys are defined in System.DTYPES
62184 """
63185 raise NotImplementedError (
64186 "%s doesn't support System.from" % (self .__class__ .__name__ )
65187 )
66188
67189 def to_system (self , data , * args , ** kwargs ):
68- """System.to.
190+ """Implement System.to that converts from System to this format .
69191
70192 Parameters
71193 ----------
72194 data : dict
73- system data
195+ system data, whose keys are defined in System.DTYPES
74196 *args : list
75- other parameters
197+ arguments that will be passed from the method
76198 **kwargs : dict
77- other parameters
199+ keyword arguments that will be passed from the method
78200 """
79201 raise NotImplementedError (
80202 "%s doesn't support System.to" % (self .__class__ .__name__ )
81203 )
82204
83205 def from_labeled_system (self , file_name , ** kwargs ):
206+ """Implement LabeledSystem.from that converts from this format to LabeledSystem.
207+
208+ Parameters
209+ ----------
210+ file_name : str
211+ file name, i.e. the first argument
212+ **kwargs : dict
213+ keyword arguments that will be passed from the method
214+
215+ Returns
216+ -------
217+ data : dict
218+ system data, whose keys are defined in LabeledSystem.DTYPES
219+ """
84220 raise NotImplementedError (
85221 "%s doesn't support LabeledSystem.from" % (self .__class__ .__name__ )
86222 )
87223
88224 def to_labeled_system (self , data , * args , ** kwargs ):
225+ """Implement LabeledSystem.to that converts from LabeledSystem to this format.
226+
227+ By default, LabeledSystem.to will fallback to System.to.
228+
229+ Parameters
230+ ----------
231+ data : dict
232+ system data, whose keys are defined in LabeledSystem.DTYPES
233+ *args : list
234+ arguments that will be passed from the method
235+ **kwargs : dict
236+ keyword arguments that will be passed from the method
237+ """
89238 return self .to_system (data , * args , ** kwargs )
90239
91240 def from_bond_order_system (self , file_name , ** kwargs ):
241+ """Implement BondOrderSystem.from that converts from this format to BondOrderSystem.
242+
243+ Parameters
244+ ----------
245+ file_name : str
246+ file name, i.e. the first argument
247+ **kwargs : dict
248+ keyword arguments that will be passed from the method
249+
250+ Returns
251+ -------
252+ data : dict
253+ system data
254+ """
92255 raise NotImplementedError (
93256 "%s doesn't support BondOrderSystem.from" % (self .__class__ .__name__ )
94257 )
95258
96259 def to_bond_order_system (self , data , rdkit_mol , * args , ** kwargs ):
260+ """Implement BondOrderSystem.to that converts from BondOrderSystem to this format.
261+
262+ By default, BondOrderSystem.to will fallback to LabeledSystem.to.
263+
264+ Parameters
265+ ----------
266+ data : dict
267+ system data
268+ rdkit_mol : rdkit.Chem.rdchem.Mol
269+ rdkit mol object
270+ *args : list
271+ arguments that will be passed from the method
272+ **kwargs : dict
273+ keyword arguments that will be passed from the method
274+ """
97275 return self .to_system (data , * args , ** kwargs )
98276
99277 class MultiModes :
100- """File mode for MultiSystems
101- 0 (default): not implemented
102- 1: every directory under the top-level directory is a system.
278+ """File mode for MultiSystems.
279+
280+ The current implemented modes are:
281+
282+ - 0 (default): not implemented
283+ - 1: every directory under the top-level directory is a system.
103284 """
104285
105286 NotImplemented = 0
@@ -108,14 +289,16 @@ class MultiModes:
108289 MultiMode = MultiModes .NotImplemented
109290
110291 def from_multi_systems (self , directory , ** kwargs ):
111- """MultiSystems.from.
292+ """Implement MultiSystems.from that converts from this format to MultiSystems.
293+
294+ By default, this method follows MultiMode to implement the conversion.
112295
113296 Parameters
114297 ----------
115298 directory : str
116299 directory of system
117300 **kwargs : dict
118- other parameters
301+ keyword arguments that will be passed from the method
119302
120303 Returns
121304 -------
@@ -133,6 +316,19 @@ def from_multi_systems(self, directory, **kwargs):
133316 )
134317
135318 def to_multi_systems (self , formulas , directory , ** kwargs ):
319+ """Implement MultiSystems.to that converts from MultiSystems to this format.
320+
321+ By default, this method follows MultiMode to implement the conversion.
322+
323+ Parameters
324+ ----------
325+ formulas : list[str]
326+ list of formulas
327+ directory : str
328+ directory of system
329+ **kwargs : dict
330+ keyword arguments that will be passed from the method
331+ """
136332 if self .MultiMode == self .MultiModes .Directory :
137333 return [os .path .join (directory , ff ) for ff in formulas ]
138334 raise NotImplementedError (
@@ -149,7 +345,7 @@ def mix_system(self, *system, type_map, **kwargs):
149345 type_map : list of str
150346 Maps atom type to name
151347 **kwargs : dict
152- other parameters
348+ keyword arguments that will be passed from the method
153349
154350 Returns
155351 -------
0 commit comments