Exemple #1
0
 def mass(self, mass):
     mass = np.asarray(mass)
     if mass.ndim != 1:
         raise pv_error.InputError('mass', 'Expected 1-dimensional array.')
     if self.natoms is None:
         self.natoms = mass.size
     elif mass.size != self.natoms:
         raise pv_error.InputError(
             'mass', 'Mass vector does not have length == natoms.')
     self.__mass = mass
Exemple #2
0
    def nconstraints_per_molecule(self, nconstraints_per_molecule):
        nconstraints_per_molecule = np.array(nconstraints_per_molecule)
        if nconstraints_per_molecule.ndim != 1:
            raise pv_error.InputError('nconstraints_per_molecule',
                                      'Expected 1-dimensional array.')
        if self.molecule_idx is not None:
            if nconstraints_per_molecule.shape != self.molecule_idx.shape:
                raise pv_error.InputError(
                    'nconstraints_per_molecule',
                    'Expected `nconstraints_per_molecule` to have'
                    'the same shape as `moldecule_idx`.')

        self.__nconstraints_per_molecule = nconstraints_per_molecule
Exemple #3
0
    def __init__(self,
                 ensemble,
                 natoms=None,
                 mu=None,
                 volume=None,
                 pressure=None,
                 energy=None,
                 temperature=None):
        self.__ensemble = None
        self.__n = None
        self.__mu = None
        self.__v = None
        self.__p = None
        self.__e = None
        self.__t = None

        if ensemble not in self.ensembles():
            raise pv_error.InputError('ensemble', 'Given ensemble unknown.')
        self.__ensemble = ensemble

        if ensemble == 'NVE':
            if natoms is None:
                warnings.warn(ensemble + ' with undefined natoms.')
            if volume is None:
                warnings.warn(ensemble + ' with undefined volume.')
            # if energy is None:
            #     warnings.warn(ensemble + ' with undefined energy.')
            self.__n = natoms
            self.__v = volume
            self.__e = energy
        if ensemble == 'NVT':
            if natoms is None:
                warnings.warn(ensemble + ' with undefined natoms.')
            if volume is None:
                warnings.warn(ensemble + ' with undefined volume.')
            if temperature is None:
                warnings.warn(ensemble + ' with undefined temperature.')
            self.__n = natoms
            self.__v = volume
            self.__t = temperature
        if ensemble == 'NPT':
            if natoms is None:
                warnings.warn(ensemble + ' with undefined natoms.')
            if pressure is None:
                warnings.warn(ensemble + ' with undefined pressure.')
            if temperature is None:
                warnings.warn(ensemble + ' with undefined temperature.')
            self.__n = natoms
            self.__p = pressure
            self.__t = temperature
        if ensemble == 'muVT':
            if mu is None:
                warnings.warn(ensemble + ' with undefined mu.')
            if volume is None:
                warnings.warn(ensemble + ' with undefined volume.')
            if temperature is None:
                warnings.warn(ensemble + ' with undefined temperature.')
            self.__mu = mu
            self.__v = volume
            self.__t = temperature
Exemple #4
0
    def compatible(data_1, data_2):
        r"""Checks whether two simulations are compatible for common validation.
    
        Parameters
        ----------
        data_1 : SimulationData
        data_2 : SimulationData
    
        Returns
        -------
        result : bool
    
        """
        if not isinstance(data_1, SimulationData):
            raise pv_error.InputError('data_1', 'Expected type SimulationData')
        if not isinstance(data_2, SimulationData):
            raise pv_error.InputError('data_2', 'Expected type SimulationData')

        return data_1.units == data_2.units
Exemple #5
0
 def molecule_idx(self, molecule_idx):
     molecule_idx = np.asarray(molecule_idx)
     if molecule_idx.ndim != 1:
         raise pv_error.InputError('molecule_idx',
                                   'Expected 1-dimensional array.')
     if (self.nconstraints_per_molecule is not None and
             self.nconstraints_per_molecule.shape != molecule_idx.shape):
         warnings.warn(
             'New `molecule_idx` does not have the same'
             'shape as previously set `nconstraints_per_molecule`.'
             'Setting `nconstraints_per_molecule = None` to avoid'
             'errors.')
         self.__nconstraints_per_molecule = None
     self.__molecule_idx = molecule_idx
