示例#1
0
def regenerate(s1_name, s2_name, rotation, initial_coordinate, sim_par, sim_dir, export_dir, colorify=True, index=1, format='cif'):
    """
    Reconstruct interpenetrated structure for given MOFs with rotation and initial coordinate.
    """
    s1_mof = MOF(os.path.join(sim_dir['mof_dir'], s1_name + '.cif'))
    s2_mof = MOF(os.path.join(sim_dir['mof_dir'], s2_name + '.cif'))
    s2_mof_length = len(s2_mof)
    first_point = initial_coordinate
    x_angle, y_angle, z_angle = [math.radians(a) for a in rotation]
    structure = {'atom_names': [], 'atom_coors': [], 'pbc_coors': []}

    for idx in range(s2_mof_length):
        if idx == 0:
            atom_name = s2_mof.atom_names[idx]
            rot_coor = s2_mof.atom_coors[idx]
            rot_coor = xyz_rotation(rot_coor, [x_angle, y_angle, z_angle])
            translation_vector = sub3(first_point, rot_coor)
        else:
            atom_name = s2_mof.atom_names[idx]
            rot_coor = s2_mof.atom_coors[idx]
            rot_coor = xyz_rotation(rot_coor, [x_angle, y_angle, z_angle])
            new_coor = add3(rot_coor, translation_vector)
            pbc_coor = pbc3(new_coor, s1_mof.to_frac, s1_mof.to_car)

            structure['atom_coors'].append(new_coor)
            structure['pbc_coors'].append(pbc_coor)
            structure['atom_names'].append(atom_name)

    new_structure = {'atom_names': structure['atom_names'], 'name': s2_mof.name}
    if sim_par['export_pbc']:
        new_structure['atom_coors'] = structure['pbc_coors']
    else:
        new_structure['atom_coors'] = structure['atom_coors']

    # Export structure file
    new_s2_mof = MOF(new_structure, file_format='dict')
    joined_mof = s1_mof.join(new_s2_mof, colorify=False)
    joined_mof.name += '_' + str(index)
    joined_mof.export(export_dir, file_format=format)

    if colorify:
        new_s2_mof = MOF(new_structure, file_format='dict')
        joined_mof_color = s1_mof.join(new_s2_mof, colorify=True)
        joined_mof_color.name += '_' + str(index) + 'C'
        joined_mof_color.export(export_dir, file_format=format)
示例#2
0
def reshape(mof, rotation, initial_coordinate):
    """
    Apply rotation and translation operations to given MOF
        - rotation = [x_angle, y_angle, z_angle] in degrees
        - initial_coordinate = [x, y, z] in cartesian coordinates
    """
    first_point = initial_coordinate
    x_angle, y_angle, z_angle = [math.radians(a) for a in rotation]
    structure = {'atom_names': [], 'atom_coors': [], 'name': mof.name}
    rot_coor = mof.packed_coors[0][0]
    translation_vector = sub3(first_point, rot_coor)
    for unit_cell in mof.packed_coors:
        for atom_coor in unit_cell:
            rot_coor = atom_coor
            rot_coor = xyz_rotation(rot_coor, [x_angle, y_angle, z_angle])
            new_coor = add3(rot_coor, translation_vector)
            structure['atom_coors'].append(new_coor)
    structure['atom_names'] = len(mof.packed_coors) * mof.atom_names
    return structure
