moreniius 0.6.3__py3-none-any.whl → 0.8.0__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.
@@ -122,6 +122,9 @@ class NXInstance:
122
122
  if not hasattr(self.nx[name], 'depends_on'):
123
123
  self.nx[name].attrs['depends_on'] = most_dependent
124
124
  most_dependent = outer_transform_dependency(self.nx['transformations'])
125
+ # Note: the depends_on entry for NX class objects is an optional dataset
126
+ # in the HDF5 group. Tools like chexus can verify its presence and
127
+ # scippnexus only uses the dataset member of a group for this.
125
128
  self.nx['depends_on'] = f'transformations/{most_dependent}'
126
129
 
127
130
  def get_nx_type(self):
@@ -131,7 +134,7 @@ class NXInstance:
131
134
  return COMPONENT_CATEGORY_TO_NEXUS[self.obj.type.category]
132
135
  if any(self.obj.type.name.startswith(x) for x in COMPONENT_GROUP_TO_NEXUS):
133
136
  return [t for k, t in COMPONENT_GROUP_TO_NEXUS.items() if self.obj.type.name.startswith(k)][0]
134
- return 'NXnote'
137
+ return 'NXcoordinate_system' if self.transforms else 'NXnote'
135
138
 
136
139
  def default_translation(self):
137
140
  import nexusformat.nexus as nexus
moreniius/mccode/instr.py CHANGED
@@ -53,7 +53,19 @@ class NXInstr:
53
53
  return NXfield(str(self.instr))
54
54
 
55
55
  def expr2nx(self, expr: Union[str, Expr, Any]):
56
- from moreniius.utils import link_specifier
56
+ """Intended to convert *Expr* objects to NeXus-representable objects"""
57
+ # FIXME this is called to wrap and re-wrap the same data
58
+ # during translation of a component with properties. It may be worth
59
+ # separating the parameter and component functionality.
60
+ from moreniius.utils import link_specifier, NotNXdict
61
+ from nexusformat.nexus import NXlog
62
+ if hasattr(expr, '_value') and isinstance(getattr(expr, '_value'), NotNXdict):
63
+ # Avoid unwrapping the non-NX dictionary at this stage since it is
64
+ # silently converted to a string-like thing which as an __iter__ property
65
+ return expr
66
+ if isinstance(expr, NXlog):
67
+ # Do not decompose a value if we already wrapped it in NXlog
68
+ return expr
57
69
  if not isinstance(expr, str) and hasattr(expr, '__iter__'):
58
70
  parts = [self.expr2nx(x) for x in expr]
59
71
  return tuple(parts) if isinstance(expr, tuple) else parts
@@ -68,6 +80,10 @@ class NXInstr:
68
80
  return evaluated.value
69
81
 
70
82
  dependencies = [par.name for par in self.instr.parameters if evaluated.depends_on(par.name)]
83
+ if len(dependencies) == 1 and str(expr) == str(dependencies[0]):
84
+ from moreniius.utils import linked_nxlog
85
+ return linked_nxlog(f'{self.nxlog_root}/{dependencies[0]}')
86
+
71
87
  if len(dependencies):
72
88
  log.warn(f'The expression {expr} depends on instrument parameter(s) {dependencies}\n'
73
89
  f'A link will be inserted for each; make sure their values are stored at {self.nxlog_root}/')
@@ -77,36 +93,53 @@ class NXInstr:
77
93
  return str(expr)
78
94
 
79
95
  def make_nx(self, nx_class, *args, **kwargs):
96
+ from nexusformat.nexus import NXlog
97
+ from moreniius.utils import NotNXdict
80
98
  nx_args = [self.expr2nx(expr) for expr in args]
81
99
  nx_kwargs = {name: self.expr2nx(expr) for name, expr in kwargs.items()}
