Пример #1
0
    def __init__(self, config, plot_config):
        #
        self.logger = get_logger('plotnm.log', 'plotnm', [])
        #
        #Get Surface Point Provider
        config_spp = self._get_spp_config(config['spp'])
        natoms, self.nstates, properties = self._get_db_info(
            config_spp['use_db']['database'])
        atomids = [1 for _ in range(natoms)]
        self.spp = SurfacePointProvider(None,
                                        properties,
                                        self.nstates,
                                        natoms,
                                        atomids,
                                        logger=self.logger,
                                        config=config_spp)
        #
        self.interpolator = self.spp.interpolator
        self.savefile = config['savefile']
        self.interpolator.train(self.savefile)
        #
        qs, crds = self.generate_crds(config['moldenfile'],
                                      mode=config['mode'],
                                      start=config['start'],
                                      end=config['end'],
                                      npoints=config['npoints'])
        energy = self._compute(crds)
        data = []
        conv = energy_converter.get_converter('au', config['energy_units'])
        for q, en in zip(qs, energy):
            en = conv(en) - conv(config['reference_energy'])
            data += [[q, *en]]
        data = np.array(data)

        if config['save_data'] == 'yes':
            np.savetxt(config['save_data']['data_file'], data)

        if config['plot_pes'] == 'yes':
            nstates = data.shape[1] - 1
            myplt = Plot(plot_config)
            myax = myplt.line_plot(data[:, [0, 1]],
                                   x_units_in=('length', 'au'),
                                   y_units_in=('energy',
                                               config['energy_units']),
                                   ax=None,
                                   show_plot=False,
                                   save_plot=False)
            for state in range(1, nstates):
                save = False
                plot = False
                if state == nstates - 1:
                    save = True
                    plot = True
                myax = myplt.line_plot(data[:, [0, state + 1]],
                                       x_units_in=('length', 'au'),
                                       y_units_in=('energy',
                                                   config['energy_units']),
                                       ax=myax,
                                       show_plot=plot,
                                       save_plot=save)
Пример #2
0
    def __init__(self, config):
        """ Class to create initial conditions due to user input. Initial conditions are saved 
            in a file for further usage.
        """
        logger = get_logger('setup_spectrum.log', 'setup_spectrum')
        logger.header('SETUP SPECTRUM', config)
        SetupBase.__init__(self, logger)
        #
        logger.info(f"Opening sampling database {config['sampling_db']}")
        sampling = Sampling.from_db(config['sampling_db'], logger=logger)

        if not exists_and_isfile(config['spp']):
            presets="""
                use_db = no
                """
            logger.info(f"Setting up SPP inputfile: {config['spp']}")
            SurfacePointProvider.generate_input(config['spp'], config=None, presets=presets)
        else:
            logger.info(f"Using SPP inputfile as it is")
            
        if not exists_and_isfile(config['sp_calc']):
            presets=f"""
                properties = {config['properties']}
                nstates = {config['nstates']}
                init_db = init.db
                """
            logger.info(f"Setting up inputfile for the single point calculations")
            SinglePointCalculation.generate_input(config['sp_calc'], config=None, presets=presets)
        else:
            logger.info(f"Using inputfile for the single point calculations as it is")

        logger.info("Starting to prepare the folders...")
        self.setup_folders(range(config['n_cond']), config, sampling)
Пример #3
0
    def __init__(self, config):
        """ Class to create initial conditions due to user input. Initial conditions are saved 
            in a file for further usage.
        """
        logger = get_logger('setup_propagation.log', 'setup_propagation')
        SetupBase.__init__(self, logger)


        # Open DB of initial conditions once, so that it is available
        sampling = Sampling.from_db(config['sampling_db'])

        #Make sure that inputfile for the SPP exists and is complete
        
        if exists_and_isfile(config['spp']): lconfig = config['spp']
        else: lconfig = None
        SurfacePointProvider.generate_input(config['spp'], config=lconfig)

        #Make sure that inputfile for RunTrajectory exists and is complete
        if exists_and_isfile(config['prop']): lconfig = config['prop']
        else: lconfig = None
        RunTrajectory.generate_input(config['prop'], config=lconfig)

        #
        if config['n_traj'] == -1:
            ntraj = len(sampling._db)
        else:
            ntraj = config['n_traj']
        if sampling.nconditions < ntraj:
            logger.error(f"Too few initial conditions in {config['sampling_db']}")

        self.setup_folders(range(ntraj), config, sampling)