Exemple #6
0
 def position(self, pos):
     """Set position"""
     pos = np.array(pos)
     if pos.ndim == 2:
         # create 3-dimensional array
         pos = np.array([pos])
     if pos.ndim != 3:
         warnings.warn('Expected 2- or 3-dimensional array.')
     if self.__nframes == 0 and self.__velocity is None:
         self.__nframes = pos.shape[0]
     elif self.__nframes != pos.shape[0]:
         raise pv_error.InputError(
             ['pos'],
             'Expected equal number of frames as in velocity trajectory.')
     self.__position = pos
Exemple #7
0
 def velocity(self, vel):
     """Set velocity"""
     vel = np.array(vel)
     if vel.ndim == 2:
         # create 3-dimensional array
         vel = np.array([vel])
     if vel.ndim != 3:
         warnings.warn('Expected 2- or 3-dimensional array.')
     if self.__nframes == 0 and self.__position is None:
         self.__nframes = vel.shape[0]
     elif self.__nframes != vel.shape[0]:
         raise pv_error.InputError(
             ['vel'],
             'Expected equal number of frames as in position trajectory.')
     self.__velocity = vel
Exemple #8
0
 def constant_of_motion(self, constant_of_motion):
     """Set constant_of_motion"""
     if constant_of_motion is None:
         self.__constant_of_motion = None
         return
     constant_of_motion = np.array(constant_of_motion)
     if constant_of_motion.ndim != 1:
         raise pv_error.InputError("constant_of_motion",
                                   "Expected 1-dimensional array.")
     if self.nframes == -1:
         self.__nframes = constant_of_motion.size
     elif self.nframes != constant_of_motion.size:
         warnings.warn(
             "Mismatch in number of frames. Setting `nframes = None`.")
         self.__nframes = None
     self.__constant_of_motion = constant_of_motion
Exemple #9
0
 def temperature(self, temperature):
     """Set temperature"""
     if temperature is None:
         self.__temperature = None
         return
     temperature = np.array(temperature)
     if temperature.ndim != 1:
         raise pv_error.InputError("temperature",
                                   "Expected 1-dimensional array.")
     if self.nframes == -1:
         self.__nframes = temperature.size
     elif self.nframes != temperature.size:
         warnings.warn(
             "Mismatch in number of frames. Setting `nframes = None`.")
         self.__nframes = None
     self.__temperature = temperature
Exemple #10
0
 def pressure(self, pressure):
     """Set pressure"""
     if pressure is None:
         self.__pressure = None
         return
     pressure = np.array(pressure)
     if pressure.ndim != 1:
         raise pv_error.InputError("pressure",
                                   "Expected 1-dimensional array.")
     if self.nframes == -1:
         self.__nframes = pressure.size
     elif self.nframes != pressure.size:
         warnings.warn(
             "Mismatch in number of frames. Setting `nframes = None`.")
         self.__nframes = None
     self.__pressure = pressure
Exemple #11
0
 def volume(self, volume):
     """Set volume"""
     if volume is None:
         self.__volume = None
         return
     volume = np.array(volume)
     if volume.ndim != 1:
         raise pv_error.InputError("volume",
                                   "Expected 1-dimensional array.")
     if self.nframes == -1:
         self.__nframes = volume.size
     elif self.nframes != volume.size:
         warnings.warn(
             "Mismatch in number of frames. Setting `nframes = None`.")
         self.__nframes = None
     self.__volume = volume
Exemple #12
0
 def total_energy(self, total_energy):
     """Set total_energy"""
     if total_energy is None:
         self.__total_energy = None
         return
     total_energy = np.array(total_energy)
     if total_energy.ndim != 1:
         raise pv_error.InputError("total_energy",
                                   "Expected 1-dimensional array.")
     if self.nframes == -1:
         self.__nframes = total_energy.size
     elif self.nframes != total_energy.size:
         warnings.warn(
             "Mismatch in number of frames. Setting `nframes = None`.")
         self.__nframes = None
     self.__total_energy = total_energy
Exemple #13
0
 def kinetic_energy(self, kinetic_energy):
     """Set kinetic_energy"""
     if kinetic_energy is None:
         self.__kinetic_energy = None
         return
     kinetic_energy = np.array(kinetic_energy)
     if kinetic_energy.ndim != 1:
         raise pv_error.InputError("kinetic_energy",
                                   "Expected 1-dimensional array.")
     if self.nframes == -1:
         self.__nframes = kinetic_energy.size
     elif self.nframes != kinetic_energy.size:
         warnings.warn(
             "Mismatch in number of frames. Setting `nframes = None`.")
         self.__nframes = None
     self.__kinetic_energy = kinetic_energy
