evefile 0.1.0rc1__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.
- evefile/__init__.py +8 -0
- evefile/__pycache__/__init__.cpython-311.pyc +0 -0
- evefile/boundaries/__init__.py +1 -0
- evefile/boundaries/__pycache__/__init__.cpython-311.pyc +0 -0
- evefile/boundaries/__pycache__/evefile.cpython-311.pyc +0 -0
- evefile/boundaries/__pycache__/eveh5.cpython-311.pyc +0 -0
- evefile/boundaries/evefile.py +554 -0
- evefile/boundaries/eveh5.py +932 -0
- evefile/controllers/__init__.py +4 -0
- evefile/controllers/__pycache__/__init__.cpython-311.pyc +0 -0
- evefile/controllers/__pycache__/joining.cpython-311.pyc +0 -0
- evefile/controllers/__pycache__/timestamp_mapping.cpython-311.pyc +0 -0
- evefile/controllers/__pycache__/version_mapping.cpython-311.pyc +0 -0
- evefile/controllers/joining.py +1138 -0
- evefile/controllers/timestamp_mapping.py +101 -0
- evefile/controllers/version_mapping.py +1152 -0
- evefile/entities/__init__.py +5 -0
- evefile/entities/__pycache__/__init__.cpython-311.pyc +0 -0
- evefile/entities/__pycache__/data.cpython-311.pyc +0 -0
- evefile/entities/__pycache__/file.cpython-311.pyc +0 -0
- evefile/entities/__pycache__/metadata.cpython-311.pyc +0 -0
- evefile/entities/data.py +1311 -0
- evefile/entities/file.py +320 -0
- evefile/entities/metadata.py +531 -0
- evefile-0.1.0rc1.dist-info/METADATA +113 -0
- evefile-0.1.0rc1.dist-info/RECORD +30 -0
- evefile-0.1.0rc1.dist-info/WHEEL +5 -0
- evefile-0.1.0rc1.dist-info/licenses/COPYING +674 -0
- evefile-0.1.0rc1.dist-info/licenses/LICENSE +15 -0
- evefile-0.1.0rc1.dist-info/top_level.txt +1 -0
evefile/__init__.py
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Interfaces of the evefile package: facades and resources."""
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
*High-level Python object representation of eveH5 file contents.*
|
|
4
|
+
|
|
5
|
+
.. sidebar:: Contents
|
|
6
|
+
|
|
7
|
+
.. contents::
|
|
8
|
+
:local:
|
|
9
|
+
:depth: 1
|
|
10
|
+
|
|
11
|
+
This module provides a high-level representation of the contents of an eveH5
|
|
12
|
+
file. Being a high-level, user-facing object representation, technically
|
|
13
|
+
speaking this module is a facade. The corresponding resource
|
|
14
|
+
(persistence-layer-facing interface) would be the :mod:`eveh5
|
|
15
|
+
<evefile.boundaries.eveh5>` module.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
Overview
|
|
19
|
+
========
|
|
20
|
+
|
|
21
|
+
A first overview of the classes implemented in this module and their
|
|
22
|
+
hierarchy is given in the UML diagram below.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
.. figure:: /uml/evefile.boundaries.evefile.*
|
|
26
|
+
:align: center
|
|
27
|
+
|
|
28
|
+
Class hierarchy of the :mod:`evefile.boundaries.evefile` module,
|
|
29
|
+
providing the facade (user-facing interface) for an eveH5 file.
|
|
30
|
+
Basically, it inherits from :class:`evefile.entities.file.File`
|
|
31
|
+
and adds behaviour. Most of this behaviour is contributed by the various
|
|
32
|
+
modules of the :mod:`controllers <evefile.controllers>`
|
|
33
|
+
subpackage.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Key aspects
|
|
37
|
+
===========
|
|
38
|
+
|
|
39
|
+
While the :mod:`evefile <evefile.boundaries.evefile>` module is the
|
|
40
|
+
high-level interface (facade) of the ``evefile`` package,
|
|
41
|
+
it is still, from a functional viewpoint, close to the actual eveH5 files,
|
|
42
|
+
providing a faithful representation of all information contained in an eveH5
|
|
43
|
+
file. Nevertheless, it is clearly an abstraction from the actual data files.
|
|
44
|
+
Hence, the key characteristics of the module are:
|
|
45
|
+
|
|
46
|
+
* Stable interface to eveH5 files, regardless of their version.
|
|
47
|
+
|
|
48
|
+
* Some features may only be available for newer eveH5 versions, though.
|
|
49
|
+
|
|
50
|
+
* Powerful abstractions on the device level.
|
|
51
|
+
|
|
52
|
+
* Options to devices appear as attributes of the device objects, not as
|
|
53
|
+
separate datasets.
|
|
54
|
+
|
|
55
|
+
* Actual **data are loaded on demand**, not when loading the file.
|
|
56
|
+
|
|
57
|
+
* This does *not* apply to the metadata of the individual datasets.
|
|
58
|
+
Those are read upon reading the file.
|
|
59
|
+
* Reading data on demand should save time and resources, particularly
|
|
60
|
+
for larger files.
|
|
61
|
+
* Often, you are only interested in a subset of the available data.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
Usage
|
|
65
|
+
=====
|
|
66
|
+
|
|
67
|
+
Loading the contents of a data file of a measurement may be as simple as:
|
|
68
|
+
|
|
69
|
+
.. code-block::
|
|
70
|
+
|
|
71
|
+
evefile = EveFile(filename="my_measurement_file.h5")
|
|
72
|
+
|
|
73
|
+
If you are interested in a convenient overview of the contents of the
|
|
74
|
+
eveH5 file just loaded, try this:
|
|
75
|
+
|
|
76
|
+
.. code-block::
|
|
77
|
+
|
|
78
|
+
evefile.show_info()
|
|
79
|
+
|
|
80
|
+
This will output a human-readable summary of the file metadata,
|
|
81
|
+
log messages, and a list of datasets in the data, snapshot, and monitor
|
|
82
|
+
section. See the documentation of the :meth:`EveFile.show_info` method for
|
|
83
|
+
details.
|
|
84
|
+
|
|
85
|
+
Data are stored within a :class:`EveFile` object with their IDs rather than
|
|
86
|
+
the "given" names users are familiar with. Hence, to get an overview of all
|
|
87
|
+
the data(sets) contained in a file, use the :meth:`EveFile.get_data_names`
|
|
88
|
+
method:
|
|
89
|
+
|
|
90
|
+
.. code-block::
|
|
91
|
+
|
|
92
|
+
evefile.get_data_names()
|
|
93
|
+
|
|
94
|
+
This will return a list of "given" data names.
|
|
95
|
+
|
|
96
|
+
Similarly, if you know the "given" name of a dataset or a list of datasets,
|
|
97
|
+
you can retrieve the corresponding :class:`Data <evefile.entities.data.Data>`
|
|
98
|
+
objects by using the :meth:`EveFile.get_data` method:
|
|
99
|
+
|
|
100
|
+
.. code-block::
|
|
101
|
+
|
|
102
|
+
# Get list of datasets by name
|
|
103
|
+
evefile.get_data(["name1", "name2"])
|
|
104
|
+
|
|
105
|
+
# Get single dataset by name
|
|
106
|
+
evefile.get_data("name")
|
|
107
|
+
|
|
108
|
+
To get the data marked as preferred in the scan, use the
|
|
109
|
+
:meth:`EveFile.get_preferred_data` method:
|
|
110
|
+
|
|
111
|
+
.. code-block::
|
|
112
|
+
|
|
113
|
+
evefile.get_preferred_data()
|
|
114
|
+
|
|
115
|
+
This will return a list with three elements, ``[preferred_axis,
|
|
116
|
+
preferred_channel, preferred_normalisation_channel]``, where each of these
|
|
117
|
+
elements is either of type :class:`evefile.entities.data.Data` or
|
|
118
|
+
:obj:`None`.
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
Internals: What happens when reading an eveH5 file?
|
|
122
|
+
===================================================
|
|
123
|
+
|
|
124
|
+
Reading an eveH5 file is not as simple as reading contents of an HDF5 file
|
|
125
|
+
and present its contents as Python object hierarchy. At least, if you would
|
|
126
|
+
like to view, process, and analyse your data more conveniently, you should
|
|
127
|
+
not stop here. The idea behind the ``evefile`` package, and in parts behind
|
|
128
|
+
the :class:`EveFile` class, is to provide you as consumer of the data with
|
|
129
|
+
powerful abstractions and structured information. To this end, a series of
|
|
130
|
+
steps are necessary:
|
|
131
|
+
|
|
132
|
+
* Read the eveH5 file (actually, an HDF5 file).
|
|
133
|
+
* Get the correct :class:`VersionMapper
|
|
134
|
+
<evefile.controllers.version_mapping.VersionMapper>` class.
|
|
135
|
+
* Map the file contents to the proper :mod:`data structures
|
|
136
|
+
<evefile.entities.data>` provided by the ``evefile`` package.
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
Module documentation
|
|
140
|
+
====================
|
|
141
|
+
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
import logging
|
|
145
|
+
import os
|
|
146
|
+
|
|
147
|
+
import pandas as pd
|
|
148
|
+
|
|
149
|
+
from evefile.entities.file import File
|
|
150
|
+
from evefile.boundaries.eveh5 import HDF5File
|
|
151
|
+
from evefile.controllers import version_mapping, joining
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
logger = logging.getLogger(__name__)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class EveFile(File):
|
|
158
|
+
"""
|
|
159
|
+
High-level Python object representation of eveH5 file contents.
|
|
160
|
+
|
|
161
|
+
This class serves as facade to the entire ``evefile`` package and provides
|
|
162
|
+
a rather high-level representation of the contents of an individual
|
|
163
|
+
eveH5 file.
|
|
164
|
+
|
|
165
|
+
Individual measurements are saved in HDF5 files using a particular
|
|
166
|
+
schema (eveH5). Besides file-level metadata, there are log messages
|
|
167
|
+
and the actual data.
|
|
168
|
+
|
|
169
|
+
The data are organised in three functionally different sections: data,
|
|
170
|
+
snapshots, and monitors. While the "data" section contains the data of
|
|
171
|
+
motor axes moved and detector channels read out during the scan,
|
|
172
|
+
the "snapshot" section contains values at distinct times (usually at
|
|
173
|
+
the very beginning of a scan), usually of more devices than used in
|
|
174
|
+
the scan. The "monitors" section contains data of all those devices
|
|
175
|
+
monitored during the scan, meaning that only changes in values are
|
|
176
|
+
recorded, together with their timestamp (rather than position count).
|
|
177
|
+
|
|
178
|
+
Values from axes contained in the "snapshot" section are used for data
|
|
179
|
+
joining, while all other values can be regarded as either options
|
|
180
|
+
of individual devices or telemetry data for the setup. All values from
|
|
181
|
+
the "monitors" section are strictly telemetry data for the setup.
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
Attributes
|
|
185
|
+
----------
|
|
186
|
+
metadata : :class:`evefile.entities.file.Metadata`
|
|
187
|
+
File metadata
|
|
188
|
+
|
|
189
|
+
log_messages : :class:`list`
|
|
190
|
+
Log messages from an individual measurement
|
|
191
|
+
|
|
192
|
+
Each item in the list is an instance of
|
|
193
|
+
:class:`evefile.entities.file.LogMessage`.
|
|
194
|
+
|
|
195
|
+
data : :class:`dict`
|
|
196
|
+
Data recorded from the devices involved in the scan.
|
|
197
|
+
|
|
198
|
+
The keys of the dictionary are the (guaranteed to be unique) HDF
|
|
199
|
+
dataset names, not the "given" names usually familiar to the users.
|
|
200
|
+
Use the :meth:`get_data` method to retrieve data objects by their
|
|
201
|
+
"given" name.
|
|
202
|
+
|
|
203
|
+
Each item is an instance of
|
|
204
|
+
:class:`evefile.entities.data.Data`.
|
|
205
|
+
|
|
206
|
+
snapshots : :class:`dict`
|
|
207
|
+
Device data recorded as snapshot during a measurement.
|
|
208
|
+
|
|
209
|
+
Only those device data that are not options belonging to any of
|
|
210
|
+
the devices in the :attr:`data` attribute are stored here.
|
|
211
|
+
|
|
212
|
+
The keys of the dictionary are the (guaranteed to be unique) HDF
|
|
213
|
+
dataset names, not the "given" names usually familiar to the users.
|
|
214
|
+
|
|
215
|
+
Each item is an instance of
|
|
216
|
+
:class:`evefile.entities.data.Data`.
|
|
217
|
+
|
|
218
|
+
monitors : :class:`dict`
|
|
219
|
+
Device data monitored during a measurement.
|
|
220
|
+
|
|
221
|
+
The keys of the dictionary are the (guaranteed to be unique) HDF
|
|
222
|
+
dataset names, not the "given" names usually familiar to the users.
|
|
223
|
+
|
|
224
|
+
Each item is an instance of
|
|
225
|
+
:class:`evefile.entities.data.MonitorData`.
|
|
226
|
+
|
|
227
|
+
position_timestamps : :class:`evefile.entities.data.TimestampData`
|
|
228
|
+
Timestamps for each individual position.
|
|
229
|
+
|
|
230
|
+
Monitors have timestamps (milliseconds since start of the scan)
|
|
231
|
+
rather than positions as primary quantisation axis. This object
|
|
232
|
+
provides a mapping between timestamps and positions and can be used
|
|
233
|
+
to map monitor data to positions.
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
Parameters
|
|
237
|
+
----------
|
|
238
|
+
filename : :class:`str`
|
|
239
|
+
Name of the file to be loaded.
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
Raises
|
|
243
|
+
------
|
|
244
|
+
ValueError
|
|
245
|
+
Raised if no filename is provided.
|
|
246
|
+
|
|
247
|
+
FileNotFoundError
|
|
248
|
+
Raised if provided file could not be found.
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
Examples
|
|
252
|
+
--------
|
|
253
|
+
Loading the contents of a data file of a measurement may be as simple as:
|
|
254
|
+
|
|
255
|
+
.. code-block::
|
|
256
|
+
|
|
257
|
+
evefile = EveFile(filename="my_measurement_file.h5")
|
|
258
|
+
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
def __init__(self, filename="", load=True):
|
|
262
|
+
super().__init__()
|
|
263
|
+
self.filename = filename
|
|
264
|
+
self._join_factory = joining.JoinFactory(evefile=self)
|
|
265
|
+
if load:
|
|
266
|
+
if not filename:
|
|
267
|
+
raise ValueError("No filename given")
|
|
268
|
+
if not os.path.exists(filename):
|
|
269
|
+
raise FileNotFoundError(f"File {filename} does not exist.")
|
|
270
|
+
self._read_and_map_eveh5_file()
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
def filename(self):
|
|
274
|
+
"""
|
|
275
|
+
Name of the file to be loaded.
|
|
276
|
+
|
|
277
|
+
Returns
|
|
278
|
+
-------
|
|
279
|
+
filename : :class:`str`
|
|
280
|
+
Name of the file to be loaded.
|
|
281
|
+
|
|
282
|
+
"""
|
|
283
|
+
return self.metadata.filename
|
|
284
|
+
|
|
285
|
+
@filename.setter
|
|
286
|
+
def filename(self, filename=""):
|
|
287
|
+
self.metadata.filename = filename
|
|
288
|
+
|
|
289
|
+
def _read_and_map_eveh5_file(self):
|
|
290
|
+
eveh5 = HDF5File()
|
|
291
|
+
eveh5.read_attributes = True
|
|
292
|
+
eveh5.close_file = False
|
|
293
|
+
eveh5.read(filename=self.metadata.filename)
|
|
294
|
+
mapper_factory = version_mapping.VersionMapperFactory()
|
|
295
|
+
mapper = mapper_factory.get_mapper(eveh5)
|
|
296
|
+
mapper.map(source=eveh5, destination=self)
|
|
297
|
+
eveh5.close()
|
|
298
|
+
|
|
299
|
+
def get_data(self, name=None):
|
|
300
|
+
"""
|
|
301
|
+
Retrieve data objects by name.
|
|
302
|
+
|
|
303
|
+
While generally, you can get the data objects by accessing the
|
|
304
|
+
:attr:`data <evefile.entities.file.File.data>` attribute directly,
|
|
305
|
+
there, they are stored using their HDF5 dataset name as key.
|
|
306
|
+
Usually, however, data are accessed by their "given" name.
|
|
307
|
+
|
|
308
|
+
Parameters
|
|
309
|
+
----------
|
|
310
|
+
name : :class:`str` | :class:`list`
|
|
311
|
+
Name or list of names of data to retrieve
|
|
312
|
+
|
|
313
|
+
Returns
|
|
314
|
+
-------
|
|
315
|
+
data : :class:`evefile.entities.data.Data` | :class:`list`
|
|
316
|
+
Data object(s) corresponding to the name(s).
|
|
317
|
+
|
|
318
|
+
In case of a list of data objects, each object is of type
|
|
319
|
+
:class:`evefile.entities.data.Data`.
|
|
320
|
+
|
|
321
|
+
"""
|
|
322
|
+
data = []
|
|
323
|
+
names = {item.metadata.name: key for key, item in self.data.items()}
|
|
324
|
+
if isinstance(name, (list, tuple)):
|
|
325
|
+
for item in name:
|
|
326
|
+
data.append(self.data[names[item]])
|
|
327
|
+
else:
|
|
328
|
+
data.append(self.data[names[name]])
|
|
329
|
+
if len(data) == 1:
|
|
330
|
+
data = data[0]
|
|
331
|
+
return data
|
|
332
|
+
|
|
333
|
+
def get_data_names(self):
|
|
334
|
+
"""
|
|
335
|
+
Retrieve "given" names of data objects.
|
|
336
|
+
|
|
337
|
+
Data are stored in the :attr:`data <evefile.entities.file.File.data>`
|
|
338
|
+
attribute using their HDF5 dataset name as key. Usually, however,
|
|
339
|
+
data are accessed by their "given" name.
|
|
340
|
+
|
|
341
|
+
This method returns a list of all "given" names of the datasets
|
|
342
|
+
stored in :attr:`data <evefile.entities.file.File.data>`.
|
|
343
|
+
|
|
344
|
+
Returns
|
|
345
|
+
-------
|
|
346
|
+
data : :class:`list`
|
|
347
|
+
List of names of the data object(s) in :attr:`data`.
|
|
348
|
+
|
|
349
|
+
"""
|
|
350
|
+
names = [item.metadata.name for key, item in self.data.items()]
|
|
351
|
+
return names
|
|
352
|
+
|
|
353
|
+
def get_preferred_data(self):
|
|
354
|
+
"""
|
|
355
|
+
Retrieve data objects marked as preferred.
|
|
356
|
+
|
|
357
|
+
Within a scan, a preferred motor axis, a preferred detector
|
|
358
|
+
channel, and a preferred channel for normalisation can be
|
|
359
|
+
named explicitly. The preferred axis and channel are used for
|
|
360
|
+
plotting within the eve GUI during measurement.
|
|
361
|
+
|
|
362
|
+
.. note::
|
|
363
|
+
|
|
364
|
+
The datasets returned are guaranteed to be commensurate
|
|
365
|
+
and compatible and can hence directly be plotted against each
|
|
366
|
+
other. This is due to the fact that preferred axis and channel
|
|
367
|
+
currently must come from the same scan module of a scan.
|
|
368
|
+
|
|
369
|
+
Returns
|
|
370
|
+
-------
|
|
371
|
+
data : :class:`list`
|
|
372
|
+
Data objects corresponding to the preference settings.
|
|
373
|
+
|
|
374
|
+
A list with three elements:
|
|
375
|
+
|
|
376
|
+
#. preferred axis
|
|
377
|
+
#. preferred channel
|
|
378
|
+
#. preferred normalisation channel
|
|
379
|
+
|
|
380
|
+
If the preference has been set in the scan description,
|
|
381
|
+
the item in the list is of type
|
|
382
|
+
:class:`evefile.entities.data.MeasureData`, otherwise
|
|
383
|
+
:obj:`None`.
|
|
384
|
+
|
|
385
|
+
"""
|
|
386
|
+
output = [None, None, None]
|
|
387
|
+
if self.metadata.preferred_axis:
|
|
388
|
+
output[0] = self.data[self.metadata.preferred_axis]
|
|
389
|
+
if self.metadata.preferred_channel:
|
|
390
|
+
output[1] = self.data[self.metadata.preferred_channel]
|
|
391
|
+
if self.metadata.preferred_normalisation_channel:
|
|
392
|
+
output[2] = self.data[
|
|
393
|
+
self.metadata.preferred_normalisation_channel
|
|
394
|
+
]
|
|
395
|
+
return output
|
|
396
|
+
|
|
397
|
+
def get_joined_data(self, data=None, mode="AxisOrChannelPositions"):
|
|
398
|
+
"""
|
|
399
|
+
Retrieve data objects with commensurate dimensions.
|
|
400
|
+
|
|
401
|
+
For details on joining see the :mod:`joining
|
|
402
|
+
<evefile.controllers.joining>` module.
|
|
403
|
+
|
|
404
|
+
Parameters
|
|
405
|
+
----------
|
|
406
|
+
data : :class:`list`
|
|
407
|
+
(Names/IDs of) data objects whose data should be joined.
|
|
408
|
+
|
|
409
|
+
You can provide either names or IDs or the actual data objects.
|
|
410
|
+
|
|
411
|
+
If no data are given, by default all data available will be
|
|
412
|
+
joined.
|
|
413
|
+
|
|
414
|
+
Default: :obj:`None`
|
|
415
|
+
|
|
416
|
+
mode : :class:`str`
|
|
417
|
+
Name of the join mode to be used. This must be a mode
|
|
418
|
+
understood by the :class:`JoinFactory
|
|
419
|
+
<evefile.controllers.joining.JoinFactory>`.
|
|
420
|
+
|
|
421
|
+
Default: "AxisOrChannelPositions"
|
|
422
|
+
|
|
423
|
+
Returns
|
|
424
|
+
-------
|
|
425
|
+
data : :class:`list`
|
|
426
|
+
List of data objects.
|
|
427
|
+
|
|
428
|
+
Each item in the list is of type
|
|
429
|
+
:class:`evefile.entities.data.MeasureData`.
|
|
430
|
+
|
|
431
|
+
"""
|
|
432
|
+
if not data:
|
|
433
|
+
data = list(self.data.values())
|
|
434
|
+
joiner = self._join_factory.get_join(mode=mode)
|
|
435
|
+
return joiner.join(data)
|
|
436
|
+
|
|
437
|
+
def get_dataframe(self, data=None, mode="AxisOrChannelPositions"):
|
|
438
|
+
"""
|
|
439
|
+
Retrieve Pandas DataFrame with given data objects as columns.
|
|
440
|
+
|
|
441
|
+
Internally, the :meth:`get_joined_data` method will be called with
|
|
442
|
+
the data provided. If the ``data`` parameter is omitted,
|
|
443
|
+
all datasets will be used.
|
|
444
|
+
|
|
445
|
+
The names of the columns of the returned DataFrame are the names (not
|
|
446
|
+
IDs) of the respective datasets.
|
|
447
|
+
|
|
448
|
+
.. important::
|
|
449
|
+
|
|
450
|
+
While working with a Pandas DataFrame may seem convenient,
|
|
451
|
+
you're loosing basically all the relevant metadata of the
|
|
452
|
+
datasets. Hence, this method is rather a convenience method to
|
|
453
|
+
be backwards-compatible to older interfaces, but it is
|
|
454
|
+
explicitly *not* suggested for extensive use.
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
Parameters
|
|
458
|
+
----------
|
|
459
|
+
data : :class:`list`
|
|
460
|
+
(Names/IDs of) data objects whose data should be joined.
|
|
461
|
+
|
|
462
|
+
You can provide either names or IDs or the actual data objects.
|
|
463
|
+
|
|
464
|
+
If no data are given, by default all data available will be
|
|
465
|
+
joined.
|
|
466
|
+
|
|
467
|
+
Default: :obj:`None`
|
|
468
|
+
|
|
469
|
+
mode : :class:`str`
|
|
470
|
+
Name of the join mode to be used. This must be a mode
|
|
471
|
+
understood by the :class:`JoinFactory
|
|
472
|
+
<evefile.controllers.joining.JoinFactory>`.
|
|
473
|
+
|
|
474
|
+
Default: "AxisOrChannelPositions"
|
|
475
|
+
|
|
476
|
+
Returns
|
|
477
|
+
-------
|
|
478
|
+
dataframe : :class:`pandas.DataFrame`
|
|
479
|
+
Pandas DataFrame containing the given data objects as columns.
|
|
480
|
+
|
|
481
|
+
The names of the columns are the names (not IDs) of the
|
|
482
|
+
respective datasets.
|
|
483
|
+
|
|
484
|
+
"""
|
|
485
|
+
if not data:
|
|
486
|
+
data = list(self.data.values())
|
|
487
|
+
joined_data = self.get_joined_data(data=data, mode=mode)
|
|
488
|
+
dataframe = pd.DataFrame(
|
|
489
|
+
{item.metadata.name: item.data for item in joined_data}
|
|
490
|
+
)
|
|
491
|
+
dataframe.index.name = "PosRef"
|
|
492
|
+
return dataframe
|
|
493
|
+
|
|
494
|
+
def show_info(self):
|
|
495
|
+
"""
|
|
496
|
+
Print basic information regarding the contents of the loaded file.
|
|
497
|
+
|
|
498
|
+
Often, it is convenient to get a brief overview of the contents of
|
|
499
|
+
a file after it has been loaded. The output of this method
|
|
500
|
+
currently contains the following sections:
|
|
501
|
+
|
|
502
|
+
* metadata
|
|
503
|
+
* log messages
|
|
504
|
+
* data
|
|
505
|
+
* snapshots
|
|
506
|
+
* monitors
|
|
507
|
+
|
|
508
|
+
The output could look similar to the following:
|
|
509
|
+
|
|
510
|
+
.. code-block:: none
|
|
511
|
+
|
|
512
|
+
METADATA
|
|
513
|
+
filename: file.h5
|
|
514
|
+
eveh5_version: 7
|
|
515
|
+
eve_version: 2.0
|
|
516
|
+
xml_version: 9.2
|
|
517
|
+
measurement_station: Unittest
|
|
518
|
+
start: 2024-06-03 12:01:32
|
|
519
|
+
end: 2024-06-03 12:01:37
|
|
520
|
+
description:
|
|
521
|
+
simulation: False
|
|
522
|
+
preferred_axis: SimMot:01
|
|
523
|
+
preferred_channel: SimChan:01
|
|
524
|
+
preferred_normalisation_channel: SimChan:01
|
|
525
|
+
|
|
526
|
+
LOG MESSAGES
|
|
527
|
+
20250812T09:06:05: Lorem ipsum
|
|
528
|
+
|
|
529
|
+
DATA
|
|
530
|
+
foo (SimMot:01) <AxisData>
|
|
531
|
+
bar (SimChan:01) <SinglePointChannelData>
|
|
532
|
+
|
|
533
|
+
SNAPSHOTS
|
|
534
|
+
bar (SimChan:01) <AxisData>
|
|
535
|
+
bazfoo (SimChan:03) <AxisData>
|
|
536
|
+
foo (SimMot:01) <AxisData>
|
|
537
|
+
|
|
538
|
+
MONITORS
|
|
539
|
+
|
|
540
|
+
"""
|
|
541
|
+
print("METADATA")
|
|
542
|
+
print(self.metadata)
|
|
543
|
+
print("\nLOG MESSAGES")
|
|
544
|
+
for message in self.log_messages:
|
|
545
|
+
print(message)
|
|
546
|
+
print("\nDATA")
|
|
547
|
+
for item in self.data.values():
|
|
548
|
+
print(item)
|
|
549
|
+
print("\nSNAPSHOTS")
|
|
550
|
+
for item in self.snapshots.values():
|
|
551
|
+
print(item)
|
|
552
|
+
print("\nMONITORS")
|
|
553
|
+
for item in self.monitors.values():
|
|
554
|
+
print(item)
|