Example #1
0
def qt(input_file,
       tmax=-1.0,
       tmax_fraction=0.75,
       tsamples=60,
       func='logx',
       *input_files,
       **global_args):
    """Collective overlap correlation function"""
    global_args = _compat(global_args)
    func = _func_db[func]
    for th in _get_trajectories([input_file] + list(input_files), global_args):
        if tmax > 0:
            t_grid = [0.0] + func(th.timestep, tmax, tsamples)
        elif tmax_fraction > 0:
            t_grid = [0.0] + func(th.timestep, tmax_fraction * th.total_time,
                                  tsamples)
        else:
            t_grid = None
        pp.CollectiveOverlap(
            th, t_grid,
            norigins=global_args['norigins']).do(update=global_args['update'])
        ids = distinct_species(th[0].particle)
        if len(ids) > 1:
            Partial(pp.CollectiveOverlap,
                    ids,
                    th,
                    t_grid,
                    norigins=global_args['norigins']).do(
                        update=global_args['update'])
Example #2
0
def _default_rcut(th):
    """
    Look for the first minimum in the partial g(r)
    """
    from atooms.system.particle import distinct_species
    from atooms.postprocessing.partial import Partial
    from atooms.postprocessing import RadialDistributionFunction
    from .helpers import ifabsmm

    ids = distinct_species(th[0].particle)
    gr = Partial(RadialDistributionFunction, ids, th, dr=0.1)
    gr.do(update=False)
    rcut = {}
    for isp in ids:
        for jsp in ids:
            # First find absolute maximum
            _, m = ifabsmm(list(gr.partial[(isp, jsp)].grid),
                           list(gr.partial[(isp, jsp)].value))
            # Then look for first minimum after the maximum
            for i in range(len(gr.partial[(isp, jsp)].grid)):
                if gr.partial[(isp, jsp)].grid[i] >= m[0]:
                    delta = gr.partial[(isp, jsp)].value[i+1] - gr.partial[(isp, jsp)].value[i]
                    if delta >= 0:
                        rcut[(isp, jsp)] = gr.partial[(isp, jsp)].grid[i]
                        break
    
    return rcut
Example #3
0
def vacf(input_file,
         tmax=-1.0,
         tmax_fraction=0.10,
         tsamples=30,
         func='linear',
         *input_files,
         **global_args):
    """Velocity autocorrelation function"""
    global_args = _compat(global_args)
    func = _func_db[func]
    for th in _get_trajectories([input_file] + list(input_files), global_args):
        if tmax > 0:
            t_grid = [0.0] + func(th.timestep, min(th.total_time, tmax),
                                  tsamples)
        elif tmax_fraction > 0:
            t_grid = [0.0] + func(th.timestep, tmax_fraction * th.total_time,
                                  tsamples)
        else:
            t_grid = None
        pp.VelocityAutocorrelation(
            th, t_grid,
            norigins=global_args['norigins']).do(update=global_args['update'])
        ids = distinct_species(th[0].particle)
        if len(ids) > 1:
            Partial(pp.VelocityAutocorrelation,
                    ids,
                    th,
                    t_grid,
                    norigins=global_args['norigins']).do(
                        update=global_args['update'])
Example #4
0
def alpha2(input_file,
           tmax=-1.0,
           tmax_fraction=0.75,
           tsamples=60,
           func='logx',
           *input_files,
           **global_args):
    """Non-Gaussian parameter"""
    global_args = _compat(global_args)
    func = _func_db[func]
    for th in _get_trajectories([input_file] + list(input_files), global_args):
        if tmax > 0:
            t_grid = [0.0] + func(th.timestep, tmax, tsamples)
        elif tmax_fraction > 0:
            t_grid = [0.0] + func(th.timestep, tmax_fraction * th.total_time,
                                  tsamples)
        else:
            t_grid = None
        pp.NonGaussianParameter(
            th, t_grid,
            norigins=global_args['norigins']).do(update=global_args['update'])
        ids = distinct_species(th[0].particle)
        if len(ids) > 1:
            Partial(pp.NonGaussianParameter,
                    ids,
                    th,
                    t_grid,
                    norigins=global_args['norigins']).do(
                        update=global_args['update'])
