fastMONAI 0.5.4__py3-none-any.whl → 0.6.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.
fastMONAI/vision_patch.py CHANGED
@@ -18,8 +18,10 @@ from typing import Callable
18
18
  from torch.utils.data import DataLoader
19
19
  from tqdm.auto import tqdm
20
20
  from fastai.data.all import *
21
+ from fastai.learner import Learner
21
22
  from .vision_core import MedImage, MedMask, MedBase, med_img_reader
22
23
  from .vision_inference import _to_original_orientation, _do_resize
24
+ from .dataset_info import MedDataset, suggest_patch_size
23
25
 
24
26
  # %% ../nbs/10_vision_patch.ipynb 3
25
27
  def _get_default_device() -> torch.device:
@@ -109,7 +111,7 @@ class PatchConfig:
109
111
  queue_num_workers: Number of workers for parallel patch extraction.
110
112
  aggregation_mode: For inference, how to combine overlapping patches ('crop', 'average', 'hann').
111
113
  apply_reorder: Whether to reorder to RAS+ canonical orientation. Must match between
112
- training and inference.
114
+ training and inference. Defaults to True (the common case).
113
115
  target_spacing: Target voxel spacing [x, y, z] for resampling. Must match between
114
116
  training and inference.
115
117
  padding_mode: Padding mode for CropOrPad when image < patch_size. Default is 0 (zero padding)
@@ -124,7 +126,6 @@ class PatchConfig:
124
126
  ... samples_per_volume=16,
125
127
  ... sampler_type='label',
126
128
  ... label_probabilities={0: 0.1, 1: 0.9},
127
- ... apply_reorder=True,
128
129
  ... target_spacing=[0.5, 0.5, 0.5]
129
130
  ... )
130
131
  """
@@ -137,7 +138,7 @@ class PatchConfig:
137
138
  queue_num_workers: int = 4
138
139
  aggregation_mode: str = 'hann'
139
140
  # Preprocessing parameters - must match between training and inference
140
- apply_reorder: bool = False
141
+ apply_reorder: bool = True # Defaults to True (the common case)
141
142
  target_spacing: list = None
142
143
  padding_mode: int | float | str = 0 # Zero padding (nnU-Net standard)
143
144
  # Post-processing (binary segmentation only)
@@ -176,6 +177,74 @@ class PatchConfig:
176
177
  f"Overlap >= patch_size creates step_size <= 0 (infinite patches)."
177
178
  )
178
179
 
180
+ @classmethod
181
+ def from_dataset(
182
+ cls,
183
+ dataset: 'MedDataset',
184
+ target_spacing: list = None,
185
+ min_patch_size: list = None,
186
+ max_patch_size: list = None,
187
+ divisor: int = 16,
188
+ **kwargs
189
+ ) -> 'PatchConfig':
190
+ """Create PatchConfig with automatic patch_size from dataset analysis.
191
+
192
+ Combines dataset preprocessing suggestions with patch size calculation
193
+ for a complete, DRY configuration.
194
+
195
+ Args:
196
+ dataset: MedDataset instance with analyzed images.
197
+ target_spacing: Target voxel spacing [x, y, z]. If None, uses
198
+ dataset.get_suggestion()['target_spacing'].
199
+ min_patch_size: Minimum per dimension [32, 32, 32].
200
+ max_patch_size: Maximum per dimension [256, 256, 256].
201
+ divisor: Divisibility constraint (default 16 for UNet compatibility).
202
+ **kwargs: Additional PatchConfig parameters (samples_per_volume,
203
+ sampler_type, label_probabilities, etc.).
204
+
205
+ Returns:
206
+ PatchConfig with suggested patch_size, apply_reorder, target_spacing.
207
+
208
+ Example:
209
+ >>> from fastMONAI.dataset_info import MedDataset
210
+ >>> dataset = MedDataset(dataframe=df, mask_col='mask_path', dtype=MedMask)
211
+ >>>
212
+ >>> # Use recommended spacing
213
+ >>> config = PatchConfig.from_dataset(dataset, samples_per_volume=16)
214
+ >>>
215
+ >>> # Use custom spacing
216
+ >>> config = PatchConfig.from_dataset(
217
+ ... dataset,
218
+ ... target_spacing=[1.0, 1.0, 2.0],
219
+ ... samples_per_volume=16
220
+ ... )
221
+ """
222
+ # Get preprocessing suggestion from dataset
223
+ suggestion = dataset.get_suggestion()
224
+
225
+ # Use explicit spacing or dataset suggestion
226
+ _target_spacing = target_spacing if target_spacing is not None else suggestion['target_spacing']
227
+
228
+ # Calculate patch size for the target spacing
229
+ patch_size = suggest_patch_size(
230
+ dataset,
231
+ target_spacing=_target_spacing,
232
+ min_patch_size=min_patch_size,
233
+ max_patch_size=max_patch_size,
234
+ divisor=divisor
235
+ )
236
+
237
+ # Merge with explicit kwargs (kwargs override defaults)
238
+ # Use dataset.apply_reorder directly (not from get_suggestion() since it's not data-derived)
239
+ config_kwargs = {
240
+ 'patch_size': patch_size,
241
+ 'apply_reorder': dataset.apply_reorder,
242
+ 'target_spacing': _target_spacing,
243
+ }
244
+ config_kwargs.update(kwargs)
245
+
246
+ return cls(**config_kwargs)
247
+
179
248
  # %% ../nbs/10_vision_patch.ipynb 10
180
249
  def med_to_subject(
181
250
  img: Path | str,
@@ -374,6 +443,9 @@ class MedPatchDataLoader:
374
443
  drop_last=drop_last
375
444
  )
376
445
 
446
+ # Track cleanup state
447
+ self._closed = False
448
+
377
449
  def __iter__(self):
378
450
  """Iterate over batches, yielding (image, mask) tuples."""
379
451
  for batch in self._dl:
@@ -444,6 +516,31 @@ class MedPatchDataLoader:
444
516
  """