82
- # logged parameters are sometimes requested as NXfield objects, but should be links to the real NXlog
83
- if nx_class == NXfield and len(nx_args) == 1 and isinstance(nx_args[0], NXcollection) and \
84
- 'expression' in nx_args[0]:
85
- not_expr = [x for x in nx_args[0] if x != 'expression']
100
+
101
+ # logged parameters are sometimes requested as NXfields, but should be NXlogs
102
+ want_log = nx_class == NXfield and len(nx_args) == 1
103
+ nx_arg = nx_args[0] if want_log else None
104
+ if want_log and isinstance(nx_arg, NXlog):
105
+ # The NXlog returned by expr2nx doesn't have the needed attributes:
106
+ for k, v in nx_kwargs.items():
107
+ nx_arg.attrs[k] = v
108
+ return nx_arg
109
+ # Hopefully less often, a collection of links in an NXcollection
110
+ if want_log and isinstance(nx_arg, NXcollection) and 'expression' in nx_arg:
111
+ not_expr = [x for x in nx_arg if x != 'expression']
86
112
  if len(not_expr) == 1:
87
- not_expr_arg = nx_args[0][not_expr[0]]
88
- # if isinstance(not_expr_arg, NXfield):
89
- # # We have and want an NXfield, but it might be missing attributes specified in the nx_kwargs
90
- # # Passing the keywords to the NXfield constructor versus this method is not identical,
91
- # # since some keyword arguments are reserved (and only some of which are noted)
92
- # # Explicit keywords, used in the constructor:
93
- # # value, name, shape, dtype, group, attrs
94
- # # Keywords extracted from the kwargs dict, if present (and all controlling HDF5 file attributes?):
95
- # # chunks, compression, compression_opts, fillvalue, fletcher32, maxshape, scaleoffset, shuffle
96
- # # For now, just assume all keywords provided here are _actually_ attributes for the NXfield
97
- # # which is an extension of a dict, but can *not* use the update method, since the __setitem__
98
- # # method is overridden to wrap inputs in NXattr objects :/
99
- # for k, v in nx_kwargs.items():
100
- # not_expr_arg.attrs[k] = v
101
- # return not_expr_arg
113
+ arg = nx_arg[not_expr[0]]
114
+ if isinstance(arg, NXfield):
115
+ # if this is a link, we should not add any attributes
116
+ # since the filewriter will ignore them
117
+ if hasattr(arg, '_value') and isinstance(d:=getattr(arg, '_value'), NotNXdict) and d.get('module', '') == 'link':
118
+ return arg
119
+ # We have and want an NXfield, but it might be missing attributes specified in the nx_kwargs
120
+ # Passing the keywords to the NXfield constructor versus this method is not identical,
121
+ # since some keyword arguments are reserved (and only some of which are noted)
122
+ # Explicit keywords, used in the constructor:
123
+ # value, name, shape, dtype, group, attrs
124
+ # Keywords extracted from the kwargs dict, if present (and all controlling HDF5 file attributes?):
125
+ # chunks, compression, compression_opts, fillvalue, fletcher32, maxshape, scaleoffset, shuffle
126
+ # For now, just assume all keywords provided here are _actually_ attributes for the NXfield
127
+ # which is an extension of a dict, but can *not* use the update method, since the __setitem__
128
+ # method is overridden to wrap inputs in NXattr objects :/
129
+ for k, v in nx_kwargs.items():
130
+ arg.attrs[k] = v
131
+ return arg
102
132
 
103
133
  # TODO make this return an nx_class once we're sure that nx_kwargs is parseable (no mccode_antlr.Expr)
104
- if all(x in not_expr_arg for x in ('module', 'config')):
134
+ if all(x in arg for x in ('module', 'config')):
105
135
  # This is a file-writer stream directive? So make a group
106
- return NXgroup(entries={not_expr[0]: not_expr_arg}, **nx_kwargs)
136
+ grp = NXgroup(entries={not_expr[0]: arg})
137
+ for attr, val in nx_kwargs.items():
138
+ grp.attrs[attr] = val
139
+ return grp
107
140
  print('!!')
