def __init__(self, discretization, atom_discretization): # step 1 self.discretization = discretization self.atom_discretization = atom_discretization self.grid = np.zeros(self.discretization.d, dtype=np.int64) # step 2 atomstogrid(self.grid, self.atom_discretization.discrete_positions, self.atom_discretization.atoms.radii_as_indices, self.atom_discretization.sorted_discrete_radii, [(0, 0, 0)] + self.discretization.combined_translation_vectors, self.discretization.grid) # step 3 result = start_split_and_merge_pipeline( self.grid, self.discretization.grid, self.atom_discretization.discrete_positions, self.discretization.combined_translation_vectors, self.discretization.get_translation_vector, ObjectType.DOMAIN) self.centers, translated_areas, non_translated_areas, self.surface_point_list, self.cyclic_area_indices = result print_message("Number of domains:", len(self.centers)) self.domain_volumes = [] self.critical_domains = [ ] # count of very small domains -> domains that can disappear on cutoff radius changes for domain_index in range(len(self.centers)): current_cell_sum = (self.grid == -(domain_index + 1)).sum() if current_cell_sum == 1: self.critical_domains.append(domain_index) domain_volume = current_cell_sum * (self.discretization.s_step**3) self.domain_volumes.append(domain_volume) self.characteristic_radii = [(0.75 * volume / PI)**(1.0 / 3.0) for volume in self.domain_volumes] if translated_areas: gyration_tensor_parameters = tuple( calculate_gyration_tensor_parameters(area) for area in translated_areas) (self.mass_centers, self.squared_gyration_radii, self.asphericities, self.acylindricities, self.anisotropies) = zip(*gyration_tensor_parameters) self.mass_centers = [ self.discretization.discrete_to_continuous( point, result_inside_volume=True) for point in self.mass_centers ] self.squared_gyration_radii = [ self.discretization.discrete_to_continuous(value, unit_exponent=2) for value in self.squared_gyration_radii ] else: (self.mass_centers, self.squared_gyration_radii, self.asphericities, self.acylindricities, self.anisotropies) = 5 * ([], ) self.triangles()
def __init__(self, atoms, discretization): self.atoms = atoms self.discretization = discretization self.sorted_discrete_radii = [] self.discrete_radii = [] self.discrete_positions = [] for radius_index, position in zip(self.atoms.radii_as_indices, self.atoms.sorted_positions): radius = self.atoms.sorted_radii[radius_index] discrete_position = self.discretization.continuous_to_discrete(position) self.discrete_positions.append(discrete_position) for radius in self.atoms.sorted_radii: discrete_radius = int(floor(radius / self.discretization.s_step + 0.5)) self.sorted_discrete_radii.append(discrete_radius) print_message("Maximum radius:", self.sorted_discrete_radii[0])
def __init__(self, discretization, atom_discretization): # step 1 self.discretization = discretization self.atom_discretization = atom_discretization self.grid = np.zeros(self.discretization.d, dtype=np.int64) # step 2 atomstogrid(self.grid, self.atom_discretization.discrete_positions, self.atom_discretization.atoms.radii_as_indices, self.atom_discretization.sorted_discrete_radii, [(0, 0, 0)] + self.discretization.combined_translation_vectors, self.discretization.grid) # step 3 result = start_split_and_merge_pipeline(self.grid, self.discretization.grid, self.atom_discretization.discrete_positions, self.discretization.combined_translation_vectors, self.discretization.get_translation_vector, ObjectType.DOMAIN) self.centers, translated_areas, non_translated_areas, self.surface_point_list, self.cyclic_area_indices = result print_message("Number of domains:", len(self.centers)) self.domain_volumes = [] self.critical_domains = [] # count of very small domains -> domains that can disappear on cutoff radius changes for domain_index in range(len(self.centers)): current_cell_sum = (self.grid == -(domain_index + 1)).sum() if current_cell_sum == 1: self.critical_domains.append(domain_index) domain_volume = current_cell_sum * (self.discretization.s_step ** 3) self.domain_volumes.append(domain_volume) self.characteristic_radii = [(0.75 * volume / PI)**(1.0/3.0) for volume in self.domain_volumes] if translated_areas: gyration_tensor_parameters = tuple(calculate_gyration_tensor_parameters(area) for area in translated_areas) (self.mass_centers, self.squared_gyration_radii, self.asphericities, self.acylindricities, self.anisotropies) = zip(*gyration_tensor_parameters) self.mass_centers = [self.discretization.discrete_to_continuous(point, result_inside_volume=True) for point in self.mass_centers] self.squared_gyration_radii = [self.discretization.discrete_to_continuous(value, unit_exponent=2) for value in self.squared_gyration_radii] else: (self.mass_centers, self.squared_gyration_radii, self.asphericities, self.acylindricities, self.anisotropies) = 5*([], ) self.triangles()
def __init__(self, atoms, discretization): self.atoms = atoms self.discretization = discretization self.sorted_discrete_radii = [] self.discrete_radii = [] self.discrete_positions = [] for radius_index, position in zip(self.atoms.radii_as_indices, self.atoms.sorted_positions): radius = self.atoms.sorted_radii[radius_index] discrete_position = self.discretization.continuous_to_discrete( position) self.discrete_positions.append(discrete_position) for radius in self.atoms.sorted_radii: discrete_radius = int( floor(radius / self.discretization.s_step + 0.5)) self.sorted_discrete_radii.append(discrete_radius) print_message("Maximum radius:", self.sorted_discrete_radii[0])
def get_discretization(self, volume, d_max): """ Return a cached discretization are generate a new one, store it in the cache file and then return it. """ discretization_repr = repr(volume) + " d_max=%d" % d_max print_message("{volume}, discretization resolution: {resolution:d}".format(volume=repr(volume), resolution=d_max)) if discretization_repr in self.file['/discretizations']: stored_discretization = self.file['/discretizations/' + discretization_repr] grid = np.array(stored_discretization) discretization = Discretization(volume, d_max, grid) else: discretization = Discretization(volume, d_max) grid = discretization.grid self.file['/discretizations/' + discretization_repr] = grid self.file.flush() return discretization
def triangles(self): if hasattr(self, "cavity_triangles"): return self.cavity_triangles step = (self.domain_calculation.discretization.s_step, ) * 3 offset = self.domain_calculation.discretization.discrete_to_continuous( (0, 0, 0)) triangles = [] surface_areas = [] for i, multicavity in enumerate(self.multicavities): print_message("Generating triangles for multicavity:", i + 1) vertices, normals, surface_area = cavity_triangles( self.grid3, multicavity, 4, step, offset, self.domain_calculation.discretization.grid) triangles.append((vertices, normals)) surface_areas.append(surface_area) self.cavity_triangles = triangles self.cavity_surface_areas = surface_areas return cavity_triangles
def triangles(self): if hasattr(self, "domain_triangles"): return self.domain_triangles number_of_domains = len(self.centers) print_message("Number of domains:", number_of_domains) triangles = [] surface_areas = [] step = (self.discretization.s_step, ) * 3 offset = self.discretization.discrete_to_continuous((0, 0, 0)) for domain_index in range(number_of_domains): print_message("Calculating triangles for domain", domain_index) vertices, normals, surface_area = cavity_triangles( self.grid, [domain_index], 1, step, offset, self.discretization.grid) triangles.append((vertices, normals)) surface_areas.append(surface_area) self.domain_triangles = triangles self.domain_surface_areas = surface_areas return triangles
def triangles(self): if hasattr(self, "cavity_triangles"): return self.cavity_triangles step = (self.domain_calculation.discretization.s_step,) * 3 offset = self.domain_calculation.discretization.discrete_to_continuous((0, 0, 0)) triangles = [] surface_areas = [] for i, multicavity in enumerate(self.multicavities): print_message("Generating triangles for multicavity:", i+1) vertices, normals, surface_area = cavity_triangles( self.grid3, multicavity, 4, step, offset, self.domain_calculation.discretization.grid) triangles.append((vertices, normals)) surface_areas.append(surface_area) self.cavity_triangles = triangles self.cavity_surface_areas = surface_areas return cavity_triangles
def triangles(self): if hasattr(self, "domain_triangles"): return self.domain_triangles number_of_domains = len(self.centers) print_message("Number of domains:", number_of_domains) triangles = [] surface_areas = [] step = (self.discretization.s_step,) * 3 offset = self.discretization.discrete_to_continuous((0, 0, 0)) for domain_index in range(number_of_domains): print_message("Calculating triangles for domain", domain_index) vertices, normals, surface_area = cavity_triangles( self.grid, [domain_index], 1, step, offset, self.discretization.grid) triangles.append((vertices, normals)) surface_areas.append(surface_area) self.domain_triangles = triangles self.domain_surface_areas = surface_areas return triangles
def get_discretization(self, volume, d_max): """ Return a cached discretization are generate a new one, store it in the cache file and then return it. """ discretization_repr = repr(volume) + " d_max=%d" % d_max print_message( "{volume}, discretization resolution: {resolution:d}".format( volume=repr(volume), resolution=d_max)) if self.file is not None and discretization_repr in self.file[ '/discretizations']: stored_discretization = self.file['/discretizations/' + discretization_repr] grid = np.array(stored_discretization) discretization = Discretization(volume, d_max, grid) else: discretization = Discretization(volume, d_max) grid = discretization.grid if self.file is not None: self.file['/discretizations/' + discretization_repr] = grid self.file.flush() return discretization
def __init__(self, volume, d_max, grid=None): # step 1 self.d_max = d_max self.volume = volume self.s = volume.side_lengths self.s_max = max(self.s) if self.d_max % 2 == 1: self.d_max -= 1 self.s_step = self.s_max / (self.d_max - 4) print_message("Step length:", self.s_step) # step 2 self.d = [int(floor(self.s[i] / self.s_step) + 4) for i in dimensions] for i in dimensions: if self.d[i] % 2 == 1: self.d[i] += 1 print_message( "Resolution per axis: (x: {x:d}, y: {y:d}, z: {z:d})".format( x=self.d[0], y=self.d[1], z=self.d[2])) self.s_tilde = [(self.d[i] - 1) * self.s_step for i in dimensions] # step 3 self.translation_vectors = [[ int(floor(c / self.s_step + 0.5)) for c in v ] for v in self.volume.translation_vectors] # TODO: remove unnecesary vectors in hexagonal volumes self.combined_translation_vectors = [[ sum([v[0][j] * v[1] for v in zip(self.translation_vectors, i)]) for j in dimensions ] for i in itertools.product((-1, 0, 1), repeat=dimension) if any(i)] if grid is not None: self.grid = grid else: # step 4 self.grid = np.zeros(self.d, dtype=np.int8) # create array similar to itertools.product order = [i + 1 for i in range(dimension)] + [0] points = np.indices(self.d).transpose(*order).reshape( (-1, dimension)) # choose points that are not inside inside = self.volume.is_inside(self.discrete_to_continuous(points)) outside_points = points.compress(np.logical_not(inside), axis=0) del points # convert to tuple of indices indices = [outside_points[:, i] for i in range(dimension)] self.grid[indices] = 1 del outside_points del inside del indices # steps 5, 6, 7 mark_translation_vectors(self.grid, self.combined_translation_vectors) translation_vector_output = ", ".join([ "({0}, {1}, {2})".format(*vec) for vec in self.translation_vectors ]) print_message("Translation vectors:", translation_vector_output)
def __init__(self, volume, d_max, grid=None): # step 1 self.d_max = d_max self.volume = volume self.s = volume.side_lengths self.s_max = max(self.s) if self.d_max % 2 == 1: self.d_max -= 1 self.s_step = self.s_max / (self.d_max - 4) print_message("Step length:", self.s_step) # step 2 self.d = [int(floor(self.s[i] / self.s_step) + 4) for i in dimensions] for i in dimensions: if self.d[i] % 2 == 1: self.d[i] += 1 print_message("Resolution per axis: (x: {x:d}, y: {y:d}, z: {z:d})".format(x=self.d[0], y=self.d[1], z=self.d[2])) self.s_tilde = [(self.d[i] - 1) * self.s_step for i in dimensions] # step 3 self.translation_vectors = [[int(floor(c / self.s_step + 0.5)) for c in v] for v in self.volume.translation_vectors] # TODO: remove unnecesary vectors in hexagonal volumes self.combined_translation_vectors = [ [sum([v[0][j] * v[1] for v in zip(self.translation_vectors, i)]) for j in dimensions] for i in itertools.product((-1, 0, 1), repeat=dimension) if any(i)] if grid is not None: self.grid = grid else: # step 4 self.grid = np.zeros(self.d, dtype=np.int8) # create array similar to itertools.product order = [i + 1 for i in range(dimension)] + [0] points = np.indices(self.d).transpose(*order).reshape((-1, dimension)) # choose points that are not inside inside = self.volume.is_inside(self.discrete_to_continuous(points)) outside_points = points.compress(np.logical_not(inside), axis=0) del points # convert to tuple of indices indices = [outside_points[:, i] for i in range(dimension)] self.grid[indices] = 1 del outside_points del inside del indices # steps 5, 6, 7 mark_translation_vectors(self.grid, self.combined_translation_vectors) translation_vector_output = ", ".join(["({0}, {1}, {2})".format(*vec) for vec in self.translation_vectors]) print_message("Translation vectors:", translation_vector_output)
def calculateframe(self, filepath, frame, resolution, cutoff_radii=None, domains=False, surface=False, center=False, atoms=None, gyration_tensor_parameters=False, recalculate=False, last_frame=True): """ Get results for the given parameters. They are either loaded from the cache or calculated. **Parameters:** `filepath` : absolute path of the input file `frame` : the frame number `resolution` : resolution of the used discretization `domains` : calculate cavitiy domains `cutoff_radii` : dict that maps element symbols to cutoff radii `surface` : calculate surface-based cavities `center` : calculate center-based cavities `gyration_tensor_parameters` : gyration tensor parameters will be calculated for cavities (they are always calculated for cavity domains) `recalculate` : results will be calculated even if cached results exists **Returns:** A :class:`core.data.Results` object. """ # always recalculate if gyration tensor parameters shall be computed for center or surface based cavities recalculate = recalculate or (gyration_tensor_parameters and (center or surface)) message.progress(0) inputfile = File.open(filepath) # TODO: error handling if isinstance(inputfile, core.file.ResultFile): resultfile = inputfile else: resultfile = self.cache[filepath] try: results = resultfile.getresults(frame, resolution) except Exception as e: logger.debug("error in resultfile.getresults: {}".format(e)) results = None if atoms is None: atoms = inputfile.getatoms(frame) atoms.radii = cutoff_radii volume = atoms.volume if results is None: results = data.Results(filepath, frame, resolution, atoms, None, None, None) if recalculate: results.domains = None results.surface_cavities = None results.center_cavities = None if not ((domains and results.domains is None) or (surface and results.surface_cavities is None) or (center and results.center_cavities is None)): message.print_message("Reusing results") else: cachepath = os.path.join(self.cachedir, 'discretization_cache.hdf5') discretization_cache = DiscretizationCache(cachepath) discretization = discretization_cache.get_discretization(volume, resolution) atom_discretization = AtomDiscretization(atoms, discretization) message.progress(10) if (domains and results.domains is None) \ or (surface and results.surface_cavities is None): # CavityCalculation depends on DomainCalculation message.print_message("Calculating domains") domain_calculation = DomainCalculation(discretization, atom_discretization) if domain_calculation.critical_domains: logger.warn('Found {:d} critical domains in file {}, frame {:d}. Domain indices: {}'.format( len(domain_calculation.critical_domains), os.path.basename(filepath), frame, domain_calculation.critical_domains )) message.log('Found {:d} critical domains in file {}, frame {:d}'.format( len(domain_calculation.critical_domains), os.path.basename(filepath), frame + 1, )) if results.domains is None: results.domains = data.Domains(domain_calculation) message.progress(40) if surface and results.surface_cavities is None: message.print_message("Calculating surface-based cavities") cavity_calculation = CavityCalculation(domain_calculation, use_surface_points=True, gyration_tensor_parameters=gyration_tensor_parameters) results.surface_cavities = data.Cavities(cavity_calculation) message.progress(70) if center and results.center_cavities is None: message.print_message("Calculating center-based cavities") domain_calculation = FakeDomainCalculation(discretization, atom_discretization, results) cavity_calculation = CavityCalculation(domain_calculation, use_surface_points=False, gyration_tensor_parameters=gyration_tensor_parameters) results.center_cavities = data.Cavities(cavity_calculation) resultfile.addresults(results, overwrite=recalculate) message.progress(100) message.print_message("Calculation finished") if last_frame: message.finish() return results
def __init__(self, domain_calculation, use_surface_points=True, gyration_tensor_parameters=False): self.domain_calculation = domain_calculation if use_surface_points: self.grid = self.domain_calculation.grid num_surface_points = sum( map(len, self.domain_calculation.surface_point_list)) print_message("Number of surface points:", num_surface_points) else: self.grid = None self.sg_cube_size = self.domain_calculation.atom_discretization.sorted_discrete_radii[ 0] if use_surface_points: domain_seed_point_lists = self.domain_calculation.surface_point_list else: domain_seed_point_lists = [ [center] for center in self.domain_calculation.centers ] discretization = self.domain_calculation.discretization atom_discretization = self.domain_calculation.atom_discretization # steps 1 to 5 self.grid3 = mark_cavities( self.grid, discretization.grid, discretization.d, self.sg_cube_size, atom_discretization.discrete_positions, [(0, 0, 0)] + discretization.combined_translation_vectors, domain_seed_point_lists, use_surface_points) if gyration_tensor_parameters: result = start_split_and_merge_pipeline( self.grid3, discretization.grid, atom_discretization.discrete_positions, discretization.combined_translation_vectors, discretization.get_translation_vector, ObjectType.CAVITY) translated_areas, non_translated_areas, cyclic_area_indices = result num_domains = len(self.domain_calculation.centers) grid_volume = (discretization.grid == 0).sum() self.cavity_volumes = [] for domain_index in range(num_domains): self.cavity_volumes.append( 1.0 * (self.grid3 == -(domain_index + 1)).sum() * (discretization.s_step**3)) self.characteristic_radii = [(0.75 * volume / PI)**(1.0 / 3.0) for volume in self.cavity_volumes] # step 6 intersection_table = cavity_intersections(self.grid3, num_domains) multicavities = [] cavity_to_neighbors = num_domains * [None] for domain in range(num_domains): current_neighbors = set([domain]) for neighbor in range(num_domains): if intersection_table[domain][neighbor] == 1: current_neighbors.add(neighbor) for multicavity in multicavities[:]: if any([ neighbor in multicavity for neighbor in current_neighbors ]): current_neighbors = current_neighbors | multicavity multicavities.remove(multicavity) multicavities.append(current_neighbors) for neighbor in current_neighbors: cavity_to_neighbors[neighbor] = current_neighbors self.multicavities = multicavities self.multicavity_volumes = [] for multicavity in multicavities: self.multicavity_volumes.append( sum(self.cavity_volumes[cavity_index] for cavity_index in multicavity)) print_message("Multicavity volumes:", self.multicavity_volumes) if gyration_tensor_parameters: def key_func(cavity_index): cavity_area = non_translated_areas[cavity_index] a_single_cavity_index = -self.grid3[cavity_area[0]] - 1 max_neighbor_index = max( cavity_to_neighbors[a_single_cavity_index]) return max_neighbor_index sorted_area_indices = sorted(range(len(self.multicavities)), key=key_func) sorted_translated_areas = [ translated_areas[i] for i in sorted_area_indices ] sorted_cyclic_area_indices = [ i for i, index in enumerate(sorted_area_indices) if index in cyclic_area_indices ] self.cyclic_area_indices = sorted_cyclic_area_indices if sorted_translated_areas: gyration_tensor_parameters = tuple( calculate_gyration_tensor_parameters(area) for area in sorted_translated_areas) (self.mass_centers, self.squared_gyration_radii, self.asphericities, self.acylindricities, self.anisotropies) = zip(*gyration_tensor_parameters) self.mass_centers = [ discretization.discrete_to_continuous( point, result_inside_volume=True) for point in self.mass_centers ] self.squared_gyration_radii = [ discretization.discrete_to_continuous(value, unit_exponent=2) for value in self.squared_gyration_radii ] else: (self.mass_centers, self.squared_gyration_radii, self.asphericities, self.acylindricities, self.anisotropies) = 5 * ([], ) self.triangles()
def __init__(self, domain_calculation, use_surface_points=True, gyration_tensor_parameters=False): self.domain_calculation = domain_calculation if use_surface_points: self.grid = self.domain_calculation.grid num_surface_points = sum(map(len, self.domain_calculation.surface_point_list)) print_message("Number of surface points:", num_surface_points) else: self.grid = None self.sg_cube_size = self.domain_calculation.atom_discretization.sorted_discrete_radii[0] if use_surface_points: domain_seed_point_lists = self.domain_calculation.surface_point_list else: domain_seed_point_lists = [[center] for center in self.domain_calculation.centers] discretization = self.domain_calculation.discretization atom_discretization = self.domain_calculation.atom_discretization # steps 1 to 5 self.grid3 = mark_cavities(self.grid, discretization.grid, discretization.d, self.sg_cube_size, atom_discretization.discrete_positions, [(0, 0, 0)] + discretization.combined_translation_vectors, domain_seed_point_lists, use_surface_points) if gyration_tensor_parameters: result = start_split_and_merge_pipeline(self.grid3, discretization.grid, atom_discretization.discrete_positions, discretization.combined_translation_vectors, discretization.get_translation_vector, ObjectType.CAVITY) translated_areas, non_translated_areas, cyclic_area_indices = result num_domains = len(self.domain_calculation.centers) grid_volume = (discretization.grid == 0).sum() self.cavity_volumes = [] for domain_index in range(num_domains): self.cavity_volumes.append(1.0 * (self.grid3 == -(domain_index + 1)).sum() * (discretization.s_step ** 3)) self.characteristic_radii = [(0.75 * volume / PI)**(1.0/3.0) for volume in self.cavity_volumes] # step 6 intersection_table = cavity_intersections(self.grid3, num_domains) multicavities = [] cavity_to_neighbors = num_domains * [None] for domain in range(num_domains): current_neighbors = set([domain]) for neighbor in range(num_domains): if intersection_table[domain][neighbor] == 1: current_neighbors.add(neighbor) for multicavity in multicavities[:]: if any([neighbor in multicavity for neighbor in current_neighbors]): current_neighbors = current_neighbors | multicavity multicavities.remove(multicavity) multicavities.append(current_neighbors) for neighbor in current_neighbors: cavity_to_neighbors[neighbor] = current_neighbors self.multicavities = multicavities self.multicavity_volumes = [] for multicavity in multicavities: self.multicavity_volumes.append(sum(self.cavity_volumes[cavity_index] for cavity_index in multicavity)) print_message("Multicavity volumes:", self.multicavity_volumes) if gyration_tensor_parameters: def key_func(cavity_index): cavity_area = non_translated_areas[cavity_index] a_single_cavity_index = -self.grid3[cavity_area[0]] - 1 max_neighbor_index = max(cavity_to_neighbors[a_single_cavity_index]) return max_neighbor_index sorted_area_indices = sorted(range(len(self.multicavities)), key=key_func) sorted_translated_areas = [translated_areas[i] for i in sorted_area_indices] sorted_cyclic_area_indices = [i for i, index in enumerate(sorted_area_indices) if index in cyclic_area_indices] self.cyclic_area_indices = sorted_cyclic_area_indices if sorted_translated_areas: gyration_tensor_parameters = tuple(calculate_gyration_tensor_parameters(area) for area in sorted_translated_areas) (self.mass_centers, self.squared_gyration_radii, self.asphericities, self.acylindricities, self.anisotropies) = zip(*gyration_tensor_parameters) self.mass_centers = [discretization.discrete_to_continuous(point, result_inside_volume=True) for point in self.mass_centers] self.squared_gyration_radii = [discretization.discrete_to_continuous(value, unit_exponent=2) for value in self.squared_gyration_radii] else: (self.mass_centers, self.squared_gyration_radii, self.asphericities, self.acylindricities, self.anisotropies) = 5*([], ) self.triangles()
def calculateframe(self, filepath, frame, resolution, cutoff_radii=None, domains=False, surface=False, center=False, atoms=None, gyration_tensor_parameters=False, recalculate=False, last_frame=True): """ Get results for the given parameters. They are either loaded from the cache or calculated. **Parameters:** `filepath` : absolute path of the input file `frame` : the frame number `resolution` : resolution of the used discretization `domains` : calculate cavitiy domains `cutoff_radii` : dict that maps element symbols to cutoff radii `surface` : calculate surface-based cavities `center` : calculate center-based cavities `gyration_tensor_parameters` : gyration tensor parameters will be calculated for cavities (they are always calculated for cavity domains) `recalculate` : results will be calculated even if cached results exists **Returns:** A :class:`core.data.Results` object. """ # always recalculate if gyration tensor parameters shall be computed for center or surface based cavities recalculate = recalculate or (gyration_tensor_parameters and (center or surface)) message.progress(0) inputfile = File.open(filepath) # TODO: error handling if isinstance(inputfile, core.file.ResultFile): resultfile = inputfile else: resultfile = self.cache[filepath] try: results = resultfile.getresults(frame, resolution) except Exception as e: logger.debug("error in resultfile.getresults: {}".format(e)) results = None if atoms is None: atoms = inputfile.getatoms(frame) atoms.radii = cutoff_radii volume = atoms.volume if results is None: results = data.Results(filepath, frame, resolution, atoms, None, None, None) if recalculate: results.domains = None results.surface_cavities = None results.center_cavities = None if not ((domains and results.domains is None) or (surface and results.surface_cavities is None) or (center and results.center_cavities is None)): message.print_message("Reusing results") else: cachepath = os.path.join(self.cachedir, 'discretization_cache.hdf5') discretization_cache = DiscretizationCache(cachepath) with DiscretizationCache(cachepath) as discretization_cache: discretization = discretization_cache.get_discretization( volume, resolution) atom_discretization = AtomDiscretization(atoms, discretization) message.progress(10) if (domains and results.domains is None) \ or (surface and results.surface_cavities is None): # CavityCalculation depends on DomainCalculation message.print_message("Calculating domains") domain_calculation = DomainCalculation(discretization, atom_discretization) if domain_calculation.critical_domains: logger.warn( 'Found {:d} critical domains in file {}, frame {:d}. Domain indices: {}' .format(len(domain_calculation.critical_domains), os.path.basename(filepath), frame, domain_calculation.critical_domains)) message.log( 'Found {:d} critical domains in file {}, frame {:d}'. format( len(domain_calculation.critical_domains), os.path.basename(filepath), frame + 1, )) if results.domains is None: results.domains = data.Domains(domain_calculation) message.progress(40) if surface and results.surface_cavities is None: message.print_message("Calculating surface-based cavities") cavity_calculation = CavityCalculation( domain_calculation, use_surface_points=True, gyration_tensor_parameters=gyration_tensor_parameters) results.surface_cavities = data.Cavities(cavity_calculation) message.progress(70) if center and results.center_cavities is None: message.print_message("Calculating center-based cavities") domain_calculation = FakeDomainCalculation( discretization, atom_discretization, results) cavity_calculation = CavityCalculation( domain_calculation, use_surface_points=False, gyration_tensor_parameters=gyration_tensor_parameters) results.center_cavities = data.Cavities(cavity_calculation) resultfile.addresults(results, overwrite=recalculate) message.progress(100) message.print_message("Calculation finished") if last_frame: message.finish() return results