445
517
  return next(iter(self))
446
518
 
519
+ def close(self):
520
+ """Shut down TorchIO Queue workers. Safe to call multiple times."""
521
+ if self._closed:
522
+ return
523
+ self._closed = True
524
+ try:
525
+ # Trigger cleanup of Queue's internal DataLoader iterator
526
+ if hasattr(self, 'queue') and hasattr(self.queue, '_subjects_iterable'):
527
+ self.queue._subjects_iterable = None
528
+ except Exception:
529
+ pass # Suppress cleanup errors
530
+
531
+ def __enter__(self):
532
+ return self
533
+
534
+ def __exit__(self, exc_type, exc_val, exc_tb):
535
+ self.close()
536
+ return False
537
+
538
+ def __del__(self):
539
+ try:
540
+ self.close()
541
+ except Exception:
542
+ pass
543
+
447
544
  # %% ../nbs/10_vision_patch.ipynb 18
448
545
  class MedPatchDataLoaders:
449
546
  """fastai-compatible DataLoaders for patch-based training with LAZY loading.
@@ -491,6 +588,9 @@ class MedPatchDataLoaders:
491
588
  self._train_dl.to(self._device)
492
589
  self._valid_dl.to(self._device)
493
590
 
591
+ # Track cleanup state
592
+ self._closed = False
593
+
494
594
  @classmethod
495
595
  def from_df(
496
596
  cls,
@@ -528,6 +628,7 @@ class MedPatchDataLoaders:
528
628
  target_spacing) can be set here for DRY usage with PatchInferenceEngine.
529
629
  pre_patch_tfms: TorchIO transforms applied before patch extraction
530
630
  (after reorder/resample). Example: [tio.ZNormalization()].
631
+ Accepts both fastMONAI wrappers and raw TorchIO transforms.
531
632
  patch_tfms: TorchIO transforms applied to extracted patches (training only).
532
633
  apply_reorder: If True, reorder to RAS+ orientation. If None, uses
533
634
  patch_config.apply_reorder. Explicit value overrides config.
@@ -595,9 +696,9 @@ class MedPatchDataLoaders:
595
696
  if _target_spacing is not None:
596
697
  all_pre_tfms.append(tio.Resample(_target_spacing))
597
698
 
598
- # Add user-provided transforms
699
+ # Add user-provided transforms (normalize to raw TorchIO transforms)
599
700
  if pre_patch_tfms:
600
- all_pre_tfms.extend(pre_patch_tfms)
701
+ all_pre_tfms.extend(normalize_patch_transforms(pre_patch_tfms))
601
702
 
602
703
  # Create subjects datasets with lazy loading (paths only, ~0 MB)
603
704
  train_subjects = create_subjects_dataset(
@@ -743,9 +844,35 @@ class MedPatchDataLoaders:
743
844
  def to(self, device):
744
845
  self._device = device
745
846
  return self
847
+ def cpu(self):
848
+ """Move to CPU. Required for load_learner compatibility."""
849
+ return self.to(torch.device('cpu'))
746
850
 
747
851
  return EmptyMedPatchDataLoaders(self._device)
748
852
 
853
+ def close(self):
854
+ """Shut down all DataLoader workers. Safe to call multiple times."""
855
+ if self._closed:
856
+ return
857
+ self._closed = True
858
+ if hasattr(self, '_train_dl') and self._train_dl is not None:
859
+ self._train_dl.close()
860
+ if hasattr(self, '_valid_dl') and self._valid_dl is not None:
861
+ self._valid_dl.close()
862
+
863
+ def __enter__(self):
864
+ return self
865
+
866
+ def __exit__(self, exc_type, exc_val, exc_tb):
867
+ self.close()
868
+ return False
869
+
870
+ def __del__(self):
871
+ try:
872
+ self.close()
873
+ except Exception:
874
+ pass
875
+
749
876
  # %% ../nbs/10_vision_patch.ipynb 20
750
877
  import numbers
751
878
 
@@ -806,7 +933,8 @@ class PatchInferenceEngine:
806
933
  GridAggregator to reconstruct the full volume from predictions.
807
934
 
808
935
  Args:
809
- learner: PyTorch model or fastai Learner.
936
+ learner: fastai Learner or PyTorch model (nn.Module). When passing a raw
937
+ PyTorch model, load weights first with model.load_state_dict().
810
938
  config: PatchConfig with inference settings. Preprocessing params (apply_reorder,
811
939
  target_spacing, padding_mode) can be set here for DRY usage.
812
940
  apply_reorder: Whether to reorder to RAS+ orientation. If None, uses config value.
@@ -815,21 +943,18 @@ class PatchInferenceEngine:
815
943
  pre_inference_tfms: List of TorchIO transforms to apply before patch extraction.
816
944
  IMPORTANT: Should match the pre_patch_tfms used during training (e.g., [tio.ZNormalization()]).
817
945
  This ensures preprocessing consistency between training and inference.
946
+ Accepts both fastMONAI wrappers and raw TorchIO transforms.
818
947
 
819
948
  Example:
820
- >>> # DRY pattern: use same config for training and inference
821
- >>> config = PatchConfig(
822
- ... patch_size=[96, 96, 96],
823
- ... apply_reorder=True,
824
- ... target_spacing=[1.0, 1.0, 1.0]
825
- ... )
826
- >>> # Training
827
- >>> dls = MedPatchDataLoaders.from_df(df, 'img', 'mask', patch_config=config)
828
- >>> # Inference - no need to repeat params!
829
- >>> engine = PatchInferenceEngine(
830
- ... learn, config,
831
- ... pre_inference_tfms=[tio.ZNormalization()]
832
- ... )
949
+ >>> # Option 1: From fastai Learner
950
+ >>> engine = PatchInferenceEngine(learn, config, pre_inference_tfms=[ZNormalization()])
951
+ >>> pred = engine.predict('image.nii.gz')
952
+
953
+ >>> # Option 2: From raw PyTorch model (recommended for deployment)
954
+ >>> model = UNet(spatial_dims=3, in_channels=1, out_channels=2, ...)
955
+ >>> model.load_state_dict(torch.load('weights.pth'))
956
+ >>> model.cuda().eval()
957
+ >>> engine = PatchInferenceEngine(model, config, pre_inference_tfms=[ZNormalization()])
833
958
  >>> pred = engine.predict('image.nii.gz')
834
959
  """
