Ejemplo n.º 1
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()
Ejemplo n.º 2
0
 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])
Ejemplo n.º 3
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()
Ejemplo n.º 4
0
 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])
Ejemplo n.º 5
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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
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 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
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
    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()
Ejemplo n.º 15
0
    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()
Ejemplo n.º 16
0
    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