示例#1
0
    def test_sf_from_map(self):
        asu_atoms = sum(([atom for atom in residue] for residue in self.s), [])
        unit_cell_atom_data = []
        for tr in self.s.cs_transformations:
            for atom in asu_atoms:
                unit_cell_atom_data.append(
                    (atom, atom['element'], tr(atom['position']) * Units.Ang,
                     atom['temperature_factor'] * Units.Ang**2 /
                     (8. * N.pi**2), atom['occupancy']))

        hmax, kmax, lmax = self.reflections.maxHKL()
        density_map = ElectronDensityMap.fromUnitCellAtoms(
            self.reflections.cell, 4 * hmax, 4 * kmax, 4 * lmax,
            unit_cell_atom_data)

        sf_from_map = StructureFactor.fromElectronDensityMap(
            self.reflections, density_map)

        sf_from_unit_cell = StructureFactor.fromUnitCellAtoms(
            self.reflections, unit_cell_atom_data)

        self.assert_(sf_from_unit_cell.rFactor(sf_from_map) < 1.e-3)
        d = N.absolute(sf_from_unit_cell.array - sf_from_map.array)
        self.assert_(N.maximum.reduce(d) < 0.13)
        self.assert_(N.average(d) < 0.02)

        map_from_sf = ElectronDensityMap.fromStructureFactor(
            self.reflections.cell, 4 * hmax, 4 * kmax, 4 * lmax,
            sf_from_unit_cell)
        sf_from_test_map = StructureFactor.fromElectronDensityMap(
            self.reflections, map_from_sf)
        d = N.absolute(sf_from_unit_cell.array - sf_from_test_map.array)
        self.assert_(sf_from_unit_cell.rFactor(sf_from_test_map) < 1.e-15)
        self.assert_(N.maximum.reduce(d) < 1.e-13)
示例#2
0
    def test_sf_from_map(self):
        hmax, kmax, lmax = self.reflections.maxHKL()
        density_map = ElectronDensityMap.fromUniverse(self.reflections.cell,
                                                      4 * hmax, 4 * kmax,
                                                      4 * lmax, self.universe,
                                                      self.adps)

        sf_from_map = StructureFactor.fromElectronDensityMap(
            self.reflections, density_map)

        sf_from_universe = StructureFactor.fromUniverse(
            self.reflections, self.universe, self.adps)

        self.assert_(sf_from_universe.rFactor(sf_from_map) < 1.e-3)
        d = N.absolute(sf_from_universe.array - sf_from_map.array)
        self.assert_(N.maximum.reduce(d) < 0.13)
        self.assert_(N.average(d) < 0.02)

        map_from_sf = ElectronDensityMap.fromStructureFactor(
            self.reflections.cell, 4 * hmax, 4 * kmax, 4 * lmax,
            sf_from_universe)
        sf_from_test_map = StructureFactor.fromElectronDensityMap(
            self.reflections, map_from_sf)
        d = N.absolute(sf_from_universe.array - sf_from_test_map.array)
        self.assert_(sf_from_universe.rFactor(sf_from_test_map) < 1.e-15)
        self.assert_(N.maximum.reduce(d) < 1.e-13)
示例#3
0
 def test_P31(self):
     cell = UnitCell(3., 3., 4.,
                     90.*Units.deg, 90.*Units.deg, 120.*Units.deg)
     res_max = 0.5
     res_min = 10.
     reflections = ReflectionSet(cell, space_groups['P 31'],
                                 res_max, res_min)
     sf = StructureFactor(reflections)
     value = 1.1-0.8j
     for r in reflections:
         for re in r.symmetryEquivalents():
             sf[re] = value
             self.assert_(N.absolute(sf[re]-value) < 1.e-14)
             ri = reflections[(-re.h, -re.k, -re.l)]
             self.assert_(N.absolute(sf[ri]-N.conjugate(value)) < 1.e-13)