Example #5
0
    def _setup_arrays_onebody(self):
        """
        Setup list of numpy arrays for one-body correlations.
        
        We also take care of dumping the weight if needed, see
        `add_weight()`.
        """
        if 'pos' in self.phasespace or 'vel' in self.phasespace or 'ids' in self.phasespace:
            ids = distinct_species(self.trajectory[0].particle)
            for s in progress(self.trajectory):
                # Apply filter if there is one
                if len(self._cbk) > 0:
                    s = self._cbk[0](s, *self._cbk_args[0],
                                     **self._cbk_kwargs[0])
                if 'pos' in self.phasespace:
                    self._pos.append(s.dump('pos'))
                if 'vel' in self.phasespace:
                    self._vel.append(s.dump('vel'))
                if 'ids' in self.phasespace:
                    _ids = s.dump('species')
                    _ids = numpy.array([ids.index(_) for _ in _ids],
                                       dtype=numpy.int32)
                    self._ids.append(_ids)

        # Dump unfolded positions if requested
        if 'pos-unf' in self.phasespace:
            if self._unfolded is None:
                self._unfolded = Unfolded(self.trajectory,
                                          fixed_cm=self._fix_cm)
            for s in progress(self._unfolded):
                # Apply filter if there is one
                if len(self._cbk) > 0:
                    s = self._cbk[0](s, *self._cbk_args[0],
                                     **self._cbk_kwargs[0])
                self._pos_unf.append(s.dump('pos'))
Example #6
0
def gr(input_file,
       dr=0.04,
       grandcanonical=False,
       ndim=-1,
       rmax=-1.0,
       *input_files,
       **global_args):
    """Radial distribution function"""
    global_args = _compat(global_args)
    if global_args['legacy']:
        backend = pp.RadialDistributionFunctionLegacy
    else:
        backend = pp.RadialDistributionFunction

    for th in _get_trajectories([input_file] + list(input_files), global_args):
        th._grandcanonical = grandcanonical
        cf = backend(th,
                     dr=dr,
                     rmax=rmax,
                     norigins=global_args['norigins'],
                     ndim=ndim)
        if global_args['filter'] is not None:
            cf = pp.Filter(cf, global_args['filter'])
        cf.do(update=global_args['update'])

        ids = distinct_species(th[0].particle)
        if len(ids) > 1 and not global_args['no_partial']:
            cf = Partial(backend,
                         ids,
                         th,
                         dr=dr,
                         rmax=rmax,
                         norigins=global_args['norigins'],
                         ndim=ndim)
            cf.do(update=global_args['update'])
Example #7
0
def sk(input_file,
       nk=20,
       dk=0.1,
       kmin=-1.0,
       kmax=15.0,
       ksamples=30,
       kgrid=None,
       weight=None,
       weight_trajectory=None,
       weight_fluctuations=False,
       *input_files,
       **global_args):
    """
    Structure factor
    """
    from atooms.trajectory import TrajectoryXYZ
    global_args = _compat(global_args)
    if global_args['fast']:
        backend = pp.StructureFactorFast
    else:
        backend = pp.StructureFactorLegacy
    if kgrid is not None:
        kgrid = [float(_) for _ in kgrid.split(',')]
    for th in _get_trajectories([input_file] + list(input_files), global_args):
        cf = backend(th,
                     kgrid=kgrid,
                     norigins=global_args['norigins'],
                     kmin=kmin,
                     kmax=kmax,
                     nk=nk,
                     dk=dk,
                     ksamples=ksamples)
        if global_args['filter'] is not None:
            cf = pp.Filter(cf, global_args['filter'])
        if weight_trajectory is not None:
            weight_trajectory = TrajectoryXYZ(weight_trajectory)
        cf.add_weight(trajectory=weight_trajectory,
                      field=weight,
                      fluctuations=weight_fluctuations)
        cf.do(update=global_args['update'])

        ids = distinct_species(th[0].particle)
        if len(ids) > 1 and not global_args['no_partial']:
            cf = Partial(backend,
                         ids,
                         th,
                         kgrid=kgrid,
                         norigins=global_args['norigins'],
                         kmin=kmin,
                         kmax=kmax,
                         nk=nk,
                         dk=dk,
                         ksamples=ksamples)
            cf.add_weight(trajectory=weight_trajectory,
                          field=weight,
                          fluctuations=weight_fluctuations)
            cf.do(update=global_args['update'])
