junifer 0.0.7.dev93__py3-none-any.whl → 0.0.7.dev103__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.
- junifer/_version.py +2 -2
- junifer/pipeline/pipeline_component_registry.py +1 -0
- junifer/preprocess/__init__.pyi +2 -0
- junifer/preprocess/_temporal_filter.py +240 -0
- junifer/preprocess/tests/test_temporal_filter.py +99 -0
- {junifer-0.0.7.dev93.dist-info → junifer-0.0.7.dev103.dist-info}/METADATA +1 -1
- {junifer-0.0.7.dev93.dist-info → junifer-0.0.7.dev103.dist-info}/RECORD +12 -10
- {junifer-0.0.7.dev93.dist-info → junifer-0.0.7.dev103.dist-info}/WHEEL +0 -0
- {junifer-0.0.7.dev93.dist-info → junifer-0.0.7.dev103.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.7.dev93.dist-info → junifer-0.0.7.dev103.dist-info}/licenses/AUTHORS.rst +0 -0
- {junifer-0.0.7.dev93.dist-info → junifer-0.0.7.dev103.dist-info}/licenses/LICENSE.md +0 -0
- {junifer-0.0.7.dev93.dist-info → junifer-0.0.7.dev103.dist-info}/top_level.txt +0 -0
junifer/_version.py
CHANGED
@@ -17,5 +17,5 @@ __version__: str
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
18
18
|
version_tuple: VERSION_TUPLE
|
19
19
|
|
20
|
-
__version__ = version = '0.0.7.
|
21
|
-
__version_tuple__ = version_tuple = (0, 0, 7, '
|
20
|
+
__version__ = version = '0.0.7.dev103'
|
21
|
+
__version_tuple__ = version_tuple = (0, 0, 7, 'dev103')
|
@@ -76,6 +76,7 @@ class PipelineComponentRegistry(metaclass=Singleton):
|
|
76
76
|
"SpaceWarper": "SpaceWarper",
|
77
77
|
"fMRIPrepConfoundRemover": "fMRIPrepConfoundRemover",
|
78
78
|
"TemporalSlicer": "TemporalSlicer",
|
79
|
+
"TemporalFilter": "TemporalFilter",
|
79
80
|
},
|
80
81
|
"marker": {
|
81
82
|
"ALFFParcels": "ALFFParcels",
|
junifer/preprocess/__init__.pyi
CHANGED
@@ -4,6 +4,7 @@ __all__ = [
|
|
4
4
|
"SpaceWarper",
|
5
5
|
"Smoothing",
|
6
6
|
"TemporalSlicer",
|
7
|
+
"TemporalFilter",
|
7
8
|
]
|
8
9
|
|
9
10
|
from .base import BasePreprocessor
|
@@ -11,3 +12,4 @@ from .confounds import fMRIPrepConfoundRemover
|
|
11
12
|
from .warping import SpaceWarper
|
12
13
|
from .smoothing import Smoothing
|
13
14
|
from ._temporal_slicer import TemporalSlicer
|
15
|
+
from ._temporal_filter import TemporalFilter
|
@@ -0,0 +1,240 @@
|
|
1
|
+
"""Provide class for temporal filtering."""
|
2
|
+
|
3
|
+
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
|
4
|
+
# Leonard Sasse <l.sasse@fz-juelich.de>
|
5
|
+
# Synchon Mandal <s.mandal@fz-juelich.de>
|
6
|
+
# License: AGPL
|
7
|
+
|
8
|
+
from typing import (
|
9
|
+
Any,
|
10
|
+
ClassVar,
|
11
|
+
Optional,
|
12
|
+
Union,
|
13
|
+
)
|
14
|
+
|
15
|
+
import nibabel as nib
|
16
|
+
from nilearn import image as nimg
|
17
|
+
from nilearn._utils.niimg_conversions import check_niimg_4d
|
18
|
+
|
19
|
+
from ..api.decorators import register_preprocessor
|
20
|
+
from ..data import get_data
|
21
|
+
from ..pipeline import WorkDirManager
|
22
|
+
from ..typing import Dependencies
|
23
|
+
from ..utils import logger
|
24
|
+
from .base import BasePreprocessor
|
25
|
+
|
26
|
+
|
27
|
+
__all__ = ["TemporalFilter"]
|
28
|
+
|
29
|
+
|
30
|
+
@register_preprocessor
|
31
|
+
class TemporalFilter(BasePreprocessor):
|
32
|
+
"""Class for temporal filtering.
|
33
|
+
|
34
|
+
Temporal filtering is based on :func:`nilearn.image.clean_img`.
|
35
|
+
|
36
|
+
Parameters
|
37
|
+
----------
|
38
|
+
detrend : bool, optional
|
39
|
+
If True, detrending will be applied on timeseries (default True).
|
40
|
+
standardize : bool, optional
|
41
|
+
If True, returned signals are set to unit variance (default True).
|
42
|
+
low_pass : float, optional
|
43
|
+
Low cutoff frequencies, in Hertz. If None, no filtering is applied
|
44
|
+
(default None).
|
45
|
+
high_pass : float, optional
|
46
|
+
High cutoff frequencies, in Hertz. If None, no filtering is
|
47
|
+
applied (default None).
|
48
|
+
t_r : float, optional
|
49
|
+
Repetition time, in second (sampling period).
|
50
|
+
If None, it will use t_r from nifti header (default None).
|
51
|
+
masks : str, dict or list of dict or str, optional
|
52
|
+
The specification of the masks to apply to regions before extracting
|
53
|
+
signals. Check :ref:`Using Masks <using_masks>` for more details.
|
54
|
+
If None, will not apply any mask (default None).
|
55
|
+
|
56
|
+
"""
|
57
|
+
|
58
|
+
_DEPENDENCIES: ClassVar[Dependencies] = {"numpy", "nilearn"}
|
59
|
+
|
60
|
+
def __init__(
|
61
|
+
self,
|
62
|
+
detrend: bool = True,
|
63
|
+
standardize: bool = True,
|
64
|
+
low_pass: Optional[float] = None,
|
65
|
+
high_pass: Optional[float] = None,
|
66
|
+
t_r: Optional[float] = None,
|
67
|
+
masks: Union[str, dict, list[Union[dict, str]], None] = None,
|
68
|
+
) -> None:
|
69
|
+
"""Initialize the class."""
|
70
|
+
self.detrend = detrend
|
71
|
+
self.standardize = standardize
|
72
|
+
self.low_pass = low_pass
|
73
|
+
self.high_pass = high_pass
|
74
|
+
self.t_r = t_r
|
75
|
+
self.masks = masks
|
76
|
+
|
77
|
+
super().__init__(on="BOLD", required_data_types=["BOLD"])
|
78
|
+
|
79
|
+
def get_valid_inputs(self) -> list[str]:
|
80
|
+
"""Get valid data types for input.
|
81
|
+
|
82
|
+
Returns
|
83
|
+
-------
|
84
|
+
list of str
|
85
|
+
The list of data types that can be used as input for this
|
86
|
+
preprocessor.
|
87
|
+
|
88
|
+
"""
|
89
|
+
return ["BOLD"]
|
90
|
+
|
91
|
+
def get_output_type(self, input_type: str) -> str:
|
92
|
+
"""Get output type.
|
93
|
+
|
94
|
+
Parameters
|
95
|
+
----------
|
96
|
+
input_type : str
|
97
|
+
The input to the preprocessor.
|
98
|
+
|
99
|
+
Returns
|
100
|
+
-------
|
101
|
+
str
|
102
|
+
The data type output by the preprocessor.
|
103
|
+
|
104
|
+
"""
|
105
|
+
# Does not add any new keys
|
106
|
+
return input_type
|
107
|
+
|
108
|
+
def _validate_data(
|
109
|
+
self,
|
110
|
+
input: dict[str, Any],
|
111
|
+
) -> None:
|
112
|
+
"""Validate input data.
|
113
|
+
|
114
|
+
Parameters
|
115
|
+
----------
|
116
|
+
input : dict
|
117
|
+
Dictionary containing the ``BOLD`` data from the
|
118
|
+
Junifer Data object.
|
119
|
+
|
120
|
+
Raises
|
121
|
+
------
|
122
|
+
ValueError
|
123
|
+
If ``"data"`` is not 4D
|
124
|
+
|
125
|
+
"""
|
126
|
+
# BOLD must be 4D niimg
|
127
|
+
check_niimg_4d(input["data"])
|
128
|
+
|
129
|
+
def preprocess(
|
130
|
+
self,
|
131
|
+
input: dict[str, Any],
|
132
|
+
extra_input: Optional[dict[str, Any]] = None,
|
133
|
+
) -> tuple[dict[str, Any], Optional[dict[str, dict[str, Any]]]]:
|
134
|
+
"""Preprocess.
|
135
|
+
|
136
|
+
Parameters
|
137
|
+
----------
|
138
|
+
input : dict
|
139
|
+
A single input from the Junifer Data object to preprocess.
|
140
|
+
extra_input : dict, optional
|
141
|
+
The other fields in the Junifer Data object.
|
142
|
+
|
143
|
+
Returns
|
144
|
+
-------
|
145
|
+
dict
|
146
|
+
The computed result as dictionary. If `self.masks` is not None,
|
147
|
+
then the target data computed mask is updated for further steps.
|
148
|
+
None
|
149
|
+
Extra "helper" data types as dictionary to add to the Junifer Data
|
150
|
+
object.
|
151
|
+
|
152
|
+
"""
|
153
|
+
# Validate data
|
154
|
+
self._validate_data(input)
|
155
|
+
|
156
|
+
# Get BOLD data
|
157
|
+
bold_img = input["data"]
|
158
|
+
# Set t_r
|
159
|
+
t_r = self.t_r
|
160
|
+
if t_r is None:
|
161
|
+
logger.info("No `t_r` specified, using t_r from NIfTI header")
|
162
|
+
t_r = bold_img.header.get_zooms()[3] # type: ignore
|
163
|
+
logger.info(
|
164
|
+
f"Read t_r from NIfTI header: {t_r}",
|
165
|
+
)
|
166
|
+
|
167
|
+
# Create element-specific tempdir for storing generated data
|
168
|
+
# and / or mask
|
169
|
+
element_tempdir = WorkDirManager().get_element_tempdir(
|
170
|
+
prefix="temporal_filter"
|
171
|
+
)
|
172
|
+
|
173
|
+
# Set mask data
|
174
|
+
mask_img = None
|
175
|
+
if self.masks is not None:
|
176
|
+
# Generate mask
|
177
|
+
logger.debug(f"Masking with {self.masks}")
|
178
|
+
mask_img = get_data(
|
179
|
+
kind="mask",
|
180
|
+
names=self.masks,
|
181
|
+
target_data=input,
|
182
|
+
extra_input=extra_input,
|
183
|
+
)
|
184
|
+
# Save generated mask for use later
|
185
|
+
generated_mask_img_path = element_tempdir / "generated_mask.nii.gz"
|
186
|
+
nib.save(mask_img, generated_mask_img_path)
|
187
|
+
|
188
|
+
# Save BOLD mask and link it to the BOLD data type dict;
|
189
|
+
# this allows to use "inherit" down the pipeline
|
190
|
+
logger.debug("Setting `BOLD.mask`")
|
191
|
+
input.update(
|
192
|
+
{
|
193
|
+
"mask": {
|
194
|
+
# Update path to sync with "data"
|
195
|
+
"path": generated_mask_img_path,
|
196
|
+
# Update data
|
197
|
+
"data": mask_img,
|
198
|
+
# Should be in the same space as target data
|
199
|
+
"space": input["space"],
|
200
|
+
}
|
201
|
+
}
|
202
|
+
)
|
203
|
+
|
204
|
+
signal_clean_kwargs = {}
|
205
|
+
|
206
|
+
# Clean image
|
207
|
+
logger.info("Temporal filter image using nilearn")
|
208
|
+
logger.debug(f"\tdetrend: {self.detrend}")
|
209
|
+
logger.debug(f"\tstandardize: {self.standardize}")
|
210
|
+
logger.debug(f"\tlow_pass: {self.low_pass}")
|
211
|
+
logger.debug(f"\thigh_pass: {self.high_pass}")
|
212
|
+
logger.debug(f"\tt_r: {self.t_r}")
|
213
|
+
|
214
|
+
cleaned_img = nimg.clean_img(
|
215
|
+
imgs=bold_img,
|
216
|
+
detrend=self.detrend,
|
217
|
+
standardize=self.standardize,
|
218
|
+
low_pass=self.low_pass,
|
219
|
+
high_pass=self.high_pass,
|
220
|
+
t_r=t_r,
|
221
|
+
mask_img=mask_img,
|
222
|
+
**signal_clean_kwargs,
|
223
|
+
)
|
224
|
+
# Fix t_r as nilearn messes it up
|
225
|
+
cleaned_img.header["pixdim"][4] = t_r
|
226
|
+
# Save filtered data
|
227
|
+
filtered_data_path = element_tempdir / "filtered_data.nii.gz"
|
228
|
+
nib.save(cleaned_img, filtered_data_path)
|
229
|
+
|
230
|
+
logger.debug("Updating `BOLD`")
|
231
|
+
input.update(
|
232
|
+
{
|
233
|
+
# Update path to sync with "data"
|
234
|
+
"path": filtered_data_path,
|
235
|
+
# Update data
|
236
|
+
"data": cleaned_img,
|
237
|
+
}
|
238
|
+
)
|
239
|
+
|
240
|
+
return input, None
|
@@ -0,0 +1,99 @@
|
|
1
|
+
"""Provide tests for TemporalFilter."""
|
2
|
+
|
3
|
+
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
4
|
+
# License: AGPL
|
5
|
+
|
6
|
+
from typing import Optional
|
7
|
+
|
8
|
+
import pytest
|
9
|
+
|
10
|
+
from junifer.datareader import DefaultDataReader
|
11
|
+
from junifer.preprocess import TemporalFilter
|
12
|
+
from junifer.testing.datagrabbers import PartlyCloudyTestingDataGrabber
|
13
|
+
|
14
|
+
|
15
|
+
@pytest.mark.parametrize(
|
16
|
+
"detrend, standardize, low_pass, high_pass, t_r, masks",
|
17
|
+
(
|
18
|
+
[
|
19
|
+
True,
|
20
|
+
True,
|
21
|
+
None,
|
22
|
+
None,
|
23
|
+
None,
|
24
|
+
None,
|
25
|
+
],
|
26
|
+
[
|
27
|
+
False,
|
28
|
+
True,
|
29
|
+
0.1,
|
30
|
+
None,
|
31
|
+
None,
|
32
|
+
"compute_brain_mask",
|
33
|
+
],
|
34
|
+
[
|
35
|
+
True,
|
36
|
+
False,
|
37
|
+
None,
|
38
|
+
0.08,
|
39
|
+
None,
|
40
|
+
"compute_background_mask",
|
41
|
+
],
|
42
|
+
[
|
43
|
+
False,
|
44
|
+
False,
|
45
|
+
None,
|
46
|
+
None,
|
47
|
+
2,
|
48
|
+
None,
|
49
|
+
],
|
50
|
+
[
|
51
|
+
True,
|
52
|
+
True,
|
53
|
+
0.1,
|
54
|
+
0.08,
|
55
|
+
2,
|
56
|
+
"compute_brain_mask",
|
57
|
+
],
|
58
|
+
),
|
59
|
+
)
|
60
|
+
def test_TemporalFilter(
|
61
|
+
detrend: bool,
|
62
|
+
standardize: bool,
|
63
|
+
low_pass: Optional[float],
|
64
|
+
high_pass: Optional[float],
|
65
|
+
t_r: Optional[float],
|
66
|
+
masks: Optional[str],
|
67
|
+
) -> None:
|
68
|
+
"""Test TemporalFilter.
|
69
|
+
|
70
|
+
Parameters
|
71
|
+
----------
|
72
|
+
detrend : bool
|
73
|
+
The parametrized detrending flag.
|
74
|
+
standardize : bool
|
75
|
+
The parametrized standardization flag.
|
76
|
+
low_pass : float or None
|
77
|
+
The parametrized low pass value.
|
78
|
+
high_pass : float or None
|
79
|
+
The parametrized high pass value.
|
80
|
+
t_r : float or None
|
81
|
+
The parametrized repetition time.
|
82
|
+
masks : str or None
|
83
|
+
The parametrized mask.
|
84
|
+
|
85
|
+
"""
|
86
|
+
with PartlyCloudyTestingDataGrabber() as dg:
|
87
|
+
# Read data
|
88
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
89
|
+
# Preprocess data
|
90
|
+
output = TemporalFilter(
|
91
|
+
detrend=detrend,
|
92
|
+
standardize=standardize,
|
93
|
+
low_pass=low_pass,
|
94
|
+
high_pass=high_pass,
|
95
|
+
t_r=t_r,
|
96
|
+
masks=masks,
|
97
|
+
).fit_transform(element_data)
|
98
|
+
|
99
|
+
assert isinstance(output, dict)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: junifer
|
3
|
-
Version: 0.0.7.
|
3
|
+
Version: 0.0.7.dev103
|
4
4
|
Summary: JUelich NeuroImaging FEature extractoR
|
5
5
|
Author-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
|
6
6
|
Maintainer-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
junifer/__init__.py,sha256=2McgH1yNue6Z1V26-uN_mfMjbTcx4CLhym-DMBl5xA4,266
|
2
2
|
junifer/__init__.pyi,sha256=SsTvgq2Dod6UqJN96GH1lCphH6hJQQurEJHGNhHjGUI,508
|
3
|
-
junifer/_version.py,sha256=
|
3
|
+
junifer/_version.py,sha256=lN1OlFRhWpeMEzNQFnMVqqVCakOFOBXHCtoV4Aaux2M,528
|
4
4
|
junifer/conftest.py,sha256=PWYkkRDU8ly2lYwv7VBKMHje4et6HX7Yey3Md_I2KbA,613
|
5
5
|
junifer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
junifer/stats.py,sha256=e9aaagMGtgpRfW3Wdpz9ocpnYld1IWylCDcjFUgX9Mk,6225
|
@@ -242,7 +242,7 @@ junifer/onthefly/tests/test_read_transform.py,sha256=Ed6gtj8bsD11fe0Y1AxG2JndtIT
|
|
242
242
|
junifer/pipeline/__init__.py,sha256=rxKQGRwc6_sts1KhVIcVVpuXeiFABf11mQQ2h5jgA3U,194
|
243
243
|
junifer/pipeline/__init__.pyi,sha256=hhcvNcABhtLaUQiZdTjo5sMWC3rtDkwVshL0sxD5JAE,399
|
244
244
|
junifer/pipeline/marker_collection.py,sha256=1Kmf5f0E2MFhDpO9OBui046b_6h1u9U64AdEqrxso-o,5377
|
245
|
-
junifer/pipeline/pipeline_component_registry.py,sha256=
|
245
|
+
junifer/pipeline/pipeline_component_registry.py,sha256=N80XfOZB33tscuqUlrri0r8sMUGVkPL6Li01Of70qrA,9517
|
246
246
|
junifer/pipeline/pipeline_step_mixin.py,sha256=oXfJh27yifHs1V3V_tMPCanRiHX1ggOVIbHTvMzq3cY,7853
|
247
247
|
junifer/pipeline/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
248
248
|
junifer/pipeline/update_meta_mixin.py,sha256=yzGCx8AUbc9mMnWKRu4qaIXTBBSIxtNlGH5zIQIUvzM,1812
|
@@ -254,7 +254,8 @@ junifer/pipeline/tests/test_pipeline_step_mixin.py,sha256=KCdhFdThm9TGkUvhGzQF3z
|
|
254
254
|
junifer/pipeline/tests/test_update_meta_mixin.py,sha256=po7mWGmXCkZUi201zqgtTm7-A1HKjBgUgqMglMvedqc,1338
|
255
255
|
junifer/pipeline/tests/test_workdir_manager.py,sha256=_rXlGb_PUQJBVgV1PWmwjFvTW971MkEbyDDY9dLfJAY,4051
|
256
256
|
junifer/preprocess/__init__.py,sha256=91D43p254il88g-7sSN64M7HsCvwytYoiTS_GLEr37Y,342
|
257
|
-
junifer/preprocess/__init__.pyi,sha256=
|
257
|
+
junifer/preprocess/__init__.pyi,sha256=TM84ia0HAOO9Tt7yTnZVRa1PTE6-F6pnHXcM0ijqVe4,388
|
258
|
+
junifer/preprocess/_temporal_filter.py,sha256=_tvoCvTBOD7WgeaoR9RqxltfKD_vLQBKPTFYxsFzf2s,7241
|
258
259
|
junifer/preprocess/_temporal_slicer.py,sha256=clZdDwGZrw656JYuK5eVvml54WxNVCQ2EOTbnsHhwnQ,7160
|
259
260
|
junifer/preprocess/base.py,sha256=hARO4Yq9sQ8m2tATeuBmPMbI4BSnwNxLf2prF8Iq_Tk,6662
|
260
261
|
junifer/preprocess/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -272,6 +273,7 @@ junifer/preprocess/smoothing/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
272
273
|
junifer/preprocess/smoothing/smoothing.py,sha256=wdOnPi8XkEqzOQdUNJ0yOm_uWi3H4DnTQhOL8z7dZDs,5281
|
273
274
|
junifer/preprocess/smoothing/tests/test_smoothing.py,sha256=IYL-IaRYIuhOU7jGixgNuT-ed_i6q9gmDhK-ZpXAGeU,2389
|
274
275
|
junifer/preprocess/tests/test_preprocess_base.py,sha256=-0rpe8QjqYES36H6MHuDs3cv_6upHBdVHnFMgQsmEX4,2571
|
276
|
+
junifer/preprocess/tests/test_temporal_filter.py,sha256=ZgEDIGqpFX3dGGKOJAf1vhvg2Q4xWR1aP6MADuPUdro,2227
|
275
277
|
junifer/preprocess/tests/test_temporal_slicer.py,sha256=bbt6kxOM-Bv_s9iPn4wrf2YxpA64xO2S0kgRYUEeBNo,4061
|
276
278
|
junifer/preprocess/warping/__init__.py,sha256=rzUUP7-6H_nygQ7a7TBZ4_RY7p0ELacosYsWQbSdVZk,214
|
277
279
|
junifer/preprocess/warping/__init__.pyi,sha256=Drbqp8N3uprvXcKSxqdfj90fesz9XYVLgivhPnKAYcc,65
|
@@ -322,10 +324,10 @@ junifer/utils/tests/test_config.py,sha256=7ltIXuwb_W4Mv_1dxQWyiyM10XgUAfsWKV6D_i
|
|
322
324
|
junifer/utils/tests/test_fs.py,sha256=WQS7cKlKEZ742CIuiOYYpueeAhY9PqlastfDVpVVtvE,923
|
323
325
|
junifer/utils/tests/test_helpers.py,sha256=k5qqfxK8dFyuewTJyR1Qn6-nFaYNuVr0ysc18bfPjyU,929
|
324
326
|
junifer/utils/tests/test_logging.py,sha256=W4tFKmaf8_CxnWZ-o_-XxM7DQbhGG18RsLZJk8bZelI,8163
|
325
|
-
junifer-0.0.7.
|
326
|
-
junifer-0.0.7.
|
327
|
-
junifer-0.0.7.
|
328
|
-
junifer-0.0.7.
|
329
|
-
junifer-0.0.7.
|
330
|
-
junifer-0.0.7.
|
331
|
-
junifer-0.0.7.
|
327
|
+
junifer-0.0.7.dev103.dist-info/licenses/AUTHORS.rst,sha256=rmULKpchpSol4ExWFdm-qu4fkpSZPYqIESVJBZtGb6E,163
|
328
|
+
junifer-0.0.7.dev103.dist-info/licenses/LICENSE.md,sha256=MqCnOBu8uXsEOzRZWh9EBVfVz-kE9NkXcLCrtGXo2yU,34354
|
329
|
+
junifer-0.0.7.dev103.dist-info/METADATA,sha256=HywNKV05cZK4-bdlxc-s1VK-3nfOpBcAyt0te4yUitk,8388
|
330
|
+
junifer-0.0.7.dev103.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
331
|
+
junifer-0.0.7.dev103.dist-info/entry_points.txt,sha256=6O8ru0BP-SP7YMUZiizFNoaZ2HvJpadO2G7nKk4PwjI,48
|
332
|
+
junifer-0.0.7.dev103.dist-info/top_level.txt,sha256=4bAq1R2QFQ4b3hohjys2JBvxrl0GKk5LNFzYvz9VGcA,8
|
333
|
+
junifer-0.0.7.dev103.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|