rcsb.workflow 0.52__tar.gz → 0.53__tar.gz

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.
Files changed (34) hide show
  1. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/HISTORY.txt +1 -0
  2. {rcsb_workflow-0.52/rcsb.workflow.egg-info → rcsb_workflow-0.53}/PKG-INFO +4 -2
  3. {rcsb_workflow-0.52/rcsb/workflow/chem → rcsb_workflow-0.53/rcsb/workflow/bcif}/__init__.py +0 -0
  4. rcsb_workflow-0.53/rcsb/workflow/bcif/task_functions.py +315 -0
  5. rcsb_workflow-0.53/rcsb/workflow/cli/BcifExec.py +174 -0
  6. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/cli/__init__.py +1 -1
  7. rcsb_workflow-0.53/rcsb/workflow/wuw/BcifWorkflow.py +85 -0
  8. rcsb_workflow-0.53/rcsb/workflow/wuw/__init__.py +0 -0
  9. {rcsb_workflow-0.52 → rcsb_workflow-0.53/rcsb.workflow.egg-info}/PKG-INFO +4 -2
  10. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb.workflow.egg-info/SOURCES.txt +4 -0
  11. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb.workflow.egg-info/entry_points.txt +1 -0
  12. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb.workflow.egg-info/requires.txt +3 -1
  13. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/requirements.txt +3 -1
  14. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/setup.py +1 -1
  15. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/LICENSE +0 -0
  16. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/MANIFEST.in +0 -0
  17. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/README.md +0 -0
  18. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/__init__.py +0 -0
  19. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/__init__.py +0 -0
  20. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/chem/ChemCompFileWorkflow.py +0 -0
  21. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/chem/ChemCompImageWorkflow.py +0 -0
  22. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/chem/ChemCompSearchIndexWorkflow.py +0 -0
  23. {rcsb_workflow-0.52/rcsb/workflow/targets → rcsb_workflow-0.53/rcsb/workflow/chem}/__init__.py +0 -0
  24. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/cli/ExDbExec.py +0 -0
  25. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/cli/ImgExec.py +0 -0
  26. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/targets/ProteinTargetSequenceExecutionWorkflow.py +0 -0
  27. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/targets/ProteinTargetSequenceWorkflow.py +0 -0
  28. {rcsb_workflow-0.52/rcsb/workflow/wuw → rcsb_workflow-0.53/rcsb/workflow/targets}/__init__.py +0 -0
  29. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/wuw/ExDbWorkflow.py +0 -0
  30. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb/workflow/wuw/PdbCsmImageWorkflow.py +0 -0
  31. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb.workflow.egg-info/dependency_links.txt +0 -0
  32. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb.workflow.egg-info/not-zip-safe +0 -0
  33. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/rcsb.workflow.egg-info/top_level.txt +0 -0
  34. {rcsb_workflow-0.52 → rcsb_workflow-0.53}/setup.cfg +0 -0
@@ -46,3 +46,4 @@
46
46
  Remove IMGT from feature building after service became unavailable February 2025
47
47
  19-Feb-2025 - V0.51 Bring back IMGT
48
48
  4-Apr-2025 - V0.52 Add multi cpu execution to jpg generation
49
+ 10-Apr-2025 - V0.53 Add BCIF conversion CLI
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rcsb.workflow
3
- Version: 0.52
3
+ Version: 0.53
4
4
  Summary: RCSB Python data processing and ETL/ELT workflow entry points
5
5
  Home-page: https://github.com/rcsb/py-rcsb_workflow
6
6
  Author: John Westbrook
@@ -22,7 +22,9 @@ Requires-Dist: rcsb.utils.targets>=0.82
22
22
  Requires-Dist: rcsb.utils.seqalign>=0.31
23
23
  Requires-Dist: rcsb.utils.io>=1.48
24
24
  Requires-Dist: rcsb.exdb>=1.28
25
- Requires-Dist: rcsb.db>=1.800
25
+ Requires-Dist: rcsb.db>=1.801
26
+ Requires-Dist: requests>=2.32.3
27
+ Requires-Dist: mmcif>=0.91.0
26
28
  Provides-Extra: dev
27
29
  Requires-Dist: check-manifest; extra == "dev"
28
30
  Provides-Extra: test