Example #8
0
    def write_sample(self, system, step):
        self.trajectory.create_group_safe('/trajectory')
        self.trajectory.create_group_safe('/trajectory/realtime')
        self.trajectory.create_group_safe('/trajectory/realtime/stepindex')
        self.trajectory.create_group_safe('/trajectory/realtime/sampleindex')

        frame = len(self.steps) + 1
        csample = '/sample_%7.7i' % frame

        try:
            self.trajectory['/trajectory/realtime/stepindex' +
                            csample] = [step]
            self.trajectory['/trajectory/realtime/sampleindex' +
                            csample] = [frame]
        except RuntimeError:
            _log.error('error when writing step %s sample %s to file %s', step,
                       frame, self.filename)
            raise

        if system.particle is not None:
            self.trajectory.create_group_safe('/trajectory/particle')
            if 'position' in self.fields:
                self.trajectory.create_group_safe(
                    '/trajectory/particle/position')
                self.trajectory['/trajectory/particle/position' + csample] = [
                    p.position for p in system.particle
                ]
            if 'velocity' in self.fields:
                self.trajectory['/trajectory/particle/velocity' + csample] = [
                    p.velocity for p in system.particle
                ]
                self.trajectory.create_group_safe(
                    '/trajectory/particle/velocity')
            if 'radius' in self.fields:
                self.trajectory.create_group_safe(
                    '/trajectory/particle/radius')
                self.trajectory['/trajectory/particle/radius' +
                                csample] = [p.radius for p in system.particle]
            if 'species' in self.fields:
                self.trajectory.create_group_safe(
                    '/trajectory/particle/species')
                data = ['%-3s' % p.species for p in system.particle]
                self.trajectory['/trajectory/particle/species' +
                                csample] = [_.encode() for _ in data]
                from atooms.system.particle import distinct_species
                ids = distinct_species(system.particle)
                self.trajectory['/trajectory/particle/ids' + csample] = [
                    1 + ids.index(p.species) for p in system.particle
                ]

        if system.cell is not None:
            self.trajectory.create_group_safe('/trajectory/cell')
            if 'cell' in self.fields:
                self.trajectory.create_group_safe('/trajectory/cell/sidebox')
                self.trajectory['/trajectory/cell/sidebox' +
                                csample] = system.cell.side
Example #9
0
def fskt(input_file,
         tmax=-1.0,
         tmax_fraction=0.75,
         tsamples=60,
         kmin=7.0,
         kmax=8.0,
         ksamples=1,
         dk=0.1,
         nk=8,
         kgrid=None,
         func='logx',
         total=False,
         fix_cm=False,
         lookup_mb=64.0,
         *input_files,
         **global_args):
    """Self intermediate scattering function"""
    global_args = _compat(global_args)
    func = _func_db[func]
    if global_args['legacy']:
        backend = pp.SelfIntermediateScatteringLegacy
    else:
        backend = pp.SelfIntermediateScattering
    for th in _get_trajectories([input_file] + list(input_files), global_args):
        if tmax > 0:
            t_grid = [0.0] + func(th.timestep, tmax, tsamples)
        elif tmax_fraction > 0:
            t_grid = [0.0] + func(th.timestep, tmax_fraction * th.total_time,
                                  tsamples)
        else:
            t_grid = None
        if kgrid is not None:
            k_grid = [float(_) for _ in kgrid.split(',')]
        else:
            k_grid = linear_grid(kmin, kmax, ksamples)
        if total:
            backend(th,
                    k_grid,
                    t_grid,
                    nk,
                    dk=dk,
                    norigins=global_args['norigins'],
                    fix_cm=fix_cm,
                    lookup_mb=lookup_mb).do(update=global_args['update'])
        ids = distinct_species(th[0].particle)
        if len(ids) > 1:
            Partial(backend,
                    ids,
                    th,
                    k_grid,
                    t_grid,
                    nk,
                    dk=dk,
                    norigins=global_args['norigins'],
                    fix_cm=fix_cm,
                    lookup_mb=lookup_mb).do(update=global_args['update'])
Example #10
0
 def test_species(self):
     system = copy.copy(self.ref)
     npart = len(system.particle)
     for p in system.particle[0:10]:
         p.species = 'B'
     for p in system.particle[10:30]:
         p.species = 'C'
     from atooms.system.particle import composition, distinct_species
     self.assertEqual(distinct_species(system.particle), ['A', 'B', 'C'])
     self.assertEqual(system.distinct_species(), ['A', 'B', 'C'])
     self.assertEqual(composition(system.particle)['A'], npart - 30)
     self.assertEqual(composition(system.particle)['B'], 10)
     self.assertEqual(composition(system.particle)['C'], 20)
