Args: data: dictionary data to be processed. num_examples: number of realizations to be processed and results combined. Returns: - if `return_full_data==False`: mode, mean, std, vvc. The mode, mean and standard deviation are calcu
(
self, data: dict[str, Any], num_examples: int = 10
)
| 177 | ) |
| 178 | |
| 179 | def __call__( |
| 180 | self, data: dict[str, Any], num_examples: int = 10 |
| 181 | ) -> tuple[NdarrayOrTensor, NdarrayOrTensor, NdarrayOrTensor, float] | NdarrayOrTensor: |
| 182 | """ |
| 183 | Args: |
| 184 | data: dictionary data to be processed. |
| 185 | num_examples: number of realizations to be processed and results combined. |
| 186 | |
| 187 | Returns: |
| 188 | - if `return_full_data==False`: mode, mean, std, vvc. The mode, mean and standard deviation are |
| 189 | calculated across `num_examples` outputs at each voxel. The volume variation coefficient (VVC) |
| 190 | is `std/mean` across the whole output, including `num_examples`. See original paper for clarification. |
| 191 | - if `return_full_data==False`: data is returned as-is after applying the `inferrer_fn` and then |
| 192 | concatenating across the first dimension containing `num_examples`. This allows the user to perform |
| 193 | their own analysis if desired. |
| 194 | """ |
| 195 | d = dict(data) |
| 196 | |
| 197 | # check num examples is multiple of batch size |
| 198 | if num_examples % self.batch_size != 0: |
| 199 | raise ValueError("num_examples should be multiple of batch size.") |
| 200 | |
| 201 | # generate batch of data of size == batch_size, dataset and dataloader |
| 202 | data_in = [deepcopy(d) for _ in range(num_examples)] |
| 203 | ds = Dataset(data_in, self.transform) |
| 204 | dl = DataLoader(ds, num_workers=self.num_workers, batch_size=self.batch_size, collate_fn=pad_list_data_collate) |
| 205 | |
| 206 | outs: list = [] |
| 207 | |
| 208 | for b in tqdm(dl) if has_tqdm and self.progress else dl: |
| 209 | # do model forward pass |
| 210 | b[self._pred_key] = self.inferrer_fn(b[self.image_key].to(self.device)) |
| 211 | if self.apply_inverse_to_pred: |
| 212 | outs.extend([self.inverter(PadListDataCollate.inverse(i))[self._pred_key] for i in decollate_batch(b)]) |
| 213 | else: |
| 214 | outs.extend([i[self._pred_key] for i in decollate_batch(b)]) |
| 215 | |
| 216 | output: NdarrayOrTensor = stack(outs, 0) |
| 217 | |
| 218 | if self.return_full_data: |
| 219 | return output |
| 220 | |
| 221 | # calculate metrics |
| 222 | _mode = mode(output, dim=0) |
| 223 | mean = output.mean(0) |
| 224 | std = output.std(0) |
| 225 | vvc = (output.std() / output.mean()).item() |
| 226 | |
| 227 | return _mode, mean, std, vvc |
nothing calls this directly
no test coverage detected