@@ -0,0 +1,315 @@
1
+ ##
2
+ # File: task_functions.py
3
+ # Author: James Smith
4
+ # Date: 21-Feb-2025
5
+ ##
6
+
7
+ """
8
+ Workflow task descriptors.
9
+ """
10
+
11
+ __docformat__ = "google en"
12
+ __author__ = "James Smith"
13
+ __email__ = "james.smith@rcsb.org"
14
+ __license__ = "Apache 2.0"
15
+
16
+ import multiprocessing
17
+ import os
18
+ import shutil
19
+ import tempfile
20
+ import logging
21
+ from enum import Enum
22
+ from typing import Optional
23
+ from mmcif.api.DictionaryApi import DictionaryApi
24
+ from mmcif.io.IoAdapterPy import IoAdapterPy as IoAdapter
25
+ from rcsb.utils.io.MarshalUtil import MarshalUtil
26
+
27
+ logger = logging.getLogger(__name__)
28
+ logger.setLevel(logging.INFO)
29
+
30
+
31
+ ContentTypeEnum = Enum(
32
+ "ContentTypeEnum",
33
+ [("EXPERIMENTAL", "pdb"), ("COMPUTATIONAL", "csm"), ("INTEGRATIVE", "ihm")],
34
+ )
35
+
36
+
37
+ def convertCifFilesToBcif(
38
+ listFileName: str,
39
+ listFileBase: str,
40
+ remotePath: str,
41
+ updateBase: str,
42
+ outfileSuffix: str,
43
+ contentType: str,
44
+ outputContentType: bool,
45
+ outputHash: bool,
46
+ inputHash: bool,
47
+ batchSize: int,
48
+ maxFiles: int,
49
+ pdbxDict: str,
50
+ maDict: str,
51
+ rcsbDict: str,
52
+ ihmDict: str,
53
+ ):
54
+ """
55
+ Converts CIF files to BCIF format based on a given list file.
56
+
57
+ Raises:
58
+ FileNotFoundError: If the specified list file does not exist.
59
+ ValueError: If the list file is empty.
60
+ RuntimeError: If processing fails for some files.
61
+ """
62
+
63
+ # read sublist
64
+ listfilepath = os.path.join(listFileBase, listFileName)
65
+ logger.info(
66
+ "reading list file %s and remote path %s",
67
+ listfilepath,
68
+ remotePath,
69
+ )
70
+ files = []
71
+ if not os.path.exists(listfilepath):
72
+ raise FileNotFoundError("No list file found at %s" % listfilepath)
73
+ f = open(listfilepath, "r", encoding="utf-8")
74
+ for line in f:
75
+ files.append(line.strip())
76
+ if 0 < maxFiles <= len(files):
77
+ break
78
+ f.close()
79
+ if len(files) < 1:
80
+ raise ValueError("No files found in %s" % listfilepath)
81
+
82
+ # determine batch size
83
+ if (batchSize is None) or not str(batchSize).isdigit():
84
+ batchSize = 1
85
+ batchSize = int(batchSize)
86
+ if batchSize <= 0:
87
+ batchSize = 1
88
+ logger.info("distributing %d files across %d sublists", len(files), batchSize)
89
+
90
+ # form dictionary object
91
+ dictionaryApi = getDictionaryApi(pdbxDict, maDict, rcsbDict, ihmDict)
92
+
93
+ # traverse sublist and send each input file to converter
94
+ temppath = tempfile.mkdtemp()
95
+ if batchSize == 1:
96
+ # process one file at a time
97
+ for line in files:
98
+ args = (
99
+ line,
100
+ remotePath,
101
+ updateBase,
102
+ outfileSuffix,
103
+ outputContentType,
104
+ outputHash,
105
+ inputHash,
106
+ contentType,
107
+ dictionaryApi,
108
+ temppath,
109
+ )
110
+ singleTask(*args)
111
+ elif batchSize > 1:
112
+ pool = multiprocessing.Pool(processes=batchSize)
113
+ results = []
114
+ for line in files:
115
+ entry = line.strip()
116
+ args = (
117
+ entry,
118
+ remotePath,
119
+ updateBase,
120
+ outfileSuffix,
121
+ outputContentType,
122
+ outputHash,
123
+ inputHash,
124
+ contentType,
125
+ dictionaryApi,
126
+ temppath,
127
+ )
128
+ results.append(pool.apply_async(singleTask, args))
129
+ for r in results:
130
+ r.get(timeout=60 * 5)
131
+ pool.close()
132
+ results.clear()
133
+
134
+ try:
135
+ if os.path.exists(temppath):
136
+ shutil.rmtree(temppath)
137
+ except Exception as e:
138
+ logger.error(str(e))
139
+
140
+ logger.info("Done with CIF to BCIF conversion")
141
+
142
+
143
+ def getDictionaryApi(
144
+ pdbxDict: str, maDict: str, rcsbDict: str, ihmDict: str
145
+ ) -> DictionaryApi:
146
+ paths = [pdbxDict, maDict, rcsbDict, ihmDict]
147
+ try:
148
+ adapter = IoAdapter(raiseExceptions=True)
149
+ containers = []
150
+ for path in paths:
151
+ containers += adapter.readFile(inputFilePath=path)
152
+ dictionaryApi = DictionaryApi(containerList=containers, consolidate=True)
153
+ except Exception as e:
154
+ raise FileNotFoundError("failed to create dictionary api: %s" % str(e)) from e
155
+ return dictionaryApi
156
+
157
+
158
+ def singleTask(
159
+ pdbId: str,
160
+ remotePath: str,
161
+ updateBase: str,
162
+ outfileSuffix: str,
163
+ outputContentType: bool,
164
+ outputHash: bool,
165
+ inputHash: bool,
166
+ contentType: str,
167
+ dictionaryApi: DictionaryApi,
168
+ temppath: str,
169
+ ) -> None:
170
+ if contentType in [
171
+ ContentTypeEnum.EXPERIMENTAL.value,
172
+ ContentTypeEnum.INTEGRATIVE.value,
173
+ ]:
174
+ pdbId = pdbId.lower()
175
+ elif contentType == ContentTypeEnum.COMPUTATIONAL.value:
176
+ pdbId = pdbId.upper()
177
+ remoteFileName = "%s%s" % (
178
+ pdbId,
179
+ outfileSuffix.replace(".bcif.gz", ".cif.gz").replace(".bcif", ".cif"),
180
+ )
181
+
182
+ # form input cifFilePath
183
+ if not remotePath.startswith("http"):
184
+ # local file
185
+ cifFilePath = os.path.join(remotePath, remoteFileName)
186
+ if inputHash:
187
+ cifFilePath = os.path.join(
188
+ remotePath, getHash(pdbId, contentType), remoteFileName
189
+ )
190
+ if not os.path.exists(cifFilePath):
191
+ logger.warning("%s not found", cifFilePath)
192
+ return
193
+ else:
194
+ cifFilePath = getRemoteFilePath(pdbId, contentType, remotePath, remoteFileName)
195
+
196
+ # form output bcifFilePath
197
+ bcifFilePath = getBcifFilePath(
198
+ pdbId, outfileSuffix, updateBase, contentType, outputContentType, outputHash
199
+ )
200
+ if not bcifFilePath:
201
+ raise ValueError("could not form bcif file path for %s" % pdbId)
202
+
203
+ if os.path.exists(bcifFilePath):
204
+ # earlier timestamp ... overwrite
205
+ os.unlink(bcifFilePath)
206
+ if os.path.exists(bcifFilePath):
207
+ raise PermissionError("file %s not removed" % bcifFilePath)
208
+
209
+ # make nested directories
210
+ dirs = os.path.dirname(bcifFilePath)
211
+ if not os.path.exists(dirs):
212
+ os.makedirs(dirs)
213
+
214
+ # convert to bcif
215
+ result = convert(cifFilePath, bcifFilePath, temppath, dictionaryApi)
216
+ if not result:
217
+ raise Exception("failed to convert %s" % cifFilePath)
218
+
219
+
220
+ def getHash(pdbId: str, contentType: str) -> str:
221
+ if contentType == ContentTypeEnum.COMPUTATIONAL.value:
222
+ pdbId = pdbId.upper()
223
+ else:
224
+ pdbId = pdbId.lower()
225
+ result = pdbId[1:3]
226
+ if contentType == ContentTypeEnum.COMPUTATIONAL.value:
227
+ result = os.path.join(pdbId[0:2], pdbId[-6:-4], pdbId[-4:-2])
228
+ return result
229
+
230
+
231
+ def getRemoteFilePath(
232
+ pdbId: str, contentType: str, remotePath: str, remoteFileName: str
233
+ ) -> str:
234
+ result = os.path.join(remotePath, getHash(pdbId, contentType), remoteFileName)
235
+ if contentType == ContentTypeEnum.INTEGRATIVE.value:
236
+ result = os.path.join(
237
+ remotePath, getHash(pdbId, contentType), pdbId, "structures", remoteFileName
238
+ )
239
+ return result
240
+
241
+
242
+ def getBcifFilePath(
243
+ pdbId: str,
244
+ outfileSuffix: str,
245
+ updateBase: str,
246
+ contentType: str,
247
+ outputContentType: bool,
248
+ outputHash: bool,
249
+ ) -> Optional[str]:
250
+ bcifFileName = "%s%s" % (pdbId, outfileSuffix)
251
+ bcifFilePath = None
252
+ if contentType in [
253
+ ContentTypeEnum.EXPERIMENTAL.value,
254
+ ContentTypeEnum.INTEGRATIVE.value,
255
+ ]:
256
+ if outputContentType and outputHash:
257
+ bcifFilePath = os.path.join(
258
+ updateBase, contentType, getHash(pdbId, contentType), bcifFileName
259
+ )
260
+ elif outputContentType:
261
+ bcifFilePath = os.path.join(updateBase, contentType, bcifFileName)
262
+ elif outputHash:
263
+ bcifFilePath = os.path.join(
264
+ updateBase, getHash(pdbId, contentType), bcifFileName
265
+ )
266
+ else:
267
+ bcifFilePath = os.path.join(updateBase, bcifFileName)
268
+ elif contentType == ContentTypeEnum.COMPUTATIONAL.value:
269
+ if outputContentType and outputHash:
270
+ bcifFilePath = os.path.join(
271
+ updateBase,
272
+ contentType,
273
+ getHash(pdbId, contentType),
274
+ bcifFileName,
275
+ )
276
+ elif outputContentType:
277
+ bcifFilePath = os.path.join(
278
+ updateBase,
279
+ contentType,
280
+ bcifFileName,
281
+ )
282
+ elif outputHash:
283
+ bcifFilePath = os.path.join(
284
+ updateBase,
285
+ getHash(pdbId, contentType),
286
+ bcifFileName,
287
+ )
288
+ else:
289
+ bcifFilePath = os.path.join(
290
+ updateBase,
291
+ bcifFileName,
292
+ )
293
+ return bcifFilePath
294
+
295
+
296
+ def convert(
297
+ infile: str, outfile: str, workpath: str, dictionaryApi: DictionaryApi
298
+ ) -> bool:
299
+ mu = MarshalUtil(workPath=workpath)
300
+ data = mu.doImport(infile, fmt="mmcif")
301
+ result = mu.doExport(outfile, data, fmt="bcif", dictionaryApi=dictionaryApi)
302
+ if not result:
303
+ return False
304
+ return True
305
+
306
+
307
+ def deconvert(
308
+ infile: str, outfile: str, workpath: str, dictionaryApi: DictionaryApi
309
+ ) -> bool:
310
+ mu = MarshalUtil(workPath=workpath)
311
+ data = mu.doImport(infile, fmt="bcif")
312
+ result = mu.doExport(outfile, data, fmt="mmcif", dictionaryApi=dictionaryApi)
313
+ if not result:
314
+ return False
315
+ return True
@@ -0,0 +1,174 @@
1
+ ##
2
+ # File: BcifExec.py
3
+ # Author: James Smith
4
+ # Date: 21-Feb-2025
5
+ ##
6
+
7
+ """
8
+ Entry point for bcif command line interface.
9
+ """
10
+
11
+ __docformat__ = "google en"
12
+ __author__ = "James Smith"
13
+ __email__ = "james.smith@rcsb.org"
14
+ __license__ = "Apache 2.0"
15
+
16
+ import argparse
17
+ import os
18
+ import logging
19
+ import time
20
+ from rcsb.workflow.wuw.BcifWorkflow import BcifWorkflow
21
+
22
+ logger = logging.getLogger()
23
+
24
+
25
+ def main():
26
+
27
+ parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
28
+ # paths
29
+ parser.add_argument(
30
+ "--listFileBase",
31
+ default="/tmp",
32
+ required=True,
33
+ help="path for input lists",
34
+ )
35
+ parser.add_argument(
36
+ "--listFileName",
37
+ default="pdbx_core_ids-1.txt",
38
+ required=True,
39
+ help="name of list file to read",
40
+ )
41
+ parser.add_argument(
42
+ "--remotePath",
43
+ default="http://prereleaseftp-external-east.rcsb.org/pdb/data/structures/divided/mmCIF/",
44
+ required=True,
45
+ help="url or directory for cif files",
46
+ )
47
+ parser.add_argument(
48
+ "--outputPath",
49
+ default="/mnt/vdb1/out",
50
+ required=True,
51
+ help="output directory for bcif files",
52
+ )
53
+ # settings
54
+ parser.add_argument(
55
+ "--contentType",
56
+ default="pdb",
57
+ required=True,
58
+ choices=["pdb", "csm", "ihm"],
59
+ help="which type of experiment was performed",
60
+ )
61
+ parser.add_argument(
62
+ "--nfiles",
63
+ default=0,
64
+ required=False,
65
+ help="set 0 for all files, set less than N for a test run, will not produce exactly n files",
66
+ )
67
+ parser.add_argument(
68
+ "--outfileSuffix",
69
+ default=".bcif.gz",
70
+ required=False,
71
+ choices=[".bcif", ".bcif.gz"],
72
+ help="whether to use additional gzip compression",
73
+ )
74
+ parser.add_argument(
75
+ "--batchSize",
76
+ default=1,
77
+ required=False,
78
+ help="optional subdivisions of sublists for pdb list and csm list",
79
+ )
80
+ # output folder structure, default none (save all output files in one folder)
81
+ parser.add_argument(
82
+ "--outputContentType",
83
+ action="store_true",
84
+ default=False,
85
+ required=False,
86
+ help="whether output paths should include a directory for the content type (pdb, csm)",
87
+ )
88
+ parser.add_argument(
89
+ "--outputHash",
90
+ action="store_true",
91
+ default=False,
92
+ required=False,
93
+ help="whether output paths should include the hash for the entry",
94
+ )
95
+ # input folder structure, default none (read all input files from one folder)
96
+ parser.add_argument(
97
+ "--inputHash",
98
+ action="store_true",
99
+ default=False,
100
+ required=False,
101
+ help="whether local input paths should include the hash for the entry",
102
+ )
103
+ # config
104
+ parser.add_argument(
105
+ "--pdbxDict",
106
+ default="https://raw.githubusercontent.com/wwpdb-dictionaries/mmcif_pdbx/master/dist/mmcif_pdbx_v5_next.dic",
107
+ required=False,
108
+ )
109
+ parser.add_argument(
110
+ "--maDict",
111
+ default="https://raw.githubusercontent.com/ihmwg/ModelCIF/master/dist/mmcif_ma_ext.dic",
112
+ required=False,
113
+ )
114
+ parser.add_argument(
115
+ "--rcsbDict",
116
+ default="https://raw.githubusercontent.com/rcsb/py-rcsb_exdb_assets/master/dictionary_files/dist/rcsb_mmcif_ext.dic",
117
+ required=False,
118
+ )
119
+ parser.add_argument(
120
+ "--ihmDict",
121
+ default="https://raw.githubusercontent.com/rcsb/py-rcsb_exdb_assets/pdb-ihm-2/dictionary_files/reference/mmcif_ihm_ext.dic",
122
+ required=False,
123
+ )
124
+ # logging
125
+ parser.add_argument("--log_file_path", required=False)
126
+ parser.add_argument("--debug", action="store_true", default=False, required=False)
127
+
128
+ args = parser.parse_args()
129
+
130
+ logFilePath = args.log_file_path
131
+ debugFlag = args.debug
132
+ if debugFlag:
133
+ logger.setLevel(logging.DEBUG)
134
+ else:
135
+ logger.setLevel(logging.INFO)
136
+ if logFilePath:
137
+ logDir = os.path.dirname(logFilePath)
138
+ if not os.path.isdir(logDir):
139
+ os.makedirs(logDir)
140
+ handler = logging.FileHandler(logFilePath, mode="a")
141
+ if debugFlag:
142
+ handler.setLevel(logging.DEBUG)
143
+ else:
144
+ handler.setLevel(logging.INFO)
145
+ formatter = logging.Formatter(
146
+ fmt="%(asctime)s @%(process)s [%(levelname)s]-%(module)s: %(message)s"
147
+ )
148
+ handler.setFormatter(formatter)
149
+ logger.addHandler(handler)
150
+ else:
151
+ handler = logging.StreamHandler()
152
+ formatter = logging.Formatter(
153
+ fmt="%(asctime)s @%(process)s [%(levelname)s]-%(module)s: %(message)s"
154
+ )
155
+ handler.setFormatter(formatter)
156
+ logger.addHandler(handler)
157
+
158
+ logger.info("bcif workflow initialized")
159
+
160
+ try:
161
+ (BcifWorkflow(args))()
162
+ except RuntimeError as e:
163
+ raise Exception(str(e)) from e
164
+
165
+
166
+ if __name__ == "__main__":
167
+ t = time.time()
168
+ try:
169
+ main()
170
+ except Exception as e:
171
+ logger.exception(str(e))
172
+ raise e
173
+ t2 = time.time() - t
174
+ logger.info("completed in %.2f s", t2)
@@ -2,4 +2,4 @@ __docformat__ = "google en"
2
2
  __author__ = "John Westbrook"
