def full_report(self): N = self.adsorbophore_db.session.query(SQL_Adsorbophore).count() del self._adsorbophores del self._active_sites csv = CSV('full_report.csv') csv.set_headings("rank","N_sites", "N_unq_MOFs", "rmsd_error", "av_elstat", "stdev_elstat", "av_vdw", "stdev_vdw") for rank in range(N): adsorbophore = self.adsorbophore_from_sql(rank) nsites = len(adsorbophore.active_sites) mofs = {} for site in adsorbophore.active_sites: mofname = '.'.join(site.name.split('.')[:-1]) mofs.setdefault(mofname, 0) mofs[mofname] += 1 error, vdw_mean, vdw_std, el_mean, el_std = self.obtain_error(rank) csv.add_data(**{'rank.1': rank, 'N_sites.1':nsites, 'N_unq_MOFs.1':len(mofs.keys()), 'rmsd_error.1':error, 'av_elstat.1':el_mean, 'stdev_elstat.1':el_std, 'av_vdw.1':vdw_mean, 'stdev_vdw.1':vdw_std}) csv.write()
def _sbu_report(self): """Compute the surface areas and report them to a .csv file.""" # WARNING - this assumes that SBUs with the same name but in # different topologies are the same, and will take the last instance met_sbus = {} org_sbus = {} for sbu in self.sbu_pool: if sbu.is_metal: met_sbus[sbu.name] = sbu else: org_sbus[sbu.name] = sbu filename = os.path.join(self.options.job_dir, self.options.jobname + ".SBU_report.csv") report = CSV(name=filename) report.set_headings("sbu_id") if self.options.calc_sbu_surface_area: report.set_headings("surface_area") if self.options.calc_max_sbu_span: report.set_headings("sbu_span") # metal sbus first. for name, sbu in met_sbus.items(): info("Computing data for %s"%name) report.add_data(**{"sbu_id.1": sbu.identifier}) if self.options.calc_sbu_surface_area: report.add_data(**{"surface_area.1": sbu.surface_area}) if self.options.calc_max_sbu_span: report.add_data(**{"sbu_span.1":sbu.max_span}) # list organic SBUs second. for name, sbu in org_sbus.items(): info("Computing data for %s"%name) report.add_data(**{"sbu_id.1": sbu.identifier}) if self.options.calc_sbu_surface_area: report.add_data(**{"surface_area.1": sbu.surface_area}) if self.options.calc_max_sbu_span: report.add_data(**{"sbu_span.1": sbu.max_span}) report.write()
def _sbu_report(self): """Compute the surface areas and report them to a .csv file.""" # WARNING - this assumes that SBUs with the same name but in # different topologies are the same, and will take the last instance met_sbus = {} org_sbus = {} for sbu in self.sbu_pool: if sbu.is_metal: met_sbus[sbu.name] = sbu else: org_sbus[sbu.name] = sbu filename = os.path.join(self.options.job_dir, self.options.jobname + ".SBU_report.csv") report = CSV(name=filename) report.set_headings("sbu_id") if self.options.calc_sbu_surface_area: report.set_headings("surface_area") if self.options.calc_max_sbu_span: report.set_headings("sbu_span") # metal sbus first. for name, sbu in met_sbus.items(): info("Computing data for %s" % name) report.add_data(**{"sbu_id.1": sbu.identifier}) if self.options.calc_sbu_surface_area: report.add_data(**{"surface_area.1": sbu.surface_area}) if self.options.calc_max_sbu_span: report.add_data(**{"sbu_span.1": sbu.max_span}) # list organic SBUs second. for name, sbu in org_sbus.items(): info("Computing data for %s" % name) report.add_data(**{"sbu_id.1": sbu.identifier}) if self.options.calc_sbu_surface_area: report.add_data(**{"surface_area.1": sbu.surface_area}) if self.options.calc_max_sbu_span: report.add_data(**{"sbu_span.1": sbu.max_span}) report.write()
def obtain_rdfs(self, rank): """Return the radial distribution functions of the cliques in the original MOFs, with the cliques cut-out.""" adsorbophore = self.adsorbophore_from_sql(rank) nconfig = 0 # configurations counted nparticles = {} # number of particles counted distances = {} # keep distances in lists. densities = {} for site in adsorbophore.active_sites: indices = [i.index for i in site.indices] act_site = self.active_site_from_sql(site.name) ads_atoms = [act_site.atoms[i] for i in indices] site_eng = act_site.vdweng + act_site.eleng if site_eng <= self.options.en_max and site_eng >= self.options.en_min: mofpath = act_site.mofpath # get mof from cif mofname = os.path.split(mofpath)[-1][:-4] mof = Structure(mofname) mof.from_cif(mofpath) # get atoms to cut out of mof cut_inds = [atom.mof_id for atom in ads_atoms] cut_coords = np.array([np.array((atom.x, atom.y, atom.z)) for atom in ads_atoms]) # get co2 co2 = self.return_co2_array(act_site) rdf_centre = co2[0] # or self.centre_of_atoms(np.array([np.array([a.x, a.y, a.z]) for a in ads_atoms])) # compute the minimum image convention of a supercell around the rdf centre. # cut out the atoms in the active site SQL_ActiveSiteAtoms.mof_id for atom in ads_atoms: rdf_centre = np.array([atom.x, atom.y, atom.z]) original_indices, coordinates = self.min_img(mof, rdf_centre, (3,3,3), cut_coords)#cut_inds) dists = distance.cdist(np.column_stack(rdf_centre), coordinates) # debug #f = open('debug.xyz', 'a') #f.writelines("%i\n%s\n"%(len(coordinates)+1, "test")) #for id, coord in enumerate(coordinates): # orig_ind = original_indices[id] # element = mof.atoms[orig_ind].type # f.writelines("%s %9.5f %9.5f %9.5f\n"%(element, coord[0], coord[1], coord[2])) #f.writelines("%s %9.5f %9.5f %9.5f\n"%("As", co2[0][0], co2[0][1], co2[0][2])) #f.close() nconfig += 1 for (x,y), val in np.ndenumerate(dists): orig_ind = original_indices[y] element = mof.atoms[orig_ind].uff_type distances.setdefault(element, []).append(val) nparticles.setdefault(element, 0) nparticles[element] += 1 # add number densities from unit cell. counts = {} for atom in mof.atoms: counts.setdefault(atom.uff_type, 0) counts[atom.uff_type] += 1 for element, count in counts.items(): densities.setdefault(element, []).append(count/mof.cell.volume) # compute RDFs by atom type? element? general? for element, dis in distances.items(): rho = np.mean(densities[element]) hist, bin_edges = np.histogram(dis, bins=self.options.rdf_bins, range=(0., self.options.rdf_dist)) dr = np.diff(bin_edges)[0] norm = rho * float(nconfig) #shell_volume = 4/3*pi*pow(r, 2)*dr #rho, norm = 1., 1. rdf = [hist[i]/norm/(4./3.*pi*(pow((i+0.5)*dr, 3) - pow((i-0.5)*dr, 3))) for i in range(self.options.rdf_bins)] Emax = self.options.en_max Emin = self.options.en_min el_name = '.'.join([j for j in element.split('_') if j]) csv = CSV("RDF_rank%i_%s_Emax_%0.2f_Emin_%0.2f"%(rank, el_name, Emax, Emin)) csv.set_headings("r", "g(r)") for i, val in enumerate(rdf): csv.add_data(**{"r.1":i*dr, "g(r).1":val}) csv.write()