Source code for MRF.Online.Data_class

from ..BaseData_class import *
from ..simulate_signal import simulation 
import numpy as np
import random

[docs]class Data_class(BaseData_class): """ Class defining the way the parameters space can be sampled. """ def __init__(self, training_parameters, noise_type, noise_level, minPD, maxPD, sampling, min_values, max_values, t2_wrt_t1, CRBrequired=False): BaseData_class.__init__(self, training_parameters, noise_type, noise_level, minPD, maxPD, CRBrequired=CRBrequired) self.sampling = sampling self.min_values = min_values self.max_values = max_values self.t2_wrt_t1 = t2_wrt_t1
[docs] def dico_save(self): """ Save the parameters of the instance of the class Data_class.""" dic = (self.__dict__).copy() del dic['trparas'] dic.update(self.trparas.dico_save()) return dic
def __len__(self): """ Method required to use the Pytorch DataLoader. Return the number of fingerprints computed by epoch. """ return self.trparas.batch_size * self.trparas.nb_iterations
[docs] def sample(self): """ Define the way the parameters space can be sampled. """ random.seed() np.random.seed() if self.sampling == 'Log': m0s = random.uniform(self.min_values[0],self.max_values[0]) t1 = loguniform(np.log10(self.min_values[1]),np.log10(self.max_values[1])) if self.t2_wrt_t1 == 'no_constraint': t2 = loguniform(np.log10(self.min_values[2]),np.log10(self.max_values[2])) elif self.t2_wrt_t1 == 'below': maxi = np.min([self.max_values[2],t1]) if maxi <= self.min_values[2]: t2 = t1 else: t2 = loguniform(np.log10(self.min_values[2]),np.log10(maxi)) elif self.t2_wrt_t1 == 'below_percent': mini = np.max([self.min_values[2],0.005*t1]) maxi = np.min([self.max_values[2],t1]) if maxi <= mini: t2 = t1 else: t2 = loguniform(np.log10(mini),np.log10(maxi)) r = random.uniform(self.min_values[3],self.max_values[3]) t2s = loguniform(np.log10(self.min_values[4]),np.log10(self.max_values[4])) return(np.array([m0s,t1,t2,r,t2s])) elif self.sampling == 'YOUniform': m0s = random.uniform(self.min_values[0],self.max_values[0]) t1 = random.uniform(self.min_values[1],self.max_values[1]) if self.t2_wrt_t1 == 'no_constraint': t2 = random.uniform(self.min_values[2],self.max_values[2]) elif self.t2_wrt_t1 == 'below': maxi = np.min([self.max_values[2],t1]) if maxi <= self.min_values[2]: t2 = t1 else: t2 = random.uniform(self.min_values[2],maxi) elif self.t2_wrt_t1 == 'below_percent': mini = np.max([self.min_values[2],0.005*t1]) maxi = np.min([self.max_values[2],t1]) if maxi <= mini: t2 = t1 else: t2 = random.uniform(mini,maxi) r = random.uniform(self.min_values[3],self.max_values[3]) t2s = loguniform(np.log10(self.min_values[4]),np.log10(self.max_values[4])) return(np.array([m0s,t1,t2,r,t2s])) elif self.sampling == 'Uniform': m0s = random.uniform(0,0.7) t1 = 2.8 * random.random() + 0.2 t2f = t1 * ( random.random() * 0.5 + 0.05 ) r = 490 * random.random() + 10 t2s= 0.2 * 10**(-3) + random.random() * 150 * 10**(-3) return(np.array([m0s,t1,t2,r,t2s])) elif self.sampling == "Gaussian": m0s = 0 T1 = 0 T2f = 0 R = 0 T2s = 0 while m0s <= 0: m0s = 0.1806 + np.random.normal(0,1) * 0.1189 while T1 < .1: T1 = 1.7251 + np.random.normal(0,1) * 1.1767 while (T2f < .01 or T2f > T1): T2f = T1 * (0.0689 + np.random.normal(0,1) * 0.0897) while R < 10: R = 113.9322 + np.random.normal(0,1) * 101.7831 while T2s < .2e-3: T2s = 0.0815 + np.random.normal(0,1) * 0.0428 return(np.array([m0s,T1,T2f,R,T2s]))
def __getitem__(self,idx): """ Method required to use the Pytorch DataLoader. Return a randomly drawn fingerprints with noise. """ prms = self.sample() if self.CRBrequired: s,ds = simulation_with_grads.simulate_MT_ODE_with_grads(self.x, TR, self.t, prms[0], prms[1], prms[2], prms[3], prms[1], prms[4]) fingeprint, PD = self.proton_density_scaling(s[:,0]) noisy_fingerprint = self.add_noise(fingerprint) # We order the vector to compute the CRB in order to respect the numerotation 0=m0s, 1=T1, 2=T2f, 3=R, 4=T2s, 5=PD. return noisy_fingerprint, prms, self.compute_CRBs(s[:,[1,2,3,4,5,0]], PD) else: s,ds = simulation.simulate_MT_ODE(self.x, TR, self.t, prms[0], prms[1], prms[2], prms[3], prms[1], prms[4]) fingeprint, PD = self.proton_density_scaling(s[:,0]) noisy_fingerprint = self.add_noise(fingerprint) return noisy_fingerprint, prms, None