3
3
  __email__ = "john.westbrook@rcsb.org"
4
4
  __license__ = "Apache 2.0"
5
- __version__ = "0.52"
5
+ __version__ = "0.53"
@@ -0,0 +1,85 @@
1
+ ##
2
+ # File: BcifWorkflow.py
3
+ # Author: James Smith
4
+ # Date: 21-Feb-2025
5
+ ##
6
+
7
+ """
8
+ Run workflow for pdb entries specified in input list.
9
+ """
10
+
11
+ __docformat__ = "google en"
12
+ __author__ = "James Smith"
13
+ __email__ = "james.smith@rcsb.org"
14
+ __license__ = "Apache 2.0"
15
+
16
+ import os
17
+ import logging
18
+ from rcsb.workflow.bcif.task_functions import convertCifFilesToBcif
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class BcifWorkflow:
24
+
25
+ def __init__(self, args):
26
+
27
+ # paths and files
28
+ self.listFileBase = args.listFileBase
29
+ self.listFileName = args.listFileName
30
+ self.remotePath = args.remotePath
31
+ self.outputPath = args.outputPath
32
+ # settings
33
+ self.contentType = args.contentType
34
+ self.nfiles = int(args.nfiles)
35
+ self.outfileSuffix = args.outfileSuffix
36
+ self.outputContentType = bool(args.outputContentType)
37
+ self.outputHash = bool(args.outputHash)
38
+ self.inputHash = bool(args.inputHash)
39
+ self.batchSize = int(args.batchSize)
40
+ # config
41
+ self.pdbxDict = args.pdbxDict
42
+ self.maDict = args.maDict
43
+ self.rcsbDict = args.rcsbDict
44
+ self.ihmDict = args.ihmDict
45
+ #
46
+ self.validate()
47
+
48
+ # public method required by pylint
49
+ def validate(self):
50
+
51
+ assert (
52
+ self.outfileSuffix == ".bcif" or self.outfileSuffix == ".bcif.gz"
53
+ ), "error - require either .bcif or .bcif.gz output file"
54
+
55
+ assert self.contentType in [
56
+ "pdb",
57
+ "csm",
58
+ "ihm",
59
+ ], "error - content type must be pdb, csm, or ihm"
60
+
61
+ def __call__(self):
62
+
63
+ logger.info(
64
+ "running bcif workflow on %s and %s",
65
+ os.path.join(self.listFileBase, self.listFileName),
66
+ self.remotePath,
67
+ )
68
+
69
+ convertCifFilesToBcif(
70
+ self.listFileName,
71
+ self.listFileBase,
72
+ self.remotePath,
73
+ self.outputPath,
74
+ self.outfileSuffix,
75
+ self.contentType,
76
+ self.outputContentType,
77
+ self.outputHash,
78
+ self.inputHash,
79
+ self.batchSize,
80
+ self.nfiles,
81
+ self.pdbxDict,
82
+ self.maDict,
83
+ self.rcsbDict,
84
+ self.ihmDict,
85
+ )
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rcsb.workflow
3
- Version: 0.52
3
+ Version: 0.53
4
4
  Summary: RCSB Python data processing and ETL/ELT workflow entry points