示例#4
0
    def test_hdf5(self):
        with HDF5Store('test.h5', 'w') as store:
            store.store('test/exp_amplitudes', self.exp_amplitudes)
            retrieved = store.retrieve('test/exp_amplitudes')
            store.flush() # just for testing flush()
            store.store('test/model_sf', self.model_sf)
            store.store('test/model_intensities', self.model_sf.intensities())

        self.assert_(retrieved is not self.exp_amplitudes)

        with HDF5Store('test.h5') as store:
            exp_amplitudes = store.retrieve('test/exp_amplitudes')
            model_sf = store.retrieve('test/model_sf')
            model_intensities = store.retrieve('test/model_intensities')

        self.assert_(exp_amplitudes.reflection_set is model_sf.reflection_set)
        self.assert_(exp_amplitudes.reflection_set is model_intensities.reflection_set)
        self.assertAlmostEqual(exp_amplitudes.rFactor(model_sf),
                               self.exp_amplitudes.rFactor(self.model_sf), 5)
        rs = exp_amplitudes.reflection_set
        ea = self.exp_amplitudes.resample(rs)
        sf = self.model_sf.resample(rs)
        mi = sf.intensities()
        self.assert_(N.absolute(sf.array-model_sf.array).max() < 1.e-5)
        self.assert_(N.fabs(ea.array-exp_amplitudes.array).max() < 1.e-5)
        self.assert_(N.fabs(mi.array-model_intensities.array).max() < 3.e-4)
示例#5
0
def largestAbsoluteElement(a):
    """
    :param a: a numerical array
    :type a: Scientific.N.array_type
    :return: the largest absolute value over all array elements
    :rtype: float
    """
    return N.maximum.reduce(N.absolute(N.ravel(a)))
示例#6
0
 def _calculateModelAmplitudes(self):
     # Calculate the structure factor amplitudes for the model using the
     # current parameters.
     sf = N.zeros(self.ssq.shape, N.Complex)
     self._evaluateModel(sf, None, None, None)
     self.structure_factor = sf
     self.model_amplitudes = N.absolute(sf)
     self.working_model_amplitudes = \
             N.repeat(self.model_amplitudes, self.working_set)
     self.validation_model_amplitudes = \
             N.repeat(self.model_amplitudes, self.validation_set)
示例#7
0
 def test_symmetry_ops(self):
     for params, rb, sg in datasets:
         cell = UnitCell(*params)
         sg = space_groups[sg]
         transformations = cartesianCoordinateSymmetryTransformations(cell, sg)
         for t in transformations:
             # Check that the transformation is a rotation-translation.
             error = N.absolute(N.multiply.reduce(t.tensor.eigenvalues())-1.)
             self.assert_(error < 1.e-12)
             # Check that applying the transformation N times (where N is
             # the number of symmetry operations) yields a transformation
             # without rotation.
             ntimes = t
             for i in range(1, len(sg)):
                 ntimes = ntimes*t
             self.assert_(largestAbsoluteElement(
                            (ntimes.tensor-delta).array) < 1.e-12)
