pymzqc 1.0.0__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.
pymzqc-1.0.0/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2019-22, Mathias Walzer
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of EBI nor HUPO-PSI nor MS-Quality-Hub nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pymzqc-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,91 @@
1
+ Metadata-Version: 2.2
2
+ Name: pymzqc
3
+ Version: 1.0.0
4
+ Summary: Python library for the PSI-mzQC quality control file format.
5
+ Home-page: https://github.com/MS-Quality-hub/pymzqc
6
+ Author: Mathias Walzer
7
+ Author-email: walzer@ebi.ack.uk
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: jsonschema>=3.2.0
12
+ Requires-Dist: strict-rfc3339
13
+ Requires-Dist: rfc3339-validator
14
+ Requires-Dist: numpy
15
+ Requires-Dist: pandas>=1.1.5
16
+ Requires-Dist: pronto
17
+ Requires-Dist: requests>=2.27.1
18
+ Requires-Dist: click
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: requires-dist
25
+ Dynamic: requires-python
26
+ Dynamic: summary
27
+
28
+ # MZQC python library
29
+ [![unit-tests](https://github.com/MS-Quality-hub/pymzqc/actions/workflows/unit_tests.yml/badge.svg)](https://github.com/MS-Quality-hub/pymzqc/actions/workflows/unit_tests.yml)
30
+ [![Documentation Status](https://readthedocs.org/projects/pymzqc/badge/?version=latest)](https://pymzqc.readthedocs.io/en/latest/?badge=latest)
31
+ [![Docker Repository on Quay](https://img.shields.io/badge/container-ready-brightgreen.svg "Docker Repository on Quay")](https://quay.io/repository/mwalzer/pymzqc?tab=tags)
32
+ [![PyPi version](https://badgen.net/pypi/v/pymzqc/)](https://pypi.com/project/pymzqc)
33
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/MS-Quality-hub/pymzqc/blob/main/jupyter/mzqc_in_5/write_in_5_minutes.ipynb)
34
+
35
+ A python library to create and use mzQC files. Specifically, the library facilitates access to
36
+ mzQC files in form of a **directly usable object representation of mzQC** and offers additional
37
+ functionality to:
38
+ * serialise
39
+ * deserialise
40
+ * check syntax
41
+ * check semantics
42
+ * file-info
43
+ * experimental file-merging
44
+
45
+ **The library follows the formats versioning** (which is 'v(Major).(Minor).(Patch)').
46
+
47
+ This library implements python modules for (de-)serialisation and validity checks of the [PSI fileformat](http://www.psidev.info/groups/quality-control) [**mzQC**](https://hupo-psi.github.io/mzQC/).
48
+ Find the specification document, examples, and and further documentation there.
49
+
50
+
51
+ ## Install
52
+
53
+ ### Latest Release
54
+ Most people will want to install the latest release version of pymzqc. Please install pymzqc via [**pypi**](https://pypi.org/project/pymzqc/):
55
+ ```
56
+ pip install pymzqc
57
+ ```
58
+
59
+ ### From Git
60
+ If you want a development version, use for example :
61
+ ```
62
+ pip install -U git+https://github.com/MS-Quality-hub/pymzqc.git
63
+ ```
64
+ You can select **a development branch of your choice** by changing the command after the `.git`, see [the manual build instructions](BUILD.md).
65
+
66
+ ### Containers
67
+ However, we recommend using the ready-built [**containers**](https://quay.io/repository/mwalzer/pymzqc?tab=tags) to check out the latest updates.
68
+
69
+ ## Online docs
70
+ To get a nice and simple overview of how pymzqc works, visit [here](https://pymzqc.readthedocs.io/en/latest/examples.html).
71
+ If you've successfully installed the library and want to **jump right in and work on the library**, we suggest a peek at the [codestructure](https://pymzqc.readthedocs.io/en/latest/codestructure.html).
72
+
73
+ If you however just want to get your toes wet, or use it as-is, have a look at the interactive guides (below).
74
+
75
+ ### Interactive pymzqc
76
+ Have a go with our [interactive python notebooks](jupyter/README.md) to explore what is possible.
77
+
78
+ ## Development
79
+ Contributions are welcome! (Just fork, develop, and open PR.)
80
+
81
+ Please note that most member attributes of the MZQCFile submodule classes and many functional elements do not conform to PEP8.
82
+ The element names of the mzQC JSON-schema need to be preserved in order to create a successful and automated JSON<=>pymzqc object mapping.
83
+ Accordingly, other elements such as functions in all pymzqc modules will keep the JSON-schema names in their naming for consistency.
84
+
85
+ ### Repository structure
86
+ The python package's code is located in the `mzqc` folder, continuous testing code in `tests`, the documentation in `doc`. The libray-**use** container descriptions are in `containers`, if you want a container for library-**development**, you can use the container description within `.devcontainer`, more development presets can be found in `.vscode`.
87
+ The `jupyter` and `accessories` folders are subprojects making use of the library.
88
+ See their README in the respective sub-folders.
89
+
90
+ ### Documentation
91
+ The code documentation style convention is of the type `Sphinx/numpy`.
pymzqc-1.0.0/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # MZQC python library
2
+ [![unit-tests](https://github.com/MS-Quality-hub/pymzqc/actions/workflows/unit_tests.yml/badge.svg)](https://github.com/MS-Quality-hub/pymzqc/actions/workflows/unit_tests.yml)
3
+ [![Documentation Status](https://readthedocs.org/projects/pymzqc/badge/?version=latest)](https://pymzqc.readthedocs.io/en/latest/?badge=latest)
4
+ [![Docker Repository on Quay](https://img.shields.io/badge/container-ready-brightgreen.svg "Docker Repository on Quay")](https://quay.io/repository/mwalzer/pymzqc?tab=tags)
5
+ [![PyPi version](https://badgen.net/pypi/v/pymzqc/)](https://pypi.com/project/pymzqc)
6
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/MS-Quality-hub/pymzqc/blob/main/jupyter/mzqc_in_5/write_in_5_minutes.ipynb)
7
+
8
+ A python library to create and use mzQC files. Specifically, the library facilitates access to
9
+ mzQC files in form of a **directly usable object representation of mzQC** and offers additional
10
+ functionality to:
11
+ * serialise
12
+ * deserialise
13
+ * check syntax
14
+ * check semantics
15
+ * file-info
16
+ * experimental file-merging
17
+
18
+ **The library follows the formats versioning** (which is 'v(Major).(Minor).(Patch)').
19
+
20
+ This library implements python modules for (de-)serialisation and validity checks of the [PSI fileformat](http://www.psidev.info/groups/quality-control) [**mzQC**](https://hupo-psi.github.io/mzQC/).
21
+ Find the specification document, examples, and and further documentation there.
22
+
23
+
24
+ ## Install
25
+
26
+ ### Latest Release
27
+ Most people will want to install the latest release version of pymzqc. Please install pymzqc via [**pypi**](https://pypi.org/project/pymzqc/):
28
+ ```
29
+ pip install pymzqc
30
+ ```
31
+
32
+ ### From Git
33
+ If you want a development version, use for example :
34
+ ```
35
+ pip install -U git+https://github.com/MS-Quality-hub/pymzqc.git
36
+ ```
37
+ You can select **a development branch of your choice** by changing the command after the `.git`, see [the manual build instructions](BUILD.md).
38
+
39
+ ### Containers
40
+ However, we recommend using the ready-built [**containers**](https://quay.io/repository/mwalzer/pymzqc?tab=tags) to check out the latest updates.
41
+
42
+ ## Online docs
43
+ To get a nice and simple overview of how pymzqc works, visit [here](https://pymzqc.readthedocs.io/en/latest/examples.html).
44
+ If you've successfully installed the library and want to **jump right in and work on the library**, we suggest a peek at the [codestructure](https://pymzqc.readthedocs.io/en/latest/codestructure.html).
45
+
46
+ If you however just want to get your toes wet, or use it as-is, have a look at the interactive guides (below).
47
+
48
+ ### Interactive pymzqc
49
+ Have a go with our [interactive python notebooks](jupyter/README.md) to explore what is possible.
50
+
51
+ ## Development
52
+ Contributions are welcome! (Just fork, develop, and open PR.)
53
+
54
+ Please note that most member attributes of the MZQCFile submodule classes and many functional elements do not conform to PEP8.
55
+ The element names of the mzQC JSON-schema need to be preserved in order to create a successful and automated JSON<=>pymzqc object mapping.
56
+ Accordingly, other elements such as functions in all pymzqc modules will keep the JSON-schema names in their naming for consistency.
57
+
58
+ ### Repository structure
59
+ The python package's code is located in the `mzqc` folder, continuous testing code in `tests`, the documentation in `doc`. The libray-**use** container descriptions are in `containers`, if you want a container for library-**development**, you can use the container description within `.devcontainer`, more development presets can be found in `.vscode`.
60
+ The `jupyter` and `accessories` folders are subprojects making use of the library.
61
+ See their README in the respective sub-folders.
62
+
63
+ ### Documentation
64
+ The code documentation style convention is of the type `Sphinx/numpy`.
@@ -0,0 +1,485 @@
1
+ __author__ = 'walzer'
2
+ import json
3
+ import re
4
+ import logging
5
+ from datetime import datetime
6
+ from typing import List,Dict,Union,Any
7
+ import numpy as np
8
+ import pandas as pd
9
+
10
+ #int
11
+ #str
12
+ #float
13
+ FloatVector = List[float]
14
+ IntVector = List[int]
15
+ StringVector = List[str]
16
+ FloatMatrix = List[FloatVector]
17
+ IntMatrix = List[IntVector]
18
+ StringMatrix = List[StringVector]
19
+ #Table = Dict[str,Union(FloatVector,IntVector,StringVector)]
20
+ Table = Dict[str,List]
21
+
22
+ class JsonSerialisable(object):
23
+ """
24
+ JsonSerialisable Main structure template for mzQC objects
25
+
26
+ Sets the foundation for a mzQC object to be readily (de-)serialisable with standard
27
+ python json handling code. Facilitates reading and writing of complex objects.
28
+
29
+ """
30
+ mappings: Dict[str, Any] = dict()
31
+
32
+ @staticmethod
33
+ def time_helper(da:str) -> datetime:
34
+ """
35
+ time_helper Helper method for ISO8601 string of various length consumption
36
+
37
+ Used on JSON datetime object string representation will handle length and return
38
+ python datetime objects. JSON-schema actually follows
39
+ https://www.rfc-editor.org/rfc/rfc3339.html#section-5.6 which is a little more
40
+ stringent subset of ISO8601.
41
+
42
+ Parameters
43
+ ----------
44
+ da : str
45
+ JSON datetime object string representation
46
+
47
+ Returns
48
+ -------
49
+ datetime
50
+ Python datetime object including the same amount detail provided
51
+ """
52
+ try:
53
+ dt = pd.to_datetime(da)
54
+ except Exception as exc:
55
+ raise ValueError(f"Unknown string format: {da}") from exc
56
+ return dt
57
+
58
+ @classmethod
59
+ def class_mapper(classself, d):
60
+ """
61
+ class_mapper Maps incoming objects to their respective definition
62
+
63
+ Allows every registered object to 'know' its type map incuding recursing into
64
+ its attributes. Can be used as object_hook in the json load process.
65
+
66
+ Parameters
67
+ ----------
68
+ classself : self
69
+ The objects class self
70
+ d : dict
71
+ The dictionary mapping attributes
72
+
73
+ Returns
74
+ -------
75
+ class object
76
+ Returns an object of the 'outer-most' class
77
+
78
+ Raises
79
+ ------
80
+ ValueError
81
+ If expected date strings are invalid.
82
+ """
83
+ maxcls: Any = None
84
+ exmax: int = 0
85
+ for keys, cls in classself.mappings.items():
86
+ if keys.issuperset(d.keys()):
87
+ nx = len(set(d.keys()).intersection(set(keys)))
88
+ if nx > exmax:
89
+ maxcls = cls
90
+ exmax = nx
91
+
92
+ if maxcls is not None:
93
+ return maxcls(**d)
94
+ else:
95
+ if {'creationDate': None}.keys() == d.keys():
96
+ try:
97
+ return JsonSerialisable.time_helper(d['creationDate'])
98
+ except ValueError as exc:
99
+ raise ValueError(f"It appears the creationDate of your file is not of ISO 8601 format including time to the second: {d['creationDate']}") from exc
100
+ else:
101
+ # raise ValueError('Unable to find a matching class for object: {d} (keys: {k})' .format(d=d,k=d.keys()))
102
+ return d
103
+
104
+ @classmethod
105
+ def complex_handler(classself, obj):
106
+ """
107
+ complex_handler Handles the in-depth serialisations necessary
108
+
109
+ Facilitates the correct serialisation for each type of object (within
110
+ the registered mzQC JsonSerialisable context) through possible
111
+ serialisation specialisation by way of object type. If objects behave
112
+ like dictionaries, but are complex classes (like all pymzqc obj),
113
+ the dict needs to be returned as classical dict in order to serialise.
114
+
115
+ Parameters
116
+ ----------
117
+ classself : self
118
+ The objects class self
119
+ obj : object
120
+ The object to be deserialised
121
+
122
+ Returns
123
+ -------
124
+ obj
125
+ The correct object deconstruction into its deserialisable bits
126
+
127
+ Raises
128
+ ------
129
+ TypeError
130
+ In case a given object cannot be serialised with the given set of functionalities.
131
+ """
132
+ if isinstance(obj, datetime):
133
+ logging.debug("serialisation specialisation dates: "+str(obj))
134
+ if obj.tzinfo:
135
+ return obj.isoformat().replace('+00:00','Z')
136
+ else: #assume local time is UTC, the standard requires RFC3339 after all (see specification)
137
+ return obj.isoformat()+('Z')
138
+
139
+ if 'numpy' in str(type(obj)):
140
+ logging.debug("serialisation specialisation np.dtypes: "+str(obj))
141
+ if isinstance(obj,np.ndarray):
142
+ return obj.tolist()
143
+ return obj.item()
144
+
145
+ # needs to be last
146
+ if hasattr(obj, '__dict__'):
147
+ return {k:v for k,v in obj.__dict__.items() if v is not None and v != ""}
148
+
149
+ raise TypeError(f"Object of type {type(obj)} with value {repr(obj)} is not JSON (de)serializable.")
150
+
151
+ @classmethod
152
+ def register(classself, cls):
153
+ """
154
+ register The method for class registration in the class mapping process
155
+
156
+ Each registered class gets mapped.
157
+
158
+ Parameters
159
+ ----------
160
+ classself : self
161
+ the objects class self
162
+ cls : object
163
+ the class type
164
+
165
+ Returns
166
+ -------
167
+ cls
168
+ the class type
169
+ """
170
+ classself.mappings[frozenset(tuple([attr for attr, val in cls().__dict__.items()]))] = cls
171
+ return cls
172
+
173
+ @classmethod
174
+ def to_json(classself, obj, readability=0, complete=True):
175
+ """
176
+ to_json main method for serialisation
177
+
178
+ Parameters
179
+ ----------
180
+ classself : self
181
+ The objects class self
182
+ obj : object
183
+ The object to be serialised
184
+ readability : int, optional
185
+ The indentation level, by default 0 (=no indentation,
186
+ 1=minor indentation on MZQC objects, >1 heavy indentation for max.
187
+ human readability)
188
+ complete: bool, optional
189
+ Flag to indicate if the object is to be left without the
190
+ enclosing `mzQC` key or if the JSON is to be amended to full
191
+ schema compliance (default).
192
+
193
+ Returns
194
+ -------
195
+ str
196
+ The serialisation result
197
+ """
198
+ if readability==0:
199
+ ret = json.dumps(obj.__dict__ if isinstance(obj, MzQcFile) else
200
+ obj, default=classself.complex_handler)
201
+ elif readability == 1:
202
+ ret = json.dumps(obj.__dict__ if isinstance(obj, MzQcFile) else
203
+ obj, default=classself.complex_handler,
204
+ indent=2, cls=MzqcJSONEncoder)
205
+ else:
206
+ ret = json.dumps(obj.__dict__ if isinstance(obj, MzQcFile) else
207
+ obj, default=classself.complex_handler, indent=4)
208
+ #remove empty run/setQualities and other optinal and empty elements, return with mzqc root,
209
+ ret = re.sub(r'(\"setQualities\"\:\s+\[\s*\][,]*)|(\"runQualities\"\:\s+\[\s*\][,]*)|([,]*\s+\"fileProperties\"\:\s+\[\s*\][,]*)', "", ret)
210
+ ret = re.sub(r'(\s*\"contactName\"\:\s+"",)|(\s*\"contactAddress\"\:\s+"",)|(\s*\"description\"\:\s+"",)', "", ret)
211
+ ret = f"{{\"mzQC\": \n{ret} \n}}" if complete else ret
212
+ return ret
213
+
214
+ @classmethod
215
+ def from_json(classself, json_str, complete=False):
216
+ """
217
+ from_json main method for deserialisation
218
+
219
+ Accounts for neccessary object rectification due to same-attribute
220
+ class footprints. N.B.: for this to work the class init variables must
221
+ be same name as the corresponding member attributes (self).
222
+
223
+ Parameters
224
+ ----------
225
+ classself : self
226
+ The objects class self
227
+ json_str : str
228
+ The JSON string to be deserialised
229
+ complete : bool, optional
230
+ Flag to indicate if the whole JSON is to be returned deserialised,
231
+ or just the `mzQC` entry (default).
232
+
233
+ Returns
234
+ -------
235
+ MzQcFile object
236
+ The deserialised JSON string
237
+ """
238
+ if isinstance(json_str, str):
239
+ j = json.loads(json_str, object_hook=classself.class_mapper)
240
+ else: # assume it is a IO wrapper
241
+ j = json.load(json_str, object_hook=classself.class_mapper)
242
+ if not(complete) and 'mzQC' in j.keys():
243
+ j = j['mzQC']
244
+ return rectify(j)
245
+
246
+
247
+ def rectify(obj):
248
+ """
249
+ rectify Rectifies objects according to their position in the local hierarchy
250
+
251
+ Carries out the neccessary object rectification due to same-attribute class footprints.
252
+ Rectification depends on the object position in the local object hierarchy.
253
+
254
+ Parameters
255
+ ----------
256
+ obj : object
257
+ The object to be rectified
258
+
259
+ Returns
260
+ -------
261
+ object
262
+ The rectified object
263
+ """
264
+ static_list_typemap = {'runQualities': RunQuality, 'setQualities': SetQuality,
265
+ 'controlledVocabularies': ControlledVocabulary,
266
+ 'qualityMetrics': QualityMetric,
267
+ 'inputFiles': InputFile,
268
+ 'analysisSoftware': AnalysisSoftware,
269
+ 'fileProperties': CvParameter}
270
+ static_singlet_typemap = {'fileFormat': CvParameter, 'metadata': MetaDataParameters}
271
+ if hasattr(obj, '__dict__'):
272
+ for k,v in obj.__dict__.items():
273
+ if k in static_list_typemap.keys():
274
+ v[:] = [rectify((static_list_typemap[k])(**i.__dict__ if hasattr(i, '__dict__') else i)) for i in v]
275
+ elif k in static_singlet_typemap.keys():
276
+ k = rectify((static_singlet_typemap[k])(**v.__dict__ if hasattr(v, '__dict__') else v))
277
+ else:
278
+ rectify(v)
279
+ elif isinstance(obj, dict):
280
+ for k,v in obj.items():
281
+ rectify(v)
282
+ return obj
283
+
284
+
285
+ class MzqcJSONEncoder(json.JSONEncoder):
286
+ """
287
+ MzqcJSONEncoder The encoder used to facilitate indented encoding
288
+
289
+ Handles the string encoding and formatting of the serialised objects.
290
+ """
291
+ def iterencode(self, o, _one_shot=False):
292
+ indent_level = 0
293
+ value_scope = False
294
+ for s in super(MzqcJSONEncoder, self).iterencode(o, _one_shot=_one_shot):
295
+ if value_scope and indent_level == 0 and s.startswith('}'):
296
+ value_scope = False
297
+ elif s.startswith('"value"'):
298
+ value_scope = True
299
+ if 0 < indent_level:
300
+ s = s.replace('\n', '').rstrip().lstrip()
301
+ if s.startswith(','):
302
+ s = ',' + s[1:].lstrip()
303
+ if s.startswith('[') and value_scope:
304
+ indent_level += 1
305
+ if s.endswith(']') and value_scope:
306
+ indent_level -= 1
307
+ s = s.replace(']', '\n'+' '*self.indent*6+']').rstrip()
308
+ yield s
309
+
310
+
311
+ class JsonObject(object):
312
+ """
313
+ JsonObject Proxy object for better integration of mzQC objects
314
+
315
+ Useful for testing and validity checks as __eq__ is overridden to compare all
316
+ attributes as well.
317
+
318
+ """
319
+ def __eq__(self, other):
320
+ """
321
+ __eq__ Overrides the default implementation
322
+
323
+ Compare all attributes as well.
324
+
325
+ Parameters
326
+ ----------
327
+ other : object
328
+
329
+ Returns
330
+ -------
331
+ bool
332
+ False if the two objects are not of the same class or any of the attributes differ
333
+ """
334
+ if isinstance(other, __class__):
335
+ # TODO find difference in keys and check whether they are None or "" in the other or vice versa
336
+ snn = [k for k,v in self.__dict__.items() if (not v is None and not v == "")]
337
+ onn = [k for k,v in other.__dict__.items() if (not v is None and not v == "")]
338
+ if set(snn) == set(onn):
339
+ return all([self.__getattribute__(attr) == other.__getattribute__(attr) for attr in self.__dict__.keys()])
340
+ return False
341
+
342
+ @JsonSerialisable.register
343
+ class ControlledVocabulary(JsonObject):
344
+ """
345
+ ControlledVocabulary Object representation for mzQC schema type ControlledVocabulary
346
+
347
+ """
348
+ def __init__(self, name: str="", uri: str="", version: str=""):
349
+ self.name = name # required
350
+ self.uri = uri # required
351
+ self.version = version # optional
352
+
353
+ @JsonSerialisable.register
354
+ class CvParameter(JsonObject):
355
+ """
356
+ CvParameter Object representation for mzQC schema type CvParameter
357
+
358
+ """
359
+ def __init__(self, accession: str="",
360
+ name: str="",
361
+ description: str="",
362
+ value: Union[int,str,float,IntVector,StringVector,FloatVector,IntMatrix,StringMatrix,FloatMatrix,Table, None]=None,
363
+ unit: str=""):
364
+ self.accession = accession # required "pattern": "^[A-Z]+:[0-9]{7}$"
365
+ self.name = name # required
366
+ self.description = description # optional, "pattern": "^[A-Z]+$"
367
+ self.value = value # optional
368
+ self.unit = unit # optional, IMO this should be accession only, not annother cvParam
369
+
370
+ @JsonSerialisable.register
371
+ class AnalysisSoftware(CvParameter):
372
+ """
373
+ AnalysisSoftware Object representation for mzQC schema type AnalysisSoftware
374
+
375
+ """
376
+ def __init__(self, accession: str="",
377
+ name: str="",
378
+ description: str="",
379
+ value: str="",
380
+ unit: str="",
381
+ version: str = "",
382
+ uri: str = ""):
383
+ super().__init__(accession, name, description, value, unit) # optional, this will set None to optional omitted arguments
384
+ self.version = version # required
385
+ self.uri = uri # required
386
+
387
+ @JsonSerialisable.register
388
+ class InputFile(JsonObject):
389
+ """
390
+ InputFile Object representation for mzQC schema type InputFile
391
+
392
+ """
393
+ def __init__(self, location: str = "",
394
+ name: str = "",
395
+ fileFormat: CvParameter = None,
396
+ fileProperties: List[CvParameter] = None):
397
+ self.location = location # required , uri
398
+ self.name = name # required , string (doubles as internal and external ref anchor?)
399
+ self.fileFormat = fileFormat # required , cvParam
400
+ self.fileProperties = [] if fileProperties is None else fileProperties # optional, cvParam, at least one item
401
+
402
+ @JsonSerialisable.register
403
+ class MetaDataParameters(JsonObject):
404
+ """
405
+ MetaDataParameters Object representation for mzQC schema type MetaDataParameters
406
+
407
+ """
408
+ def __init__(self,
409
+ # fileProvenance: str="",
410
+ # cv_params: List[CvParameter] = None ,
411
+ label: str = "",
412
+ inputFiles: List[InputFile] = None,
413
+ analysisSoftware: List[AnalysisSoftware]=None
414
+ ):
415
+ # self.fileProvenance = fileProvenance # not in schema
416
+ # self.cv_params = [] if cv_params is None else cv_params # not in schema, IMO should be in there
417
+ self.label = label # optional
418
+ self.inputFiles = [] if inputFiles is None else inputFiles # required
419
+ self.analysisSoftware = [] if analysisSoftware is None else analysisSoftware # required
420
+
421
+ @JsonSerialisable.register
422
+ class QualityMetric(CvParameter):
423
+ """
424
+ QualityMetric Object representation is passed for its more concrete derivatives
425
+
426
+ """
427
+ pass
428
+ # def __init__(self, cvRef: str="",
429
+ # accession: str="",
430
+ # name: str="",
431
+ # description: str="",
432
+ # value: Union[int,str,float,IntVector,StringVector,FloatVector,IntMatrix,StringMatrix,FloatMatrix,Table, None]=None, # here we could clamp down on allowed value types
433
+ # unit: str=""):
434
+ # super().__init__(cvRef, accession, name, description, value, unit) # optional, this will set None to optional omitted arguments
435
+ # implementation: this is a different object class because we want to make
436
+ # semantical distinctions between pure metrics and generic CvParams
437
+
438
+ @JsonSerialisable.register
439
+ class BaseQuality(JsonObject):
440
+ """
441
+ BaseQuality Object representation for mzQC schema type BaseQuality
442
+
443
+ """
444
+ def __init__(self, metadata: MetaDataParameters=None,
445
+ qualityMetrics: List[QualityMetric]=None):
446
+ self.metadata = metadata # required
447
+ self.qualityMetrics = [] if qualityMetrics is None else qualityMetrics # required,
448
+
449
+ @JsonSerialisable.register
450
+ class RunQuality(BaseQuality):
451
+ """
452
+ QualityMetric Object representation is passed for its more general basis
453
+
454
+ """
455
+ pass
456
+
457
+ @JsonSerialisable.register
458
+ class SetQuality(BaseQuality):
459
+ """
460
+ SetQuality Object representation is passed for its more general basis
461
+
462
+ """
463
+ pass
464
+
465
+ @JsonSerialisable.register
466
+ class MzQcFile(JsonObject):
467
+ """
468
+ MzQcFile Object representation for mzQC schema type MzQcFile
469
+
470
+ """
471
+ def __init__(self, creationDate: Union[datetime,str] = datetime.now().replace(microsecond=0),
472
+ version: str = "1.0.0",
473
+ contactName: str = "", contactAddress: str = "", description: str = "",
474
+ runQualities: List[RunQuality]=None,
475
+ setQualities: List[SetQuality]=None,
476
+ controlledVocabularies: List[ControlledVocabulary]=None
477
+ ):
478
+ self.creationDate = JsonSerialisable.time_helper(creationDate) if isinstance(creationDate, str) else creationDate # required
479
+ self.version = version # required
480
+ self.contactName = contactName # optional
481
+ self.contactAddress = contactAddress # optional
482
+ self.description = description # optional
483
+ self.runQualities = [] if runQualities is None else runQualities # either or set required
484
+ self.setQualities = [] if setQualities is None else setQualities # either or run required
485
+ self.controlledVocabularies = [] if controlledVocabularies is None else controlledVocabularies # required