Пример #4
0
    def __init__(self, config, logger=None):
        """ 
            Args:
                config, ColtObj:
                    The config contains the information from the colt 
                    questions of the class
                logger, Logger:
                    Logger for the class. If not provided a new logger is created.
        """

        if logger is None:
            self.logger = get_logger('sp_calc.log', 'sp_calc')
            self.logger.header('Single Point Calculation', config)
        else:
            self.logger = logger
        #
        self.logger.info(f"Taking information from {config['init_db']}")
        sampling = Sampling.from_db(config['init_db'], logger=self.logger)

        if not (exists_and_isfile(config['spp'])):
            spp_config = SurfacePointProvider.generate_input(config['spp'])
        else:
            spp_config = SurfacePointProvider.generate_input(
                config['spp'], config=config['spp'])

        self.logger.debug(f"Setting up SPP with {config['spp']}")
        if sampling.molecule is not None:
            spp = SurfacePointProvider.from_config(
                spp_config,
                config['properties'],
                config['nstates'],
                sampling.natoms,
                nghost_states=config['nghost_states'],
                atomids=sampling.atomids)
        else:  #model calculation
            spp = SurfacePointProvider, from_config(spp_config,
                                                    config['properties'],
                                                    config['nstates'],
                                                    sampling.nmodes)

        crd = sampling.get_condition(0).crd

        #check that DB can take the results
        self.logger.debug(
            f"Checking whether {config['init_db']} can take the results")
        self._check_res_db(config, sampling)

        with self.logger.info_block("SPP calculation"):
            res = spp.request(crd,
                              config['properties'],
                              states=[st for st in range(config['nstates'])])

        self.logger.info(f"Writing results to: {config['init_db']}")
        for prop, value in res.iter_data():
            sampling.set(prop, value)
Пример #5
0
 def _get_spp_config(self, filename):
     questions = SurfacePointProvider.generate_questions(presets="""
             use_db=yes :: yes
             [use_db(yes)]
             fit_only = yes :: yes
             write_only = no :: no
             """)
     return questions.ask(config=filename, raise_read_error=False)
Пример #6
0
 def __init__(self, sppinp):
     #
     self.logger = get_logger('validate.log', 'validation', [])
     #
     config = self._get_spp_config(sppinp)
     #
     natoms, self.nstates, properties = self._get_db_info(config['use_db']['database'])
     atomids = [1 for _ in range(natoms)]
     self.spp = SurfacePointProvider.from_config(config, properties, self.nstates, natoms, 
                                                 atomids=atomids, logger=self.logger)
     #
     self.interpolator = self.spp.interpolator
     #
     self.weightsfile = self.spp.interpolator.weightsfile
     self.interpolator.train(self.weightsfile)
