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