835
960
 
@@ -845,11 +970,20 @@ class PatchInferenceEngine:
845
970
  if batch_size <= 0:
846
971
  raise ValueError(f"batch_size must be positive, got {batch_size}")
847
972
 
848
- # Extract model from Learner if needed
849
- self.model = learner.model if hasattr(learner, 'model') else learner
973
+ # Extract model from Learner if needed (use isinstance for robust detection)
974
+ # Note: We check for Learner explicitly because some models (e.g., MONAI UNet)
975
+ # have a .model attribute that is NOT the full model but an internal Sequential.
976
+ if isinstance(learner, Learner):
977
+ self.model = learner.model
978
+ else:
979
+ self.model = learner # Assume it's already a PyTorch model
980
+
850
981
  self.config = config
851
982
  self.batch_size = batch_size
852
- self.pre_inference_tfms = tio.Compose(pre_inference_tfms) if pre_inference_tfms else None
983
+
984
+ # Normalize transforms to raw TorchIO (accepts both fastMONAI wrappers and raw TorchIO)
985
+ normalized_tfms = normalize_patch_transforms(pre_inference_tfms)
986
+ self.pre_inference_tfms = tio.Compose(normalized_tfms) if normalized_tfms else None
853
987
 
854
988
  # Use config values, allow explicit overrides for backward compatibility