108
- print(not_expr_arg)
109
- return nx_class(not_expr_arg, **nx_kwargs)
141
+ print(arg)
142
+ return nx_class(arg, **nx_kwargs)
110
143
  else:
111
144
  raise RuntimeError('Not sure what I should do here')
112
145
  return nx_class(*nx_args, **nx_kwargs)
@@ -1,3 +1,4 @@
1
+ from nexusformat.nexus import NXfield
1
2
  from zenlog import log
2
3
  from dataclasses import dataclass, field
3
4
  from networkx import DiGraph
@@ -7,7 +8,6 @@ from .instr import NXInstr
7
8
 
8
9
  log.level('error')
9
10
 
10
-
11
11
  @dataclass
12
12
  class NXMcCode:
13
13
  nx_instr: NXInstr
@@ -19,13 +19,21 @@ class NXMcCode:
19
19
 
20
20
  def __post_init__(self):
21
21
  from copy import deepcopy
22
+
22
23
  for index, instance in enumerate(self.nx_instr.instr.components):
23
24
  self.indexes[instance.name] = index
24
- self.orientations[instance.name] = deepcopy(instance.orientation)
25
- # Attempt to re-center all component dependent orientations on the sample
26
- found = (lambda x: self.origin_name == x.name) if self.origin_name else (lambda x: 'samples' == x.type.category)
27
- possible_origins = [instance for instance in self.nx_instr.instr.components if found(instance)]
25
+ # only absolute-positioned or rotated component orientations are needed
26
+ if instance.at_relative[1] is None or instance.rotate_relative[1] is None:
27
+ self.orientations[instance.name] = deepcopy(instance.orientation)
28
28
 
29
+ # Attempt to re-center all component dependent orientations on the sample
30
+ found = (
31
+ (lambda x: self.origin_name == x.name)
32
+ if self.origin_name else
33
+ (lambda x: 'samples' == x.type.category)
34
+ )
35
+ possible_origins = [instance for instance in
36
+ self.nx_instr.instr.components if found(instance)]
29
37
  if not possible_origins:
30
38
  msg = '"sample" category components' if self.origin_name is None else f'component named {self.origin_name}'
31
39
  log.warn(f'No {msg} in instrument, using ABSOLUTE positions')
@@ -37,18 +45,72 @@ class NXMcCode:
37
45
  self.origin_name = possible_origins[0].name
38
46
  # find the position _and_ rotation of the origin
39
47
  origin = possible_origins[0].orientation
40
- # remove this from all components (re-centering on the origin)
41
- for name in self.orientations:
42
- self.orientations[name] = self.orientations[name] - origin
48
+ # remove this from all (absolute) components (re-centering on the origin)
49
+ for name, orientation in self.orientations.items():
50
+ self.orientations[name] = orientation - origin
43
51
 
44
52
  if self.graph is None:
45
53
  self.graph = self.build_graph()
46
54
  if self.reversed_graph is None:
47
55
  self.reversed_graph = self.graph.reverse(copy=True)
48
56
 