5
5
  Home-page: https://github.com/rcsb/py-rcsb_workflow
6
6
  Author: John Westbrook
@@ -22,7 +22,9 @@ Requires-Dist: rcsb.utils.targets>=0.82
22
22
  Requires-Dist: rcsb.utils.seqalign>=0.31
23
23
  Requires-Dist: rcsb.utils.io>=1.48
24
24
  Requires-Dist: rcsb.exdb>=1.28
25
- Requires-Dist: rcsb.db>=1.800
25
+ Requires-Dist: rcsb.db>=1.801
26
+ Requires-Dist: requests>=2.32.3
27
+ Requires-Dist: mmcif>=0.91.0
26
28
  Provides-Extra: dev
27
29
  Requires-Dist: check-manifest; extra == "dev"
28
30
  Provides-Extra: test
@@ -14,16 +14,20 @@ rcsb.workflow.egg-info/not-zip-safe
14
14
  rcsb.workflow.egg-info/requires.txt
15
15
  rcsb.workflow.egg-info/top_level.txt
16
16
  rcsb/workflow/__init__.py
17
+ rcsb/workflow/bcif/__init__.py
18
+ rcsb/workflow/bcif/task_functions.py
17
19
  rcsb/workflow/chem/ChemCompFileWorkflow.py