Example #11
0
    def _compute(self):
        from atooms.trajectory.decorators import change_species
        from atooms.postprocessing.realspace_wrap import compute
        from atooms.system.particle import distinct_species

        hist_all = []
        hist_one = numpy.ndarray(len(self.grid), dtype=numpy.int32)
        origins = range(0, len(self.trajectory), self.skip)
        dtheta = self.grid[1] - self.grid[0]

        # Setup array of cutoff distances based on g(r) calculated for
        # the whole trajectory.
        # We store the cutoffs into a (nsp, nsp) array 
        # where the index follows the alphabetic order of species names
        if self.rcut is None:
            rcut = _default_rcut(self.trajectory)
            ids = distinct_species(self.trajectory[0].particle)
            self.rcut = numpy.ndarray((len(ids), len(ids)))
            for species_pair in rcut:
                self.rcut[ids.index(species_pair[0]), ids.index(species_pair[1])] = rcut[species_pair]

        for isp in range(len(ids)):
            for jsp in range(len(ids)):
                self.analysis['cutoff distance {}-{}'.format(isp, jsp)] = self.rcut[isp, jsp]

        for i in progress(origins):
            system = self.trajectory[i]
            side = system.cell.side  # this should not be affected by filters
            #system = change_species(system, 'F')  # species are in fortran style
            #ids = numpy.array(system.dump('spe'), dtype=numpy.int32)
            nn = numpy.array(0, dtype=numpy.int32)
            neighbors = numpy.ndarray(50, dtype=numpy.int32)
            for idx in range(len(self._pos_0[i])):
                isp = self._ids_0[i][idx]
                compute.neighbors('C', side, self._pos_0[i][idx],
                                  self._pos_1[i].transpose(),
                                  self._ids_1[i],
                                  self.rcut[isp, :],
                                  nn, neighbors)
                #print idx, self._pos_1[i].shape, neighbors[0: nn], set(self._ids_1[i])
                compute.bond_angle(self._pos_0[i][idx, :],
                                   self._pos_1[i].transpose(),
                                   neighbors[0: nn], side, dtheta,
                                   hist_one)
                hist_all.append(hist_one.copy())

        # Normalization
        hist = numpy.sum(hist_all, axis=0)
        norm = float(numpy.sum(hist[:-1]))
        self.grid = (numpy.array(self.grid[:-1]) + numpy.array(self.grid[1:])) / 2.0
        self.value = hist[:-1] / (norm * dtheta)
Example #12
0
 def write_sample(self, system, step):
     self._setup_format()
     sp = distinct_species(system.particle)
     self.trajectory.write("%d\n" % len(system.particle))
     self.trajectory.write(self._comment(step, system))
     ndim = len(system.particle[0].position)
     for p in system.particle:
         # We get the integer index corresponding to species Ex.:
         # if species are 'A', 'B' we get 0 and 1. Note that in
         # general getting the sample back via read_sample() will
         # not preserve the species.
         isp = sp.index(p.species)
         self.trajectory.write("{0} {1.position} {1.velocity}\n".format(
             isp, p))
Example #13
0
 def write_sample(self, system, step):
     sp = distinct_species(system.particle)
     self.trajectory.write("%d\n" % len(system.particle))
     self.trajectory.write(self._comment(step, system))
     ndim = len(system.particle[0].position)
     for p in system.particle:
         # We get the integer index corresponding to species Ex.:
         # if species are 'A', 'B' we get 0 and 1. Note that in
         # general getting the sample back via read_sample() will
         # not preserve the species.
         isp = sp.index(p.species)
         self.trajectory.write(
             ("%s" + ndim * " %.6f" + ndim * " %.6f " + "\n") %
             ((isp, ) + tuple(p.position) + tuple(p.velocity)))
Example #14
0
    def write_init(self, system):
        f = open(self.filename + '.inp', 'w')
        np = len(system.particle)
        L = system.cell.side
        species_db = distinct_species(system.particle)

        # LAMMPS header
        h = '\n'
        h += "{:d} atoms\n".format(np)
        h += "{:d} atom types\n".format(len(species_db))
        h += "{:.{prec}f} {:.{prec}f} xlo xhi\n".format(-L[0] / 2,
                                                        L[0] / 2,
                                                        prec=self.precision)
        h += "{:.{prec}f} {:.{prec}f} ylo yhi\n".format(-L[1] / 2,
                                                        L[1] / 2,
                                                        prec=self.precision)
        h += "{:.{prec}f} {:.{prec}f} zlo zhi\n".format(-L[2] / 2,
                                                        L[2] / 2,
                                                        prec=self.precision)

        # LAMMPS body
        # Masses of species
        m = "\nMasses\n\n"
        for isp in range(len(species_db)):
            # Iterate over particles. Find instances of species and get masses
            for p in system.particle:
                if p.species == species_db[isp]:
                    m += '{:d} {:{prec}f}\n'.format(isp + 1,
                                                    p.mass,
                                                    prec=self.precision)
                    break

        # Atom coordinates
        r = "\nAtoms\n\n"
        v = "\nVelocities\n\n"
        for i, p in enumerate(system.particle):
            isp = species_db.index(p.species) + 1
            r += '{:d} {:d} {:{prec}} {:{prec}} {:{prec}}\n'.format(
                i + 1, isp, *p.position, prec=self.precision)
            v += '{:d}      {:{prec}} {:{prec}} {:{prec}}\n'.format(
                i + 1, *p.velocity, prec=self.precision)

        f.write(h)
        f.write(m)
        f.write(r)
        f.write(v)
        f.close()