Exemple #14
0
 def potential_energy(self, potential_energy):
     """Set potential_energy"""
     if potential_energy is None:
         self.__potential_energy = None
         return
     potential_energy = np.array(potential_energy)
     if potential_energy.ndim != 1:
         raise pv_error.InputError('potential_energy',
                                   'Expected 1-dimensional array.')
     if self.nframes == -1:
         self.__nframes = potential_energy.size
     elif self.nframes != potential_energy.size:
         warnings.warn('Mismatch in number of frames. '
                       'Setting `nframes = None`.')
         self.__nframes = None
     self.__potential_energy = potential_energy
Exemple #15
0
    def get_simulation_data(self,
                            mdp=None,
                            top=None,
                            edr=None,
                            trr=None,
                            gro=None):
        r"""

        Parameters
        ----------
        mdp: str, optional
            A string pointing to a .mdp file
        top: str, optional
            A string pointing to a .top file
        edr: str, optional
            A string pointing to a .edr file
        trr: str, optional
            A string pointing to a .trr file
        gro: str, optional
            A string pointing to a .gro file (Note: if also trr is given, gro is ignored)

        Returns
        -------
        result: SimulationData
            A SimulationData filled with the provided ensemble and
            topology objects as well as the trajectory data found in the
            edr and trr / gro files.

        """
        result = simulation_data.SimulationData()
        result.units = self.units()

        # trajectories (might be used later for the box...)
        trajectory_dict = None
        if trr is not None:
            if gro is not None:
                warnings.warn('`trr` and `gro` given. Ignoring `gro`.')

            trajectory_dict = self.__interface.read_trr(trr)
            result.trajectory = simulation_data.TrajectoryData(
                trajectory_dict['position'], trajectory_dict['velocity'])
        elif gro is not None:
            trajectory_dict = self.__interface.read_gro(gro)
            result.trajectory = simulation_data.TrajectoryData(
                trajectory_dict['position'], trajectory_dict['velocity'])

        # simulation parameters & topology
        if mdp is not None and top is not None:
            mdp_options = self.__interface.read_mdp(mdp)
            define = None
            include = None
            if 'define' in mdp_options:
                define = mdp_options['define']
            if 'include' in mdp_options:
                include = mdp_options['include']
            molecules = self.__interface.read_system_from_top(top,
                                                              define=define,
                                                              include=include)

            if 'dt' in mdp_options:
                result.dt = float(mdp_options['dt'])

            natoms = 0
            mass = []
            constraints_per_molec = []
            angles = ('constraints' in mdp_options
                      and mdp_options['constraints'] == 'all-angles')
            angles_h = (angles or 'constraints' in mdp_options
                        and mdp_options['constraints'] == 'h-angles')
            bonds = (angles_h or 'constraints' in mdp_options
                     and mdp_options['constraints'] == 'all-bonds')
            bonds_h = (bonds or 'constraints' in mdp_options
                       and mdp_options['constraints'] == 'h-bonds')

            molecule_idx = []
            next_molec = 0
            molec_bonds = []
            molec_bonds_constrained = []
            for molecule in molecules:
                natoms += molecule['nmolecs'] * molecule['natoms']
                for n in range(0, molecule['nmolecs']):
                    molecule_idx.append(next_molec)
                    next_molec += molecule['natoms']
                mass.extend(molecule['mass'] * molecule['nmolecs'])
                constraints = 0
                constrained_bonds = []
                all_bonds = molecule['bonds'] + molecule['bondsh']
                if molecule['settles']:
                    constraints = 3
                    constrained_bonds = all_bonds
                else:
                    if bonds:
                        constraints += molecule['nbonds'][0]
                        constrained_bonds.extend(molecule['bonds'])
                    if bonds_h:
                        constraints += molecule['nbonds'][1]
                        constrained_bonds.extend(molecule['bondsh'])
                    if angles:
                        constraints += molecule['nangles'][0]
                    if angles_h:
                        constraints += molecule['nangles'][1]
                constraints_per_molec.extend([constraints] *
                                             molecule['nmolecs'])
                molec_bonds.extend([all_bonds] * molecule['nmolecs'])
                molec_bonds_constrained.extend([constrained_bonds] *
                                               molecule['nmolecs'])

            topology = simulation_data.TopologyData()
            topology.natoms = natoms
            topology.mass = mass
            topology.molecule_idx = molecule_idx
            topology.nconstraints = np.sum(constraints_per_molec)
            topology.nconstraints_per_molecule = constraints_per_molec
            topology.ndof_reduction_tra = 3
            topology.ndof_reduction_rot = 0
            if 'comm-mode' in mdp_options:
                if mdp_options['comm-mode'] == 'Linear':
                    topology.ndof_reduction_tra = 3
                elif mdp_options['comm-mode'] == 'Angular':
                    topology.ndof_reduction_tra = 3
                    topology.ndof_reduction_rot = 3
                if mdp_options['comm-mode'] == 'None':
                    topology.ndof_reduction_tra = 0
            topology.bonds = molec_bonds
            topology.constrained_bonds = molec_bonds_constrained
            result.topology = topology

            thermostat = ('tcoupl' in mdp_options and mdp_options['tcoupl']
                          and mdp_options['tcoupl'] != 'no'
                          and mdp_options['tcoupl'] != 'No')
            stochastic_dyn = ('integrator' in mdp_options and
                              mdp_options['integrator'] in ['sd', 'sd2', 'bd'])
            constant_temp = thermostat or stochastic_dyn
            temperature = None
            if constant_temp:
                ref_t_key = 'ref-t'
                if ref_t_key not in mdp_options and 'ref_t' in mdp_options:
                    ref_t_key = 'ref_t'
                ref_t = [float(t) for t in mdp_options[ref_t_key].split()]
                if len(ref_t) == 1 or np.allclose(ref_t,
                                                  [ref_t[0]] * len(ref_t)):
                    temperature = ref_t[0]
                else:
                    raise pv_error.InputError(
                        'mdp', 'Ensemble definition ambiguous.')

            constant_press = ('pcoupl' in mdp_options and mdp_options['pcoupl']
                              and mdp_options['pcoupl'] != 'no'
                              and mdp_options['pcoupl'] != 'No')
            volume = None
            pressure = None
            if constant_press:
                ref_p_key = 'ref-p'
                if ref_p_key not in mdp_options and 'ref_p' in mdp_options:
                    ref_p_key = 'ref_p'
                pressure = float(mdp_options[ref_p_key])
            else:
                if trajectory_dict is not None:
                    box = trajectory_dict['box'][0]
                    # Different box shapes?
                    volume = box[0] * box[1] * box[2]
                else:
                    warnings.warn(
                        'Constant volume simulation with undefined volume.')

            if constant_temp and constant_press:
                ens = 'NPT'
            elif constant_temp:
                ens = 'NVT'
            else:
                ens = 'NVE'

            if ens == 'NVE':
                self.__gmx_energy_names['constant_of_motion'] = 'Total-Energy'
            else:
                self.__gmx_energy_names['constant_of_motion'] = 'Conserved-En.'

            result.ensemble = simulation_data.EnsembleData(
                ens,
                natoms=natoms,
                volume=volume,
                pressure=pressure,
                temperature=temperature)

        if edr is not None:
            observable_dict = self.__interface.get_quantities(
                edr, self.__gmx_energy_names.values(), args=['-dp'])

            # constant volume simulations don't write out the volume in .edr file
            if (observable_dict['Volume'] is None
                    and result.ensemble is not None
                    and result.ensemble.volume is not None):
                nframes = observable_dict['Pressure'].size
                observable_dict['Volume'] = np.ones(
                    nframes) * result.ensemble.volume

            result.observables = simulation_data.ObservableData()
            for key, gmxkey in self.__gmx_energy_names.items():
                result.observables[key] = observable_dict[gmxkey]

        return result
