Source code for ocelot.task.pkid

from collections import OrderedDict


# from schema.dimercollection import DimerCollection

[docs]class PackingIdentifier:
[docs] def __init__(self, boneconfig): """ identify packing pattern the input should be a pbc config of terminated backbones 1. heuristic rules 10.1039/c7tc02553j, that worked only for small acenes, we want more J. AM. CHEM. SOC. 2004, 126, 4318-4328, this seems quite primitive 2. finger print Hirshfield 10.1039/c1ce05763d """ self.boneconfig = boneconfig
[docs] def identify_heuristic(self): """ return a dictionary, keys are n_close_azm_and_parallel, n_close_azm_and_notparallel, n_close_vertical_and_parallel, n_close_vertical_and_notparallel, n_parallel_and_overlap, n_notparallel_and_overlap, packing these keys are defined based on: close_vertical: d.oslip within [1.5, 4] parallel: d.oangle < 15 deg close_azm: d.oslip <= 1.5 overlap: overlap > 1e-5 variables used: 1. is_not_identical: slip vector norm >= 1e-5 2. is_close: minbonedist < 5.5 3. overlap: project sites onto the plane defined by ovector of ref_mol and ref_mol.geoc, then get overlap of concave/convex hulls 4. mindist2d: min distance between two hulls 5. d.oslip: vertical slip 6. d.oangle: angle between o_vector workflow: 1. from bone config get all bone dimers, maxfold=2 2. for each molecule (a) in the unit cell 1. get first 27*z dimers, sorted by vslipnorm, whose ref_mol is (a) 2. if identical or not_close, do nothing 3. get values for the keys 4. apply classification based on the keys :return: """ bc_dimers, bc_dimers_transv_fcs = self.boneconfig.get_dimers_array(maxfold=2) report = OrderedDict() for i in range(self.boneconfig.z): n_close_azm_and_parallel = 0 # min distance between backbone proj<2, 1.5>oslip n_close_azm_and_notparallel = 0 # min distance between backbone proj<2, 1.5>oslip n_close_vertical_and_parallel = 0 # min distance between backbone proj<2, 4>oslip>1.5 n_close_vertical_and_notparallel = 0 n_parallel_and_overlap = 0 n_notparallel_and_overlap = 0 dimers_ref_i = bc_dimers[i].flatten() dimers_ref_i = sorted(dimers_ref_i, key=lambda x: x.vslipnorm)[:27 * self.boneconfig.z] # DimerCollection(dimers_ref_i).to_xyz('dimers_{}.xyz'.format(i)) for d in dimers_ref_i: if d.is_not_identical and d.is_close: # if d.is_not_identical and d.is_close: overlap, refboneproj, varboneproj, mindist2d = d.bone_overlap(algo='convex') # print(d.minbonedist) # print(mindist2d) # debug += 1 # d.to_xyz('dimer_{}.xyz'.format(debug)) # overlap, refboneproj, varboneproj = d.mol_overlap() if 1e-5 < mindist2d < 2.5: # exclude overlap as dist=0.0 that case if 4 > d.oslip > 1.5: if d.oangle < 15.0: n_close_vertical_and_parallel += 1 else: n_close_vertical_and_notparallel += 1 elif d.oslip <= 1.5: if d.oangle < 15.0: n_close_azm_and_parallel += 1 else: n_close_azm_and_notparallel += 1 if overlap > 1e-5: if d.oangle < 15.0: n_parallel_and_overlap += 1 else: n_notparallel_and_overlap += 1 if n_parallel_and_overlap > 2: packing = 'brickwork' elif n_close_vertical_and_parallel > 2 or n_close_azm_and_parallel > 2 or n_close_vertical_and_parallel + n_close_azm_and_parallel + n_parallel_and_overlap > 2: packing = 'edge_brickwork' elif n_parallel_and_overlap == 2: packing = 'slipped_stack' elif n_close_vertical_and_parallel == 2 or n_parallel_and_overlap + n_close_vertical_and_parallel + n_close_azm_and_parallel == 2: packing = 'edge_slipped_stack' elif n_notparallel_and_overlap >= 1: packing = 'herringbone' elif n_close_vertical_and_notparallel >= 1 or n_close_azm_and_notparallel >= 1: packing = 'edge_herringbone' elif n_parallel_and_overlap == 1 or n_close_vertical_and_parallel == 1: packing = 'dimerized' elif n_notparallel_and_overlap == n_parallel_and_overlap == n_close_azm_and_notparallel == n_close_azm_and_parallel == n_close_vertical_and_parallel == n_close_vertical_and_notparallel == 0: packing = 'sparse' else: packing = 'other' report[i] = OrderedDict( n_close_azm_and_parallel=n_close_azm_and_parallel, # min distance between backbone proj<2, 1.5>oslip n_close_azm_and_notparallel=n_close_azm_and_notparallel, # min distance between backbone proj<2, 1.5>oslip n_close_vertical_and_parallel=n_close_vertical_and_parallel, # min distance between backbone proj<2, 4>oslip>1.5 n_close_vertical_and_notparallel=n_close_vertical_and_notparallel, n_parallel_and_overlap=n_parallel_and_overlap, n_notparallel_and_overlap=n_notparallel_and_overlap, packing=packing, ) return report
# return [report[i]['packing'] for i in report.keys()]
[docs] def identify_hirshfield(self): """ TODO use multwfn to generate hirshfield finger print, then analysze it based on 10.1039/c1ce05763d """ pass