Example #15
0
    def _comment(self, step, system):
        def first_of_species(system, species):
            for i, p in enumerate(system.particle):
                if p.species == species:
                    return i
            raise ValueError('no species %d found in system' % species)

        sp = distinct_species(system.particle)
        mass = [
            system.particle[first_of_species(system, isp)].mass for isp in sp
        ]
        hdr = 'ioformat=1 dt=%g timeStepIndex=%d boxLengths=' + \
              '%.12f,%.12f,%.12f' + \
              ' numTypes=%d mass=' + '%g,'*(len(sp)) + \
              ' columns=type,x,y,z,vx,vy,vz\n'
        return hdr % tuple([self.timestep, step] + list(system.cell.side) +
                           [len(sp)] + mass)
Example #16
0
    def _setup_arrays_twobody(self):
        """Setup list of numpy arrays for two-body correlations."""
        if len(self._cbk) <= 1:
            self._setup_arrays_onebody()
            self._pos_0 = self._pos
            self._pos_1 = self._pos
            self._vel_0 = self._vel
            self._vel_1 = self._vel
            self._ids_0 = self._ids
            self._ids_1 = self._ids
            return

        if 'pos' in self.phasespace or 'vel' in self.phasespace or 'ids' in self.phasespace:
            ids = distinct_species(self.trajectory[0].particle)
            for s in progress(self.trajectory):
                s0 = self._cbk[0](s, *self._cbk_args[0], **self._cbk_kwargs[0])
                s1 = self._cbk[1](s, *self._cbk_args[1], **self._cbk_kwargs[1])
                if 'pos' in self.phasespace:
                    self._pos_0.append(s0.dump('pos'))
                    self._pos_1.append(s1.dump('pos'))
                if 'vel' in self.phasespace:
                    self._vel_0.append(s0.dump('vel'))
                    self._vel_1.append(s1.dump('vel'))
                if 'ids' in self.phasespace:
                    _ids_0 = s0.dump('species')
                    _ids_1 = s1.dump('species')
                    _ids_0 = numpy.array([ids.index(_) for _ in _ids_0],
                                         dtype=numpy.int32)
                    _ids_1 = numpy.array([ids.index(_) for _ in _ids_1],
                                         dtype=numpy.int32)
                    self._ids_0.append(_ids_0)
                    self._ids_1.append(_ids_1)

        # Dump unfolded positions if requested
        if 'pos-unf' in self.phasespace:
            for s in progress(Unfolded(self.trajectory)):
                s0 = self._cbk[0](s, *self._cbk_args[0], **self._cbk_kwargs[0])
                s1 = self._cbk[1](s, *self._cbk_args[1], **self._cbk_kwargs[1])
                self._pos_unf_0.append(s0.dump('pos'))
                self._pos_unf_1.append(s1.dump('pos'))
Example #17
0
def fkt(input_file,
        tmax=-1.0,
        tmax_fraction=0.75,
        tsamples=60,
        kmin=7.0,
        kmax=7.0,
        ksamples=1,
        dk=0.1,
        nk=100,
        kgrid=None,
        func='logx',
        fix_cm=False,
        *input_files,
        **global_args):
    """Total intermediate scattering function"""
    global_args = _compat(global_args)
    func = _func_db[func]
    for th in _get_trajectories([input_file] + list(input_files), global_args):
        if tmax > 0:
            t_grid = [0.0] + func(th.timestep, tmax, tsamples)
        elif tmax_fraction > 0:
            t_grid = [0.0] + func(th.timestep, tmax_fraction * th.total_time,
                                  tsamples)
        else:
            t_grid = None
        if kgrid is not None:
            k_grid = [float(_) for _ in kgrid.split(',')]
        else:
            k_grid = linear_grid(kmin, kmax, ksamples)
        ids = distinct_species(th[0].particle)
        if len(ids) > 1:
            Partial(pp.IntermediateScattering,
                    ids,
                    th,
                    k_grid,
                    t_grid,
                    norigins=global_args['norigins'],
                    nk=nk,
                    dk=dk,
                    fix_cm=fix_cm).do(update=global_args['update'])