18
20
  rcsb/workflow/chem/ChemCompImageWorkflow.py
19
21
  rcsb/workflow/chem/ChemCompSearchIndexWorkflow.py
20
22
  rcsb/workflow/chem/__init__.py
23
+ rcsb/workflow/cli/BcifExec.py
21
24
  rcsb/workflow/cli/ExDbExec.py
22
25
  rcsb/workflow/cli/ImgExec.py
23
26
  rcsb/workflow/cli/__init__.py
24
27
  rcsb/workflow/targets/ProteinTargetSequenceExecutionWorkflow.py
25
28
  rcsb/workflow/targets/ProteinTargetSequenceWorkflow.py
26
29
  rcsb/workflow/targets/__init__.py
30
+ rcsb/workflow/wuw/BcifWorkflow.py
27
31
  rcsb/workflow/wuw/ExDbWorkflow.py
28
32
  rcsb/workflow/wuw/PdbCsmImageWorkflow.py
29
33
  rcsb/workflow/wuw/__init__.py
@@ -1,3 +1,4 @@
1
1
  [console_scripts]
2
+ bcif_exec_cli = rcsb.workflow.cli.BcifExec:main
2
3
  exdb_wf_cli = rcsb.workflow.cli.ExDbExec:main
3
4
  imgs_exec_cli = rcsb.workflow.cli.ImgExec:main
