micress-micpy 0.2.17b0__py3-none-any.whl → 0.3.1b0__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.
- micpy/bin.py +217 -230
- micpy/geo.py +6 -5
- micpy/matplotlib.py +18 -47
- micpy/utils.py +0 -11
- micpy/version.py +1 -1
- micress_micpy-0.3.1b0.dist-info/METADATA +46 -0
- micress_micpy-0.3.1b0.dist-info/RECORD +12 -0
- micress_micpy-0.2.17b0.dist-info/METADATA +0 -186
- micress_micpy-0.2.17b0.dist-info/RECORD +0 -12
- {micress_micpy-0.2.17b0.dist-info → micress_micpy-0.3.1b0.dist-info}/LICENSE +0 -0
- {micress_micpy-0.2.17b0.dist-info → micress_micpy-0.3.1b0.dist-info}/WHEEL +0 -0
- {micress_micpy-0.2.17b0.dist-info → micress_micpy-0.3.1b0.dist-info}/top_level.txt +0 -0
micpy/bin.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"""The `micpy.bin` module provides methods to read and write binary files."""
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Callable, IO, List, Tuple,
|
|
4
|
+
from typing import Callable, Generator, IO, List, Optional, Tuple, Union
|
|
5
5
|
|
|
6
6
|
import gzip
|
|
7
7
|
import os
|
|
8
8
|
import sys
|
|
9
|
-
import warnings
|
|
10
9
|
import zlib
|
|
11
10
|
|
|
12
11
|
import numpy as np
|
|
@@ -16,7 +15,7 @@ from micpy import utils
|
|
|
16
15
|
from micpy.matplotlib import matplotlib, pyplot
|
|
17
16
|
|
|
18
17
|
|
|
19
|
-
__all__ = ["File"]
|
|
18
|
+
__all__ = ["File", "Field", "Series", "plot", "PlotArgs"]
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
@dataclass
|
|
@@ -263,9 +262,9 @@ class Index(List[Position]):
|
|
|
263
262
|
class Field(np.ndarray):
|
|
264
263
|
"""A field."""
|
|
265
264
|
|
|
266
|
-
def __new__(cls, data, time: float, spacing: float
|
|
265
|
+
def __new__(cls, data, time: float, spacing: Tuple[float, float, float]):
|
|
267
266
|
obj = np.asarray(data).view(cls)
|
|
268
|
-
obj.time =
|
|
267
|
+
obj.time = time
|
|
269
268
|
obj.spacing = spacing
|
|
270
269
|
return obj
|
|
271
270
|
|
|
@@ -353,223 +352,102 @@ class Field(np.ndarray):
|
|
|
353
352
|
|
|
354
353
|
return Field.from_bytes(field_data, shape=shape, spacing=spacing)
|
|
355
354
|
|
|
356
|
-
def
|
|
357
|
-
"""Write the field to a binary file.
|
|
358
|
-
file.write(self.to_bytes())
|
|
355
|
+
def to_file(self, file: IO[bytes], geometry: bool = True):
|
|
356
|
+
"""Write the field to a binary file.
|
|
359
357
|
|
|
360
|
-
|
|
361
|
-
|
|
358
|
+
Args:
|
|
359
|
+
file (IO[bytes]): Binary file.
|
|
360
|
+
geometry (bool, optional): `True` if geometry should be written, `False`
|
|
361
|
+
otherwise. Defaults to `True`.
|
|
362
|
+
"""
|
|
362
363
|
|
|
363
|
-
|
|
364
|
-
raise ValueError("Invalid plane")
|
|
364
|
+
file.write(self.to_bytes())
|
|
365
365
|
|
|
366
|
-
|
|
366
|
+
if geometry:
|
|
367
|
+
geo_filename, geo_data = geo.build(file.name, self.shape, self.spacing)
|
|
368
|
+
geo.write(geo_filename, geo_data, geo.Type.BASIC)
|
|
367
369
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
reshape_operations = {
|
|
371
|
-
1: lambda data: data.reshape((z, 1)),
|
|
372
|
-
2: lambda data: data.reshape((z, x)),
|
|
373
|
-
3: lambda data: data,
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
data = reshape_operations[dimensions](self)
|
|
377
|
-
|
|
378
|
-
slice_operations = {
|
|
379
|
-
1: {
|
|
380
|
-
"xz": lambda data: data,
|
|
381
|
-
"zx": lambda data: data.T,
|
|
382
|
-
"xy": lambda data: data[slice_id : slice_id + 1],
|
|
383
|
-
"yx": lambda data: data[slice_id : slice_id + 1],
|
|
384
|
-
"zy": lambda data: data.T,
|
|
385
|
-
"yz": lambda data: data,
|
|
386
|
-
},
|
|
387
|
-
2: {
|
|
388
|
-
"xz": lambda data: data,
|
|
389
|
-
"zx": lambda data: data.T,
|
|
390
|
-
"xy": lambda data: data[slice_id : slice_id + 1],
|
|
391
|
-
"yx": lambda data: data[slice_id : slice_id + 1].T,
|
|
392
|
-
"zy": lambda data: data.T[slice_id : slice_id + 1],
|
|
393
|
-
"yz": lambda data: data.T[slice_id : slice_id + 1].T,
|
|
394
|
-
},
|
|
395
|
-
3: {
|
|
396
|
-
"xy": lambda data: data[slice_id, :, :],
|
|
397
|
-
"yx": lambda data: data[slice_id, :, :].T,
|
|
398
|
-
"xz": lambda data: data[:, slice_id, :],
|
|
399
|
-
"zx": lambda data: data[:, slice_id, :].T,
|
|
400
|
-
"yz": lambda data: data[:, :, slice_id],
|
|
401
|
-
"zy": lambda data: data[:, :, slice_id].T,
|
|
402
|
-
},
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
return slice_operations[dimensions][plane](data)
|
|
406
|
-
|
|
407
|
-
# pylint: disable=too-many-arguments
|
|
408
|
-
def plot(
|
|
370
|
+
def write(
|
|
409
371
|
self,
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
figsize: Tuple[float, float] = None,
|
|
416
|
-
dpi: int = None,
|
|
417
|
-
aspect: str = "equal",
|
|
418
|
-
ax: "matplotlib.Axes" = None,
|
|
419
|
-
cax: "matplotlib.Axes" = None,
|
|
420
|
-
vmin: float = None,
|
|
421
|
-
vmax: float = None,
|
|
422
|
-
cmap: str = "micpy",
|
|
423
|
-
) -> Tuple["matplotlib.Figure", "matplotlib.Axes"]:
|
|
424
|
-
"""Plot a slice of the field.
|
|
372
|
+
filename: str,
|
|
373
|
+
compressed: bool = True,
|
|
374
|
+
geometry: bool = True,
|
|
375
|
+
):
|
|
376
|
+
"""Write the field to a binary file.
|
|
425
377
|
|
|
426
378
|
Args:
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
figsize (Tuple[float, float], optional): Figure size. Defaults to `None`
|
|
433
|
-
(auto).
|
|
434
|
-
dpi (int, optional): Figure DPI. Defaults to `None` (auto).
|
|
435
|
-
aspect (str, optional): Aspect ratio. Defaults to `equal`.
|
|
436
|
-
ax (Axes, optional): Axes to plot on. Defaults to `None`.
|
|
437
|
-
cax (Axes, optional): Axes to plot color bar on. Defaults to `None`.
|
|
438
|
-
vmin (float, optional): Minimum value of the color bar. Defaults to `None`.
|
|
439
|
-
vmax (float, optional): Maximum value of the color bar. Defaults to `None`.
|
|
440
|
-
cmap (str, optional): Color map. Defaults to `micpy`.
|
|
441
|
-
|
|
442
|
-
Returns:
|
|
443
|
-
Figure and axes of the plot.
|
|
379
|
+
filename (str): Filename of the binary file.
|
|
380
|
+
compressed (bool, optional): `True` if file should be compressed, `False`
|
|
381
|
+
otherwise. Defaults to `True`.
|
|
382
|
+
geometry (bool, optional): `True` if geometry should be written, `False`
|
|
383
|
+
otherwise. Defaults to `True`.
|
|
444
384
|
"""
|
|
445
|
-
if matplotlib is None:
|
|
446
|
-
raise ImportError("matplotlib is not installed")
|
|
447
|
-
|
|
448
|
-
slice = self.get_slice(plane, slice_id) if self.ndim == 3 else self
|
|
449
|
-
|
|
450
|
-
fig, ax = (
|
|
451
|
-
pyplot.subplots(figsize=figsize, dpi=dpi)
|
|
452
|
-
if ax is None
|
|
453
|
-
else (ax.get_figure(), ax)
|
|
454
|
-
)
|
|
455
|
-
|
|
456
|
-
if title is not None:
|
|
457
|
-
ax.set_title(title)
|
|
458
|
-
else:
|
|
459
|
-
ax.set_title(f"t={np.round(self.time, 7)}s")
|
|
460
|
-
if xlabel is not None:
|
|
461
|
-
ax.set_xlabel(xlabel)
|
|
462
|
-
else:
|
|
463
|
-
ax.set_xlabel(plane[0])
|
|
464
|
-
if ylabel is not None:
|
|
465
|
-
ax.set_ylabel(ylabel)
|
|
466
|
-
else:
|
|
467
|
-
ax.set_ylabel(plane[1])
|
|
468
|
-
if aspect is not None:
|
|
469
|
-
ax.set_aspect(aspect)
|
|
470
|
-
ax.set_frame_on(False)
|
|
471
|
-
|
|
472
|
-
mesh = ax.pcolormesh(slice, cmap=cmap, vmin=vmin, vmax=vmax)
|
|
473
|
-
|
|
474
|
-
bar = pyplot.colorbar(mesh, ax=ax, cax=cax)
|
|
475
|
-
bar.locator = matplotlib.ticker.MaxNLocator(
|
|
476
|
-
integer=np.issubdtype(slice.dtype, np.integer)
|
|
477
|
-
)
|
|
478
|
-
bar.outline.set_visible(False)
|
|
479
|
-
bar.update_ticks()
|
|
480
|
-
|
|
481
|
-
return fig, ax
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
class FieldList(List[Field]):
|
|
485
|
-
"""A list of fields."""
|
|
486
385
|
|
|
487
|
-
|
|
488
|
-
|
|
386
|
+
file_open = gzip.open if compressed else open
|
|
387
|
+
with file_open(filename, "wb") as file:
|
|
388
|
+
self.to_file(file, geometry)
|
|
489
389
|
|
|
490
|
-
def append(self, field: Field):
|
|
491
|
-
"""Append a field to the list."""
|
|
492
|
-
super().append(field)
|
|
493
390
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
391
|
+
class Series(np.ndarray):
|
|
392
|
+
def __new__(cls, fields: List[Field]):
|
|
393
|
+
obj = np.asarray(fields).view(cls)
|
|
394
|
+
obj.times = [field.time for field in fields]
|
|
395
|
+
obj.spacings = [field.spacing for field in fields]
|
|
396
|
+
return obj
|
|
397
|
+
|
|
398
|
+
def __array_finalize__(self, obj):
|
|
399
|
+
if obj is None:
|
|
400
|
+
return
|
|
497
401
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
with file_open(filename, "wb") as file:
|
|
502
|
-
for field in self:
|
|
503
|
-
field.write(file)
|
|
402
|
+
# pylint: disable=attribute-defined-outside-init
|
|
403
|
+
self.times = getattr(obj, "times", None)
|
|
404
|
+
self.spacings = getattr(obj, "spacings", None)
|
|
504
405
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
)
|
|
509
|
-
geo.write(geo_filename, geo_data, geo_type, compressed=compressed)
|
|
406
|
+
def __iter__(self):
|
|
407
|
+
for item, time, spacing in zip(self, self.times, self.spacings):
|
|
408
|
+
yield Field(item, time, spacing)
|
|
510
409
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
self,
|
|
514
|
-
cols: int = None,
|
|
515
|
-
normalize: bool = False,
|
|
516
|
-
sharex: bool = False,
|
|
517
|
-
sharey: bool = False,
|
|
518
|
-
figsize: Tuple[float, float] = None,
|
|
519
|
-
dpi: int = None,
|
|
520
|
-
**kwargs,
|
|
521
|
-
) -> Tuple["matplotlib.Figure", "matplotlib.Axes"]:
|
|
522
|
-
"""Plot the fields in a grid.
|
|
410
|
+
def get(self, index: Union[int, list, slice]) -> Field:
|
|
411
|
+
"""Get one or more fields from the series.
|
|
523
412
|
|
|
524
413
|
Args:
|
|
525
|
-
|
|
526
|
-
normalize (bool, optional): Normalize the color bar. Defaults to `False`.
|
|
527
|
-
sharex (bool, optional): Share x-axis. Defaults to `False`.
|
|
528
|
-
sharey (bool, optional): Share y-axis. Defaults to `False`.
|
|
529
|
-
figsize (Tuple[float, float], optional): Figure size. Defaults to `None`
|
|
530
|
-
(auto).
|
|
531
|
-
dpi (int, optional): Figure DPI. Defaults to `None` (auto).
|
|
532
|
-
**kwargs: Keyword arguments passed to `Field.plot()`.
|
|
414
|
+
index (Union[int, list, slice]): Index of the field.
|
|
533
415
|
|
|
534
416
|
Returns:
|
|
535
|
-
|
|
417
|
+
Field.
|
|
536
418
|
"""
|
|
537
|
-
if matplotlib is None:
|
|
538
|
-
raise ImportError("matplotlib is not installed")
|
|
539
419
|
|
|
540
|
-
if
|
|
541
|
-
|
|
420
|
+
if isinstance(index, int):
|
|
421
|
+
return Field(self[index], self.times[index], self.spacings[index])
|
|
422
|
+
elif isinstance(index, slice):
|
|
423
|
+
series = self[index]
|
|
424
|
+
series.times = self.times[index]
|
|
425
|
+
series.spacings = self.spacings[index]
|
|
426
|
+
return series
|
|
427
|
+
elif isinstance(index, list):
|
|
428
|
+
series = self[index]
|
|
429
|
+
series.times = [self.times[i] for i in index]
|
|
430
|
+
series.spacings = [self.spacings[i] for i in index]
|
|
431
|
+
return series
|
|
432
|
+
raise TypeError("Invalid argument type")
|
|
542
433
|
|
|
543
|
-
rows = (len(self) + cols - 1) // cols
|
|
544
434
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
)
|
|
435
|
+
def write(self, filename: str, compressed: bool = True, geometry: bool = True):
|
|
436
|
+
"""Write the series to a binary file.
|
|
548
437
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
if
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
if normalize
|
|
557
|
-
else kwargs.pop("vmax", None)
|
|
558
|
-
)
|
|
559
|
-
|
|
560
|
-
flat_ax = ax.flatten() if isinstance(ax, np.ndarray) else [ax]
|
|
561
|
-
|
|
562
|
-
for i, field in enumerate(self):
|
|
563
|
-
field.plot(ax=flat_ax[i], vmin=vmin, vmax=vmax, **kwargs)
|
|
564
|
-
|
|
565
|
-
for i in range(len(self), len(flat_ax)):
|
|
566
|
-
fig.delaxes(flat_ax[i])
|
|
567
|
-
|
|
568
|
-
with warnings.catch_warnings():
|
|
569
|
-
warnings.simplefilter("ignore")
|
|
570
|
-
fig.tight_layout()
|
|
438
|
+
Args:
|
|
439
|
+
filename (str): Filename of the binary file.
|
|
440
|
+
compressed (bool, optional): `True` if file should be compressed, `False`
|
|
441
|
+
otherwise. Defaults to `True`.
|
|
442
|
+
geometry (bool, optional): `True` if geometry should be written, `False`
|
|
443
|
+
otherwise. Defaults to `True`.
|
|
444
|
+
"""
|
|
571
445
|
|
|
572
|
-
|
|
446
|
+
file_open = gzip.open if compressed else open
|
|
447
|
+
with file_open(filename, "wb") as file:
|
|
448
|
+
for field in self:
|
|
449
|
+
field.to_file(file, geometry)
|
|
450
|
+
geometry = False
|
|
573
451
|
|
|
574
452
|
|
|
575
453
|
class File:
|
|
@@ -609,12 +487,12 @@ class File:
|
|
|
609
487
|
self.spacing: np.ndarray[(3,), np.float32] = None
|
|
610
488
|
|
|
611
489
|
try:
|
|
612
|
-
self.
|
|
490
|
+
self.find_geometry()
|
|
613
491
|
except (geo.GeometryFileNotFoundError, geo.MultipleGeometryFilesError):
|
|
614
492
|
if self._verbose:
|
|
615
493
|
self._warn("Caution: A geometry file was not found.")
|
|
616
494
|
|
|
617
|
-
def __getitem__(self, key: int
|
|
495
|
+
def __getitem__(self, key: Union[int, slice, list, Callable[[Field], bool]]):
|
|
618
496
|
return self.read(key)
|
|
619
497
|
|
|
620
498
|
def __enter__(self):
|
|
@@ -704,42 +582,43 @@ class File:
|
|
|
704
582
|
"""
|
|
705
583
|
return [position.time for position in self.index()]
|
|
706
584
|
|
|
707
|
-
def
|
|
585
|
+
def set_geometry(
|
|
586
|
+
self, shape: Tuple[int, int, int], spacing: Tuple[float, float, float]
|
|
587
|
+
):
|
|
708
588
|
"""Set the geometry.
|
|
709
589
|
|
|
710
590
|
Args:
|
|
711
591
|
shape (Tuple[int, int, int]): Shape of the geometry.
|
|
712
|
-
spacing (Tuple[float, float, float]): Spacing of the geometry in μm
|
|
592
|
+
spacing (Tuple[float, float, float]): Spacing of the geometry in μm.
|
|
713
593
|
"""
|
|
714
594
|
|
|
715
595
|
self.shape = np.array(shape)
|
|
716
596
|
self.spacing = np.array(spacing)
|
|
717
597
|
|
|
718
|
-
self.
|
|
598
|
+
self.print_geometry()
|
|
719
599
|
|
|
720
|
-
def
|
|
721
|
-
self, filename: str, type: geo.Type = geo.Type.EXTENDED, compressed: bool = True
|
|
722
|
-
):
|
|
600
|
+
def read_geometry(self, filename: str, compressed: Optional[bool] = None):
|
|
723
601
|
"""Read geometry from a file.
|
|
724
602
|
|
|
725
603
|
Args:
|
|
726
604
|
filename (str): Filename of a geometry file.
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
otherwise. Defaults to True.
|
|
605
|
+
compressed (bool, optional): `True` if file is compressed, `False`
|
|
606
|
+
otherwise. Defaults to `None` (auto).
|
|
730
607
|
"""
|
|
731
|
-
|
|
608
|
+
if compressed is None:
|
|
609
|
+
compressed = utils.is_compressed(filename)
|
|
732
610
|
|
|
733
|
-
|
|
734
|
-
spacing = utils.convert_si(geo_dict["spacing"], "cm", "μm")
|
|
611
|
+
geometry = geo.read(filename, type=geo.Type.BASIC, compressed=compressed)
|
|
735
612
|
|
|
736
|
-
|
|
613
|
+
shape = geometry["shape"]
|
|
614
|
+
spacing = geometry["spacing"]
|
|
737
615
|
|
|
738
|
-
|
|
616
|
+
self.set_geometry(shape, spacing)
|
|
617
|
+
|
|
618
|
+
def find_geometry(self, compressed: Optional[bool] = None):
|
|
739
619
|
"""Find geometry file and read it.
|
|
740
620
|
|
|
741
621
|
Args:
|
|
742
|
-
type (Type, optional): Data type to be read. Defaults to `Type.EXTENDED`.
|
|
743
622
|
compressed (bool, optional): True if file is compressed, False otherwise.
|
|
744
623
|
Defaults to `None` (auto).
|
|
745
624
|
|
|
@@ -749,12 +628,9 @@ class File:
|
|
|
749
628
|
"""
|
|
750
629
|
filename = geo.find(self._filename)
|
|
751
630
|
|
|
752
|
-
|
|
753
|
-
compressed = utils.is_compressed(filename)
|
|
754
|
-
|
|
755
|
-
self.read_geo(filename, type=type, compressed=compressed)
|
|
631
|
+
self.read_geometry(filename, compressed=compressed)
|
|
756
632
|
|
|
757
|
-
def
|
|
633
|
+
def print_geometry(self):
|
|
758
634
|
"""Get a string representation of the geometry."""
|
|
759
635
|
|
|
760
636
|
if self.shape is None or self.spacing is None:
|
|
@@ -763,36 +639,38 @@ class File:
|
|
|
763
639
|
|
|
764
640
|
dimensions = Field.dimensions(self.shape)
|
|
765
641
|
cells = self.shape
|
|
766
|
-
spacing = np.round(self.spacing, 7)
|
|
642
|
+
spacing = 1e4 * np.round(self.spacing.astype(float), 7)
|
|
767
643
|
size = cells * spacing
|
|
768
644
|
|
|
769
645
|
self._info(f"Geometry: {dimensions}-Dimensional Grid")
|
|
770
|
-
self._info(f"Grid Size: {tuple(size)}
|
|
646
|
+
self._info(f"Grid Size [μm]: {tuple(size)}")
|
|
771
647
|
self._info(f"Grid Shape (Cell Count): {tuple(cells)}")
|
|
772
|
-
self._info(f"Grid Spacing (Cell Size): {tuple(spacing)}
|
|
648
|
+
self._info(f"Grid Spacing (Cell Size) [μm]: {tuple(spacing)}")
|
|
773
649
|
|
|
774
650
|
def iterate(self) -> Generator[Field, None, None]:
|
|
775
651
|
"""Iterate over fields in the file.
|
|
776
652
|
|
|
777
653
|
Returns:
|
|
778
|
-
|
|
654
|
+
A generator of fields.
|
|
779
655
|
"""
|
|
780
656
|
for position in self.index():
|
|
781
657
|
yield Field.read(position, shape=self.shape, spacing=self.spacing)
|
|
782
658
|
|
|
783
|
-
def read(
|
|
784
|
-
|
|
659
|
+
def read(
|
|
660
|
+
self, key: Optional[Union[int, slice, list, Callable[[Field], bool]]] = None
|
|
661
|
+
) -> Series:
|
|
662
|
+
"""Read field data from the file.
|
|
785
663
|
|
|
786
664
|
Args:
|
|
787
|
-
key (int
|
|
665
|
+
key (Union[int, slice, list, Callable[[Field], bool], optional): Key to
|
|
788
666
|
list of field IDs, a slice object, or a condition function.
|
|
789
667
|
Defaults to `None`.
|
|
790
668
|
|
|
791
669
|
Returns:
|
|
792
|
-
|
|
670
|
+
A series of fields.
|
|
793
671
|
"""
|
|
794
672
|
|
|
795
|
-
def read_field(self, field_id: int
|
|
673
|
+
def read_field(self, field_id: Union[int, slice, list]):
|
|
796
674
|
position = self._index[field_id]
|
|
797
675
|
return Field.read(position, shape=self.shape, spacing=self.spacing)
|
|
798
676
|
|
|
@@ -819,4 +697,113 @@ class File:
|
|
|
819
697
|
else:
|
|
820
698
|
raise TypeError("Invalid argument type")
|
|
821
699
|
|
|
822
|
-
return
|
|
700
|
+
return Series(fields)
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
@dataclass
|
|
704
|
+
class PlotArgs:
|
|
705
|
+
"""Arguments for plotting a field.
|
|
706
|
+
|
|
707
|
+
Args:
|
|
708
|
+
title (str, optional): Title of the plot. Defaults to `None`.
|
|
709
|
+
xlabel (str, optional): Label of the x-axis. Defaults to `None`.
|
|
710
|
+
ylabel (str, optional): Label of the y-axis. Defaults to `None`.
|
|
711
|
+
figsize (Tuple[float, float], optional): Figure size. Defaults to `None`.
|
|
712
|
+
dpi (int, optional): Figure DPI. Defaults to `None`.
|
|
713
|
+
aspect (str, optional): Aspect ratio. Defaults to `equal`.
|
|
714
|
+
ax (matplotlib.Axes, optional): Axes of the plot. Defaults to `None`.
|
|
715
|
+
cax (matplotlib.Axes, optional): Axes of the color bar. Defaults to `None`.
|
|
716
|
+
vmin (float, optional): Minimum value of the color bar. Defaults to `None`.
|
|
717
|
+
vmax (float, optional): Maximum value of the color bar. Defaults to `None`.
|
|
718
|
+
cmap (str, optional): Colormap. Defaults to `micpy`.
|
|
719
|
+
"""
|
|
720
|
+
|
|
721
|
+
title: Optional[str] = None
|
|
722
|
+
xlabel: Optional[str] = None
|
|
723
|
+
ylabel: Optional[str] = None
|
|
724
|
+
figsize: Optional[Tuple[float, float]] = None
|
|
725
|
+
dpi: Optional[int] = None
|
|
726
|
+
aspect: str = "equal"
|
|
727
|
+
ax: "matplotlib.Axes" = None
|
|
728
|
+
cax: "matplotlib.Axes" = None
|
|
729
|
+
vmin: Optional[float] = None
|
|
730
|
+
vmax: Optional[float] = None
|
|
731
|
+
cmap: str = "micpy"
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
def plot(
|
|
735
|
+
field: Field,
|
|
736
|
+
axis: str = "y",
|
|
737
|
+
index: int = 0,
|
|
738
|
+
args: Optional[PlotArgs] = None,
|
|
739
|
+
) -> Tuple["matplotlib.Figure", "matplotlib.Axes"]:
|
|
740
|
+
"""Plot a slice of the field.
|
|
741
|
+
|
|
742
|
+
Args:
|
|
743
|
+
field (Field): Field to plot.
|
|
744
|
+
axis (str, optional): Axis to plot. Possible values are `x`, `y`, and `z`.
|
|
745
|
+
Defaults to `y`.
|
|
746
|
+
index (int, optional): Index of the slice. Defaults to `0`.
|
|
747
|
+
args (PlotArgs, optional): Arguments for plotting. Defaults to `None`.
|
|
748
|
+
|
|
749
|
+
Returns:
|
|
750
|
+
Matplotlib figure and axes of the plot.
|
|
751
|
+
"""
|
|
752
|
+
|
|
753
|
+
if matplotlib is None:
|
|
754
|
+
raise ImportError("matplotlib is not installed")
|
|
755
|
+
|
|
756
|
+
if axis not in ["x", "y", "z"]:
|
|
757
|
+
raise ValueError("Invalid axis")
|
|
758
|
+
|
|
759
|
+
if field.ndim != 3:
|
|
760
|
+
raise ValueError("Invalid field shape")
|
|
761
|
+
|
|
762
|
+
if args is None:
|
|
763
|
+
args = PlotArgs()
|
|
764
|
+
|
|
765
|
+
if axis == "z":
|
|
766
|
+
x, y = "x", "y"
|
|
767
|
+
slice_2d = field[index, :, :]
|
|
768
|
+
elif axis == "y":
|
|
769
|
+
x, y = "x", "z"
|
|
770
|
+
slice_2d = field[:, index, :]
|
|
771
|
+
if Field.dimensions(field.shape) == 2:
|
|
772
|
+
slice_2d = slice_2d.reshape(slice_2d.shape[1], slice_2d.shape[0])
|
|
773
|
+
elif axis == "x":
|
|
774
|
+
x, y = "y", "z"
|
|
775
|
+
slice_2d = field[:, :, index]
|
|
776
|
+
|
|
777
|
+
fig, ax = (
|
|
778
|
+
pyplot.subplots(figsize=args.figsize, dpi=args.dpi)
|
|
779
|
+
if args.ax is None
|
|
780
|
+
else (args.ax.get_figure(), args.ax)
|
|
781
|
+
)
|
|
782
|
+
|
|
783
|
+
if args.title is not None:
|
|
784
|
+
ax.set_title(args.title)
|
|
785
|
+
else:
|
|
786
|
+
if isinstance(field, Field):
|
|
787
|
+
ax.set_title(f"t={np.round(field.time, 7)}s")
|
|
788
|
+
if args.xlabel is not None:
|
|
789
|
+
ax.set_xlabel(args.xlabel)
|
|
790
|
+
else:
|
|
791
|
+
ax.set_xlabel(x)
|
|
792
|
+
if args.ylabel is not None:
|
|
793
|
+
ax.set_ylabel(args.ylabel)
|
|
794
|
+
else:
|
|
795
|
+
ax.set_ylabel(y)
|
|
796
|
+
if args.aspect is not None:
|
|
797
|
+
ax.set_aspect(args.aspect)
|
|
798
|
+
ax.set_frame_on(False)
|
|
799
|
+
|
|
800
|
+
mesh = ax.pcolormesh(slice_2d, cmap=args.cmap, vmin=args.vmin, vmax=args.vmax)
|
|
801
|
+
|
|
802
|
+
bar = pyplot.colorbar(mesh, ax=ax, cax=args.cax)
|
|
803
|
+
bar.locator = matplotlib.ticker.MaxNLocator(
|
|
804
|
+
integer=np.issubdtype(slice_2d.dtype, np.integer)
|
|
805
|
+
)
|
|
806
|
+
bar.outline.set_visible(False)
|
|
807
|
+
bar.update_ticks()
|
|
808
|
+
|
|
809
|
+
return fig, ax
|
micpy/geo.py
CHANGED
|
@@ -5,6 +5,7 @@ import gzip
|
|
|
5
5
|
|
|
6
6
|
from typing import Tuple
|
|
7
7
|
from pathlib import Path
|
|
8
|
+
from typing import Optional
|
|
8
9
|
|
|
9
10
|
import numpy as np
|
|
10
11
|
from numpy import ndarray
|
|
@@ -89,7 +90,7 @@ def read(filename: str, type: Type = Type.EXTENDED, compressed: bool = True) ->
|
|
|
89
90
|
|
|
90
91
|
Args:
|
|
91
92
|
filename (str): Filename of a geometry file.
|
|
92
|
-
type (Type, optional): Data type to be read.
|
|
93
|
+
type (Type, optional): Data type to be read. Defaults to `Type.EXTENDED`.
|
|
93
94
|
compressed (bool, optional): True if file is compressed, False otherwise.
|
|
94
95
|
Defaults to `True`.
|
|
95
96
|
|
|
@@ -131,7 +132,7 @@ def write(
|
|
|
131
132
|
filename (str): Filename of a geometry file.
|
|
132
133
|
data (dict): Dictionary representation of a geometry file.
|
|
133
134
|
type (Type, optional): Data type to be written. Defaults to `Type.EXTENDED`.
|
|
134
|
-
compressed (bool, optional): `True` if file should be compressed, `False`
|
|
135
|
+
compressed (bool, optional): `True` if file should be compressed, `False`
|
|
135
136
|
otherwise. Defaults to `True`.
|
|
136
137
|
"""
|
|
137
138
|
array_data = _dict_to_ndarray(data, type)
|
|
@@ -157,7 +158,7 @@ def write_ndarray(filename: str, data: ndarray, compressed: bool = True):
|
|
|
157
158
|
f.write(data.tobytes())
|
|
158
159
|
|
|
159
160
|
|
|
160
|
-
def
|
|
161
|
+
def build(
|
|
161
162
|
filename: str, shape: Tuple[int, int, int], spacing: Tuple[float, float, float]
|
|
162
163
|
) -> Tuple[str, dict, Type]:
|
|
163
164
|
"""Create a basic geometry.
|
|
@@ -174,7 +175,7 @@ def get_basic(
|
|
|
174
175
|
"spacing": spacing,
|
|
175
176
|
"basic_footer": 24,
|
|
176
177
|
}
|
|
177
|
-
return geo_filename, geo_data
|
|
178
|
+
return geo_filename, geo_data
|
|
178
179
|
|
|
179
180
|
|
|
180
181
|
def _get_basename(path: Path) -> Path:
|
|
@@ -194,7 +195,7 @@ def _get_basename(path: Path) -> Path:
|
|
|
194
195
|
return path.with_suffix("")
|
|
195
196
|
|
|
196
197
|
|
|
197
|
-
def _validate_data_type(data: np.ndarray) -> bool:
|
|
198
|
+
def _validate_data_type(data: Optional[np.ndarray]) -> bool:
|
|
198
199
|
"""Validate the data type."""
|
|
199
200
|
if not isinstance(data, np.ndarray):
|
|
200
201
|
return False
|
micpy/matplotlib.py
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
from distutils.version import LooseVersion
|
|
3
|
-
|
|
1
|
+
from packaging import version
|
|
4
2
|
|
|
5
3
|
try:
|
|
6
4
|
import matplotlib
|
|
@@ -13,31 +11,30 @@ except ImportError:
|
|
|
13
11
|
|
|
14
12
|
def _register_colormaps():
|
|
15
13
|
colors = [
|
|
16
|
-
"#1102d8",
|
|
17
|
-
"#3007ba",
|
|
18
|
-
"#500b9d",
|
|
19
|
-
"#6f0e81",
|
|
20
|
-
"#8d1364",
|
|
21
|
-
"#ac1748",
|
|
22
|
-
"#cb1b2b",
|
|
23
|
-
"#ea1e0f",
|
|
24
|
-
"#f83605",
|
|
25
|
-
"#fa600f",
|
|
26
|
-
"#fb8817",
|
|
27
|
-
"#fdb120",
|
|
28
|
-
"#ffda29",
|
|
29
|
-
"#ffed4d",
|
|
30
|
-
"#fff380",
|
|
31
|
-
"#fffbb4",
|
|
14
|
+
"#1102d8",
|
|
15
|
+
"#3007ba",
|
|
16
|
+
"#500b9d",
|
|
17
|
+
"#6f0e81",
|
|
18
|
+
"#8d1364",
|
|
19
|
+
"#ac1748",
|
|
20
|
+
"#cb1b2b",
|
|
21
|
+
"#ea1e0f",
|
|
22
|
+
"#f83605",
|
|
23
|
+
"#fa600f",
|
|
24
|
+
"#fb8817",
|
|
25
|
+
"#fdb120",
|
|
26
|
+
"#ffda29",
|
|
27
|
+
"#ffed4d",
|
|
28
|
+
"#fff380",
|
|
29
|
+
"#fffbb4",
|
|
32
30
|
]
|
|
33
|
-
version = LooseVersion(matplotlib.__version__) >= LooseVersion("3.7")
|
|
34
31
|
|
|
35
32
|
create = matplotlib.colors.LinearSegmentedColormap.from_list
|
|
36
33
|
|
|
37
34
|
colormap = create(name="micpy", colors=colors, N=1024)
|
|
38
35
|
colormap_r = create(name="micpy_r", colors=colors[::-1], N=1024)
|
|
39
36
|
|
|
40
|
-
if version:
|
|
37
|
+
if version.parse(matplotlib.__version__) >= version.parse("3.7"):
|
|
41
38
|
register = matplotlib.colormaps.register
|
|
42
39
|
register(colormap)
|
|
43
40
|
register(colormap_r)
|
|
@@ -47,28 +44,6 @@ def _register_colormaps():
|
|
|
47
44
|
register("micpy_r", colormap_r)
|
|
48
45
|
|
|
49
46
|
|
|
50
|
-
def _set_aixvipmap_font():
|
|
51
|
-
font = "IBM Plex Sans"
|
|
52
|
-
if font in matplotlib.font_manager.get_font_names():
|
|
53
|
-
pyplot.rcParams["font.family"] = font
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def _set_aixvipmap_colors():
|
|
57
|
-
colors = [
|
|
58
|
-
"#00549F",
|
|
59
|
-
"#F6A800",
|
|
60
|
-
"#57AB27",
|
|
61
|
-
"#CC071E",
|
|
62
|
-
"#612158",
|
|
63
|
-
"#006165",
|
|
64
|
-
"#E30066",
|
|
65
|
-
"#0098A1",
|
|
66
|
-
"#BDCD00",
|
|
67
|
-
"#0098A1",
|
|
68
|
-
]
|
|
69
|
-
pyplot.rcParams["axes.prop_cycle"] = pyplot.cycler(color=colors)
|
|
70
|
-
|
|
71
|
-
|
|
72
47
|
def configure():
|
|
73
48
|
if not matplotlib:
|
|
74
49
|
return
|
|
@@ -77,7 +52,3 @@ def configure():
|
|
|
77
52
|
_register_colormaps()
|
|
78
53
|
except ValueError:
|
|
79
54
|
pass
|
|
80
|
-
|
|
81
|
-
if "AIXVIPMAP_HOME" in os.environ:
|
|
82
|
-
_set_aixvipmap_font()
|
|
83
|
-
_set_aixvipmap_colors()
|
micpy/utils.py
CHANGED
|
@@ -4,17 +4,6 @@ import sys
|
|
|
4
4
|
import time
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def convert_si(value, unit_in, unit_out):
|
|
8
|
-
"""Convert value from one SI unit to another SI unit."""
|
|
9
|
-
SI = {"μm": 0.000001, "mm": 0.001, "cm": 0.01, "m": 1.0}
|
|
10
|
-
|
|
11
|
-
if isinstance(value, (float, int)):
|
|
12
|
-
return value * SI[unit_in] / SI[unit_out]
|
|
13
|
-
elif isinstance(value, (tuple, list)):
|
|
14
|
-
return [v * SI[unit_in] / SI[unit_out] for v in value]
|
|
15
|
-
raise ValueError("Unsupported value type.")
|
|
16
|
-
|
|
17
|
-
|
|
18
7
|
def progress_indicator(iterable, description="Progress", unit="Iteration", start=1):
|
|
19
8
|
"""Progress indicator for iterable."""
|
|
20
9
|
|
micpy/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.3.1b0"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: micress-micpy
|
|
3
|
+
Version: 0.3.1b0
|
|
4
|
+
Summary: MicPy is a Python package to facilitate MICRESS workflows.
|
|
5
|
+
Author: Lukas Koschmieder
|
|
6
|
+
Author-email: l.koschmieder@access-technology.de
|
|
7
|
+
License: BSD-3-Clause (Copyright (c) 2024 Access e.V.)
|
|
8
|
+
Keywords: MICRESS
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Natural Language :: English
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Requires-Python: >=3.9
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: matplotlib
|
|
18
|
+
Requires-Dist: pandas
|
|
19
|
+
|
|
20
|
+
<center>
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
</center>
|
|
25
|
+
|
|
26
|
+
# MicPy
|
|
27
|
+
|
|
28
|
+
MicPy is a Python package to facilitate [MICRESS](https://www.micress.de) workflows. Whether you aim to visualize, convert, or manipulate MICRESS data, MicPy provides the necessary tools.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
pip install micress-micpy
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Dependencies
|
|
37
|
+
|
|
38
|
+
MicPy requires the following dependencies:
|
|
39
|
+
|
|
40
|
+
- Python (>= 3.9)
|
|
41
|
+
- Pandas (>= 1.1)
|
|
42
|
+
- Matplotlib (>= 3) as an optional dependency for plotting
|
|
43
|
+
|
|
44
|
+
## Documentation
|
|
45
|
+
|
|
46
|
+
https://docs.micress.de/micpy
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
micpy/__init__.py,sha256=7wQUaseppjQYZW1iAVNm2WSDjvBLlqtY8tiHsfDaW5Q,148
|
|
2
|
+
micpy/bin.py,sha256=3xclBJLbbBW9N8w9izFEgFh3S2yKgYzrdQKjJsXftSU,25831
|
|
3
|
+
micpy/geo.py,sha256=lVRTtPnTEykkSXNyLm3wnxXOwz72PFu0Spv8ZGHyUHo,7417
|
|
4
|
+
micpy/matplotlib.py,sha256=GF2ghyBORC5RRjW00DdsHu5aSkpMFdI9wqg6d_psPsI,1198
|
|
5
|
+
micpy/tab.py,sha256=QCnfggxRWkKgS9-zGj8kyCjhfUw7QeTgGZWedHh4MTw,3548
|
|
6
|
+
micpy/utils.py,sha256=Kt1AvhMvWer9uftbb88X7N27aXtQdJl26grHmmm2vOQ,859
|
|
7
|
+
micpy/version.py,sha256=o80l_DIF5j_g0KFIiC8SP5DtyipTIK4_NRfkjHjz1Mk,25
|
|
8
|
+
micress_micpy-0.3.1b0.dist-info/LICENSE,sha256=seHdCiArizUoWZ6bEFg6N3K2ZtfPK35wvOwg0kH-f6o,1488
|
|
9
|
+
micress_micpy-0.3.1b0.dist-info/METADATA,sha256=UFUfB1rNxBQxj1OlMO9Qo3YX92weqibYc59tujF8lBo,1229
|
|
10
|
+
micress_micpy-0.3.1b0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
11
|
+
micress_micpy-0.3.1b0.dist-info/top_level.txt,sha256=RiopkpW0AGNYdtOW2eQUWgm3yHGC13q9pWlHb2alhiE,6
|
|
12
|
+
micress_micpy-0.3.1b0.dist-info/RECORD,,
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: micress-micpy
|
|
3
|
-
Version: 0.2.17b0
|
|
4
|
-
Summary: MicPy is a Python package to facilitate MICRESS workflows.
|
|
5
|
-
Author: Lukas Koschmieder
|
|
6
|
-
Author-email: l.koschmieder@access-technology.de
|
|
7
|
-
License: BSD-3-Clause (Copyright (c) 2024 Access e.V.)
|
|
8
|
-
Keywords: MICRESS
|
|
9
|
-
Classifier: Development Status :: 4 - Beta
|
|
10
|
-
Classifier: Intended Audience :: Science/Research
|
|
11
|
-
Classifier: Natural Language :: English
|
|
12
|
-
Classifier: Operating System :: OS Independent
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
-
Requires-Python: >=3.9
|
|
15
|
-
Description-Content-Type: text/markdown
|
|
16
|
-
License-File: LICENSE
|
|
17
|
-
Requires-Dist: matplotlib
|
|
18
|
-
Requires-Dist: pandas
|
|
19
|
-
|
|
20
|
-
<center>
|
|
21
|
-
|
|
22
|
-

|
|
23
|
-
|
|
24
|
-
</center>
|
|
25
|
-
|
|
26
|
-
# MicPy
|
|
27
|
-
|
|
28
|
-
MicPy is a Python package to facilitate [MICRESS](https://www.micress.de) workflows. Whether you aim to visualize, convert, or manipulate MICRESS data, MicPy provides the necessary tools.
|
|
29
|
-
|
|
30
|
-
## Installation
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
pip install micress-micpy
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Dependencies
|
|
37
|
-
|
|
38
|
-
MicPy requires the following dependencies:
|
|
39
|
-
|
|
40
|
-
- Python (>= 3.9)
|
|
41
|
-
- Pandas (>= 1.1)
|
|
42
|
-
- Matplotlib (>= 3) as an optional dependency for plotting
|
|
43
|
-
|
|
44
|
-
## Examples
|
|
45
|
-
|
|
46
|
-
Below are some examples demonstrating how to use MicPy.
|
|
47
|
-
|
|
48
|
-
### `bin` module
|
|
49
|
-
|
|
50
|
-
#### Read one field at a time
|
|
51
|
-
|
|
52
|
-
```python
|
|
53
|
-
from micpy import bin
|
|
54
|
-
|
|
55
|
-
for field in bin.File("A001_Delta_Gamma.conc1"):
|
|
56
|
-
print(field)
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
#### Read all fields
|
|
60
|
-
|
|
61
|
-
```python
|
|
62
|
-
|
|
63
|
-
from micpy import bin
|
|
64
|
-
|
|
65
|
-
with bin.File("A001_Delta_Gamma.conc1") as file:
|
|
66
|
-
fields = file.read()
|
|
67
|
-
|
|
68
|
-
print(fields)
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
#### Read a subset of fields providing a list of indices
|
|
72
|
-
|
|
73
|
-
```python
|
|
74
|
-
from micpy import bin
|
|
75
|
-
|
|
76
|
-
with bin.File("A001_Delta_Gamma.conc1") as file:
|
|
77
|
-
fields = file.read([0, 1, -2, -1])
|
|
78
|
-
|
|
79
|
-
print(fields)
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
#### Read a subset of fields providing a condition function
|
|
83
|
-
|
|
84
|
-
```python
|
|
85
|
-
from micpy import bin
|
|
86
|
-
|
|
87
|
-
with bin.File("A001_Delta_Gamma.conc1") as file:
|
|
88
|
-
fields = file.read(lambda field: field.time >= 10 and field.time <= 20)
|
|
89
|
-
|
|
90
|
-
print(fields)
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
#### Read fields opening and closing the file manually
|
|
94
|
-
|
|
95
|
-
```python
|
|
96
|
-
from micpy import bin
|
|
97
|
-
|
|
98
|
-
file = bin.File("A001_Delta_Gamma.conc1")
|
|
99
|
-
|
|
100
|
-
file.open()
|
|
101
|
-
|
|
102
|
-
first_field = file.read(0)
|
|
103
|
-
second_field = file.read(1)
|
|
104
|
-
|
|
105
|
-
file.close()
|
|
106
|
-
|
|
107
|
-
print(first_field, second_field)
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
#### Plot a field
|
|
111
|
-
|
|
112
|
-
```python
|
|
113
|
-
from micpy import bin
|
|
114
|
-
|
|
115
|
-
with bin.File("A001_Delta_Gamma.conc1") as file:
|
|
116
|
-
field = file[-1]
|
|
117
|
-
|
|
118
|
-
fig, ax = field.plot()
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
#### Plot a list of fields normalizing the data
|
|
122
|
-
|
|
123
|
-
```python
|
|
124
|
-
from micpy import bin
|
|
125
|
-
|
|
126
|
-
with bin.File("A001_Delta_Gamma.conc1") as file:
|
|
127
|
-
fields = file[[0, 1, -2, -1]]
|
|
128
|
-
|
|
129
|
-
fig, ax = fields.plot(normalize=True, figsize=(8, 8))
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
#### Plot a specific plane of a field
|
|
133
|
-
|
|
134
|
-
```python
|
|
135
|
-
from micpy import bin
|
|
136
|
-
|
|
137
|
-
with bin.File("A005_Grain_Growth_Misorientation_3D.korn") as file:
|
|
138
|
-
field = file[0]
|
|
139
|
-
|
|
140
|
-
fig, ax = field.plot(plane="xy", slice=50)
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### `tab` module
|
|
144
|
-
|
|
145
|
-
#### Read a table
|
|
146
|
-
|
|
147
|
-
```python
|
|
148
|
-
from micpy import tab
|
|
149
|
-
|
|
150
|
-
table = tab.read("A001_Delta_Gamma.TabF")
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
#### Plot a table
|
|
154
|
-
|
|
155
|
-
```python
|
|
156
|
-
from micpy import tab
|
|
157
|
-
|
|
158
|
-
table = tab.read("A001_Delta_Gamma.TabF")
|
|
159
|
-
|
|
160
|
-
fig, ax = table.plot(x=1, y=[2, 3, 4])
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
#### Extract a subset of a table
|
|
164
|
-
|
|
165
|
-
```python
|
|
166
|
-
from micpy import tab
|
|
167
|
-
|
|
168
|
-
table = tab.read("A001_Delta_Gamma.TabF")
|
|
169
|
-
|
|
170
|
-
table.loc[
|
|
171
|
-
table["Fraction Phase 2 FCC_A1"] > 0,
|
|
172
|
-
["Temperature [K]", "Fraction Phase 1 BCC_A2", "Fraction Phase 2 FCC_A1"]
|
|
173
|
-
]
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
#### Convert a table to different file formats
|
|
177
|
-
|
|
178
|
-
```python
|
|
179
|
-
from micpy import tab
|
|
180
|
-
|
|
181
|
-
table = tab.read("A001_Delta_Gamma.TabF")
|
|
182
|
-
|
|
183
|
-
table.to_csv("A001_Delta_Gamma.TabF.csv")
|
|
184
|
-
table.to_excel("A001_Delta_Gamma.TabF.xlsx")
|
|
185
|
-
table.to_json("A001_Delta_Gamma.TabF.json")
|
|
186
|
-
```
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
micpy/__init__.py,sha256=7wQUaseppjQYZW1iAVNm2WSDjvBLlqtY8tiHsfDaW5Q,148
|
|
2
|
-
micpy/bin.py,sha256=GzY0Gva3wp0n6vcKqv9yR3zzcg6ib1GtFzCKv8yXsR0,26777
|
|
3
|
-
micpy/geo.py,sha256=pwMDSwG8i9XqmX2DWrSWuvtpni_Z7VLO586LNgEuORk,7366
|
|
4
|
-
micpy/matplotlib.py,sha256=SLfk7H1v5L7H_L-a_FqobS0nKY3eSbFRF01h433SpVQ,2090
|
|
5
|
-
micpy/tab.py,sha256=QCnfggxRWkKgS9-zGj8kyCjhfUw7QeTgGZWedHh4MTw,3548
|
|
6
|
-
micpy/utils.py,sha256=-JS5SRqH4QMD6_pXBKPVw5zPNTbaqkcOUu9ej5Gi0QU,1282
|
|
7
|
-
micpy/version.py,sha256=JOpzAb63fvBI_jPvlsPW3cGBI7CByIaM5IXZyr6SXOU,26
|
|
8
|
-
micress_micpy-0.2.17b0.dist-info/LICENSE,sha256=seHdCiArizUoWZ6bEFg6N3K2ZtfPK35wvOwg0kH-f6o,1488
|
|
9
|
-
micress_micpy-0.2.17b0.dist-info/METADATA,sha256=z2YjOYSHKOAtMtFk1NXS1bHkV31fKPHJcJZllNB1ZjQ,3824
|
|
10
|
-
micress_micpy-0.2.17b0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
11
|
-
micress_micpy-0.2.17b0.dist-info/top_level.txt,sha256=RiopkpW0AGNYdtOW2eQUWgm3yHGC13q9pWlHb2alhiE,6
|
|
12
|
-
micress_micpy-0.2.17b0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|