Example #18
0
def chi4qs(input_file,
           tsamples=60,
           a=0.3,
           tmax=-1.0,
           func='logx',
           tmax_fraction=0.75,
           total=False,
           *input_files,
           **global_args):
    """Dynamic susceptibility of self overlap"""
    global_args = _compat(global_args)
    func = _func_db[func]
    if global_args['fast']:
        backend = pp.Chi4SelfOverlapOpti
    else:
        backend = pp.Chi4SelfOverlap

    for th in _get_trajectories([input_file] + list(input_files), global_args):
        if tmax > 0:
            t_grid = [0.0] + func(th.timestep, min(th.total_time, tmax),
                                  tsamples)
        elif tmax_fraction > 0:
            t_grid = [0.0] + func(th.timestep, tmax_fraction * th.total_time,
                                  tsamples)
        else:
            t_grid = None
        if total:
            backend(th, t_grid, a=a, norigins=global_args['norigins']).do(
                update=global_args['update'])
        ids = distinct_species(th[0].particle)
        if not total and len(ids) > 1:
            Partial(backend,
                    ids,
                    th,
                    t_grid,
                    a=a,
                    norigins=global_args['norigins']).do(
                        update=global_args['update'])
Example #19
0
def msd(input_file,
        tmax=-1.0,
        tmax_fraction=0.75,
        tsamples=30,
        sigma=1.0,
        func='linear',
        rmsd_max=-1.0,
        fix_cm=False,
        *input_files,
        **global_args):
    """Mean square displacement"""
    func = _func_db[func]
    global_args = _compat(global_args)
    for th in _get_trajectories([input_file] + list(input_files), global_args):
        dt = th.timestep
        if tmax > 0:
            t_grid = [0.0] + func(dt, min(th.total_time, tmax), tsamples)
        elif tmax_fraction > 0:
            t_grid = [0.0] + func(dt, tmax_fraction * th.total_time, tsamples)
        else:
            t_grid = None
        ids = distinct_species(th[0].particle)
        pp.MeanSquareDisplacement(
            th,
            tgrid=t_grid,
            norigins=global_args['norigins'],
            sigma=sigma,
            rmax=rmsd_max,
            fix_cm=fix_cm).do(update=global_args['update'])
        if len(ids) > 1:
            Partial(pp.MeanSquareDisplacement,
                    ids,
                    th,
                    tgrid=t_grid,
                    norigins=global_args['norigins'],
                    sigma=sigma,
                    rmax=rmsd_max).do(update=global_args['update'])
Example #20
0
def change_species(system, layout):
    """
    Return a modified `system` with particle species changed according
    to `layout`.

    The possible values of `layout` are:

    - 'A': alphabetic, i.e. species are strings like 'A', 'B', ...
    - 'C': C-like, i.e. species are integers starting from 0
    - 'F': F-like, i.e. species are integers starting from 1

    If the current layout already matches the requested one, the
    system is returned unchanged.
    """
    if layout not in ['A', 'C', 'F']:
        raise ValueError('species layout must be A, C, or F (not %s)' % layout)

    # Detect species layout (A=alphabetic, C=C style, F=fortran style)
    try:
        species = [int(p.species) for p in system.particle]
    except ValueError:
        # The species cannot be converted to int, thus layout is
        # alphabetical
        current_layout = 'A'
    else:
        min_sp = numpy.min(species)
        if min_sp == 0:
            current_layout = 'C'
        elif min_sp == 1:
            current_layout = 'F'
        else:
            raise ValueError('Numeric species should start from 0 or 1')

    # Do nothing if the layout is already ok
    if layout == current_layout:
        return system

    # Convert to new layout
    import string
    if layout == 'A':
        # We get the index of the species map:
        # - if current layout is F (min_sp=1), we subtract one.
        # - if current layout is C (min_sp=0), we do nothing
        species_map = string.ascii_uppercase
        for p in system.particle:
            p.species = species_map[int(p.species) - min_sp]
    else:
        # Output layout is numerical (C or F)
        from atooms.system.particle import distinct_species
        offset = 1 if layout == 'F' else 0
        # Note that distinct_species is sorted alphabetically
        species_list = distinct_species(system.particle)
        if current_layout == 'A':
            for p in system.particle:
                p.species = str(species_list.index(p.species) + offset)
        else:
            # If layout=C, current_layout is F and we subtract 2*offset-1=-1
            # If layout=F, current_layout is C and we add 2*offset-1=+1
            for p in system.particle:
                p.species = str(int(p.species) + 2 * offset - 1)
    return system