@@ -4,7 +4,9 @@ rcsb.utils.targets>=0.82
4
4
  rcsb.utils.seqalign>=0.31
5
5
  rcsb.utils.io>=1.48
6
6
  rcsb.exdb>=1.28
7
- rcsb.db>=1.800
7
+ rcsb.db>=1.801
8
+ requests>=2.32.3
9
+ mmcif>=0.91.0
8
10
 
9
11
  [dev]
10
12
  check-manifest
@@ -6,4 +6,6 @@ rcsb.utils.targets >= 0.82
6
6
  rcsb.utils.seqalign >= 0.31
7
7
  rcsb.utils.io >= 1.48
8
8
  rcsb.exdb >= 1.28 # v1.28 is when circular dependency was removed
9
- rcsb.db >= 1.800
9
+ rcsb.db >= 1.801
10
+ requests >= 2.32.3
11
+ mmcif >= 0.91.0
@@ -49,7 +49,7 @@ setup(
49
49
  "Programming Language :: Python :: 3.10",
50
50
  ],
51
51
  # entry_points={"console_scripts": ["cactvs_annotate_mol=rcsb.workflow.cactvsAnnotateMol:main"]},
52
- entry_points={"console_scripts": ["exdb_wf_cli=rcsb.workflow.cli.ExDbExec:main", "imgs_exec_cli=rcsb.workflow.cli.ImgExec:main"]},
52
+ entry_points={"console_scripts": ["exdb_wf_cli=rcsb.workflow.cli.ExDbExec:main", "imgs_exec_cli=rcsb.workflow.cli.ImgExec:main", "bcif_exec_cli=rcsb.workflow.cli.BcifExec:main"]},
53
53
  # The following is somewhat flakey --
54
54
  # dependency_links=[],
55
55
  install_requires=packagesRequired[1:],
File without changes
File without changes
File without changes
File without changes