Source code for tomophantom.generator

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
The set of functions to generate random 2D/3D phantoms

The TomoPhantom package is released under Apache License, Version 2.0
@author: Daniil Kazantsev
"""


[docs]def rand_init2D(x0min, x0max, y0min, y0max, c0min, c0max, ab_min, ab_max): import numpy as np x0 = np.random.uniform(low=x0min, high=x0max) y0 = np.random.uniform(low=y0min, high=y0max) c0 = np.random.uniform(low=c0min, high=c0max) ab = np.random.uniform(low=ab_min, high=ab_max) return (x0, y0, c0, ab)
[docs]def rand_init3D(x0min, x0max, y0min, y0max, z0min, z0max, c0min, c0max, ab_min, ab_max): import numpy as np x0 = np.random.uniform(low=x0min, high=x0max) y0 = np.random.uniform(low=y0min, high=y0max) z0 = np.random.uniform(low=z0min, high=z0max) c0 = np.random.uniform(low=c0min, high=c0max) ab = np.random.uniform(low=ab_min, high=ab_max) return (x0, y0, z0, c0, ab)
# Function to generate 2D foam-like structures using randomly located circles
[docs]def foam2D( x0min, x0max, y0min, y0max, c0min, c0max, ab_min, ab_max, N_size, tot_objects, object_type, ): import numpy as np import math import random # 2D functions from tomophantom import TomoP2D from tomophantom.TomoP2D import Objects2D attemptsNo = 2000 # the number of attempts to fit the object # objects accepted: 'ellipse', 'parabola', 'gaussian', 'mix' mix_objects = False if object_type == "ellipse": object_type = Objects2D.ELLIPSE elif object_type == "parabola": object_type = Objects2D.PARABOLA elif object_type == "gaussian": object_type = Objects2D.GAUSSIAN elif object_type == "mix": mix_objects = True else: raise TypeError("object_type can be only ellipse, parabola, gaussian or mix") X0 = np.float32(np.zeros(tot_objects)) Y0 = np.float32(np.zeros(tot_objects)) AB = np.float32(np.zeros(tot_objects)) C0_var = np.float32(np.zeros(tot_objects)) for i in range(0, tot_objects): (x0, y0, c0, ab) = rand_init2D( x0min, x0max, y0min, y0max, c0min, c0max, ab_min, ab_max ) if i > 0: breakj = False for j in range(0, attemptsNo): if breakj == True: (x0, y0, c0, ab) = rand_init2D( x0min, x0max, y0min, y0max, c0min, c0max, ab_min, ab_max ) breakj = False else: for l in range( 0, i ): # checks consistency with previously created objects dist = math.sqrt((X0[l] - x0) ** 2 + (Y0[l] - y0) ** 2) if (dist < (ab + AB[l])) or ( (abs(x0) + ab) ** 2 + (abs(y0) + ab) ** 2 > 1.0 ): breakj = True break if breakj == False: # re-initialise if doesn't fit the criteria X0[i] = x0 Y0[i] = y0 AB[i] = ab C0_var[i] = c0 break if AB[i] == 0.0: X0[i] = x0 Y0[i] = y0 AB[i] = 0.0001 C0_var[i] = c0 myObjects = [] # dictionary of objects for obj in range(0, len(X0)): if mix_objects == True: rand_obj = random.randint(0, 2) if rand_obj == 0: object_type = Objects2D.ELLIPSE if rand_obj == 1: object_type = Objects2D.PARABOLA if rand_obj == 2: object_type = Objects2D.GAUSSIAN curr_obj = { "Obj": object_type, "C0": C0_var[obj], "x0": X0[obj], "y0": Y0[obj], "a": AB[obj], "b": AB[obj], "phi": 0.0, } myObjects.append(curr_obj) Object = TomoP2D.Object(N_size, myObjects) return (Object, myObjects)
# Function to generate 3D foam-like structures using randomly located spheres
[docs]def foam3D( x0min, x0max, y0min, y0max, z0min, z0max, c0min, c0max, ab_min, ab_max, N_size, tot_objects, object_type, ): import numpy as np import math import random # 3D functions from tomophantom import TomoP3D from tomophantom.TomoP3D import Objects3D attemptsNo = 2000 # objects accepted: 'ellipsoid', 'paraboloid', 'gaussian', 'mix' mix_objects = False if object_type == "ellipsoid": object_type = Objects3D.ELLIPSOID elif object_type == "paraboloid": object_type = Objects3D.PARABOLOID elif object_type == "gaussian": object_type = Objects3D.GAUSSIAN elif object_type == "mix": mix_objects = True else: raise TypeError("object_type can be only ellipse, parabola, gaussian or mix") X0 = np.float32(np.zeros(tot_objects)) Y0 = np.float32(np.zeros(tot_objects)) Z0 = np.float32(np.zeros(tot_objects)) AB = np.float32(np.zeros(tot_objects)) C0_var = np.float32(np.zeros(tot_objects)) for i in range(0, tot_objects): (x0, y0, z0, c0, ab) = rand_init3D( x0min, x0max, y0min, y0max, z0min, z0max, c0min, c0max, ab_min, ab_max ) if i > 0: breakj = False for j in range(0, attemptsNo): if breakj: (x0, y0, z0, c0, ab) = rand_init3D( x0min, x0max, y0min, y0max, z0min, z0max, c0min, c0max, ab_min, ab_max, ) breakj = False else: for l in range( 0, i ): # checks consistency with previously created objects dist = math.sqrt( (X0[l] - x0) ** 2 + (Y0[l] - y0) ** 2 + (Z0[l] - z0) ** 2 ) if (dist < (ab + AB[l])) or ( (abs(x0) + ab) ** 2 + (abs(y0) + ab) ** 2 + (abs(z0) + ab) ** 2 > 1.0 ): breakj = True break if breakj == False: # re-initialise if doesn't fit the criteria X0[i] = x0 Y0[i] = y0 Z0[i] = z0 AB[i] = ab C0_var[i] = c0 break if AB[i] == 0.0: X0[i] = x0 Y0[i] = y0 AB[i] = 0.0001 C0_var[i] = c0 myObjects = [] # dictionary of objects for obj in range(0, len(X0)): if mix_objects == True: rand_obj = random.randint(0, 2) if rand_obj == 0: object_type = Objects3D.ELLIPSOID if rand_obj == 1: object_type = Objects3D.PARABOLOID if rand_obj == 2: object_type = Objects3D.GAUSSIAN curr_obj = { "Obj": object_type, "C0": C0_var[obj], "x0": X0[obj], "y0": Y0[obj], "z0": Z0[obj], "a": AB[obj], "b": AB[obj], "c": AB[obj], "phi1": 0.0, } myObjects.append(curr_obj) Object3D = TomoP3D.Object(N_size, myObjects) return (Object3D, myObjects)