49
- def transformations(self, name):
50
- from .orientation import NXOrient
51
- return NXOrient(self.nx_instr, self.orientations[name]).transformations(name)
57
+ def transformations(self, name) -> dict[str, NXfield]:
58
+ from mccode_antlr.instr.orientation import Vector, Angles, Parts
59
+ from .orientation import NXOrient, NXParts
60
+
61
+ def abs_ref(ref):
62
+ # FIXME find a better way to ensure this is correct
63
+ return f'/entry/instrument/{ref}'
64
+
65
+ def last_ref(refs: list[tuple[str, NXfield]]) -> str | None:
66
+ try:
67
+ return next(reversed(refs))[0]
68
+ except StopIteration:
69
+ pass
70
+
71
+ at_vec, at_rel = self.nx_instr.instr.components[self.indexes[name]].at_relative
72
+ rot_ang, rot_rel = self.nx_instr.instr.components[self.indexes[name]].rotate_relative
73
+
74
+ nx_orientation = None
75
+ if at_rel is None or rot_rel is None:
76
+ nx_orientation = NXOrient(self.nx_instr, self.orientations[name])
77
+
78
+ if at_rel is None and rot_rel is None:
79
+ # ABSOLUTE definition, so we pull information from self.orientations
80
+ # since we had to remove the (possibly different) origin
81
+ return nx_orientation.transformations(name)
82
+
83
+ trans = []
84
+ if at_rel is not None and rot_rel is not None and at_rel == rot_rel:
85
+ at_vec = Vector(*at_vec) if isinstance(at_vec, tuple) else at_vec
86
+ rot_ang = Angles(*rot_ang) if isinstance(rot_ang, tuple) else rot_ang
87
+ at_parts = Parts.from_at_rotated(at_vec, Angles(), True)
88
+ rot_parts = Parts.from_at_rotated(Vector(), rot_ang, True)
89
+ nx_parts = NXParts(self.nx_instr, at_parts, rot_parts)
90
+ trans.extend(nx_parts.transformations(name, abs_ref(at_rel.name)))
91
+ else:
92
+ raise RuntimeError("All mixed reference-type orientations untested. "
93
+ "Only 'AT (x, y, z) ABSOLUTE ROTATE (a, b, c) REF' might work")
94
+ # elif at_rel is None:
95
+ # # absolute position with relative rotation
96
+ # trans.extend(nx_orientation.position_transformations(name))
97
+ # # Get the _rotation_ of the reference to add here before any new rotation
98
+ # # FIXME this can only work if rot_rel.name is in self.orientations!
99
+ # rel_ori = NXOrient(self.nx_instr, self.orientations[rot_rel.name])
100
+ # trans.extend(rel_ori.rotation_transformations(rot_rel.name, last_ref(trans)))
101
+ # # Now add our relative rotation onto the referenced rotation
102
+ # rot_ang = Angles(*rot_ang) if isinstance(rot_ang, tuple) else rot_ang
103
+ # rot = Parts(Parts.from_at_rotated(Vector(), rot_ang, True).stack()).reduce()
104
+ # nx_parts = NXParts(self.nx_instr, rot, rot)
105
+ # trans.extend(nx_parts.rotation_transformations(name, last_ref(trans)))
106
+ # elif rot_rel is None:
107
+ # # relative position with absolute rotations
108
+ # raise RuntimeError("I can not handle this yet")
109
+ # else:
110
+ # # relative position and rotation but different references.
111
+ # raise RuntimeError("I cnat no handle this ytet")
112
+
113
+ return {k: v for k, v in trans}
52
114
 
53
115
  def inputs(self, name):
54
116
  """Return the other end of edges ending at the named node"""
@@ -64,7 +126,7 @@ class NXMcCode:
64
126
  instance = self.nx_instr.instr.components[self.indexes[name]]
65
127
  transformations = self.transformations(name)
66
128
  nxinst = NXInstance(self.nx_instr, instance, self.indexes[name], transformations, only_nx=only_nx)
67
- if transformations and nxinst.nx['transformations'] != transformations:
129
+ if transformations and nxinst.nx['transformations'] != transformations and name in self.orientations:
68
130
  # if the component modifed the transformations group, make sure we don't use our version again
69
131
  del self.orientations[name]
70
132
  if len(inputs := self.inputs(name)):
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from zenlog import log
4
- from dataclasses import dataclass
4
+ from dataclasses import dataclass, field
5
5
  from mccode_antlr.instr import Orient, Parts, Part
6
6
  from nexusformat.nexus import NXfield
7
7
  from .instr import NXInstr
@@ -73,27 +73,52 @@ class NXParts:
73
73
  position: Parts
74
74
  rotation: Parts
75
75
 
