Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
 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()
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
    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()