示例#8
0
    def internalRun(self):
        """Runs the analysis."""
        
        self.chrono = default_timer()

        orderedAtoms = sorted(self.universe.atomList(), key = operator.attrgetter('index'))

        selectedAtoms = Collection([orderedAtoms[ind] for ind in self.subset])
                
        M1_2 = N.zeros((3*self.nSelectedAtoms,), N.Float)
        
        weightList = [N.sqrt(el[1]) for el in sorted([(at.index, at.mass()) for at in selectedAtoms])]
        
        for i in range(len(weightList)):
            M1_2[3*i:3*(i+1)] = weightList[i]
            
        invM1_2 = (1.0/M1_2)*N.identity(3*self.nSelectedAtoms, typecode = N.Float)
            
        # The initial structure configuration.
        initialStructure = self.trajectory.configuration[self.first]

        averageStructure = ParticleVector(self.universe)

        for conf in self.trajectory.configuration[self.first:self.last:self.skip]:
            averageStructure += self.universe.configurationDifference(initialStructure, conf)

        averageStructure = averageStructure/self.nFrames
        averageStructure = initialStructure + averageStructure        
        
        mdr  = N.zeros((self.nFrames, 3*self.nSelectedAtoms), N.Float)
        
        # Calculate the fluctuation matrix.
        sigmaPrim = N.zeros((3*self.nSelectedAtoms, 3*self.nSelectedAtoms), N.Float)
        comp = 0
        for conf in self.trajectory.configuration[self.first:self.last:self.skip]:
            mdr[comp,:] = M1_2*N.ravel(N.compress(self.mask,(conf-averageStructure).array,0)) 
            sigmaPrim += mdr[comp,:, N.NewAxis] * mdr[N.NewAxis, comp, :]            
            comp += 1
                        
        sigmaPrim = sigmaPrim/float(self.nFrames)

        try:
            # Calculate the quasiharmonic modes
            omega, dx = Heigenvectors(sigmaPrim)
            
        except MemoryError:
            raise Error('Not enough memory to diagonalize the %sx%s fluctuation matrix.' % sigmaPrim.shape)
            
        # Due to numerical imprecisions, the result can have imaginary parts.
        # In that case, throw the imaginary parts away.
        # Conversion from uma*nm2 to kg*m2 (SI)
        omega = omega.real/(Units.kg*Units.m**2)        
        omega = (Units.Hz/Units.invcm)*N.sqrt((Units.k_B*Units.K*self.temperature/Units.J)*(1.0/omega))

        dx = dx.real
        dx = N.dot(invM1_2, dx)

        # Sort eigen vectors by decreasing fluctuation amplitude.
        indices = N.argsort(omega)[::-1]
        
        omega = N.take(omega, indices)
        dx = N.take(dx, indices)

        # Eq 66 of the reference paper.
        mdr = N.take(mdr, indices, axis = 1)
        at = N.dot(mdr,N.transpose(dx))
        
        # The NetCDF output file is opened.
        outputFile       = NetCDFFile(self.output, 'w')
        outputFile.title = self.__class__.__name__
        outputFile.jobinfo = self.information + '\nOutput file written on: %s\n\n' % asctime()

        # The universe is emptied from its objects keeping just its topology.
        self.universe.removeObject(self.universe.objectList()[:])
        # The atoms of the subset are copied
        atoms = copy.deepcopy(selectedAtoms.atomList())
        
        # And their parent attribute removed to allow their transfer in the empty universe.
        for a in atoms:
            a.parent = None
        ac = AtomCluster(atoms,name='QHACluster')
        self.universe.addObject(ac)

        # Some dimensions are created.
        # NEIVALS = the number eigen values
        outputFile.createDimension('NEIGENVALS', len(omega))

        # UDESCR = the universe description length
        outputFile.createDimension('UDESCR', len(self.universe.description()))

        # NATOMS = the number of atoms of the universe
        outputFile.createDimension('NATOMS', self.nSelectedAtoms)

        # NFRAMES = the number of frames.
        outputFile.createDimension('NFRAMES', self.nFrames)

        # NCOORDS = the number of coordinates (always = 3).
        outputFile.createDimension('NCOORDS', 3)

        # 3N.
        outputFile.createDimension('3N', 3*self.nSelectedAtoms)

        if self.universe.cellParameters() is not None:
            outputFile.createDimension('BOXDIM', len(self.universe.cellParameters()))

        # Creation of the NetCDF output variables.
        # EIVALS = the eigen values.
        OMEGA = outputFile.createVariable('omega', N.Float, ('NEIGENVALS',))
        OMEGA[:] = omega

        # EIVECS = array of eigen vectors.
        DX = outputFile.createVariable('dx', N.Float, ('NEIGENVALS','NEIGENVALS'))
        DX[:,:] = dx

        # The time.
        TIMES = outputFile.createVariable('time', N.Float, ('NFRAMES',))
        TIMES[:] = self.times[:]
        TIMES.units = 'ps'

        # MODE = the mode number.
        MODE = outputFile.createVariable('mode', N.Float, ('3N',))
        MODE[:] = 1 + N.arange(3*self.nSelectedAtoms)
                
        # LCI = local character indicator. See eq 56.
        LCI = outputFile.createVariable('local_character_indicator', N.Float, ('3N',))
        LCI[:] = (dx**4).sum(0)
        
        # GCI = global character indicator. See eq 57.
        GCI = outputFile.createVariable('global_character_indicator', N.Float, ('3N',))
        GCI[:] = (N.sqrt(3.0*self.nSelectedAtoms)/(N.absolute(dx)).sum(0))**4

        # Projection of MD traj onto normal modes. See eq 66..
        AT = outputFile.createVariable('at', N.Float, ('NFRAMES','3N'))
        AT[:,:] = at[:,:]
        
        # DESCRIPTION = the universe description.
        DESCRIPTION = outputFile.createVariable('description', N.Character, ('UDESCR',))
        DESCRIPTION[:] = self.universe.description()

        # AVGSTRUCT = the average structure.
        AVGSTRUCT = outputFile.createVariable('avgstruct', N.Float, ('NATOMS','NCOORDS'))
        AVGSTRUCT[:,:] = N.compress(self.mask,averageStructure.array,0)

        # If the universe is periodic, create an extra variable storing the box size.
        if self.universe.cellParameters() is not None:
            BOXSIZE = outputFile.createVariable('box_size', N.Float, ('BOXDIM',))
            BOXSIZE[:] = self.universe.cellParameters()

        outputFile.close()

        self.toPlot = None

        self.chrono = default_timer() - self.chrono
        
        return None