76
- def transformations(self, name: str) -> list[tuple[str, NXfield]]:
77
- nxt = []
78
- dep = '.'
79
- for index, o in enumerate(self.position.stack()):
80
- nxt.extend(NXPart(self.instr, o).transformations(f'{name}_t{index}', dep))
81
- dep = nxt[-1][0] if len(nxt) and len(nxt[-1]) else '.'
82
- for index, o in enumerate(self.rotation.stack()):
83
- nxt.extend(NXPart(self.instr, o).transformations(f'{name}_r{index}', dep))
84
- dep = nxt[-1][0] if len(nxt) and len(nxt[-1]) else '.'
85
- return nxt
76
+ def _transformations(self, name: str, dep: str, typ: str, stack):
77
+ nx_transformations = []
78
+ for i, op in enumerate(stack):
79
+ parts = NXPart(self.instr, op).transformations(f'{name}_{typ}{i}', dep)
80
+ nx_transformations.extend(parts)
81
+ if len(parts) and len(parts[-1]):
82
+ dep = parts[-1][0]
83
+ return nx_transformations
84
+
85
+ def position_transformations(self, name: str, dep: str | None = None ) -> list[tuple[str, NXfield]]:
86
+ dep = dep or '.'
87
+ return self._transformations(name, dep, 't', self.position.stack())
88
+
89
+ def rotation_transformations(self, name: str, dep: str | None = None) -> list[tuple[str, NXfield]]:
90
+ dep = dep or '.'
91
+ return self._transformations(name, dep, 'r', self.rotation.stack())
92
+
93
+ def transformations(self, name: str, dep: str | None = None) -> list[tuple[str, NXfield]]:
94
+ parts = self.position_transformations(name, dep=dep)
95
+ # If there were any positioning transformations, we need to update
96
+ # the dependency chained name, otherwise it should stay the same
97
+ dep = parts[-1][0] if len(parts) and len(parts[-1]) else dep
98
+ return parts + self.rotation_transformations(name, dep=dep)
86
99
 
87
100
 
88
101
  @dataclass
89
102
  class NXOrient:
90
103
  instr: NXInstr
91
104
  do: Orient
105
+ nx_parts: NXParts | None = None
92
106
 
93
- def transformations(self, name: str) -> dict[str, NXfield]:
107
+ def __post_init__(self):
94
108
  # collapse all possible chained orientation information
95
109
  # But keep the rotations and translations separate
96
110
  pos, rot = self.do.position_parts(), self.do.rotation_parts()
97
111
  # make an ordered list of the requisite NXfield entries
98
- nxt = NXParts(self.instr, pos, rot).transformations(name)
99
- return {k: v for k, v in nxt}
112
+ self.nx_parts = NXParts(self.instr, pos, rot)
113
+
114
+ def transformations(self, name: str) -> dict[str, NXfield]:
115
+ # make an ordered list of the requisite NXfield entries, and turn it into a dict
116
+ return {k: v for k, v in self.nx_parts.transformations(name)}
117
+
118
+ def position_transformations(self, name: str, dep: str | None = None) -> list[tuple[str, NXfield]]:
119
+ return self.nx_parts.position_transformations(name, dep)
120
+
121
+ def rotation_transformations(self, name: str, dep: str | None = None) -> list[tuple[str, NXfield]]:
122
+ return self.nx_parts.rotation_transformations(name, dep)
123
+
124
+
moreniius/utils.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from mccode_antlr.instr import Instance
2
- from nexusformat.nexus import NXevent_data, NXfield
2
+ from nexusformat.nexus import NXevent_data, NXfield, NXlog
3
3
 
4
4
  class NotNXdict:
5
5
  """Wrapper class to prevent NXfield-parsing of the held dictionary"""
@@ -16,6 +16,10 @@ class NotNXdict:
16
16
  from json import dumps
17
17
  return dumps(self.value)
18
18
 
19
+ def get(self, item, default=None):
20
+ return self.value.get(item, default)
21
+
22
+
19
23
 
20
24
  def outer_transform_dependency(transformations):