Пример #7
0
class AnalyseFitPesNm(Colt):

    _questions = """
        spp = spp.inp :: existing_file
        savefile = :: str
        mode =  :: int
        energy_units = eV :: str :: [eV, au, cm-1, nm]
        reference_energy = 0 :: float
        plot_input = plot_fit_pes_nm.inp :: file
        start = -2 :: float
        end = 2 :: float
        npoints = 100 :: int
        save_data = yes :: str :: [yes, no]
        plot_pes = yes :: str :: [yes, no]
        moldenfile = molden.in :: existing_file
    """

    _save_data = {'yes': "data_file = fit_pes_nm.dat :: file", 'no': " "}

    _plot_pes = {
        'yes': "plot_inputfile = plot_fit_pes_nm.inp :: file",
        'no': ""
    }

    @classmethod
    def _extend_questions(cls, questions):
        questions.generate_cases(
            'save_data', {name: mode
                          for name, mode in cls._save_data.items()})
        questions.generate_cases(
            'plot_pes', {name: mode
                         for name, mode in cls._plot_pes.items()})

    @classmethod
    def from_inputfile(cls, inputfile):
        if not (exists_and_isfile(inputfile)):
            config = cls.generate_input(inputfile, config=None)
        else:
            config = cls.generate_input(inputfile, config=inputfile)
        quests = cls.generate_questions(config=inputfile)
        config = quests.check_only(inputfile)

        plot_config = {}
        if config['plot_pes'].value == 'yes':
            plot_config = {}
            plot_config['x_label'] = 'mode'
            plot_config['x_label_unit'] = False
            plot_config['y_label_unit'] = True
            plot_config['y_label'] = 'energy'
            plot_config = {'': plot_config}

            presets = ''
            presets += f"y_label = energy\n"
            presets += f"x_label_unit = True\n"
            presets += f"[save_plot(yes)]\nplot_file = plot_fit_pes_nm.png\n"
            presets += "legend = {}\n"

            plot_input = config['plot_pes']['plot_inputfile']
            if exists_and_isfile(plot_input):
                plot_config = Plot.generate_input(plot_input,
                                                  config=plot_input,
                                                  presets=presets)
            else:
                plot_config = Plot.generate_input(plot_input,
                                                  config=plot_config,
                                                  presets=presets)
        return cls(config, plot_config)

    def __init__(self, config, plot_config):
        #
        self.logger = get_logger('plotnm.log', 'plotnm', [])
        #
        #Get Surface Point Provider
        config_spp = self._get_spp_config(config['spp'])
        natoms, self.nstates, properties = self._get_db_info(
            config_spp['use_db']['database'])
        atomids = [1 for _ in range(natoms)]
        self.spp = SurfacePointProvider(None,
                                        properties,
                                        self.nstates,
                                        natoms,
                                        atomids,
                                        logger=self.logger,
                                        config=config_spp)
        #
        self.interpolator = self.spp.interpolator
        self.savefile = config['savefile']
        self.interpolator.train(self.savefile)
        #
        qs, crds = self.generate_crds(config['moldenfile'],
                                      mode=config['mode'],
                                      start=config['start'],
                                      end=config['end'],
                                      npoints=config['npoints'])
        energy = self._compute(crds)
        data = []
        conv = energy_converter.get_converter('au', config['energy_units'])
        for q, en in zip(qs, energy):
            en = conv(en) - conv(config['reference_energy'])
            data += [[q, *en]]
        data = np.array(data)

        if config['save_data'] == 'yes':
            np.savetxt(config['save_data']['data_file'], data)

        if config['plot_pes'] == 'yes':
            nstates = data.shape[1] - 1
            myplt = Plot(plot_config)
            myax = myplt.line_plot(data[:, [0, 1]],
                                   x_units_in=('length', 'au'),
                                   y_units_in=('energy',
                                               config['energy_units']),
                                   ax=None,
                                   show_plot=False,
                                   save_plot=False)
            for state in range(1, nstates):
                save = False
                plot = False
                if state == nstates - 1:
                    save = True
                    plot = True
                myax = myplt.line_plot(data[:, [0, state + 1]],
                                       x_units_in=('length', 'au'),
                                       y_units_in=('energy',
                                                   config['energy_units']),
                                       ax=myax,
                                       show_plot=plot,
                                       save_plot=save)

    def _get_spp_config(self, filename):
        questions = SurfacePointProvider.generate_questions(presets="""
                use_db=yes :: yes
                [use_db(yes)]
                fit_only = yes :: yes
                write_only = no :: no
                """)
        return questions.ask(config=filename, raise_read_error=False)

    def _get_db_info(self, database):
        db = PySurfDB.load_database(database, read_only=True)
        rep = db.dbrep
        natoms = rep.dimensions.get('natoms', None)
        if natoms is None:
            natoms = rep.dimensions['nmodes']
        nstates = rep.dimensions['nstates']
        return natoms, nstates, db.saved_properties

    def generate_crds(self, moldenfile, mode, start=-5, end=5, npoints=50):
        molden = MoldenParser(moldenfile,
                              ['Info', 'Freqs', 'FrCoords', 'FrNormCoords'])
        # get molecule info
        atoms = [atom for atom, _, _, _ in molden['FrCoords']]
        atomids = np.array([ATOMNAME_TO_ID[atom] for atom in atoms])
        crd = np.array([[x, y, z] for _, x, y, z in molden['FrCoords']])
        masses = np.array([MASSES[idx] * U_TO_AMU for idx in atomids])
        # create molecule
        molecule = Molecule(atomids, crd, masses)
        #
        print('nmsampler, molecule', molecule)
        modes = [
            Mode(freq * CM_TO_HARTREE, np.array(molden['FrNormCoords'][imode]))
            for imode, freq in enumerate(molden['Freqs'])
        ]
        #
        modes = nm.create_mass_weighted_normal_modes(modes, molecule)

        crds = np.empty((npoints, *crd.shape))
        qs = np.linspace(start, end, npoints)
        for i, q in enumerate(qs):
            crds[i] = crd + q * modes[mode].displacements
        return qs, crds

    def validate(self, filename, properties):
        db = PySurfDB.load_database(filename, read_only=True)
        self._compute(db, properties)

    def save_pes(self, filename, database):
        db = PySurfDB.load_database(database, read_only=True)
        results, _ = self._compute(db, ['energy'])

        def str_join(values):
            return ' '.join(str(val) for val in values)

        with open(filename, 'w') as f:
            f.write("\n".join(f"{i} {str_join(fitted)} {str_join(exact)}"
                              for i, (fitted,
                                      exact) in enumerate(results['energy'])))

    def _compute(self, crds):
        ndata = len(crds)
        energy = []
        for i, crd in enumerate(crds):
            result = self.spp.request(crd, ['energy'])
            #
            energy += [np.copy(result['energy'])]
        return energy