Example #21
0
def info(trajectory, keys=None):
    """Return a string with information about a `trajectory` instance."""
    from atooms.system.particle import distinct_species, composition
    system = trajectory[0]
    if keys is None:

        # Default: full info
        txt = ''
        txt += 'path                 = %s\n' % trajectory.filename
        txt += 'format               = %s\n' % trajectory.__class__
        txt += 'frames               = %s\n' % len(trajectory)
        txt += 'megabytes            = %s\n' % (
            os.path.getsize(trajectory.filename) / 1e6)
        txt += 'particles            = %s\n' % len(system.particle)
        txt += 'species              = %s\n' % ', '.join(
            distinct_species(system.particle))
        txt += 'composition          = %s\n' % dict(
            composition(system.particle))
        txt += 'size dispersion      = %s\n' % (
            numpy.std([p.radius for p in system.particle]) /
            numpy.mean([p.radius for p in system.particle]))
        txt += 'density              = %s\n' % round(system.density, 10)
        if system.cell is not None:
            txt += 'cell side            = %s\n' % str(list(
                system.cell.side))[1:-1]
            txt += 'cell volume          = %s\n' % system.cell.volume
        if len(trajectory) > 1:
            txt += 'steps                = %s\n' % trajectory.steps[-1]
            txt += 'duration             = %s\n' % trajectory.times[-1]
            txt += 'timestep             = %s\n' % trajectory.timestep
            txt += 'block size           = %s\n' % trajectory.block_size
            if trajectory.block_size == 1:
                txt += 'steps between frames = %s\n' % (trajectory.steps[1] -
                                                        trajectory.steps[0])
                txt += 'time between frames  = %s\n' % (trajectory.times[1] -
                                                        trajectory.times[0])
            else:
                txt += 'block steps          = %s\n' % trajectory.steps[
                    trajectory.block_size - 1]
                txt += 'block                = %s\n' % ([
                    trajectory.steps[i] for i in range(trajectory.block_size)
                ])
            txt += 'grandcanonical       = %s' % trajectory.grandcanonical
        return txt

    else:
        # Selected infos.
        # TODO: of course, it would be cleaner to have a little class for that
        outs = []
        for key in keys.split(','):
            if key == 'path':
                outs.append(trajectory.filename)
            elif key == 'format':
                outs.append(trajectory.__class__)
            elif key == 'frames':
                outs.append(len(trajectory))
            elif key == 'megabytes':
                outs.append(os.path.getsize(trajectory.filename) / 1e6)
            elif key == 'particles':
                outs.append(len(system.particle))
            elif key == 'species':
                outs.append(', '.join(distinct_species(system.particle)))
            elif key == 'composition':
                outs.append(dict(composition(system.particle)))
            elif key == 'cell density':
                outs.append(round(system.density, 10))
            elif key == 'cell side':
                outs.append(str(list(system.cell.side))[1:-1])
            elif key == 'cell volume':
                outs.append(system.cell.volume)
            elif key == 'steps':
                outs.append(trajectory.steps[-1])
            elif key == 'duration':
                outs.append(trajectory.times[-1])
            elif key == 'timestep':
                outs.append(trajectory.timestep)
            elif key == 'block size':
                outs.append(trajectory.block_size)
            elif key == 'steps between frames':
                outs.append(trajectory.steps[1] - trajectory.steps[0])
            elif key == 'time between frames':
                outs.append(trajectory.times[1] - trajectory.times[0])
            elif key == 'block steps':
                outs.append(trajectory.steps[trajectory.block_size - 1])
            elif key == 'block':
                outs.append([
                    trajectory.steps[i] for i in range(trajectory.block_size)
                ])
            elif key == 'grandcanonical':
                outs.append(trajectory.grandcanonical)

        txt = ''
        fmt = '%%-%ds : %%s\n' % (max([len(key) for key in keys.split(',')]))
        for key, out in zip(keys.split(','), outs):
            txt += fmt % (key, out)

        return txt.strip('\n')