21
25
  """For a NXtransformations group, find the most-dependent transformation name
@@ -175,6 +179,26 @@ def ev44_event_data_group(source: str, topic: str) -> NXevent_data:
175
179
  return NXevent_data(data=ess_flatbuffer_specifier('ev44', {'source': source, 'topic': topic}))
176
180
 
177
181
 
182
+ def nxlog_data_links(source: str):
183
+ """
184
+ Return link module specifications for the datasets inserted by a f144 module
185
+ """
186
+ datasets = (
187
+ 'alarm_message', 'alarm_severity', 'alarm_time', 'average_value',
188
+ 'connection_status', 'connection_status_time', 'cue_index',
189
+ 'cue_timestamp_zero', 'description', 'maximum_value', 'minimum_value',
190
+ 'time', 'value'
191
+ )
192
+ return {k: link_specifier(k, f'{source}/{k}') for k in datasets}
193
+
194
+
195
+ def linked_nxlog(source: str, attrs: dict | None = None) -> NXlog:
196
+ nxlog = NXlog(**nxlog_data_links(source))
197
+ if attrs:
198
+ nxlog.attrs.update(attrs)
199
+ return nxlog
200
+
201
+
178
202
  def link_specifier(name: str, source: str) -> NotNXdict:
179
203
  """
180
204
  Constructs a specifier to insert a NeXus link into an ESS produced NeXus file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: moreniius
3
- Version: 0.6.3
3
+ Version: 0.8.0
4
4
  Author-email: Gregory Tucker <gregory.tucker@ess.eu>
5
5
  Classifier: License :: OSI Approved :: BSD License
6
6
  Classifier: Development Status :: 2 - Pre-Alpha
@@ -14,8 +14,8 @@ Classifier: Programming Language :: Python :: 3.14
14
14
  Description-Content-Type: text/markdown
15
15
  Requires-Dist: zenlog>=1.1
16
16
  Requires-Dist: platformdirs>=3.11
17
- Requires-Dist: mccode-antlr[hdf5]>=0.17.0
18
- Requires-Dist: nexusformat>=1.0.6
17
+ Requires-Dist: mccode-antlr[hdf5]>=0.17.2
18
+ Requires-Dist: nexusformat>=2.0.0
19
19
  Requires-Dist: networkx
20
20
 
21
21
  # moreniius