Пример #8
0
    def __init__(self, config, plot_config):
        #
        self.logger = get_logger('plotnm.log', 'plotnm', [])
        #
        #Get Surface Point Provider
        config_spp = self._get_spp_config(config['spp'])
        natoms, self.nstates, properties = self._get_db_info(
            config_spp['use_db']['database'])
        atomids = [1 for _ in range(natoms)]
        self.spp = SurfacePointProvider.from_config(config_spp,
                                                    properties,
                                                    self.nstates,
                                                    natoms,
                                                    atomids=atomids,
                                                    logger=self.logger)
        #
        self.interpolator = self.spp.interpolator
        self.interpolator.train()
        #
        qx, qy, crds = self.generate_crds(
            config['moldenfile'],
            mode=(config['mode'], config['mode2']),
            start=(config['start'], config['start2']),
            end=(config['end'], config['end2']),
            npoints=(config['npoints'], config['npoints2']))
        energy = self._compute(crds)
        data = []
        conv = energy_converter.get_converter('au', config['energy_units'])
        for qxi, qyi, en in zip(np.ravel(qx), np.ravel(qy), energy):
            en = conv(en) - conv(config['reference_energy'])
            data += [[qxi, qyi, *en]]
        data = np.array(data)
        nstates = data.shape[1] - 2
        energy = data[:, 2:]
        energy = energy.T.reshape((nstates, *qx.shape))

        # Take only states according to user input
        if config['states'] is None:
            statelist = [i for i in range(nstates)]
        else:
            statelist = config['states']

        if config['save_data'] == 'yes':
            np.savetxt(config['save_data']['data_file'], data)

        if config['plot_pes'] == 'yes':
            myplt = Plot3D(plot_config)

            save = False
            plot = False
            for state in statelist:
                if state == nstates - 1:
                    save = True
                    plot = True
                if state == statelist[0]:
                    myax = myplt.surface_plot(
                        (qx, qy, energy[state]),
                        x_units_in=('length', 'au'),
                        y_units_in=('length', 'au'),
                        z_units_in=('energy', config['energy_units']),
                        ax=None,
                        show_plot=plot,
                        save_plot=save)
                else:
                    myax = myplt.surface_plot(
                        (qx, qy, energy[state]),
                        x_units_in=('length', 'au'),
                        y_units_in=('length', 'au'),
                        z_units_in=('energy', config['energy_units']),
                        ax=myax,
                        show_plot=plot,
                        save_plot=save)