def setupPyroServer(): import Pyro.errors import Pyro.naming # Gets a PyRO proxy for the name server. locator = Pyro.naming.NameServerLocator() # Try to get an existing name server. try: LogMessage('info', 'Searching for a Pyro Name server. Please wait ...', ['console']) ns = locator.getNS() LogMessage('info', 'A Pyro Name server was found on your machine. nMOLDYN will use it.', ['console']) return None # Otherwise, start a new one. except Pyro.errors.NamingError: LogMessage('info', 'No Pyro Name server found on your machine.', ['console']) LogMessage('info', 'Setting a new Pyro Name server. Please wait ...', ['console']) s = subprocess.Popen([sys.executable, '-O', '-c', "import Pyro.naming; Pyro.naming.main([])"], stdout = subprocess.PIPE) ns = None while ns is None: try: ns = locator.getNS() except Pyro.errors.NamingError: pass LogMessage('info', 'Pyro Name server ready.', ['console']) return s
def testAnalysis(option, opt_str, value, parser): """ """ if len(parser.rargs) == 0: raise Error('No arguments for %s option.' % option) if 'ALL' in parser.rargs: selectedTests = availableTests else: selectedTests = parser.rargs for n in selectedTests: try: t = eval(n.strip().upper() + 'Tests()') except NameError: LogMessage('error', '%s test is not a valid analysis benchmark name.' % n, ['console']) else: try: t.run() except: raise Error('An error occured when running %s test.' % n) else: LogMessage('info', t.summary, ['console']) sys.exit(0)
def downloadVersion(version): """Fetch the requested version of nMOLDYN from the nMOLDYN server. """ # Find automatically the proxies if some are defined. httpProxy = urllib2.getproxies() # The requests will go through the http proxy. proxy = urllib2.ProxyHandler(httpProxy) # Open the connection possibly through the proxy.. opener = urllib2.build_opener(proxy) if PLATFORM == 'WINDOWS': filename = 'nMOLDYN-%s.exe' % version # Case of Linux. else: filename = 'nMOLDYN-%s.zip' % version url = 'http://dirac.cnrs-orleans.fr/~nmoldyn/' + filename dest_filename = os.path.join(PREFERENCES['outputfile_path'], filename) try: fileReq = urllib2.Request(url) src = opener.open(fileReq) except urllib2.URLError: LogMessage('warning', 'Could not open the url %s.' % url, ['console', 'gui']) else: try: dst = open(dest_filename, 'w') except IOError: LogMessage( 'warning', 'Can not open the file %s for writing. Maybe a permission problem.' % dest_filename, ['console', 'gui']) return else: LogMessage('info', 'Downloading %s file. Please wait ...' % filename, ['console']) shutil.copyfileobj(src, dst) dst.close() LogMessage( 'info', '%s file successfully downloaded in %s' % (filename, dest_filename), ['console']) opener.close()
def validate(self): if not self.trajectory: raise Error('No MMTK trajectory file loaded for animation.') if self.trajectory != self.fileBrowser.getValue(): raise Error( 'Mismatch between the loaded trajectory and the displayed MMTK trajectory file name.\ You should validate that file by pressing Return on its corresponding entry.') self.viewableAtoms = self.trajectory.universe.atomsWithDefinedPositions( ) if not self.firstStepEntry.getValue(): self.first = 0 LogMessage( 'warning', 'First frame undefined. Frame 1 will be taken by default.', ['gui']) else: self.first = self.firstStepEntry.getValue() - 1 if self.first < 0: raise Error('First frame not within [1,%d].' % len(self.trajectory)) if not self.lastStepEntry.getValue(): self.last = 1 LogMessage( 'warning', 'Last frame undefined. Frame 1 will be taken by default.', ['gui']) else: self.last = self.lastStepEntry.getValue() if self.last > len(self.trajectory): raise Error('Last frame not within [1,%d].' % len(self.trajectory)) if not self.skipStepEntry.getValue(): self.skip = 1 LogMessage('warning', 'Frame skip undefined. 1 will be taken by default.', ['gui']) else: self.skip = self.skipStepEntry.getValue() if (self.skip < 1) or (self.skip >= len(self.trajectory)): raise Error('Last frame not within [1,%d[.' % len(self.trajectory)) return True
def _display_qvectors(self): LogMessage("info", "Q shells contents:", ["file"]) for comp in range(len(self.qRadii)): LogMessage( "info", "Q = %8.3f h k l qx qy qz" % self.qRadii[comp], ["file"]) for comp1 in range(len(self.qVectors[comp])): LogMessage( "info", " %3d %3d %3d %8.3f %8.3f %8.3f" % tuple( list(self.hkls[comp][comp1]) + list(self.qVectors[comp][comp1])), ["file"]) LogMessage("info", "", ["file"])
def interpreteInputParameters(self): """Parse the input parameters for the analysis. """ # Parses the parameters that are common to different analysis. Analysis.interpreteInputParameters(self) self.buildTimeInfo() if (self.referenceFrame < 0) or (self.referenceFrame > len( self.trajectory)): self.referenceFrame = 0 LogMessage( 'warning', 'The reference frame must be an integer in [1,%s].\n\ It will be set to 1 for the running analysis.' % len(self.trajectory), ['console']) self.group = self.selectGroups(self.groupDefinition) self.nGroups = len(self.group) self.groupsSize = [len(g) for g in self.group] if self.architecture != 'monoprocessor': # The attribute trajectory is removed because it can not be pickled by Pyro. delattr(self, 'trajectory')
def startSlaves(taskName, architecture, numberOfProcs): """Starts the slaves. @param architecture: the type of pyro server. One of 'multiprocessor' or 'cluster'. @type architecture: string. @param numberOfProcs: the number of procs allocated for the analysis. @type numberOfProcs: int. """ # Case of an analysis launched only on localhost. if architecture == 'multiprocessor': script = os.path.abspath(os.path.join(GVAR['nmoldyn_path'], 'Analysis', 'Slave.py')) for comp in range(numberOfProcs): subprocess.Popen([sys.executable, script, taskName]) elif architecture == 'cluster': LogMessage('warning', "\nThe analysis will be run in cluster mode. \n\n\ The analysis will not be run right now. To do so, you have to:\n\n\ 1) log in on one or several remote machine on which the analysis should be dispatched\n\ 2) enter:\n\ \ttask_manager slave %s \n\n\ once per process to be run on the remote machine." % taskName, ['gui', 'console'])
def _explicit_qvectors(self, qMin, qMax, indRange): qVects = [] hkls = [] dimen = len(self.qDirections) for ind in indRange: qVect = Vector() for i in range(dimen): qVect += ind[i] * self.qDirections[i] if qMin < qVect.length() <= qMax: if not qVect in qVects: qVects.append(qVect) hkl = Vector([0, 0, 0]) for i in range(dimen): hkl += ind[i] * self.hkl_dir[i] hkls.append(hkl) if len(qVects) >= self.qVectorsPerShell: break LogMessage( 'info', '%d explicit Q vectors generated for shell [%s,%s].' % (len(qVects), qMin, qMax), ['file', 'console']) return qVects, hkls
def __init__(self, extra=None): """ The constructor. @param message: the error message. @type message: string """ # Store the information about the most recent exception caught by an except if any. self.type, self.value, self.traceback = sys.exc_info() # Store the extra message provided by the usert. self.extra = extra # The default handlers on which the error will be displayed. self.handlers = ['file', 'console'] msg = "\n" * 2 + "!" * 90 + "\n" msg += "\nnMOLDYN ERROR\n\n" if self.type is not None: msg += "\n\t".join( traceback.format_exception(self.type, self.value, self.traceback)) if self.extra is not None: msg += "\nAdditional message:\n\t%s\n" % self.extra msg += '\nPlease look in the log file for more details.' msg += "\n\n" + "!" * 90 # Send the error message into the selected handlers. LogMessage('error', msg, self.handlers)
def apply(self): """ This method is called when the user clicks on the OK button of the conversion dialog. It performs the conversion from the loaded NetCDF file to the selected ASCII file. """ convertASCIIToNetCDF(self.inputFile, self.outputFile) LogMessage('info', 'Conversion successful', ['gui'])
def validate(self): if not self.trajectory: raise Error('No MMTK trajectory file loaded for extraction.') if self.trajectory.filename != self.fileBrowser.getValue(): raise Error( 'Mismatch between the loaded trajectory and the displayed MMTK trajectory file name.\ You should validate that file by pressing Return on its corresponding entry.') # A frame selection must have been set. if not self.selectedStepEntry.getValue(): self.selectedFrames = '1' LogMessage( 'warning', 'No frame selected. Frame 1 will be extracted by default.', ['gui']) else: self.selectedFrames = self.selectedStepEntry.getValue().strip() try: self.selectedFrames = eval(self.selectedFrames) # The entry can be an integer. if isinstance(self.selectedFrames, int): self.selectedFrames = [self.selectedFrames] # The entry can be a list or a tuple. elif isinstance(self.selectedFrames, (list, tuple)): pass except: try: temp = [] self.selectedFrames = [ temp.extend(range(int(v[0]), int(v[1]) + 1, int(v[2]))) for v in re.findall('(\d+):(\d+):(\d+)', self.selectedFrames) ] self.selectedFrames = temp except: raise Error('Wrong format for frame selection.') # Check that every selected step is valid. for s in self.selectedFrames: if not isinstance(s, int): raise Error('Wrong entry for frame selection.') if (s <= 0) or (s > len(self.trajectory)): raise Error( 'Some selected frame number are not within [1,%d].' % len(self.trajectory)) # A PDB output file name must have been set. self.pdbFile = self.pdbFileBrowser.getValue() if not self.pdbFile: raise Error('Please enter a PDB output file.') return True
def set_pref_from_command_line(option, opt_str, value, parser): """This function will change the selected PREFERENCES variables with the value given in command-line. """ PREFERENCES[option.dest] = value LogMessage( 'info', 'Preferences variable "%s" changed to %s' % (option.dest, value), ["console", "file"])
def getCPUInfo(): """Sets the total numbers of processors, the number of loaded and free processors on the host machine or on the different nodes of a cluster. """ cpuInfo = None # Pyro server in cluster mode implemented only for linux platform. if PLATFORM == 'LINUX': nProcs = file('/proc/cpuinfo', 'r').read().count('processor\t:') nLoadedProcs = min(nProcs, int(os.getloadavg()[1] + 0.5)) nFreeProcs = max(0, nProcs - nLoadedProcs) elif PLATFORM == 'DARWIN': try: nProcs = int( subprocess.Popen(['/usr/sbin/sysctl', '-n', 'hw.ncpu'], stdout=subprocess.PIPE).stdout.read()) except: nProcs = 1 nLoadedProcs = min(nProcs, int(os.getloadavg()[1] + 0.5)) nFreeProcs = max(0, nProcs - nLoadedProcs) hostname = subprocess.Popen(['/bin/hostname'], stdout=subprocess.PIPE).stdout.read() elif PLATFORM == 'WINDOWS': try: from win32com.client import GetObject nProcs = 0 loadAvg = 0.0 wmi = GetObject('winmgmts:') cpu = wmi.InstancesOf('Win32_Processor') for c in cpu: nProcs += c.Properties_('NumberOfCores').Value loadAvg += c.Properties_('LoadPercentage').Value loadAvg /= nProcs nLoadedProcs = int(nProcs * loadAvg / 100.0) nFreeProcs = max(0, nProcs - nLoadedProcs) except: LogMessage( 'warning', 'You do not have the priviledge to perform win32 calls.\n\ nMOLDYN can not define the actual number of loaded processors.', ['gui', 'console']) nProcs = nFreeProcs = int(os.environ['NUMBER_OF_PROCESSORS']) nLoadedProcs = 0 cpuInfo = (nProcs, nLoadedProcs, nFreeProcs) return cpuInfo
def interpreteInputParameters(self): """Parse the input parameters for the analysis. """ # Parses the parameters that are common to different analysis. Analysis.interpreteInputParameters(self) self.buildTimeInfo() if (self.referenceFrame < 0) or (self.referenceFrame > len( self.trajectory)): self.referenceFrame = 0 LogMessage( 'warning', 'The reference frame must be an integer in [1,%s].\n\ It will be set to 1 for the running analysis.' % len(self.trajectory), ['console']) # The 'wignerindexes' input parameter. It must be string of the form j,m,n where j, m and n are the Wigner # indexes. if isinstance(self.parameters['wignerindexes'], str): # Must be a string of three comma-separated integers. try: j, m, n = [ int(v) for v in self.parameters['wignerindexes'].split(',') ] except: raise Error( 'Error when parsing "wignerindexes" parameter: must be a string of the form "j,m,n".' ) else: if j < 0: raise Error( 'Error when parsing "wignerindexes" parameter: j must be >= 0.' ) if m > j: raise Error( 'Error when parsing "wignerindexes" parameter: m must be <= j.' ) if abs(n) > m: raise Error( 'Error when parsing "wignerindexes" parameter: n must be <= n.' ) self.wignerIndexes = (j, m, n) self.group = self.selectGroups(self.groupDefinition) self.nGroups = len(self.group) if self.architecture != 'monoprocessor': # The attribute trajectory is removed because it can not be pickled by Pyro. delattr(self, 'trajectory')
def checkForUpdate(option, opt_str, value, parser): newVersion = checkForNewVersion() if newVersion is not None: LogMessage('info', 'nMOLDYN %s is available.' % newVersion, ['console']) downloadIt = '' while not downloadIt in ['y', 'yes', 'n', 'no']: LogMessage('info', 'Do you want to download it ? [y]es|[n]o', ['console']) downloadIt = raw_input().strip().lower() if downloadIt in ['y', 'yes']: downloadVersion(newVersion) sys.exit(0)
def apply(self): """ This method is called when the user clicks on the OK button of the conversion dialog. It performs the conversion from the loaded NetCDF file to the selected ASCII/CDL file. """ convertNetCDFToASCII(inputFile = self.inputFile,\ outputFile = self.outputFile,\ variables = self.selectedVariables,\ floatPrecision = self.floatPrecision,\ doublePrecision = self.doublePrecision) LogMessage('info', 'Conversion successful', ['gui'])
def runTest(self): # Some information about the test to run are displayed in the console and file loggers. LogMessage('info', 'ANALYSIS: %s --- TEST No: %s' % (self.longName, self.id), ['console', 'file']) subprocess.call([ sys.executable, GVAR['pmoldyn_path'], self.pMoldynArg, "--input", os.path.join(self.testPath, self.shortName + "%s_Reference.py" % self.id) ]) subprocess.call([ sys.executable, os.path.join(self.testPath, self.shortName + "%d_Current.py" % self.id) ]) refFileName = os.path.join(TEMP_DIR, self.shortName + "_Reference.nc") curFileName = os.path.join(TEMP_DIR, self.shortName + "_Current.nc") refFile = NetCDFFile(refFileName, 'r') curFile = NetCDFFile(curFileName, 'r') for key, val in refFile.variables.items(): if val.typecode() != 'c': if not curFile.variables.has_key(key): continue refValue = val.getValue() curValue = curFile.variables[key].getValue() # Their difference is computed. errorMax = max(abs(N.ravel(refValue - curValue))) self.errors[key] = errorMax # Throws an assertion error if the difference is bigger than 1.0E-6. self.assertAlmostEqual(errorMax, 0.0, 6) curFile.close() refFile.close() try: os.remove(refFileName) os.remove(curFileName) except: pass
def runAnalysis(self): """Runs the analysis directly from the GUI. """ self.parameters['estimate'] = 'no' if not self.parameters.has_key('pyroserver'): self.actualAnalysis = eval( '%s_serial(parameters = self.parameters, statusBar = self.statusBar)' % self.db_internalname) else: if self.parameters['pyroserver'].lower() == 'monoprocessor': self.actualAnalysis = eval( '%s_serial(parameters = self.parameters, statusBar = self.statusBar)' % self.db_internalname) elif self.parameters['pyroserver'][:14].lower( ) == 'multiprocessor': self.actualAnalysis = eval( '%s_parallel(parameters = self.parameters, statusBar = self.statusBar)' % self.db_internalname) elif self.parameters['pyroserver'][:7].lower() == 'cluster': self.actualAnalysis = eval( '%s_parallel(parameters = self.parameters, statusBar = self.statusBar)' % self.db_internalname) else: raise Error('The pyro server was not set properly') t = self.actualAnalysis.runAnalysis() self.parent.info.insert(contents='\n\n\nPERFORMED ANALYSIS:\n\n') self.parent.info.insert(contents=self.actualAnalysis.information) message = 'Analysis run successfully in \n %(days)s days %(hours)s hours %(minutes)s minutes %(seconds)s seconds.\n\n' % t if self.actualAnalysis.toPlot is None: # The information dialog with the predicted analysis time. LogMessage('info', message, ['gui']) else: # Try to import the matplotlib module. try: from nMOLDYN.GUI.PlotNetCDFVariableDialog import PlotNetCDFVariableDialog except: return else: message += 'Do you want to plot the results right now ?' q = askyesno(title='Question', message=message) if q: PlotNetCDFVariableDialog(self, **self.actualAnalysis.toPlot)
def internalRun(self): """Performs the analysis in parallel mode. """ from Scientific.DistributedComputing.MasterSlave import initializeMasterProcess, TaskRaisedException, GlobalStateValue pyroServer = setUpPyroServer() if self.taskName is None: # This should be enough to create a unique task name. self.taskName = '%s_%s_%s' % (self.db_shortname, getpass.getuser(), '_'.join(asctime().split())) if self.architecture == 'multiprocessor': tasks = initializeMasterProcess(self.taskName) elif self.architecture == 'cluster': tasks = initializeMasterProcess(self.taskName, slave_module='nMOLDYN.Analysis.Slave') else: raise Error('Illegal parallel mode %s' % self.architecture) # The instance of the running analysis is made global for all the process. tasks.setGlobalState(analysis=self) # The master registers the tasks to be done by the slave. for fIndex in self.frameIndexes: task_id = tasks.requestTask("analysisPerElement", GlobalStateValue(1, 'analysis'), fIndex, self.trajectoryFilename) # The slaves are started but the calculation is not started actually. # In case of a cluster run, wait for calls to the task_manager. startSlaves(self.taskName, self.architecture, self.numberOfProcs) # The analysis actual starting time. self.chrono = default_timer() for fIndex in self.frameIndexes: try: task_id, tag, (frameIndex, x) = tasks.retrieveResult("analysisPerElement") self.combine(frameIndex,x) self.updateJobProgress(self.nFrames) except TaskRaisedException, e: LogMessage('error', e.traceback, ['console']) raise except:
def validate(self): try: if not self.selectedModeLb.lb.curselection(): LogMessage('warning','Please select a vibration mode.',['gui']) raise self.selectedMode = [int(v) - 1 for v in self.selectedModeLb.lb.curselection()] self.amplitude = self.amplitudeEntry.getValue() self.nFrames = self.nFramesEntry.getValue() if self.amplitude <= 0.0: raise if self.nFrames < 0: raise except: LogMessage('warning','Bad input. Please try again.',['gui']) return False return True
def estimateAnalysis(self): """Estimates the time taken by the analysis directly from the GUI. """ self.parameters['estimate'] = 'yes' self.actualAnalysis = eval( '%s_serial(parameters = self.parameters, statusBar = self.statusBar)' % self.db_internalname) t = self.actualAnalysis.runAnalysis() # The information dialog with the predicted analysis time. LogMessage( 'info', '\nThe analysis should take:\n %(days)s days %(hours)s hours %(minutes)s minutes %(seconds)s seconds.\n' % t, ['gui'])
def internalRun(self): """Performs the analysis in parallel mode. """ from Scientific.DistributedComputing.MasterSlave import initializeMasterProcess, TaskRaisedException, GlobalStateValue # The Pyro server is setup. pyroServer = setUpPyroServer() # If no task name was assigned to the job, build one. if self.taskName is None: self.taskName = '%s_%s_%s' % (self.db_shortname, getpass.getuser(), '_'.join(asctime().split())) if self.architecture == 'multiprocessor': tasks = initializeMasterProcess(self.taskName) elif self.architecture == 'cluster': tasks = initializeMasterProcess(self.taskName, slave_module='nMOLDYN.Analysis.Slave') else: raise Error('Illegal parallel mode %s' % self.architecture) tasks.setGlobalState(analysis=self) for aIndex in self.subset: task_id = tasks.requestTask("analysisPerElement", GlobalStateValue(1, 'analysis'), aIndex, self.trajectoryFilename) startSlaves(self.taskName, self.architecture, self.numberOfProcs) # The analysis actual starting time. self.chrono = default_timer() for aIndex in self.subset: try: task_id, tag, (atomIndex, x) = tasks.retrieveResult("analysisPerElement") self.combine(atomIndex, x) self.updateJobProgress(self.nSelectedAtoms) except TaskRaisedException, e: LogMessage('error', e.traceback, ['console']) raise except:
def openTrajectory(self, event=None): """ The method is called when the user clicks on the 'Browse' button of the trajectory visualization dialog. It opens a file browser. After the file selection some of the dialog widgets are updated with the informations coming from the loaded trajectory. Arguments: - event: Tkinter event. """ # Case where the user enters a file name directly in the entry widget without using the browser. if event is not None: if event.widget == self.fileBrowser.entry: filename = self.fileBrowser.getValue() else: return else: # The name of the NetCDF file to load. filename = askopenfilename(parent = self,\ filetypes = [('NetCDF file','*.nc')],\ initialdir = PREFERENCES['trajfile_path']) # The file must exist. if filename: try: # The trajectory is loaded. self.trajectory = Trajectory(None, filename, 'r') except IOError: LogMessage('warning', 'Problem when reading the trajectory.', ['gui']) self.fileBrowser.setValue('') self.firstStepEntry.setValue('') self.lastStepEntry.setValue('') self.skipStepEntry.setValue('') else: # The control variables are updated with the informations about the loaded trajectory. self.fileBrowser.setValue(filename) self.firstStepEntry.setValue(1) self.lastStepEntry.setValue(1) self.skipStepEntry.setValue(1) return 'break'
def checkForNewVersion(): # Find automatically the proxies if some are defined. httpProxy = urllib2.getproxies() # The requests will go through the http proxy. proxy = urllib2.ProxyHandler(httpProxy) # Open the connection possibly through the proxy.. opener = urllib2.build_opener(proxy) # The url for the file storing the last nMOLDYN version. url = 'http://dirac.cnrs-orleans.fr/~nmoldyn/last_version' # Build the url request for the file storing the last nMOLDYN version. req = urllib2.Request(url) # Open the url. try: f = opener.open(req) # The url could not be opened. Raises an error. except urllib2.URLError: LogMessage( 'warning', 'Could not open the url %s.\nPerhaps a problem with a proxy.\n\n\ Can not check whether a new version of nMOLDYN was released.' % url, ['console', 'gui']) return # The url could be opened. Its contents will be extracted. else: # The name of the last nMOLDYN version. lastVersion = f.read().strip() f.close() opener.close() if LooseVersion(vstring=lastVersion) > LooseVersion( vstring=Cfg.nmoldyn_version): return lastVersion else: return None
def validate(self, runMode): self.parameters = {'version': NMOLDYN_VERSION} # Loop over the self.widgets dictionnary. for widgetName, widget in self.widgets.items(): try: if widgetName == "qvectors": self.parameters[widgetName] = eval(widget.getValue(), {"__builtins__": None}) else: self.parameters[widgetName] = widget.getValue() except: LogMessage('warning', 'Bad input for %s. Please try again.' % widgetName, ['gui']) return False return True
def checkValue(self, event=None, contents=None): """Check that the contents of the Tkinter Entry widget is actually a string that possibly match the |self.pattern| pattern it is not None.. @param event: the keyboard event that triggers the checking of the contents of the Tkinter Entry widget. @type event: a Tkinter.Event object @param contents: the contents of the Tkinter Entry widget to check. @type contents: string """ if self.pattern is None: return contents if self.variable.get(): if not re.findall(self.pattern, self.variable.get()): LogMessage( 'warning', '%s does not math the pattern %s' % (self.variable.get(), self.pattern), ['gui']) return None else: return contents
import os import sys sys.path.insert(0, '/home/cs/pellegrini/nMOLDYN/development') from nMOLDYN.Core.Logger import LogMessage from nMOLDYN.Core.IO import convertASCIIToNetCDF pMoldyn='/home/cs/pellegrini/nMOLDYN/nMOLDYN2.2.5/nMoldyn/bin/pMoldyn' if len(sys.argv) > 1: selectedTests = [int(v) for v in sys.argv[1:]] else: selectedTests = range(1,11) a = 'AVACF' for i in selectedTests: LogMessage('info', "Run test %d" % i, ['console']) os.system(pMoldyn + ' --avacf --input=%s%s_Reference.inp' % (a,i)) os.system('mv test.plot %s%s_Reference.plot' % (a,i)) convertASCIIToNetCDF('%s%s_Reference.plot' % (a,i), '%s%s_Reference.nc' % (a,i))
def _random_qvectors(self, qMin, qMax): nRedundant = 0 qVects = [] hkls = [] while (len(qVects) < self.qVectorsPerShell): # A random vector is generated. qVect = randomVector(None) * uniform(qMin, qMax) # Case of a periodic universe. The q vector is rounded to the closest q vectors pointing on a reciprocal node. if self.recBasis is not None: # This is a shortcut to get hkl from h=q.a, k=q.b, l=q.c. hkl = Vector([ round(v) for v in N.array(self.dirBasis * qVect, typecode=N.Float) ]) # The approximated reciprocal space vector. qVect = self.transRecBasis * hkl else: hkl = qVect # Checks whether the q vector falls inside the q shell. if qMin < qVect.length() <= qMax: # If the q vector is already stored in |generatedQVectors| list skip it. if qVect in qVects: # Increment the redundancy counter. nRedundant += 1 # After 5000 trials to generate a new q vector, gives up and returns # the generated q vectors list in its current state. if nRedundant == 5000: # Displays on the console and file loggers that no more q vectors could be generated for that shell. LogMessage( 'warning', 'Give up to generate a new q vector for shell with radius [%s,%s] after 5000 trials.' % (qMin, qMax), ['file', 'console']) break # Otherwise append it to the |qVects| and |hkls| list. else: qVects.append(qVect) hkls.append(hkl) # A new q vector could be found, so reset the redundancy counter to 0. nRedundant = 0 # If not, retries a new q vector generation else: # Increment the redundancy counter. nRedundant += 1 # After 5000 trials to generate a new q vector, gives up and returns the q vector list in its current state. if nRedundant == 5000: # Displays on the console and file loggers that no more q vectors could be generated for that shell. LogMessage( 'warning', 'Give up to generate a new q vector for shell with radius [%s,%s] after 5000 trials.' % (qMin, qMax), ['file', 'console']) break LogMessage( 'info', '%d random Q vectors generated for shell [%s,%s].' % (len(qVects), qMin, qMax), ['file', 'console']) return qVects, hkls
def openNetCDFFile(self, event = None): """ This method open the NetCDF that contains the effective modes. Arguments: - event: Tkinter event. """ # Case where the user enters a file name directly in the entry widget without using the browser. if event is not None: if event.widget == self.fileBrowser.entry: filename = self.fileBrowser.getValue() else: return else: # The name of the NetCDF file to load. filename = askopenfilename(parent = self,\ filetypes = [('NetCDF file','*.nc')],\ initialdir = PREFERENCES['trajfile_path']) # The file must exist. if filename: try: self.netcdf = NetCDFFile(filename, 'r') except IOError: LogMessage('warning','Problem when reading the NetCDF file.',['gui']) self.fileBrowser.setValue('') self.selectedModeEntry.setValue('') self.nFramesEntry.setValue('') self.amplitudeEntry.setValue('') try: self.description = self.netcdf.variables['description'][:].tostring() # The frequencies values. self.omega = self.netcdf.variables['omega'].getValue() # The displacements. self.dx = self.netcdf.variables['dx'].getValue() # The average structure. self.avgStruct = self.netcdf.variables['avgstruct'].getValue() except KeyError: LogMessage('warning','The NetCDF file %s miss some QHA analysis keywords.' % filename,['gui']) self.fileBrowser.setValue(filename) self.selectedModeLb.lb.delete(0, END) for i in range(len(self.omega)): ome = self.omega[i] self.selectedModeLb.lb.insert(END, 'Mode %s (%s cm-1)' % (i+1, ome)) self.nFramesEntry.setValue(10) self.amplitudeEntry.setValue(0.1) try: self.cell = self.netcdf.variables['box_size'][:] except KeyError: self.cell = None self.netcdf.close() return 'break'
def informationAboutWidget(event): """Checks the label of the Tkinter LabelFrame of a combo widget and displays the corresponding informations documented in nMOLDYN users guide. @param event: the event triggering the request for information about the combo widget. @type event: a Tkinter.Event object """ tagName = event.widget.nametowidget(event.widget.winfo_parent()).tagName if tags.has_key(tagName): docStyle = PREFERENCES['documentation_style'] if docStyle == 'html': url = os.path.join(GVAR['nmoldyn_path'], 'Doc', 'UsersGuide', 'HTML', tags[tagName]['html']) top = PortableToplevel() top.title('Information') top.wm_minsize(400, 200) viewer = tkHTMLViewer(top) viewer.display(url) top.wait_visibility() top.grab_set() top.focus_set() top.wait_window(top) elif docStyle == 'pdf': # The name of the users guide pdf file. pdfFile = os.path.join(GVAR['nmoldyn_path'], 'Doc', 'UsersGuide', 'PDF', 'nMOLDYN_ug.pdf') if PLATFORM == 'WINDOWS': try: subprocess.call([ PREFERENCES['acroread_path'], '/a nameddest=%s' % tags[tagName]['pdf'], pdfFile ]) except: os.startfile(pdfFile) elif PLATFORM == 'DARWIN': try: os.system( 'osascript -e \'tell application "Adobe Reader"\nopen "%s" options "nameddest=%s"\nend tell\'' % (pdfFile, tags[tagName]['pdf'])) except: subprocess.call(['open', pdfFile]) else: try: subprocess.call([ PREFERENCES['acroread_path'], '/a nameddest=%s' % tags[tagName]['pdf'], pdfFile ]) except: LogMessage( 'warning', 'Unable to read the file %s\nwith the acrobat reader located in %s.' % (pdfFile, PREFERENCES['acroread_path']), ['gui']) pass else: return else: tkMessageBox.showinfo("nMOLDYN help", "Not documented.")