@@ -0,0 +1,18 @@
1
+ moreniius/__init__.py,sha256=33SUBkXWhH5rog5oaGJr1Kwqjhwz97w4E0Da7rArYi4,154
2
+ moreniius/additions.py,sha256=6Hhhc4LDUsnBj27Iil-EFFzQm1xd2M45hfcVQYEjxiI,17615
3
+ moreniius/moreniius.py,sha256=UZgQycAed5OWIqxYXZLaD68YUHFgQ8fVb-aCP6hvT9Q,1544
4
+ moreniius/nexus_structure.py,sha256=C_ohhilsE6xdfSpFVhsFEK9EC3sBXPGWxCIGk_4UFvI,1853
5
+ moreniius/nxoff.py,sha256=WHp9wYNn_4Hcx8Nzi9rpX1p8_iwI-AdgTQouSAEG8N4,3288
6
+ moreniius/utils.py,sha256=WhKQ5NzzwiIruNtaSC2FbmNxNa570GqL4hwGIR4WLwA,9982
7
+ moreniius/writer.py,sha256=zgrbo7RfAriAGrOpPhFHSwwn3yWG4_ZJndIi6HhTzss,6815
8
+ moreniius/mccode/__init__.py,sha256=1QiZdh90G3gp_WlVpdJB_ZGauoW0GJEQ13Nelaqa5JE,151
9
+ moreniius/mccode/comp.py,sha256=iaOooI2nIevA0Vhz5jZQJCqXYgmZ3jMm0s3gUtR8Unc,9637
10
+ moreniius/mccode/instance.py,sha256=J0NgNLlJwe9YshZZhKxpH6IixLe9kMjhRyhRfI7uJQM,8355
11
+ moreniius/mccode/instr.py,sha256=jpIKir3xiZGSq0uP3wMevOZ-6dUvfvsgXG0oaVK4pEk,7864
12
+ moreniius/mccode/mccode.py,sha256=6CsAF4nKVEyfPv7mrthTAUYirUiGzb0zk2DcsfSFLh8,7489
13
+ moreniius/mccode/orientation.py,sha256=Y5u_c2Wt3lAAAwohKO223v68WNUjWWy58ZjyEuMzQOk,5122
14
+ moreniius-0.8.0.dist-info/METADATA,sha256=cYaaykjkYD7K09_mcf6S-KGrK5KHSRHth3XRmhkANc8,946
15
+ moreniius-0.8.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
16
+ moreniius-0.8.0.dist-info/entry_points.txt,sha256=Ga3k4P4fyBt5_dJ03Oapic2Qlgqv9jufQGdxWiz_j2A,63
17
+ moreniius-0.8.0.dist-info/top_level.txt,sha256=RzMo23UfVhgQeuOYeS5P9I0qVbxx4Gbe6Roc29Mr02c,10
18
+ moreniius-0.8.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,18 +0,0 @@
1
- moreniius/__init__.py,sha256=33SUBkXWhH5rog5oaGJr1Kwqjhwz97w4E0Da7rArYi4,154
2
- moreniius/additions.py,sha256=6Hhhc4LDUsnBj27Iil-EFFzQm1xd2M45hfcVQYEjxiI,17615
3
- moreniius/moreniius.py,sha256=UZgQycAed5OWIqxYXZLaD68YUHFgQ8fVb-aCP6hvT9Q,1544
4
- moreniius/nexus_structure.py,sha256=C_ohhilsE6xdfSpFVhsFEK9EC3sBXPGWxCIGk_4UFvI,1853
5
- moreniius/nxoff.py,sha256=WHp9wYNn_4Hcx8Nzi9rpX1p8_iwI-AdgTQouSAEG8N4,3288
6
- moreniius/utils.py,sha256=R81eHjc0EWjMsP-Z8WI9sZkc_QY357z_aYziflQAUEU,9238
7
- moreniius/writer.py,sha256=zgrbo7RfAriAGrOpPhFHSwwn3yWG4_ZJndIi6HhTzss,6815
8
- moreniius/mccode/__init__.py,sha256=1QiZdh90G3gp_WlVpdJB_ZGauoW0GJEQ13Nelaqa5JE,151
9
- moreniius/mccode/comp.py,sha256=iaOooI2nIevA0Vhz5jZQJCqXYgmZ3jMm0s3gUtR8Unc,9637
10
- moreniius/mccode/instance.py,sha256=yydYeMGITlZrVWBVYregBWQ0Sd_2A71hgoyCrLLW-Jk,8058
11
- moreniius/mccode/instr.py,sha256=D4B3ylD4BMfkiP5t2hx5xop9c7yk7QVSleT1wvpK17E,6161
12
- moreniius/mccode/mccode.py,sha256=0Ck9xFUHU3EkBGTNIXelMgtLA1JXOs976Sj2wXfMQng,4237
13
- moreniius/mccode/orientation.py,sha256=khT0jTMXyXkPCoEpDg-eLKulF-J2wIqNhUi1NzFWvto,3907
14
- moreniius-0.6.3.dist-info/METADATA,sha256=1S-tgxjhVxaMc4a9BCqGIiMqI5WRCAGdSQMGVJTiOH4,946
15
- moreniius-0.6.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- moreniius-0.6.3.dist-info/entry_points.txt,sha256=Ga3k4P4fyBt5_dJ03Oapic2Qlgqv9jufQGdxWiz_j2A,63
17
- moreniius-0.6.3.dist-info/top_level.txt,sha256=RzMo23UfVhgQeuOYeS5P9I0qVbxx4Gbe6Roc29Mr02c,10
18
- moreniius-0.6.3.dist-info/RECORD,,