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)
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)
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)
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)
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)))
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)
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)
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