def run(self): logger.info("gensei generator running") from gensei.base import Config, Object from gensei import Objects, Box from gensei.utils import get_suffix conf = { 'objects': default_objects, 'box': default_box, 'options': default_options } config = Config.from_conf(conf, required=['objects', 'box'], optional=['options']) if isinstance(config.box['dims'], str): config.box['dims'] = eval(config.box['dims']) if isinstance(config.box['resolution'], str): aux = tuple([int(r) for r in config.box['resolution'].split('x')]) config.box['resolution'] = aux # config.box["resolution"] = 1/self.voxelsize_mm[1:] # config.box['dims'] = self.area_shape config.box["resolution"] = tuple(self.resolution.astype(int).tolist()) config.box['dims'] = self.dims.astype(int).tolist() config.box['n_slice'] = int(self.n_slice) box = Box(**config.box) options = Object(name='options', **config.options) output(box) output(options) object_classes = Objects.from_conf(config.objects, box) objects = object_classes.place_objects(box, options) self.objects = objects self.box = box self.options = options pass
def from_conf(conf, box): objs = Objects(conf.keys(), conf.values(), is_placed=False) n_object = objs.init_counts(box.n_object) objs.init_trait('n_object_requested', n_object) for key, val in conf.iteritems(): output(('*** %s ' % key) + 50*'*') obj_conf = Object.objects_from_dict(val, name='obj_conf', flag=(1,)) obj_conf.init_trait('n_object', objs.n_object_requested[key]) obj_conf0 = obj_conf.copy(deep=True) obj = reduce_to_fit(obj_conf, box) obj.set_conf(obj_conf, obj_conf0) obj.name = key output(obj._format(mode='set_only')) ## print obj.conf ## print obj.requested_conf objs[key] = obj return objs
def format_intersection_statistics(self, is_output=False): if is_output: space = '' else: space = ' ' msg = [] for axis, num in ordered_iteritems(self.box.n_slice): msg.append(space + 'axis %s (%d sections):' % (axis, num)) ok = True for key, obj in ordered_iteritems(self): if not obj.has_intersection(axis): msg.append(space + ' warning: object %s is not intersected' % key) ok = False if ok: msg.append(space + ' all objects intersected by at least one section') if is_output: output('\n'.join(msg)) return msg
def reduce_to_fit(obj_conf, box): """ Adjusts obj_conf parameters of object so that the circumscribed sphere radius fits in the box. """ rtf = obj_conf.reduce_to_fit while 1: obj = AnyObject.from_conf(obj_conf, box) if obj_conf.n_object == 0: break r = obj.get_radius() rbox = 0.5 * box.dims.min() if rbox > r: break for attr, ratio in rtf.iteritems(): val0 = getattr(obj_conf, attr) val = ratio * val0 setattr(obj_conf, attr, val) output('reducing %s: %s -> %s' % (attr, val0, val)) return obj
def place_objects(self, box, options): """Generate non-intersecting objects fully contained in the specimen's block. """ objs = Objects(is_placed=True) objs.box = box objs.init_trait('n_object_requested', self.n_object_requested) stats_per_class = {} for key in self.names: obj_class = self[key] stats = Object(volume=0.0, surface=0.0, length=0.0) stats_per_class[key] = stats for ii in xrange(self.n_object_requested[key]): output(('*** %s: %d ' % (key, ii)) + 50*'*') obj = obj_class.copy(deep=True) obj.init_trait('obj_class', key) t0 = time.clock() ok = True while 1: if (time.clock() - t0) > options.timeout: output('timeout -> try reducing object size!') ok = False break obj.setup_orientation() bbox = obj.get_origin_bounding_box() ## This "fixes" the bounding box until exact bounding boxes ## for all kinds of objects are implemented. r = obj.get_radius() bbox[:,1] = np.minimum(r, bbox[:,1]) assert_((bbox[:,1] < (0.5 * box.dims)).all()) centre = get_random(bbox[:,1], box.dims - bbox[:,1]) obj.set_centre(centre) obj.is_placed = True for ip, prev in enumerate(objs.itervalues()): bad = prev.intersects(obj) ## print '%d. intersects: %d' % (ip, bad) if bad: break else: ## print 'ok' break if ok: output('accepted:', obj) obj_class.accepted() obj.name = key.replace('class', 'object') + ('_%d' % ii) objs[key + ' ' + obj.name] = obj obj.update_stats(stats) else: break objs.init_trait('n_object', {}.fromkeys(self.n_object_requested.keys(), 0)) for key in self.names: obj_class = self[key] # This was updated in obj_class.accepted() call above. objs.n_object[key] = obj_class.conf.n_object object_volume = object_surface = object_length = 0.0 for stats in stats_per_class.itervalues(): object_volume += stats.volume object_surface += stats.surface object_length += stats.length objs.stats_per_class = stats_per_class objs.init_trait('total_object_volume', object_volume) objs.init_trait('total_object_volume_fraction', object_volume / box.volume) objs.init_trait('total_object_surface', object_surface) objs.init_trait('total_object_surface_fraction', object_surface / box.volume) objs.init_trait('total_object_length', object_length) objs.init_trait('total_object_length_density', object_length / box.volume) objs.section_volumes = {} objs.section_surfaces = {} return objs
def generate_slices(objects, box, options, output_filename_trunk): """ Save images of the specimen slices along the specified axes of the block. Each image displays a planar cut plane of the block intersecting the ellipsoids. """ from gensei.base import output, assert_ from gensei import Objects, Box from gensei.utils import get_suffix resolution = box.resolution imshape = resolution[::-1] + (3, ) aspect = float(resolution[1]) / resolution[0] figsize = plt.figaspect(aspect) dpi = resolution[0] / figsize[0] objects.init_section_based_data() objects.points = [] for pb, points, delta, n_slice, axis, am in box.get_points(): suffix = get_suffix(n_slice) # dpi=dpi in plt.figure() messes with figsize... ??? fig = plt.figure(1, figsize=figsize, dpi=dpi) fig.set_figwidth(figsize[0]) fig.set_figheight(figsize[1]) ax = fig.add_axes([0, 0, 1, 1]) objects.init_section_based_data(axis) x1b, x2b = pb[am[0]], pb[am[1]] for islice, x3b in enumerate(pb[am[2]]): x3b_name = ('%05.2f' % x3b).replace('.', '_') filename = '.'.join((output_filename_trunk, axis, suffix % islice, x3b_name, options.output_format)) output(islice, x3b, filename, '...') output('computing') points[:, am[2]] = x3b mask = np.zeros(points.shape[0], dtype=np.int8) cmask = np.zeros((points.shape[0], 3), dtype=np.float64) for obj in objects.itervalues(): color = np.array(colorConverter.to_rgb(obj.conf.color)) bbox = obj.get_aligned_bounding_box()[am] ix1 = np.where((x1b > bbox[0, 0]) & (x1b < bbox[0, 1]))[0] ix2 = np.where((x2b > bbox[1, 0]) & (x2b < bbox[1, 1]))[0] a, b = np.meshgrid(ix1, resolution[0] * ix2) ii = (a + b).ravel() _mask = obj.contains(points[ii]) mask[ii] += _mask cmask[ii[_mask]] = color objects.update_section_based_data(_mask, a.shape, axis, delta, islice, x3b, obj) obj.store_intersection(_mask, axis, x3b) objects.points.append((axis, islice, x3b)) try: assert_(np.alltrue(mask <= 1)) except: import pdb pdb.set_trace() output('drawing') ax.cla() ax.set_axis_off() ax.imshow(cmask.reshape(imshape), origin='upper') output('saving') plt.savefig(filename, format=options.output_format, dpi=dpi) output('...done')