示例#3
0
def check_interpenetration(sim_par, base_mof, mobile_mof, emap, atom_list):
    """
    Run interpenetration algorithm with given simulation parameters and energy map.
    Returns simulation summary and structural information on the discovered structures.
    """
    # Initialize simulation parameters
    structure_energy_limit = sim_par['structure_energy_limit']
    atom_energy_limit = sim_par['atom_energy_limit']
    # atom_energy_limit = sim_par['energy_density_limit'] * mobile_mof.ucv
    energy_density_limit = sim_par['energy_density_limit']
    rotation_freedom = sim_par['rotation_freedom']
    summary_percent = sim_par['summary_percent']
    try_all_rotations = sim_par['try_all_rotations']
    # Get energy map dimensions for trilinear interpolation
    emap_max = [emap[-1][0], emap[-1][1], emap[-1][2]]
    emap_min = [emap[0][0], emap[0][1], emap[0][2]]
    side_length = [emap_max[0] - emap_min[0] + 1, emap_max[1] - emap_min[1] + 1, emap_max[2] - emap_min[2] + 1]
    x_length, y_length = int(side_length[1] * side_length[2]), int(side_length[2])

    if try_all_rotations:
        all_rot_degrees = possible_rotations(sim_par['rotation_freedom'])
        rotation_limit = len(all_rot_degrees)
        sim_par['rotation_limit'] = rotation_limit
    else:
        rotation_limit = sim_par['rotation_limit']

    initial_coors = initial_coordinates(base_mof, emap, atom_list, atom_energy_limit)
    trial_limit = len(initial_coors) * rotation_limit
    div = round(trial_limit / (100 / summary_percent))
    rot_freedom = 360 / rotation_freedom
    # omitted_coordinates = len(emap) - len(initial_coors)

    summary = {'percent': [], 'structure_count': [], 'trial_count': []}
    new_structures = []
    abort_ip = False
    mobile_mof_length = len(mobile_mof)
    structure_count = 0
    structure_total_energy = 0
    ucv = mobile_mof.ucv
    energy_density = 0
    initial_coor_index = 0
    rotation_index = 0

    # Interpenetration trial loop for different positions and orientations
    for t in range(trial_limit):
        abort_ip = False
        # Interpenetration trial loop for a specific position and different orientations
        for idx in range(mobile_mof_length):

            if not abort_ip:
                # If the interpenetration is just starting select rotation angles
                if idx == 0:
                    # Determine random angles for rotation in 3D space

                    # Determine first point for interpenetrating structure
                    if t % rotation_limit == 0:
                        # Start with original orientation for first trial
                        x_angle, y_angle, z_angle = [0, 0, 0]
                        first_point = initial_coors[initial_coor_index]
                        initial_coor_index += 1
                        rotation_index = 0
                    elif try_all_rotations:
                        x_angle, y_angle, z_angle = all_rot_degrees[rotation_index]
                    else:
                        x_angle = 2 * math.pi * math.floor(random() * rot_freedom) / rot_freedom
                        y_angle = 2 * math.pi * math.floor(random() * rot_freedom) / rot_freedom
                        z_angle = 2 * math.pi * math.floor(random() * rot_freedom) / rot_freedom

                    rotation_index += 1
                    # Rotate first atom of the mobile MOF
                    atom_name = mobile_mof.atom_names[idx]
                    rot_coor = mobile_mof.atom_coors[idx]
                    rot_coor = xyz_rotation(rot_coor, [x_angle, y_angle, z_angle])
                    translation_vector = sub3(first_point, rot_coor)

                    # Initialize new structure dictionary
                    structure = {'atom_names': [], 'atom_coors': [], 'pbc_coors': []}
                    structure['first_point'] = first_point
                    structure['translation_vector'] = translation_vector
                    structure['atom_coors'].append(first_point)
                    structure['pbc_coors'].append(first_point)
                    structure['atom_names'].append(atom_name)
                    structure['rotation'] = [x_angle, y_angle, z_angle]

                # If interpenetration is still going on
                elif idx < mobile_mof_length - 1:
                    atom_name = mobile_mof.atom_names[idx]
                    rot_coor = mobile_mof.atom_coors[idx]
                    rot_coor = xyz_rotation(rot_coor, [x_angle, y_angle, z_angle])
                    new_coor = add3(rot_coor, translation_vector)
                    pbc_coor = pbc3(new_coor, base_mof.to_frac, base_mof.to_car)

                    emap_atom_index = energy_map_atom_index(atom_name, atom_list)
                    point_energy = tripolate(pbc_coor, emap_atom_index, emap, x_length, y_length)
                    structure_total_energy += point_energy
                    energy_density += point_energy / ucv

                    if energy_density > energy_density_limit:
                        structure_total_energy = 0
                        energy_density = 0
                        abort_ip = True
                        break  # Fix this part (break interpenetration trial loop)
                    else:
                        structure['atom_coors'].append(new_coor)
                        structure['pbc_coors'].append(pbc_coor)
                        structure['atom_names'].append(atom_name)

                # If interpenetration trial ended with no collision - record structure info
                else:
                    structure['energy'] = structure_total_energy
                    structure['energy_density'] = energy_density
                    new_structures.append(structure)
                    structure_count += 1
                    structure_total_energy = 0
                    energy_density = 0

        # Record simulation progress according to division (div) and summary
        if t % div == 0:
            percent_complete = round(t / trial_limit * 100)
            summary['percent'].append(percent_complete)
            summary['structure_count'].append(structure_count)
            summary['trial_count'].append(t)

    return summary, new_structures