def __load_datasheet__(self, path): # open file try: fd = open(path,'r') except: raise Logger.error("Couldn't open analysis file %r." %path) # read keys firstLine = fd.readline() fd.close() try: keys = [key.strip() for key in firstLine.split('#')[1].split(';')] except: raise Logger.error("Couldn't read the 'first line' from analysis datasheet file %r first line." %path) # read values try: values = np.loadtxt(path, delimiter = ";") except: raise Logger.error("Couldn't read the 'data' from analysis datasheet file %r." %path) # test size if values.shape[1] != len(keys): raise Logger.error("values and keys length doesn't match, datasheet file %r seems corrupted." %path) # update results for idx in range(len(keys)): key = keys[idx] if key in self.results: Logger.warn("analysis name %r already exists. Previous values will be erased and updated with the new ones" %key) self.results[key] = values[:,idx]
def __load_binary__(self, path): # open file try: fd = open(path,'r') except: raise Logger.error("Couldn't open analysis binary file %r." %path) # read file try: resDict = pickle.load(fd) except: fd.close() raise Logger.error("Couldn't read analysis binary file data %r." %path) else: fd.close() for key, values in resDict.items(): if key in self.results: Logger.warn("analysis name %r already exists. Previous values will be erased and updated with the new ones" %key) self.results[key] = values
def plot(self, x, y): """ Simple plotting tool to visualize the analysis data.\n for this function matplotlib must be installed :Parameters: #. x (key, numpy.array): a key from self.results or a numpy.array that will be x-axis of the plot #. y (key, numpy.array): a key from self.results or a numpy.array that will be the y-axis of the plot """ try: import matplotlib.pyplot as plt except: Logger.warn("matplotlib is not installed. Plotting cannot be proceeded") return if isinstance(x, str): assert x in self.results xLabel = x x = self.results[x] else: assert isinstance(x, (list, tuple, np.ndarray)) xLabel = "x" if isinstance(y, str): assert y in self.results yLabel = y y = self.results[y] else: assert isinstance(y, (list, tuple, np.ndarray)) yLabel = "y" xData = np.array(x) yData = np.array(y) assert xData.shape == yData.shape # plot plt.plot(xData,yData) plt.xlabel(xLabel) plt.ylabel(yLabel) plt.legend() plt.show()
def __load_ascii__(self, path): tempDir = tempfile.gettempdir() # create temp dir tempDir = os.path.join(tempDir,"pdbparserTmpDir") if not os.path.exists(tempDir): try: os.makedirs(tempDir) except: raise Logger.error("Couldn't create temporary folder %r to extract data" %tempDir) # open zipfile try: zf = zipfile.ZipFile(path, 'r') except: raise Logger.error("Couldn't open analysis ascii zip file %r." %path) # get files names and extract them all to tempDir files = zf.namelist() zf.extractall(tempDir) # read analysis files data for file in files: if os.path.basename(file) in self.results: Logger.warn("analysis name %r already exists. Previous values will be erased and updated with the new ones" %file) self.results[os.path.basename(file)] = np.loadtxt(os.path.join(tempDir,file))
def __initialize_variables__(self, grouping, bondLength, thresholdTime, bin, toleranceShells, toleranceTime, bondAngleLimits, belowAngleToleranceTime, bondStartAtCore, bondStartWithinAngle, smoothHfJumps): # set grouping if grouping is not None: assert isinstance( grouping, str), Logger.error("grouping must be a string convertible") grouping = str(grouping).lower() assert grouping in self.structure[0].keys(), Logger.error( "grouping must be a pdbparser record key") self.grouping = grouping if self.grouping is None: self.groups = self.structure.indexes else: self.groups = [ rec[self.grouping] for rec in self.structure.records ] self.hydrogenAtomsGroup = [ self.groups[idx] for idx in self.hydrogenAtomsIndexes ] self.acceptorAtomsGroup = [ self.groups[idx] for idx in self.acceptorAtomsIndexes ] # set bondLength try: bondLength = float(bondLength) except: raise Logger.error("bondLength must be positive number") assert bondLength > 0.5, Logger.error( "bondLength must be bigger than 0.5") self.bondLength = bondLength # set thresholdTime try: thresholdTime = float(thresholdTime) except: raise Logger.error("thresholdTime must be a number") assert bondLength >= 0, Logger.error( "thresholdTime must be a positive number") self.thresholdTime = thresholdTime # set bondAngleLimits assert isinstance( bondAngleLimits, (list, set, tuple)), Logger.error("bondAngleLimits must be a lists") assert len(bondAngleLimits) == 2, Logger.error( "bondAngleLimits must be a list of 2 items") try: bondAngleLimits = sorted( [float(bondAngleLimits[0]), float(bondAngleLimits[1])]) except: raise Logger.error( "bondAngleLimits must be a list of positive 2 floats") assert bondAngleLimits[0] >= 0, Logger.error( "bondAngleLimits items must be a positive number") assert bondAngleLimits[1] <= 180, Logger.error( "bondAngleLimits items must be smaller than 180") self.bondAngleLimits = bondAngleLimits # set belowAngleToleranceTime try: belowAngleToleranceTime = float(belowAngleToleranceTime) except: raise Logger.error("belowAngleToleranceTime must be a number") assert belowAngleToleranceTime > 0, Logger.error( "bondAngleLimits must be bigger than 0") self.belowAngleToleranceTime = belowAngleToleranceTime # set tolerance shells and time if toleranceShells is None: toleranceShells = [] toleranceTime = [] else: assert isinstance( toleranceShells, (list, set, tuple)), Logger.error( "toleranceShells must be a list of positive floats") assert isinstance(toleranceTime, (list, set, tuple)), Logger.error( "toleranceTime must be a list of positive floats") toleranceShells = list(toleranceShells) toleranceTime = list(toleranceTime) assert len(toleranceShells) == len(toleranceTime), Logger.error( "toleranceShells and toleranceTime list must have the same number of items" ) try: toleranceShells = [float(item) for item in toleranceShells] except: raise Logger.error( "toleranceShells must be a list of float positive numbers") try: toleranceTime = [float(item) for item in toleranceTime] except: raise Logger.error("toleranceTime must be a list of numbers") assert len(toleranceShells) == sum( [1 for item in toleranceShells if item >= 0]), Logger.error( "toleranceShells must be a list of float positive numbers") assert len(toleranceTime) == sum( [1 for item in toleranceTime if item >= 0]), Logger.error( "toleranceTime must be a list of float positive numbers") self.toleranceShells = [] self.toleranceTime = [] for idx in range(len(toleranceShells)): if toleranceShells[idx] > 0 and toleranceTime[idx] > 0: self.toleranceShells.append(toleranceShells[idx]) self.toleranceTime.append(toleranceTime[idx]) self.hbondAllShells = [self.bondLength] self.hbondAllShells.extend(self.toleranceShells) self.hbondAllShellsTime = [np.Inf] self.hbondAllShellsTime.extend(self.toleranceTime) self.cumsumhbondAllShells = np.cumsum(self.hbondAllShells) self.cumsumToleranceShells = np.cumsum(self.toleranceShells) self.totalToleranceThichness = self.bondLength + sum( self.toleranceShells) # bondStartAtCore assert isinstance( bondStartAtCore, bool), Logger.error("bondStartAtCore must be boolean") self.bondStartAtCore = bondStartAtCore # bondStartWithinAngle assert isinstance( bondStartWithinAngle, bool), Logger.error("bondStartWithinAngle must be boolean") self.bondStartWithinAngle = bondStartWithinAngle # smoothHfJumps assert isinstance(smoothHfJumps, bool), Logger.error("smoothHfJumps must be boolean") self.smoothHfJumps = smoothHfJumps # set bin try: bin = float(bin) except: raise Logger.error("bin must be positive number") assert bin > 0, Logger.error("bin must be non-zero positive number") assert bin <= 1, Logger.error("bin must be smaller than 1 Angstrom") self.bin = bin self.bins = np.arange(0, self.totalToleranceThichness + self.bin, self.bin) # check selections self.elements = self._trajectory.elements for idx in self.donorsAtomsIndexes: if self.elements[idx].lower() not in ('o', 'n', 'f'): Logger.warn( "donorsAtomsIndexes index '%s' is found to be '%s' instead of an oxygen 'o' or nitrogen 'n' or fluorine 'f'" % (idx, self.elements[idx].lower())) for idx in self.hydrogenAtomsIndexes: if self.elements[idx].lower() != "h": Logger.warn( "hydrogenAtomsIndexes index '%s' is found to be '%s' instead of a hydrogen 'h'" % (idx, self.elements[idx].lower())) for idx in self.acceptorAtomsIndexes: if self.elements[idx].lower() not in ('o', 'n', 'f'): Logger.warn( "acceptorAtomsIndexes index '%s' is found to be '%s' instead of an oxygen 'o' or nitrogen 'n' or fluorine 'f'" % (idx, self.elements[idx].lower())) # needed variables for analysis self.bondsDistances = -1 * np.ones( (len(self.hydrogenAtomsIndexes), len(self.time)), dtype=np.float) self.bondsAngles = -1 * np.ones( (len(self.hydrogenAtomsIndexes), len(self.time)), dtype=np.float) self.acceptorsIndex = -1 * np.ones( (len(self.hydrogenAtomsIndexes), len(self.time)), dtype=np.long)
def __convert_charmm__(self): # create new trajectory instance traj = pdbTrajectory() # set structure traj.set_structure(self.pdb) # Open the DCD trajectory file for reading. dcd = DCDFile(self.dcd) # set boundary conditions if dcd.has_pbc_data: traj._boundaryConditions = PeriodicBoundaries() else: traj._boundaryConditions = InfiniteBoundaries() # set indexes if self.indexes is None: self.indexes = range(dcd.numberOfConfigurations) elif self.indexes[-1] >= dcd.numberOfConfigurations: Logger.warn( "Some of the given indexes exceed '%s' which is the number of configurations in dcd file" % dcd.numberOfConfigurations) self.indexes = [ index for index in self.indexes if index < dcd.numberOfConfigurations ] # check number of atoms in dcd and structure assert dcd.natoms == traj.numberOfAtoms, Logger.error( "pdb file and dcd file must have the same number of atoms") # The starting step number. step = dcd.istart # The step increment. stepIncrement = dcd.nsavc # The MD time steps round it to 6 decimals to avoid noise. dt = np.around(dcd.delta, 6) # store trajectory info info = {} info["software"] = 'charmm' info["software_version"] = dcd.charmmVersion traj._info = info # The cell parameters a, b, c, alpha, beta and gamma (stored in |unit_cell|) # and the x, y and z values of the first frame. # log conversion start self.status(0, dcd.fileSize) confIdx = -1 while self.indexes: confIdx += 1 if isinstance(self.indexes, list): idx = self.indexes.pop(0) else: idx = confIdx # check configuration number while confIdx < idx: try: dcd.skip_step() except: Logger.warn( "file reading ended unexpectedly. Trajectory conversion stopped. all recorded data are still valid" ) break confIdx += 1 # read step try: unit_cell, x, y, z = dcd.read_step() except: Logger.warn( "file reading ended unexpectedly. Trajectory conversion stopped. all recorded data are still valid" ) break # append coordinates traj._coordinates.append(np.transpose([x, y, z])) # append boundary conditions if dcd.has_pbc_data: traj._boundaryConditions.set_vectors( self.__unit_cell_to_basis_vectors__(*unit_cell)) else: traj._boundaryConditions.set_vectors() # append time traj._time.append(confIdx * stepIncrement * dt) # log status self.status(dcd.currentPosition, dcd.fileSize) return traj