Exemple #16
0
def check(data_sim_one,
          data_sim_two,
          total_energy=False,
          screen=False,
          filename=None,
          quiet=False):
    r"""
    Check the ensemble. The correct check is inferred from the
    simulation data given.
    
    Parameters
    ----------
    data_sim_one : SimulationData
    data_sim_two : SimulationData
    total_energy : bool
    screen : bool
        Plot distributions on screen. Default: False.
    filename : string
        Plot distributions to `filename`.pdf. Default: None.
    quiet : bool
        Turns off nearly all messages. Default: False.

    Returns
    -------

    """
    if not simulation_data.SimulationData.compatible(data_sim_one,
                                                     data_sim_two):
        raise pv_error.InputError(['data_sim_one', 'data_sim_two'],
                                  'Simulation data not compatible.')

    if data_sim_one.ensemble.ensemble != data_sim_two.ensemble.ensemble:
        raise pv_error.InputError(
            ['data_sim_one', 'data_sim_two'],
            'The two simulations were sampling different ensembles. '
            'The simulations are expected to differ in state point '
            '(e.g. target temperature, target pressure), but not '
            'in their sampled ensemble (e.g. NVT, NPT).')

    ensemble = data_sim_one.ensemble.ensemble

    if ensemble == 'NVE' or ensemble == 'muVE':
        raise pv_error.InputError(['data_sim_one', 'data_sim_two'],
                                  'Test of ensemble ' + ensemble +
                                  ' is not implemented '
                                  '(yet).')

    n1 = data_sim_one.observables.nframes
    n2 = data_sim_two.observables.nframes

    if total_energy:
        e1 = data_sim_one.observables.total_energy
        e2 = data_sim_two.observables.total_energy
    else:
        e1 = data_sim_one.observables.potential_energy
        e2 = data_sim_two.observables.potential_energy

    # padding the array - checkensemble requires same length
    if n1 < n2:
        e1 = np.append(e1, np.zeros(n2 - n1))
    if n2 < n1:
        e2 = np.append(e2, np.zeros(n1 - n2))

    number_of_samples = np.array([n1, n2])
    energy = np.array([e1, e2])

    do_linear_fit = True
    do_non_linear_fit = False
    do_max_likelhood = True
    do_maxwell = False

    quantiles = None

    if ensemble == 'NVT':
        temperatures = np.array([
            data_sim_one.ensemble.temperature,
            data_sim_two.ensemble.temperature
        ])

        analysis_type = 'dbeta-constV'

        ge = []
        for e in energy:
            ge.append(timeseries.statisticalInefficiency(e, fast=False))

        quantiles = checkensemble.ProbabilityAnalysis(
            number_of_samples,
            type=analysis_type,
            T_k=temperatures,
            P_k=None,
            mu_k=None,
            U_kn=energy,
            V_kn=None,
            N_kn=None,
            nbins=40,
            reptype=None,
            g=ge,
            bMaxwell=do_maxwell,
            bLinearFit=do_linear_fit,
            bNonLinearFit=do_non_linear_fit,
            bMaxLikelihood=do_max_likelhood,
            kB=data_sim_one.units.kb,
            units=data_sim_one.units,
            filename=filename,
            screen=screen,
            quiet=quiet)

    elif ensemble == 'NPT':
        temperatures = np.array([
            data_sim_one.ensemble.temperature,
            data_sim_two.ensemble.temperature
        ])
        pressures = np.array(
            [data_sim_one.ensemble.pressure, data_sim_two.ensemble.pressure])
        equal_temps = temperatures[0] == temperatures[1]
        equal_press = pressures[0] == pressures[1]

        v1 = data_sim_one.observables.volume
        v2 = data_sim_two.observables.volume
        # padding the array - checkensemble requires same length
        if n1 < n2:
            v1 = np.append(v1, np.zeros(n2 - n1))
        if n2 < n1:
            v2 = np.append(v2, np.zeros(n1 - n2))
        volume = np.array([v1, v2])

        if equal_press and not equal_temps:
            analysis_type = 'dbeta-constP'
        elif equal_temps and not equal_press:
            analysis_type = 'dpressure-constB'
        else:
            analysis_type = 'dbeta-dpressure'
            do_linear_fit = False
            do_non_linear_fit = False

        ge = []
        for e in energy:
            ge.append(timeseries.statisticalInefficiency(e, fast=False))
        gv = []
        for v in volume:
            gv.append(timeseries.statisticalInefficiency(v, fast=False))
        g = np.maximum(ge, gv)

        quantiles = checkensemble.ProbabilityAnalysis(
            number_of_samples,
            type=analysis_type,
            T_k=temperatures,
            P_k=pressures,
            mu_k=None,
            U_kn=energy,
            V_kn=volume,
            N_kn=None,
            kB=data_sim_one.units.kb,
            nbins=40,
            bMaxLikelihood=do_max_likelhood,
            bLinearFit=do_linear_fit,
            bNonLinearFit=do_non_linear_fit,
            reptype=None,
            g=g,
            bMaxwell=do_maxwell,
            units=data_sim_one.units,
            screen=screen,
            filename=filename,
            quiet=quiet)

    return quantiles