osiris-utils 1.1.4__tar.gz → 1.1.6__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.
- {osiris_utils-1.1.4/osiris_utils.egg-info → osiris_utils-1.1.6}/PKG-INFO +1 -1
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/__init__.py +8 -2
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/data/data.py +316 -42
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/data/diagnostic.py +691 -233
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/data/simulation.py +30 -17
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/postprocessing/derivative.py +29 -49
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/postprocessing/fft.py +8 -14
- osiris_utils-1.1.6/osiris_utils/postprocessing/field_centering.py +168 -0
- osiris_utils-1.1.6/osiris_utils/postprocessing/heatflux_correction.py +193 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/postprocessing/mft.py +14 -28
- osiris_utils-1.1.6/osiris_utils/postprocessing/pressure_correction.py +171 -0
- osiris_utils-1.1.6/osiris_utils/utils.py +283 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6/osiris_utils.egg-info}/PKG-INFO +1 -1
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils.egg-info/SOURCES.txt +4 -1
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/setup.py +1 -1
- osiris_utils-1.1.4/osiris_utils/utils.py +0 -144
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/LICENSE.txt +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/MANIFEST.in +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/README.rst +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/data/__init__.py +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/decks/__init__.py +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/decks/decks.py +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/decks/species.py +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/gui/__init__.py +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/gui/gui.py +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/postprocessing/__init__.py +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/postprocessing/mft_for_gridfile.py +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils/postprocessing/postprocess.py +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils.egg-info/dependency_links.txt +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils.egg-info/requires.txt +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/osiris_utils.egg-info/top_level.txt +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/pyproject.toml +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/requirements.txt +0 -0
- {osiris_utils-1.1.4 → osiris_utils-1.1.6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: osiris_utils
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.6
|
|
4
4
|
Summary: Utilities to manipulate and visualize OSIRIS framework output data
|
|
5
5
|
Author: ['João Pedro Ferreira Biu', 'João Cândido', 'Diogo Carvalho']
|
|
6
6
|
Author-email: ['joaopedrofbiu@tecnico.ulisboa.pt']
|
|
@@ -8,7 +8,7 @@ from .utils import (
|
|
|
8
8
|
courant2D,
|
|
9
9
|
)
|
|
10
10
|
from .gui.gui import LAVA_Qt, LAVA
|
|
11
|
-
from .data.data import OsirisGridFile, OsirisRawFile, OsirisData, OsirisHIST
|
|
11
|
+
from .data.data import OsirisGridFile, OsirisRawFile, OsirisData, OsirisHIST, OsirisTrackFile
|
|
12
12
|
from .data.simulation import Simulation, Species_Handler
|
|
13
13
|
from .data.diagnostic import Diagnostic
|
|
14
14
|
|
|
@@ -25,4 +25,10 @@ from .postprocessing.mft import (
|
|
|
25
25
|
MFT_Diagnostic,
|
|
26
26
|
MFT_Diagnostic_Average,
|
|
27
27
|
MFT_Diagnostic_Fluctuations,
|
|
28
|
-
)
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
from .postprocessing.field_centering import FieldCentering_Simulation, FieldCentering_Diagnostic
|
|
31
|
+
|
|
32
|
+
from .postprocessing.pressure_correction import PressureCorrection_Simulation, PressureCorrection_Diagnostic
|
|
33
|
+
|
|
34
|
+
from .postprocessing.heatflux_correction import HeatfluxCorrection_Simulation, HeatfluxCorrection_Diagnostic
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import pandas as pd
|
|
3
3
|
import h5py
|
|
4
|
+
from osiris_utils.utils import create_file_tags
|
|
5
|
+
from typing import Literal
|
|
4
6
|
|
|
5
7
|
class OsirisData():
|
|
6
8
|
"""
|
|
@@ -343,42 +345,65 @@ class OsirisRawFile(OsirisData):
|
|
|
343
345
|
'''
|
|
344
346
|
Class to read the raw data from an OSIRIS HDF5 file.
|
|
345
347
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
+
Parameters
|
|
349
|
+
----------
|
|
350
|
+
filename : str
|
|
351
|
+
Path to OSIRIS HDF5 track file (.h5 extension)
|
|
348
352
|
|
|
349
353
|
Attributes:
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
354
|
+
-----------
|
|
355
|
+
axis : dict[str, dict[str, str]]
|
|
356
|
+
Dictionary where each key is a dataset name, and each value is another dictionary containing:
|
|
357
|
+
- 'name' (str): Short name of the quantity (e.g., 'x1', 'ene')
|
|
358
|
+
- 'units' (str): Units (LaTeX formatted, e.g., 'c/\\omega_p', 'm_e c^2')
|
|
359
|
+
- 'long_name' (str): Descriptive name (LaTeX formatted, e.g., 'x_1', 'En2')
|
|
360
|
+
data : dict[str, np.ndarray]
|
|
361
|
+
Dataset values indexed by dataset name (quants).
|
|
362
|
+
dim : int
|
|
363
|
+
Number of spatial dimensions.
|
|
364
|
+
dt : float
|
|
365
|
+
Time step between iterations.
|
|
366
|
+
grid : np.ndarray
|
|
367
|
+
Grid boundaries as ((x1_min, x1_max), (x2_min, x2_max), ...)
|
|
368
|
+
iter : int
|
|
369
|
+
Iteration number corresponding to the data.
|
|
370
|
+
name : str
|
|
371
|
+
Name of the species.
|
|
372
|
+
time : list[float, str]
|
|
373
|
+
Simulation time and its units (e.g., [12.5, '1/\\omega_p']).
|
|
374
|
+
type : str
|
|
375
|
+
Type of data (e.g., 'particles' for raw files).
|
|
376
|
+
labels : list[str]
|
|
377
|
+
Field labels/names (LaTeX formatted, e.g., 'x_1')
|
|
378
|
+
quants : list[str]
|
|
379
|
+
field names of the data
|
|
380
|
+
units : list[str]
|
|
381
|
+
Units of each field of the data (LaTeX formatted, e.g., 'c/\\omega_p')
|
|
374
382
|
|
|
383
|
+
Example
|
|
384
|
+
-------
|
|
385
|
+
>>> import osiris_utils as ou
|
|
386
|
+
>>> raw = ou.raw = ou.OsirisRawFile("path/to/raw/file.h5")
|
|
387
|
+
>>> print(raw.data.keys())
|
|
388
|
+
>>> # Access x1 position of first 10 particles
|
|
389
|
+
>>> print(raw.data[\"x1\"][0:10])
|
|
390
|
+
>>> # Write beautiful labels and units
|
|
391
|
+
>>> print("${} = $".format(raw.labels[\"x1\"]) + "$[{}]$".format(track.units[\"x1\"]))
|
|
392
|
+
'''
|
|
393
|
+
|
|
375
394
|
def __init__(self, filename):
|
|
376
395
|
super().__init__(filename)
|
|
377
396
|
|
|
378
|
-
self.
|
|
397
|
+
self._grid = np.array([self._file['SIMULATION'].attrs['XMIN'], self._file['SIMULATION'].attrs['XMAX']]).T
|
|
379
398
|
|
|
380
|
-
self.
|
|
381
|
-
|
|
399
|
+
self._quants = [byte.decode('utf-8') for byte in self._file.attrs['QUANTS'][:]]
|
|
400
|
+
units_list = [byte.decode('utf-8') for byte in self._file.attrs['UNITS'][:]]
|
|
401
|
+
labels_list = [byte.decode('utf-8') for byte in self._file.attrs['LABELS'][:]]
|
|
402
|
+
self._units = dict(zip(self._quants, units_list))
|
|
403
|
+
self._labels = dict(zip(self._quants, labels_list))
|
|
404
|
+
|
|
405
|
+
self._data = {}
|
|
406
|
+
self._axis = {}
|
|
382
407
|
for key in self._file.keys():
|
|
383
408
|
if key == 'SIMULATION': continue
|
|
384
409
|
|
|
@@ -390,29 +415,278 @@ class OsirisRawFile(OsirisData):
|
|
|
390
415
|
'units': self._file.attrs['UNITS'][idx][0].decode('utf-8'),
|
|
391
416
|
'long_name': self._file.attrs['LABELS'][idx][0].decode('utf-8'),
|
|
392
417
|
}
|
|
393
|
-
self.
|
|
418
|
+
self._axis[key] = axis_data
|
|
419
|
+
|
|
420
|
+
def raw_to_file_tags(self, filename, type: Literal["all", "random"] = "all", n_tags=10, mask=None):
|
|
421
|
+
"""
|
|
422
|
+
Function to write a file_tags file from raw data.
|
|
423
|
+
this file is used to choose particles for the OSIRIS track diagnostic.
|
|
424
|
+
|
|
425
|
+
Parameters
|
|
426
|
+
----------
|
|
427
|
+
filename : str
|
|
428
|
+
Path to the output file where tags will be stored.
|
|
429
|
+
type : {'all', 'random'}, optional
|
|
430
|
+
Selection mode for tags:
|
|
431
|
+
- 'all': Includes all available tags.
|
|
432
|
+
- 'random': Randomly selects `n_tags` tags.
|
|
433
|
+
n_tags : int, optional
|
|
434
|
+
Number of tags to randomly select when `type` is 'random'. Default is 10.
|
|
435
|
+
mask : np.ndarray, optional
|
|
436
|
+
Boolean mask array applied to filter valid tags before selection.
|
|
437
|
+
|
|
438
|
+
Returns
|
|
439
|
+
------
|
|
440
|
+
A file_tags file with path \"filename\" to be used for the OSIRIS track diagnostic.
|
|
441
|
+
|
|
442
|
+
Notes
|
|
443
|
+
-----
|
|
444
|
+
The first element of the tag of a particle that is already being tracked is negative,
|
|
445
|
+
so we apply the absolute function when generating the file
|
|
446
|
+
|
|
447
|
+
"""
|
|
448
|
+
|
|
449
|
+
if mask is not None:
|
|
450
|
+
# Apply mask to select certain tags
|
|
451
|
+
if not isinstance(mask, np.ndarray) or mask.dtype != bool or mask.shape[0] != self.data["tag"].shape[0]:
|
|
452
|
+
raise ValueError("Mask must be a boolean NumPy array of the same length as 'tag'.")
|
|
453
|
+
filtered_indices = np.where(mask)[0]
|
|
454
|
+
filtered_tags = self.data["tag"][filtered_indices]
|
|
455
|
+
else:
|
|
456
|
+
filtered_tags = self.data["tag"]
|
|
457
|
+
|
|
458
|
+
if type == "all":
|
|
459
|
+
tags = filtered_tags
|
|
460
|
+
elif type == "random":
|
|
461
|
+
if len(filtered_tags) < n_tags:
|
|
462
|
+
raise ValueError("Not enough tags to sample from.")
|
|
463
|
+
random_indices = np.random.choice(len(filtered_tags), size=n_tags, replace=False)
|
|
464
|
+
tags = filtered_tags[random_indices]
|
|
465
|
+
else:
|
|
466
|
+
raise TypeError("Invalid type", type)
|
|
467
|
+
|
|
468
|
+
create_file_tags(filename, tags)
|
|
469
|
+
print("Tag_file created: ", filename)
|
|
470
|
+
|
|
471
|
+
# Getters
|
|
472
|
+
@property
|
|
473
|
+
def grid(self):
|
|
474
|
+
return self._grid
|
|
475
|
+
@property
|
|
476
|
+
def data(self):
|
|
477
|
+
return self._data
|
|
478
|
+
@property
|
|
479
|
+
def units(self):
|
|
480
|
+
return self._units
|
|
481
|
+
@property
|
|
482
|
+
def labels(self):
|
|
483
|
+
return self._labels
|
|
484
|
+
@property
|
|
485
|
+
def quants(self):
|
|
486
|
+
return self._quants
|
|
487
|
+
@property
|
|
488
|
+
def axis(self):
|
|
489
|
+
return self._axis
|
|
394
490
|
|
|
395
491
|
class OsirisHIST(OsirisData):
|
|
396
492
|
''''
|
|
397
493
|
Class to read the data from an OSIRIS HIST file.'
|
|
398
494
|
|
|
399
|
-
Input
|
|
400
|
-
|
|
495
|
+
Input
|
|
496
|
+
-----
|
|
497
|
+
filename: the path to the HIST file
|
|
401
498
|
|
|
402
|
-
Attributes
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
pandas.DataFrame
|
|
499
|
+
Attributes
|
|
500
|
+
----------
|
|
501
|
+
filename: the path to the file
|
|
502
|
+
str
|
|
503
|
+
df: the data in a pandas DataFrame
|
|
504
|
+
pandas.DataFrame
|
|
409
505
|
'''
|
|
410
506
|
def __init__(self, filename):
|
|
411
507
|
super().__init__(filename)
|
|
412
508
|
|
|
413
509
|
@property
|
|
414
510
|
def df(self):
|
|
415
|
-
"""
|
|
416
|
-
Returns the data in a pandas DataFrame
|
|
417
|
-
"""
|
|
418
511
|
return self._df
|
|
512
|
+
|
|
513
|
+
class OsirisTrackFile(OsirisData):
|
|
514
|
+
"""
|
|
515
|
+
Handles structured track data from OSIRIS HDF5 simulations.
|
|
516
|
+
|
|
517
|
+
Parameters
|
|
518
|
+
----------
|
|
519
|
+
filename : str
|
|
520
|
+
Path to OSIRIS HDF5 track file (.h5 extension)
|
|
521
|
+
|
|
522
|
+
Attributes
|
|
523
|
+
----------
|
|
524
|
+
data: numpy.ndarray of shape (num_particles, num_time_iter),
|
|
525
|
+
dtype = [(field_name, float) for field_name in field_names]
|
|
526
|
+
A structured numpy array with the track data
|
|
527
|
+
Accessed as data[particles, time_iters][quant]
|
|
528
|
+
grid : np.ndarray
|
|
529
|
+
Grid boundaries as ((x1_min, x1_max), (x2_min, x2_max), ...)
|
|
530
|
+
labels : list[str]
|
|
531
|
+
Field labels/names (LaTeX formatted, e.g., 'x_1')
|
|
532
|
+
num_particles : int
|
|
533
|
+
Number of particlest tracked, they are accessed from 0 to num_particles-1
|
|
534
|
+
num_time_iters : int
|
|
535
|
+
Number of time iteratis, they are accessed from 0 to num_time_iters-1
|
|
536
|
+
quants : list[str]
|
|
537
|
+
field names of the data
|
|
538
|
+
units : list[str]
|
|
539
|
+
Units of each field of the data (LaTeX formatted, e.g., 'c/\\omega_p')
|
|
540
|
+
|
|
541
|
+
Example
|
|
542
|
+
-------
|
|
543
|
+
>>> import osiris_utils as ou
|
|
544
|
+
>>> track = ou.OsirisTrackFile(path/to/track_file.h5)
|
|
545
|
+
>>> print(track.data[0:10, :]["x1"]) # Access x1 position of first 10 particles over all time steps
|
|
546
|
+
"""
|
|
547
|
+
|
|
548
|
+
def __init__(self, filename):
|
|
549
|
+
super().__init__(filename)
|
|
550
|
+
|
|
551
|
+
self._grid = np.array([self._file['SIMULATION'].attrs['XMIN'], self._file['SIMULATION'].attrs['XMAX']]).T
|
|
552
|
+
|
|
553
|
+
self._quants = [byte.decode('utf-8') for byte in self._file.attrs['QUANTS'][1:]]
|
|
554
|
+
units_list = [byte.decode('utf-8') for byte in self._file.attrs['UNITS'][1:]]
|
|
555
|
+
labels_list = [byte.decode('utf-8') for byte in self._file.attrs['LABELS'][1:]]
|
|
556
|
+
self._units = dict(zip(self._quants, units_list))
|
|
557
|
+
self._labels = dict(zip(self._quants, labels_list))
|
|
558
|
+
|
|
559
|
+
self._num_particles = self._file.attrs['NTRACKS'][0]
|
|
560
|
+
|
|
561
|
+
unordered_data = self._file['data'][:]
|
|
562
|
+
itermap = self._file['itermap'][:]
|
|
563
|
+
|
|
564
|
+
idxs = get_track_indexes(itermap, self._num_particles)
|
|
565
|
+
self._data = reorder_track_data(unordered_data, idxs, self._quants)
|
|
566
|
+
self._time = self._data[0][:]["t"]
|
|
567
|
+
self._num_time_iters = np.shape(self._time.shape)
|
|
568
|
+
self._close_file()
|
|
569
|
+
|
|
570
|
+
def _load_basic_attributes(self, f: h5py.File) -> None:
|
|
571
|
+
'''Load common attributes from HDF5 file'''
|
|
572
|
+
self._dt = float(f['SIMULATION'].attrs['DT'][0])
|
|
573
|
+
self._dim = int(f['SIMULATION'].attrs['NDIMS'][0])
|
|
574
|
+
self._time = None
|
|
575
|
+
self._iter = None
|
|
576
|
+
self._name = f.attrs['NAME'][0].decode('utf-8')
|
|
577
|
+
self._type = f.attrs['TYPE'][0].decode('utf-8')
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
# Getters
|
|
581
|
+
@property
|
|
582
|
+
def grid(self):
|
|
583
|
+
return self._grid
|
|
584
|
+
@property
|
|
585
|
+
def data(self):
|
|
586
|
+
return self._data
|
|
587
|
+
@property
|
|
588
|
+
def units(self):
|
|
589
|
+
return self._units
|
|
590
|
+
@property
|
|
591
|
+
def labels(self):
|
|
592
|
+
return self._labels
|
|
593
|
+
@property
|
|
594
|
+
def quants(self):
|
|
595
|
+
return self._quants
|
|
596
|
+
@property
|
|
597
|
+
def num_particles(self):
|
|
598
|
+
return self._num_particles
|
|
599
|
+
@property
|
|
600
|
+
def num_time_iters(self):
|
|
601
|
+
return self._num_time_iters
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
# Setters
|
|
605
|
+
@data.setter
|
|
606
|
+
def data(self, data):
|
|
607
|
+
self._data = data
|
|
608
|
+
|
|
609
|
+
def __str__(self):
|
|
610
|
+
# write me a template to print with the name, label, units, iter, grid, nx, dx, axis, dt, dim in a logical way
|
|
611
|
+
return rf'{self.name}' + f'\n' + f'Iteration: {self.iter}' + f'\n' + f'Grid: {self.grid}' + f'\n' + f'dx: {self.dx}' + f'\n' + f'Dimensions: {self.dim}D'
|
|
612
|
+
|
|
613
|
+
def __array__(self):
|
|
614
|
+
return np.asarray(self.data)
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
def reorder_track_data(unordered_data, indexes, field_names):
|
|
619
|
+
'''
|
|
620
|
+
Reorder data from HDF5 track file such data it can be accessed more intuitively
|
|
621
|
+
|
|
622
|
+
Parameters
|
|
623
|
+
----------
|
|
624
|
+
unordered_data: np.array
|
|
625
|
+
The data from a HDF5 osiris track file
|
|
626
|
+
|
|
627
|
+
indexes : list[list[int]]
|
|
628
|
+
Output of get_track_indexes(), list with the indexes associated with each particle
|
|
629
|
+
|
|
630
|
+
field_names: list[str]
|
|
631
|
+
Names for the quantities on the output file.
|
|
632
|
+
Recommended: field_names = [byte.decode('utf-8') for byte in file.attrs['QUANTS'][1:]]
|
|
633
|
+
|
|
634
|
+
Returns
|
|
635
|
+
-------
|
|
636
|
+
data_sorted: numpy.ndarray of shape (num_particles, num_time_iter),
|
|
637
|
+
dtype = [(field_name, float) for field_name in field_names]
|
|
638
|
+
A structured numpy array where data is reordered according to indexes.
|
|
639
|
+
|
|
640
|
+
'''
|
|
641
|
+
# Initialize the sorted data structure
|
|
642
|
+
num_particles = len(indexes)
|
|
643
|
+
num_time_iter = len(indexes[0])
|
|
644
|
+
data_sorted = np.empty((num_particles, num_time_iter), dtype=[(name, float) for name in field_names])
|
|
645
|
+
|
|
646
|
+
# Fill the sorted data based on the indexes
|
|
647
|
+
for particle in range(num_particles):
|
|
648
|
+
for time_iter in range(num_time_iter):
|
|
649
|
+
index = indexes[particle][time_iter]
|
|
650
|
+
if len(unordered_data[index]) != len(field_names):
|
|
651
|
+
raise ValueError(f"Data at index {index} has {len(unordered_data[index])} elements, "
|
|
652
|
+
f"but {len(field_names)} are expected.")
|
|
653
|
+
data_sorted[particle, time_iter] = tuple(unordered_data[index])
|
|
654
|
+
|
|
655
|
+
return (data_sorted)
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
def get_track_indexes(itermap, num_particles):
|
|
659
|
+
'''
|
|
660
|
+
Returns the indexes for each particle to read track data directly from the hd5 file
|
|
661
|
+
(before it is ordered)
|
|
662
|
+
|
|
663
|
+
Parameters
|
|
664
|
+
----------
|
|
665
|
+
itermap: np.array
|
|
666
|
+
Itermap from a HDF5 osiris track file
|
|
667
|
+
num_particles: int
|
|
668
|
+
num of particles tracked, recomended file.attrs['NTRACKS'][0]
|
|
669
|
+
|
|
670
|
+
Returns
|
|
671
|
+
-------
|
|
672
|
+
indexes : list[list[int]]
|
|
673
|
+
Returns a list with the indexes associated with each particle
|
|
674
|
+
shape(num_particles, num_time_iters)
|
|
675
|
+
'''
|
|
676
|
+
|
|
677
|
+
itermapshape = itermap.shape
|
|
678
|
+
for i in range(itermapshape[0]):
|
|
679
|
+
part_number,npoints,nstart = itermap[i,:]
|
|
680
|
+
track_indices = np.zeros(num_particles)
|
|
681
|
+
|
|
682
|
+
data_index = 0
|
|
683
|
+
indexes = [[] for _ in range(num_particles)]
|
|
684
|
+
for i in range(itermapshape[0]):
|
|
685
|
+
part_number,npoints,nstart = itermap[i,:]
|
|
686
|
+
|
|
687
|
+
indexes[part_number-1].extend(list(range(data_index, data_index + npoints)))
|
|
688
|
+
|
|
689
|
+
data_index += npoints
|
|
690
|
+
track_indices[part_number-1] += npoints
|
|
691
|
+
|
|
692
|
+
return indexes
|