855
989
  self.apply_reorder = apply_reorder if apply_reorder is not None else config.apply_reorder
@@ -1024,7 +1158,7 @@ class PatchInferenceEngine:
1024
1158
  self.model.to(device)
1025
1159
  return self
1026
1160
 
1027
- # %% ../nbs/10_vision_patch.ipynb 21
1161
+ # %% ../nbs/10_vision_patch.ipynb 22
1028
1162
  def patch_inference(
1029
1163
  learner,
1030
1164
  config: PatchConfig,
fastMONAI/vision_plot.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_vision_plot.ipynb.
2
2
 
3
3
  # %% auto 0
4
- __all__ = ['validate_anatomical_plane', 'show_med_img', 'find_max_slice']
4
+ __all__ = ['validate_anatomical_plane', 'show_med_img', 'find_max_slice', 'show_segmentation_comparison']
5
5
 
6
6
  # %% ../nbs/00_vision_plot.ipynb 1
7
7
  import warnings
@@ -115,3 +115,91 @@ def find_max_slice(mask_data, anatomical_plane):
115
115
  idx = np.argmax(sums)
116
116
 
117
117
  return idx
118
+
119
+ # %% ../nbs/00_vision_plot.ipynb 7
120
+ def show_segmentation_comparison(
121
+ image, ground_truth, prediction,
122
+ slice_index: int = None,
123
+ anatomical_plane: int = 2,
124
+ metric_value: float = None,
125
+ metric_name: str = 'DSC',
126
+ channel: int = 0,
127
+ figsize: tuple = (15, 5),
128
+ cmap_img: str = 'gray',
129
+ cmap_mask: str = 'gray',
130
+ voxel_size = None
131
+ ):
132
+ """Display 3-panel comparison: Image | Ground Truth | Prediction.
133
+
134
+ Useful for validating segmentation results, especially after patch-based
135
+ inference where results are not in standard fastai batch format.
136
+
137
+ Args:
138
+ image: Input image (MedImage, MedMask, or tensor [C, H, W, D])
139
+ ground_truth: Ground truth mask (MedMask or tensor [C, H, W, D])
140
+ prediction: Predicted mask (tensor [C, H, W, D])
141
+ slice_index: Slice to display. If None, uses find_max_slice on ground_truth.
142
+ anatomical_plane: 0=sagittal, 1=coronal, 2=axial (default)
143
+ metric_value: Optional metric value to display in prediction title
144
+ metric_name: Name of metric for title (default 'DSC')
145
+ channel: Channel to display for multi-channel data (default 0)
146
+ figsize: Figure size (default (15, 5))
147
+ cmap_img: Colormap for image (default 'gray')
148
+ cmap_mask: Colormap for masks (default 'gray')
149
+ voxel_size: Voxel spacing for aspect ratio. If None, aspect=1.
150
+
151
+ Example::
152
+
153
+ # After patch_inference()
154
+ show_segmentation_comparison(
155
+ image=val_img,
156
+ ground_truth=val_gt,
157
+ prediction=predictions[0],
158
+ metric_value=results_df.iloc[0]['DSC'],
159
+ anatomical_plane=2
160
+ )
161
+ """
162
+ validate_anatomical_plane(anatomical_plane)
163
+
164
+ # Ensure we have tensor data
165
+ img_data = image.data if hasattr(image, 'data') else image
166
+ gt_data = ground_truth.data if hasattr(ground_truth, 'data') else ground_truth
167
+ pred_data = prediction.data if hasattr(prediction, 'data') else prediction
168
+
169
+ # Move to CPU if needed
170
+ if hasattr(img_data, 'cpu'): img_data = img_data.cpu()
171
+ if hasattr(gt_data, 'cpu'): gt_data = gt_data.cpu()
172
+ if hasattr(pred_data, 'cpu'): pred_data = pred_data.cpu()
173
+
174
+ # Find optimal slice if not provided
175
+ if slice_index is None:
176
+ gt_np = gt_data[channel].numpy()
177
+ slice_index = find_max_slice(gt_np, anatomical_plane)
178
+
179
+ # Create figure
180
+ fig, axes = plt.subplots(1, 3, figsize=figsize)
181
+
182
+ # Get slices with proper aspect ratio using existing _get_slice helper
183
+ img_slice, img_aspect = _get_slice(img_data, channel, slice_index, anatomical_plane, voxel_size)
184
+ gt_slice, gt_aspect = _get_slice(gt_data, channel, slice_index, anatomical_plane, voxel_size)
185
+ pred_slice, pred_aspect = _get_slice(pred_data, channel, slice_index, anatomical_plane, voxel_size)
186
+
187
+ # Plot panels
188
+ axes[0].imshow(img_slice, cmap=cmap_img, aspect=img_aspect)
189
+ axes[0].set_title('Input Image')
190
+ axes[0].axis('off')
191
+
192
+ axes[1].imshow(gt_slice, cmap=cmap_mask, aspect=gt_aspect)
193
+ axes[1].set_title('Ground Truth')
194
+ axes[1].axis('off')
195
+
196
+ # Build prediction title
197
+ pred_title = 'Prediction'
198
+ if metric_value is not None:
199
+ pred_title = f'Prediction ({metric_name}: {metric_value:.4f})'
200
+
201
+ axes[2].imshow(pred_slice, cmap=cmap_mask, aspect=pred_aspect)
202
+ axes[2].set_title(pred_title)
203
+ axes[2].axis('off')
204
+
205
+ plt.tight_layout()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastMONAI
3
- Version: 0.5.4
3
+ Version: 0.6.0
4
4
  Summary: fastMONAI library
5
5
  Home-page: https://github.com/MMIV-ML/fastMONAI
6
6
  Author: Satheshkumar Kaliyugarasan
@@ -0,0 +1,21 @@
1
+ fastMONAI/__init__.py,sha256=cID1jLnC_vj48GgMN6Yb1FA3JsQ95zNmCHmRYE8TFhY,22
2
+ fastMONAI/_modidx.py,sha256=9e2FCrV3l4HYPJ-qcHUVqI_Q6ps6UVxEEdD3OBCSwhw,66249
3
+ fastMONAI/dataset_info.py,sha256=hLNX0Jps8dPCbF6HYPO2PScZtn2qqAQBH07LtSubeFM,16306
4
+ fastMONAI/external_data.py,sha256=Ofa6RmSKYj8LKlzWqPGfg9lu9lTjBmolJTo1zVgTe6g,12263
5
+ fastMONAI/research_utils.py,sha256=LZu62g8BQAVYS4dD7qDsKHJXZnDd1uLkJ6LoaMDhUhk,590
6
+ fastMONAI/utils.py,sha256=8avga5wIGK4IlJ04SrN_Ba5STkBSuEA5G06EvdDHNBs,30493
7
+ fastMONAI/vision_all.py,sha256=L2JVYQq77X7Ko2SmzKUGAXwVjw898V_skGuQuYxjVd8,385
8
+ fastMONAI/vision_augmentation.py,sha256=nhFA-usts59AIYdDtzX8QJ1HrGY3bcEKu2koP3HZews,20604
9
+ fastMONAI/vision_core.py,sha256=xXGnutYD3sdWzpoMZHSfClUFmphsB7yFsDcY91Fa844,9539
10
+ fastMONAI/vision_data.py,sha256=_SgwSlNm4ZOooFnrp5vYnA7ZAweV60a3XaOnozDKm6w,11569
11
+ fastMONAI/vision_inference.py,sha256=fRPgIO-3XifBlCZY7qaucgymSLQQajcKvmZKWg0XfS4,7688
12
+ fastMONAI/vision_loss.py,sha256=NrHnk1yD4EBKsp6aippppXU4l-mwmsZOqE_bsZP3ZNI,3591
13
+ fastMONAI/vision_metrics.py,sha256=OED2ewWaZUtmkqc5CjmBWDboTVUlpsnsuFU-ZrIw4tI,18572
14
+ fastMONAI/vision_patch.py,sha256=SkEdOc_U2nrpjIVZ3wW4qwgciKnOCuzQXixRGyK3KaA,50118
15
+ fastMONAI/vision_plot.py,sha256=7HLkKQAwmwPvwrDxWlKP5IIHNNwWIrLkdsejqlOc27k,7282
16
+ fastmonai-0.6.0.dist-info/licenses/LICENSE,sha256=xV8xoN4VOL0uw9X8RSs2IMuD_Ss_a9yAbtGNeBWZwnw,11337
17
+ fastmonai-0.6.0.dist-info/METADATA,sha256=vdTSIppLb0xQtNgaAtKQfyTDKH7qqVd2sZFsv1cKgoI,7075
18
+ fastmonai-0.6.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
19
+ fastmonai-0.6.0.dist-info/entry_points.txt,sha256=mVBsykSXMairzzk3hJaQ8c-UiwUZqGnn4aFZ24CpsBM,40
20
+ fastmonai-0.6.0.dist-info/top_level.txt,sha256=o8y7SWF9odtnIT3jvYtUn9okbJRlaAMCy7oPFCeQvQ8,10
21
+ fastmonai-0.6.0.dist-info/RECORD,,
@@ -1,21 +0,0 @@
1
- fastMONAI/__init__.py,sha256=DITpct-LrdIsTgwx2NgH5Ghx5y8Xgz1YMimy1ZV5RTY,22
2
- fastMONAI/_modidx.py,sha256=eEccmLX_gTevLLfGe2ywec46xRkZrduEndx1lDMEync,59028
3
- fastMONAI/dataset_info.py,sha256=BzbTZAGTQ5idyXqf-tna84No5tu9Fjo2RJA6lTqhaW8,11043
4
- fastMONAI/external_data.py,sha256=Ofa6RmSKYj8LKlzWqPGfg9lu9lTjBmolJTo1zVgTe6g,12263
5
- fastMONAI/research_utils.py,sha256=LZu62g8BQAVYS4dD7qDsKHJXZnDd1uLkJ6LoaMDhUhk,590
6
- fastMONAI/utils.py,sha256=6bUgyVzUenkAUtf9gxJXeRsz2xc8uzjqsvzU2UVDKNI,19944
7
- fastMONAI/vision_all.py,sha256=L2JVYQq77X7Ko2SmzKUGAXwVjw898V_skGuQuYxjVd8,385
8
- fastMONAI/vision_augmentation.py,sha256=EFEUkpU7xaGJGZd6iCqOfDe56zVrgAV8t_UC0iAAum0,15611
9
- fastMONAI/vision_core.py,sha256=xXGnutYD3sdWzpoMZHSfClUFmphsB7yFsDcY91Fa844,9539
10
- fastMONAI/vision_data.py,sha256=_SgwSlNm4ZOooFnrp5vYnA7ZAweV60a3XaOnozDKm6w,11569
11
- fastMONAI/vision_inference.py,sha256=fRPgIO-3XifBlCZY7qaucgymSLQQajcKvmZKWg0XfS4,7688
12
- fastMONAI/vision_loss.py,sha256=NrHnk1yD4EBKsp6aippppXU4l-mwmsZOqE_bsZP3ZNI,3591
13
- fastMONAI/vision_metrics.py,sha256=OED2ewWaZUtmkqc5CjmBWDboTVUlpsnsuFU-ZrIw4tI,18572
14
- fastMONAI/vision_patch.py,sha256=C-LQEYt1bYCdmWG9PZJdCqlB1ucqNEA40qVF5gDA_Bs,44927
15
- fastMONAI/vision_plot.py,sha256=hdQQtS2fRdImKQABaUtK0vpmRw4hHEE8oZnsKAGy-0o,3808
16
- fastmonai-0.5.4.dist-info/licenses/LICENSE,sha256=xV8xoN4VOL0uw9X8RSs2IMuD_Ss_a9yAbtGNeBWZwnw,11337
17
- fastmonai-0.5.4.dist-info/METADATA,sha256=ssu77BruDlG-RdrjO2ee7x43WzbPN1WSytpmLgkd4YE,7075
18
- fastmonai-0.5.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
19
- fastmonai-0.5.4.dist-info/entry_points.txt,sha256=mVBsykSXMairzzk3hJaQ8c-UiwUZqGnn4aFZ24CpsBM,40
20
- fastmonai-0.5.4.dist-info/top_level.txt,sha256=o8y7SWF9odtnIT3jvYtUn9okbJRlaAMCy7oPFCeQvQ8,10
21
- fastmonai-0.5.4.dist-info/RECORD,,