junifer 0.0.4.dev576__py3-none-any.whl → 0.0.4.dev594__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 CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.0.4.dev576'
16
- __version_tuple__ = version_tuple = (0, 0, 4, 'dev576')
15
+ __version__ = version = '0.0.4.dev594'
16
+ __version_tuple__ = version_tuple = (0, 0, 4, 'dev594')
junifer/api/functions.py CHANGED
@@ -418,7 +418,10 @@ def _queue_condor(
418
418
  env_name = env["name"]
419
419
  executable = "run_venv.sh"
420
420
  arguments = f"{env_name} junifer"
421
- # TODO: Copy run_venv.sh to jobdir
421
+ exec_path = jobdir / executable
422
+ logger.info(f"Copying {executable} to {exec_path.absolute()!s}")
423
+ shutil.copy(Path(__file__).parent / "res" / executable, exec_path)
424
+ make_executable(exec_path)
422
425
  elif env["kind"] == "local":
423
426
  executable = "junifer"
424
427
  arguments = ""
junifer/api/parser.py CHANGED
@@ -99,4 +99,17 @@ def parse_yaml(filepath: Union[str, Path]) -> Dict:
99
99
  contents["storage"]["uri"] = str(
100
100
  (filepath.parent / uri_path).resolve()
101
101
  )
102
+
103
+ # Allow relative path if queue env kind is venv; same motivation as above
104
+ if "queue" in contents:
105
+ if "env" in contents["queue"]:
106
+ if "venv" == contents["queue"]["env"]["kind"]:
107
+ # Check if the env name is relative
108
+ venv_path = Path(contents["queue"]["env"]["name"])
109
+ if not venv_path.is_absolute():
110
+ # Compute the absolute path
111
+ contents["queue"]["env"]["name"] = str(
112
+ (filepath.parent / venv_path).resolve()
113
+ )
114
+
102
115
  return contents
@@ -1,17 +1,17 @@
1
1
  #!/bin/bash
2
2
 
3
3
  if [ $# -lt 2 ]; then
4
- echo "This script is meant to run a command within a python environment"
4
+ echo "This script is meant to run a command within a conda environment."
5
5
  echo "It needs at least 2 parameters."
6
6
  echo "The first one must be the environment name."
7
- echo "The rest will be the command"
7
+ echo "The rest will be the command."
8
8
  exit 255
9
9
  fi
10
10
 
11
11
  eval "$(conda shell.bash hook)"
12
12
  env_name=$1
13
13
  echo "Activating ${env_name}"
14
- conda activate "$1"
14
+ conda activate "${env_name}"
15
15
  shift 1
16
16
 
17
17
  if [ -f "pre_run.sh" ]; then
@@ -19,5 +19,5 @@ if [ -f "pre_run.sh" ]; then
19
19
  . ./pre_run.sh
20
20
  fi
21
21
 
22
- echo "Running ${*} in virtual environment"
22
+ echo "Running ${*} in conda environment"
23
23
  "$@"
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+
3
+ if [ $# -lt 2 ]; then
4
+ echo "This script is meant to run a command within a Python virtual environment."
5
+ echo "It needs at least 2 parameters."
6
+ echo "The first one must be the virtualenv path."
7
+ echo "The rest will be the command."
8
+ exit 255
9
+ fi
10
+
11
+ env_path=$1
12
+ echo "Activating ${env_path}"
13
+ source "${env_path}"/bin/activate
14
+ shift 1
15
+
16
+ if [ -f "pre_run.sh" ]; then
17
+ echo "Sourcing pre_run.sh"
18
+ . ./pre_run.sh
19
+ fi
20
+
21
+ echo "Running ${*} in Python virtual environment"
22
+ "$@"
@@ -13,8 +13,13 @@ from typing import (
13
13
  Union,
14
14
  )
15
15
 
16
+ import nibabel as nib
17
+ from templateflow import api as tflow
18
+
16
19
  from ..api.decorators import register_preprocessor
17
- from ..utils import logger, raise_error
20
+ from ..data import get_template, get_xfm
21
+ from ..pipeline import WorkDirManager
22
+ from ..utils import logger, raise_error, run_ext_cmd
18
23
  from .ants.ants_apply_transforms_warper import _AntsApplyTransformsWarper
19
24
  from .base import BasePreprocessor
20
25
  from .fsl.apply_warper import _ApplyWarper
@@ -27,7 +32,13 @@ class BOLDWarper(BasePreprocessor):
27
32
  Parameters
28
33
  ----------
29
34
  reference : str
30
- The data type to use as reference for warping.
35
+ The data type to use as reference for warping, can be either a data
36
+ type like "T1w" or a template space like "MNI152NLin2009cAsym".
37
+
38
+ Raises
39
+ ------
40
+ ValueError
41
+ If ``reference`` is invalid.
31
42
 
32
43
  """
33
44
 
@@ -49,9 +60,15 @@ class BOLDWarper(BasePreprocessor):
49
60
  def __init__(self, reference: str) -> None:
50
61
  """Initialize the class."""
51
62
  self.ref = reference
52
- super().__init__(
53
- on="BOLD", required_data_types=["BOLD", self.ref, "Warp"]
54
- )
63
+ # Initialize superclass based on reference
64
+ if self.ref == "T1w":
65
+ super().__init__(
66
+ on="BOLD", required_data_types=["BOLD", self.ref, "Warp"]
67
+ )
68
+ elif self.ref in tflow.templates():
69
+ super().__init__(on="BOLD", required_data_types=["BOLD"])
70
+ else:
71
+ raise_error(f"Unknown reference: {self.ref}")
55
72
 
56
73
  def get_valid_inputs(self) -> List[str]:
57
74
  """Get valid data types for input.
@@ -97,7 +114,8 @@ class BOLDWarper(BasePreprocessor):
97
114
  The BOLD input from the Junifer Data object.
98
115
  extra_input : dict, optional
99
116
  The other fields in the Junifer Data object. Must include the
100
- ``Warp`` and ``ref`` value's keys.
117
+ ``Warp`` and ``ref`` value's keys if native space transformation is
118
+ needed.
101
119
 
102
120
  Returns
103
121
  -------
@@ -110,46 +128,117 @@ class BOLDWarper(BasePreprocessor):
110
128
  Raises
111
129
  ------
112
130
  ValueError
113
- If ``extra_input`` is None.
131
+ If ``extra_input`` is None when transforming to native space
132
+ i.e., using "T1w" as reference.
114
133
  RuntimeError
115
- If warp / transformation file extension is not ".mat" or ".h5".
134
+ If warp / transformation file extension is not ".mat" or ".h5"
135
+ when transforming to native space or
136
+ if the BOLD data is in the correct space and does not require
137
+ warping.
116
138
 
117
139
  """
118
- logger.debug("Warping BOLD using BOLDWarper")
119
- # Check for extra inputs
120
- if extra_input is None:
121
- raise_error(
122
- f"No extra input provided, requires `Warp` and `{self.ref}` "
123
- "data types in particular."
124
- )
125
- # Check for warp file type to use correct tool
126
- warp_file_ext = extra_input["Warp"]["path"].suffix
127
- if warp_file_ext == ".mat":
128
- logger.debug("Using FSL with BOLDWarper")
129
- # Initialize ApplyWarper for computation
130
- apply_warper = _ApplyWarper(reference=self.ref, on="BOLD")
131
- # Replace original BOLD data with warped BOLD data
132
- _, input = apply_warper.preprocess(
133
- input=input,
134
- extra_input=extra_input,
135
- )
136
- elif warp_file_ext == ".h5":
137
- logger.debug("Using ANTs with BOLDWarper")
138
- # Initialize AntsApplyTransformsWarper for computation
139
- ants_apply_transforms_warper = _AntsApplyTransformsWarper(
140
- reference=self.ref, on="BOLD"
141
- )
142
- # Replace original BOLD data with warped BOLD data
143
- _, input = ants_apply_transforms_warper.preprocess(
144
- input=input,
145
- extra_input=extra_input,
146
- )
140
+ logger.info(f"Warping BOLD to {self.ref} space using BOLDWarper")
141
+ # Transform to native space
142
+ if self.ref == "T1w":
143
+ # Check for extra inputs
144
+ if extra_input is None:
145
+ raise_error(
146
+ "No extra input provided, requires `Warp` and "
147
+ f"`{self.ref}` data types in particular."
148
+ )
149
+ # Check for warp file type to use correct tool
150
+ warp_file_ext = extra_input["Warp"]["path"].suffix
151
+ if warp_file_ext == ".mat":
152
+ logger.debug("Using FSL with BOLDWarper")
153
+ # Initialize ApplyWarper for computation
154
+ apply_warper = _ApplyWarper(reference=self.ref, on="BOLD")
155
+ # Replace original BOLD data with warped BOLD data
156
+ _, input = apply_warper.preprocess(
157
+ input=input,
158
+ extra_input=extra_input,
159
+ )
160
+ elif warp_file_ext == ".h5":
161
+ logger.debug("Using ANTs with BOLDWarper")
162
+ # Initialize AntsApplyTransformsWarper for computation
163
+ ants_apply_transforms_warper = _AntsApplyTransformsWarper(
164
+ reference=self.ref, on="BOLD"
165
+ )
166
+ # Replace original BOLD data with warped BOLD data
167
+ _, input = ants_apply_transforms_warper.preprocess(
168
+ input=input,
169
+ extra_input=extra_input,
170
+ )
171
+ else:
172
+ raise_error(
173
+ msg=(
174
+ "Unknown warp / transformation file extension: "
175
+ f"{warp_file_ext}"
176
+ ),
177
+ klass=RuntimeError,
178
+ )
179
+ # Transform to template space
147
180
  else:
148
- raise_error(
149
- msg=(
150
- "Unknown warp / transformation file extension: "
151
- f"{warp_file_ext}"
152
- ),
153
- klass=RuntimeError,
154
- )
181
+ # Check pre-requirements for space manipulation
182
+ if self.ref == input["space"]:
183
+ raise_error(
184
+ (
185
+ f"Skipped warping as the BOLD data is in {self.ref} "
186
+ "space which would mean that you can remove the "
187
+ "BOLDWarper from the preprocess step."
188
+ ),
189
+ klass=RuntimeError,
190
+ )
191
+ else:
192
+ # Get xfm file
193
+ xfm_file_path = get_xfm(src=input["space"], dst=self.ref)
194
+ # Get template space image
195
+ template_space_img = get_template(
196
+ space=self.ref,
197
+ target_data=input,
198
+ extra_input=None,
199
+ )
200
+
201
+ # Create component-scoped tempdir
202
+ tempdir = WorkDirManager().get_tempdir(prefix="boldwarper")
203
+ # Create element-scoped tempdir so that warped BOLD is
204
+ # available later as nibabel stores file path reference for
205
+ # loading on computation
206
+ element_tempdir = WorkDirManager().get_element_tempdir(
207
+ prefix="boldwarper"
208
+ )
209
+
210
+ # Save template
211
+ template_space_img_path = tempdir / f"{self.ref}_T1w.nii.gz"
212
+ nib.save(template_space_img, template_space_img_path)
213
+
214
+ # Create a tempfile for warped output
215
+ warped_bold_path = (
216
+ element_tempdir
217
+ / f"bold_warped_from_{input['space']}_to_{self.ref}.nii.gz"
218
+ )
219
+
220
+ logger.debug(
221
+ f"Using ANTs to warp BOLD "
222
+ f"from {input['space']} to {self.ref}"
223
+ )
224
+ # Set antsApplyTransforms command
225
+ apply_transforms_cmd = [
226
+ "antsApplyTransforms",
227
+ "-d 3",
228
+ "-e 3",
229
+ "-n LanczosWindowedSinc",
230
+ f"-i {input['path'].resolve()}",
231
+ f"-r {template_space_img_path.resolve()}",
232
+ f"-t {xfm_file_path.resolve()}",
233
+ f"-o {warped_bold_path.resolve()}",
234
+ ]
235
+ # Call antsApplyTransforms
236
+ run_ext_cmd(
237
+ name="antsApplyTransforms", cmd=apply_transforms_cmd
238
+ )
239
+
240
+ # Modify target data
241
+ input["data"] = nib.load(warped_bold_path)
242
+ input["space"] = self.ref
243
+
155
244
  return "BOLD", input
@@ -7,6 +7,7 @@ import socket
7
7
  from typing import TYPE_CHECKING, List, Tuple
8
8
 
9
9
  import pytest
10
+ from numpy.testing import assert_array_equal, assert_raises
10
11
 
11
12
  from junifer.datagrabber import DataladHCP1200, DMCC13Benchmark
12
13
  from junifer.datareader import DefaultDataReader
@@ -83,7 +84,7 @@ def test_BOLDWarper_get_output_type(input_: List[str]) -> None:
83
84
  socket.gethostname() != "juseless",
84
85
  reason="only for juseless",
85
86
  )
86
- def test_BOLDWarper_preprocess(
87
+ def test_BOLDWarper_preprocess_to_native(
87
88
  datagrabber: "BaseDataGrabber", element: Tuple[str, ...]
88
89
  ) -> None:
89
90
  """Test BOLDWarper preprocess.
@@ -106,3 +107,70 @@ def test_BOLDWarper_preprocess(
106
107
  )
107
108
  assert data_type == "BOLD"
108
109
  assert isinstance(data, dict)
110
+
111
+
112
+ @pytest.mark.parametrize(
113
+ "datagrabber, element, space",
114
+ [
115
+ [
116
+ DMCC13Benchmark(
117
+ types=["BOLD"],
118
+ sessions=["wave1bas"],
119
+ tasks=["Rest"],
120
+ phase_encodings=["AP"],
121
+ runs=["1"],
122
+ native_t1w=False,
123
+ ),
124
+ ("f9057kp", "wave1bas", "Rest", "AP", "1"),
125
+ "MNI152NLin2009aAsym",
126
+ ],
127
+ [
128
+ DMCC13Benchmark(
129
+ types=["BOLD"],
130
+ sessions=["wave1bas"],
131
+ tasks=["Rest"],
132
+ phase_encodings=["AP"],
133
+ runs=["1"],
134
+ native_t1w=False,
135
+ ),
136
+ ("f9057kp", "wave1bas", "Rest", "AP", "1"),
137
+ "MNI152NLin6Asym",
138
+ ],
139
+ ],
140
+ )
141
+ @pytest.mark.skipif(
142
+ _check_ants() is False, reason="requires ANTs to be in PATH"
143
+ )
144
+ @pytest.mark.skipif(
145
+ socket.gethostname() != "juseless",
146
+ reason="only for juseless",
147
+ )
148
+ def test_BOLDWarper_preprocess_to_multi_mni(
149
+ datagrabber: "BaseDataGrabber", element: Tuple[str, ...], space: str
150
+ ) -> None:
151
+ """Test BOLDWarper preprocess.
152
+
153
+ Parameters
154
+ ----------
155
+ datagrabber : DataGrabber-like object
156
+ The parametrized DataGrabber objects.
157
+ element : tuple of str
158
+ The parametrized elements.
159
+ space : str
160
+ The parametrized template space to transform to.
161
+
162
+ """
163
+ with datagrabber as dg:
164
+ # Read data
165
+ element_data = DefaultDataReader().fit_transform(dg[element])
166
+ pre_xfm_data = element_data["BOLD"]["data"].get_fdata().copy()
167
+ # Preprocess data
168
+ data_type, data = BOLDWarper(reference=space).preprocess(
169
+ input=element_data["BOLD"],
170
+ extra_input=element_data,
171
+ )
172
+ assert data_type == "BOLD"
173
+ assert isinstance(data, dict)
174
+ assert data["space"] == space
175
+ with assert_raises(AssertionError):
176
+ assert_array_equal(pre_xfm_data, data["data"])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: junifer
3
- Version: 0.0.4.dev576
3
+ Version: 0.0.4.dev594
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,13 +1,14 @@
1
1
  junifer/__init__.py,sha256=x1UR2jUcrUdm2HNl-3Qvyi4UUrU6ms5qm2qcmNY7zZk,391
2
- junifer/_version.py,sha256=Edi-6wTxm5peiCW_YzRz7zYTCQLJv7NFz4LzFJ1rBWE,428
2
+ junifer/_version.py,sha256=Ji34482-PAWG6zwQO7I8NdFGpe6EM1-bfdOTbh3Sv4k,428
3
3
  junifer/stats.py,sha256=sU5IZ2qFZWbzgSutQS_z42miIVItpSGmQYBn6KkD5fA,6162
4
4
  junifer/api/__init__.py,sha256=YILu9M7SC0Ri4CVd90fELH2OnK_gvCYAXCoqBNCFE8E,257
5
5
  junifer/api/cli.py,sha256=T6FTW3vDRlsdkSYerbQD7Q05uA9bV6f8oHvK1jxGUa8,12882
6
6
  junifer/api/decorators.py,sha256=8bnwHPAe7VgzKxl--M_e0umdAlTVSzaJQHEJZ5kof5k,2580
7
- junifer/api/functions.py,sha256=XSliwA2Q9NaplfYFcK9vy6G-B-EZz894ec9LsV2RA-s,23058
8
- junifer/api/parser.py,sha256=a0IBvH3KN1PJaEpF3cnSv8g7VCVpDY1VsCvc8b8FFmE,3849
7
+ junifer/api/functions.py,sha256=ZNB9g7TRy6-r9U087sncKKD8ZGdQAgyplH4RHcZFRdU,23238
8
+ junifer/api/parser.py,sha256=a3SSC2xO-PF1pqXZXFq8Sh9aVd-dmHolJbCkGyOUTAM,4416
9
9
  junifer/api/utils.py,sha256=dyjTdPMwX9qeCrn8SQT2Pjshfnu-y1FEyujV7lCzvm0,3333
10
- junifer/api/res/run_conda.sh,sha256=GerhBGReDw-_fp6RPnaorMHT9IHrp3LRgHJY4mgK4_Y,501
10
+ junifer/api/res/run_conda.sh,sha256=eskIn-fotITOlh--IUQKXh-SBOZkDkK8QvDcdQsyJ0M,509
11
+ junifer/api/res/run_venv.sh,sha256=OF-LOdOdpjCU0JX6Dz1boG4ErPutTiVVD_N7j520Fvk,499
11
12
  junifer/api/res/afni/3dAFNItoNIFTI,sha256=Fsy5S5rwIBb1MepLfl_5FQhE7gv6NDwNyAR_k036NmM,51
12
13
  junifer/api/res/afni/3dRSFC,sha256=MkPtS_nKEoJOHDAT3ZP9IA-SvMdhyzZDiyxObV_XI3g,44
13
14
  junifer/api/res/afni/3dReHo,sha256=Jb5B97iPPPQ14zAz7tK5BVG4jPZyOe9c6kgM6ixKaY8,44
@@ -193,7 +194,7 @@ junifer/pipeline/tests/test_update_meta_mixin.py,sha256=UeWwpUi-Q5WVd36Fgfn_utXp
193
194
  junifer/pipeline/tests/test_workdir_manager.py,sha256=E1WY4C-GDsx2c49sePqr1WR_Y3nZ1kiRn4Veu506uTs,2801
194
195
  junifer/preprocess/__init__.py,sha256=-3exohZnw-gJ-MjVM63WcXzBW1mbSetEVozcDfs5etc,342
195
196
  junifer/preprocess/base.py,sha256=syiNqI8pUjoGyShZSjs_RTsd5VHhwoqzIfPfFstr4f4,6230
196
- junifer/preprocess/bold_warper.py,sha256=KOYCPCTJE92yI1juXK-3yl7VUxUhbzqqQxJrCYgk-0E,4572
197
+ junifer/preprocess/bold_warper.py,sha256=d99ZraDBXXd0UXxJJ3s-FTy76GY_AIhzBbNCzNN0QEY,8314
197
198
  junifer/preprocess/ants/__init__.py,sha256=Uobmbhh6_gOowkF2hQNSQOh3AYeaXzarBXEcLJzhERE,112
198
199
  junifer/preprocess/ants/ants_apply_transforms_warper.py,sha256=V3y9EIGdIeJhJpnEVi123fHTK3R0sv_-OmWY7R_DC1M,6627
199
200
  junifer/preprocess/ants/tests/test_ants_apply_transforms_warper.py,sha256=ibLLISss0o0wg3lqpLhL1oO7MfU_bZF5PBqY3OOd9sg,3737
@@ -203,7 +204,7 @@ junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py,sha256=OKAC
203
204
  junifer/preprocess/fsl/__init__.py,sha256=DerGFQ-dIuX5PT9a_BH6QkIXkJZVymjYy-woXF7tYGc,111
204
205
  junifer/preprocess/fsl/apply_warper.py,sha256=_HU1-63A32cSQw9eNdgpKN52BFivn6cZaDa0_at-4UY,6215
205
206
  junifer/preprocess/fsl/tests/test_apply_warper.py,sha256=b--MMPlaJw284gJWw-QV8rz6Rb2zmcBjYaY-cb6-uNU,3024
206
- junifer/preprocess/tests/test_bold_warper.py,sha256=X4rs-IBu_Oe9wF81Xlh6ih9BCu8SUyDm64lXKk-l9Q8,2831
207
+ junifer/preprocess/tests/test_bold_warper.py,sha256=oQooJt4yC09LzXJuFDL7ytlYMuhcf4SeCAWKGdVLJdQ,4890
207
208
  junifer/preprocess/tests/test_preprocess_base.py,sha256=UHuH_YOK7AU3AfApWqgB6YLG-J669BgztuxNSWCtmtI,2560
208
209
  junifer/storage/__init__.py,sha256=QlzBw9UrRhmg_f7zQVas9h313u3sfZIBicA3_0Skm4M,337
209
210
  junifer/storage/base.py,sha256=UxDvj81gSmqqHspbSs1X_i9HvW5wXysDippI7HWM7aM,9654
@@ -234,10 +235,10 @@ junifer/utils/logging.py,sha256=T0HgiCI6cS2tp9nbI4cM3nVzMMjiVzgoxuyo5Y1rCyY,9124
234
235
  junifer/utils/tests/test_fs.py,sha256=WQS7cKlKEZ742CIuiOYYpueeAhY9PqlastfDVpVVtvE,923
235
236
  junifer/utils/tests/test_helpers.py,sha256=k5qqfxK8dFyuewTJyR1Qn6-nFaYNuVr0ysc18bfPjyU,929
236
237
  junifer/utils/tests/test_logging.py,sha256=l8oo-AiBV7H6_IzlsNcj__cLeZBUvgIGoaMszD9VaJg,7754
237
- junifer-0.0.4.dev576.dist-info/AUTHORS.rst,sha256=rmULKpchpSol4ExWFdm-qu4fkpSZPYqIESVJBZtGb6E,163
238
- junifer-0.0.4.dev576.dist-info/LICENSE.md,sha256=MqCnOBu8uXsEOzRZWh9EBVfVz-kE9NkXcLCrtGXo2yU,34354
239
- junifer-0.0.4.dev576.dist-info/METADATA,sha256=qUaRguN0cYYG_C8L_ZnNdk0D-6w0EOdEICc6-Gvivl0,8128
240
- junifer-0.0.4.dev576.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
241
- junifer-0.0.4.dev576.dist-info/entry_points.txt,sha256=DxFvKq0pOqRunAK0FxwJcoDfV1-dZvsFDpD5HRqSDhw,48
242
- junifer-0.0.4.dev576.dist-info/top_level.txt,sha256=4bAq1R2QFQ4b3hohjys2JBvxrl0GKk5LNFzYvz9VGcA,8
243
- junifer-0.0.4.dev576.dist-info/RECORD,,
238
+ junifer-0.0.4.dev594.dist-info/AUTHORS.rst,sha256=rmULKpchpSol4ExWFdm-qu4fkpSZPYqIESVJBZtGb6E,163
239
+ junifer-0.0.4.dev594.dist-info/LICENSE.md,sha256=MqCnOBu8uXsEOzRZWh9EBVfVz-kE9NkXcLCrtGXo2yU,34354
240
+ junifer-0.0.4.dev594.dist-info/METADATA,sha256=ARdjzo_GyiF8LMNkJZ3lnDrF2czE2b44g4ChzZhqjGk,8128
241
+ junifer-0.0.4.dev594.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
242
+ junifer-0.0.4.dev594.dist-info/entry_points.txt,sha256=DxFvKq0pOqRunAK0FxwJcoDfV1-dZvsFDpD5HRqSDhw,48
243
+ junifer-0.0.4.dev594.dist-info/top_level.txt,sha256=4bAq1R2QFQ4b3hohjys2JBvxrl0GKk5LNFzYvz9VGcA,8
244
+ junifer-0.0.4.dev594.dist-info/RECORD,,