Example #22
0
    def read_sample(self, frame):
        # Setup fields again, in case they have changed
        if self.__cache_fields != self.fields:
            self._setup_fields()
        # Read metadata of this frame
        meta = self._read_comment(frame)
        # Define read callbacks list before reading lines
        callbacks_read = []

        def _skip(p, data, meta):
            return data[1:]

        for key in self.fields:
            # If the key is associated to a explicit callback, go
            # for it. Otherwise we throw the field in an particle
            # attribute named key. If the key is None it means we skip
            # this column.
            if key is None:
                callbacks_read.append(_skip)
            elif key in self.callback_read:
                callbacks_read.append(self.callback_read[key])
            else:
                # Trick. We instantiate dynamically a fallback function
                # to avoid adding `key` to the other callbacks' interface
                namespace = {}
                exec(
                    """
from atooms.core.utils import tipify
def fallback(p, data, meta):
    p.__dict__['%s'] = tipify(data[0])
    return data[1:]
""" % key, namespace)
                callbacks_read.append(namespace['fallback'])

        # Read frame now
        self.trajectory.seek(self._index_frame[frame])
        particle = []
        for i in range(meta['npart']):
            p = Particle()
            # Note: we cannot optimize by shifting an index instead of
            # cropping lists all the time
            data = self.trajectory.readline().split()
            for cbk in callbacks_read:
                data = cbk(p, data, meta)
            particle.append(p)

        # Fix the masses.
        # We assume masses read from the header are sorted by species name.
        # The mass metadata must be adjusted to the given frame.
        if 'mass' in meta:
            if isinstance(meta['mass'], list) or isinstance(
                    meta['mass'], tuple):
                species = distinct_species(particle)
                # We must have as many mass entries as species
                if len(species) != len(meta['mass']):
                    raise ValueError('mass metadata issue %s, %s' %
                                     (species, meta['mass']))
                db = {}
                for key, value in zip(species, meta['mass']):
                    db[key] = value
                for p in particle:
                    p.mass = float(db[p.species])
            else:
                for p in particle:
                    p.mass = float(meta['mass'])

        # Add cell info
        if 'cell' in meta:
            cell = Cell(meta['cell'])
        else:
            cell = None

        return System(particle, cell)
Example #23
0
    def write_init(self, system):
        from atooms.system.particle import distinct_species
        self.trajectory.create_group_safe('/initialstate')
        self.trajectory['DIMENSIONS'] = [3]
        self.trajectory['NAME_SYS'] = [b'Unknown']
        self.trajectory['VERSION_TRJ'] = [b'1.2']
        self.trajectory['VERSION_MD'] = [b'X.X.X']

        # Particles
        group = '/initialstate/particle/'
        if system.particle is not None:
            self.trajectory.create_group_safe(group)
            particle = system.particle
            species = distinct_species(particle)
            particle_h5 = {
                'number_of_species': [len(species)],
                'number_of_particles': [len(particle)],
                'identity': [species.index(p.species) + 1 for p in particle],
                'element': [p.species.encode() for p in particle],
                'mass': [p.mass for p in particle],
                'radius': [p.radius for p in particle],
                'position': [p.position for p in particle],
                'velocity': [p.velocity for p in particle],
            }
            _write_datasets(self.trajectory, group, particle_h5)

        # Matrix
        group = '/initialstate/matrix/'
        if system.matrix is not None:
            self.trajectory.create_group_safe(group)
            matrix = system.matrix
            species = distinct_species(matrix)
            matrix_h5 = {
                'type': [b''],
                'id': [0],
                'number_of_species': [len(species)],
                'number_of_particles': [len(matrix)],
                'identity': [species.index(p.species) + 1 for p in matrix],
                'element': [p.species.encode() for p in matrix],
                'mass': [p.mass for p in matrix],
                'position': [p.position for p in matrix],
            }
            _write_datasets(self.trajectory, group, matrix_h5)

        # Cell
        group = '/initialstate/cell/'
        if system.cell is not None:
            self.trajectory.create_group_safe(group)
            self.trajectory[group + 'sidebox'] = system.cell.side

        # Thermostat
        group = '/initialstate/thermostat/'
        if system.thermostat is not None:
            self.trajectory.create_group_safe(group)
            self.trajectory[group +
                            'temperature'] = system.thermostat.temperature
            self.trajectory[group + 'type'] = system.thermostat.name
            self.trajectory[group + 'mass'] = system.thermostat.mass
            self.trajectory[
                group +
                'collision_period'] = system.thermostat.collision_period

        # Interaction
        if system.interaction is not None:
            if type(system.interaction) is list:
                raise TypeError('interaction must be list')
            self.trajectory.copy(system.interaction,
                                 '/initialstate/interaction/')