source: branch/2frame/GSASIIpath.py @ 2936

Last change on this file since 2936 was 2936, checked in by toby, 5 years ago

bail out when bin lookup fails

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 29.0 KB
Line 
1# -*- coding: utf-8 -*-
2'''
3*GSASIIpath: locations & updates*
4---------------------------------
5
6Routines for dealing with file locations, etc.
7
8Determines the location of the compiled (.pyd or .so) libraries.
9
10Interfaces with subversion (svn):
11Determine the subversion release number by determining the highest version number
12where :func:`SetVersionNumber` is called (best done in every GSASII file).
13Other routines will update GSASII from the subversion server if svn can be
14found.
15
16Accesses configuration options, as defined in config.py
17'''
18
19import os
20import sys
21import platform
22import glob
23import subprocess
24import numpy as np
25
26g2home = 'https://subversion.xray.aps.anl.gov/pyGSAS'
27'Define the location of the GSAS-II subversion repository'
28   
29path2GSAS2 = os.path.dirname(os.path.realpath(__file__)) # location of this file; save before any changes in pwd
30
31def GetConfigValue(key,default=None):
32    '''Return the configuration file value for key or a default value if not present
33   
34    :param str key: a value to be found in the configuration (config.py) file
35    :param default: a value to be supplied is none is in the config file or
36      the config file is not found. Defaults to None
37    :returns: the value found or the default.
38    '''
39    return configDict.get(key,default)
40
41def SetConfigValue(parmdict):
42    '''Set configuration variables from a dictionary where elements are lists
43    First item in list is the default value and second is the value to use.
44    '''
45    global configDict
46    for var in parmdict:
47        if var in configDict:
48            del configDict[var]
49        if isinstance(parmdict[var],tuple):
50            configDict[var] = parmdict[var]
51        else:
52            if parmdict[var][1] is None: continue
53            if parmdict[var][1] == '': continue
54            if parmdict[var][0] == parmdict[var][1]: continue
55            configDict[var] = parmdict[var][1]
56
57# routines for looking a version numbers in files
58version = -1
59def SetVersionNumber(RevString):
60    '''Set the subversion version number
61
62    :param str RevString: something like "$Revision: 2936 $"
63      that is set by subversion when the file is retrieved from subversion.
64
65    Place ``GSASIIpath.SetVersionNumber("$Revision: 2936 $")`` in every python
66    file.
67    '''
68    try:
69        RevVersion = int(RevString.split(':')[1].split()[0])
70        global version
71        version = max(version,RevVersion)
72    except:
73        pass
74       
75def GetVersionNumber():
76    '''Return the maximum version number seen in :func:`SetVersionNumber`
77    '''
78    if version > 1000:
79        return version
80    else:
81        return "unknown"
82
83def LoadConfigFile(filename):
84    '''Read a GSAS-II configuration file.
85    Comments (starting with "%") are removed, as are empty lines
86   
87    :param str filename: base file name (such as 'file.dat'). Files with this name
88      are located from the path and the contents of each are concatenated.
89    :returns: a list containing each non-empty (after removal of comments) line
90      found in every matching config file.
91    '''
92    info = []
93    for path in sys.path:
94        fil = os.path.join(path,filename)
95        if not os.path.exists(fil): continue
96        try:
97            i = 0
98            fp = open(fil,'r')
99            for line in fp:
100                expr = line.split('#')[0].strip()
101                if expr:
102                    info.append(expr)
103                    i += 1
104            print(str(i)+' lines read from config file '+fil)
105        finally:
106            fp.close()
107    return info
108
109
110# routines to interface with subversion
111proxycmds = []
112'Used to hold proxy information for subversion, set if needed in whichsvn'
113svnLocCache = None
114'Cached location of svn to avoid multiple searches for it'
115
116def whichsvn():
117    '''Returns a path to the subversion exe file, if any is found.
118    Searches the current path after adding likely places where GSAS-II
119    might install svn.
120
121    :returns: None if svn is not found or an absolute path to the subversion
122      executable file.
123    '''
124    # use a previosuly cached svn location
125    global svnLocCache
126    if svnLocCache: return svnLocCache
127    # prepare to find svn
128    is_exe = lambda fpath: os.path.isfile(fpath) and os.access(fpath, os.X_OK)
129    svnprog = 'svn'
130    if sys.platform.startswith('win'): svnprog += '.exe'
131    gsaspath = os.path.split(__file__)[0]
132    # check for a proxy
133    proxyinfo = os.path.join(gsaspath,"proxyinfo.txt")
134    if os.path.exists(proxyinfo):
135        global proxycmds
136        proxycmds = []
137        fp = open(proxyinfo,'r')
138        host = fp.readline().strip()
139        port = fp.readline().strip()
140        fp.close()
141        proxycmds.append('--config-option')
142        proxycmds.append('servers:global:http-proxy-host='+host)
143        proxycmds.append('--config-option')
144        proxycmds.append('servers:global:http-proxy-port='+port)
145    # add likely places to find subversion when installed with GSAS-II
146    pathlist = os.environ["PATH"].split(os.pathsep)
147    pathlist.append(os.path.split(sys.executable)[0])
148    pathlist.append(gsaspath)
149    for rpt in ('..','bin'),('..','Library','bin'),('svn','bin'),('svn',),('.'):
150        pt = os.path.normpath(os.path.join(gsaspath,*rpt))
151        if os.path.exists(pt):
152            pathlist.insert(0,pt)   
153    # search path for svn or svn.exe
154    for path in pathlist:
155        exe_file = os.path.join(path, svnprog)
156        if is_exe(exe_file):
157            try:
158                p = subprocess.Popen([exe_file,'help'],stdout=subprocess.PIPE)
159                res = p.stdout.read()
160                p.communicate()
161                svnLocCache = os.path.abspath(exe_file)
162                return svnLocCache
163            except:
164                pass       
165    svnLocCache = None
166
167def svnVersion(svn=None):
168    '''Get the version number of the current subversion executable
169
170    :returns: a string with a version number such as "1.6.6" or None if
171      subversion is not found.
172
173    '''
174    if not svn: svn = whichsvn()
175    if not svn: return
176
177    cmd = [svn,'--version','--quiet']
178    s = subprocess.Popen(cmd,
179                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
180    out,err = s.communicate()
181    if err:
182        print 'subversion error!\nout=',out
183        print 'err=',err
184        return None
185    return out.strip()
186
187def svnVersionNumber(svn=None):
188    '''Get the version number of the current subversion executable
189
190    :returns: a fractional version number such as 1.6 or None if
191      subversion is not found.
192
193    '''
194    ver = svnVersion(svn)
195    if not ver: return 
196    M,m = ver.split('.')[:2]
197    return int(M)+int(m)/10.
198
199def svnGetLog(fpath=os.path.split(__file__)[0],version=None):
200    '''Get the revision log information for a specific version of the specified package
201
202    :param str fpath: path to repository dictionary, defaults to directory where
203       the current file is located.
204    :param int version: the version number to be looked up or None (default)
205       for the latest version.
206
207    :returns: a dictionary with keys (one hopes) 'author', 'date', 'msg', and 'revision'
208
209    '''
210    import xml.etree.ElementTree as ET
211    svn = whichsvn()
212    if not svn: return
213    if version is not None:
214        vstr = '-r'+str(version)
215    else:
216        vstr = '-rHEAD'
217
218    cmd = [svn,'log',fpath,'--xml',vstr]
219    if proxycmds: cmd += proxycmds
220    s = subprocess.Popen(cmd,
221                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
222    out,err = s.communicate()
223    if err:
224        print 'out=',out
225        print 'err=',err
226        return None
227    x = ET.fromstring(out)
228    d = {}
229    for i in x.iter('logentry'):
230        d = {'revision':i.attrib.get('revision','?')}
231        for j in i:
232            d[j.tag] = j.text
233        break # only need the first
234    return d
235
236svnLastError = ''
237def svnGetRev(fpath=os.path.split(__file__)[0],local=True):
238    '''Obtain the version number for the either the last update of the local version
239    or contacts the subversion server to get the latest update version (# of Head).
240
241    :param str fpath: path to repository dictionary, defaults to directory where
242       the current file is located
243    :param bool local: determines the type of version number, where
244       True (default): returns the latest installed update
245       False: returns the version number of Head on the server
246
247    :Returns: the version number as an str or
248       None if there is a subversion error (likely because the path is
249       not a repository or svn is not found). The error message is placed in
250       global variable svnLastError
251    '''
252
253    import xml.etree.ElementTree as ET
254    svn = whichsvn()
255    if not svn: return
256    if local:
257        cmd = [svn,'info',fpath,'--xml']
258    else:
259        cmd = [svn,'info',fpath,'--xml','-rHEAD']
260    if svnVersionNumber() >= 1.6:
261        cmd += ['--non-interactive', '--trust-server-cert']
262    if proxycmds: cmd += proxycmds
263    s = subprocess.Popen(cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
264    out,err = s.communicate()
265    if err:
266        print 'svn failed\n',out
267        print 'err=',err
268        global svnLastError
269        svnLastError = err
270        return None
271    x = ET.fromstring(out)
272    for i in x.iter('entry'):
273        rev = i.attrib.get('revision')
274        if rev: return rev
275
276def svnFindLocalChanges(fpath=os.path.split(__file__)[0]):
277    '''Returns a list of files that were changed locally. If no files are changed,
278       the list has length 0
279
280    :param fpath: path to repository dictionary, defaults to directory where
281       the current file is located
282
283    :returns: None if there is a subversion error (likely because the path is
284       not a repository or svn is not found)
285
286    '''
287    import xml.etree.ElementTree as ET
288    svn = whichsvn()
289    if not svn: return
290    cmd = [svn,'status',fpath,'--xml']
291    if proxycmds: cmd += proxycmds
292    s = subprocess.Popen(cmd,
293                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
294    out,err = s.communicate()
295    if err: return None
296    x = ET.fromstring(out)
297    changed = []
298    for i in x.iter('entry'):
299        if i.find('wc-status').attrib.get('item') == 'modified': 
300            changed.append(i.attrib.get('path'))
301    return changed
302
303def svnUpdateDir(fpath=os.path.split(__file__)[0],version=None):
304    '''This performs an update of the files in a local directory from a server.
305
306    :param str fpath: path to repository dictionary, defaults to directory where
307       the current file is located
308    :param version: the number of the version to be loaded. Used only
309       cast as a string, but should be an integer or something that corresponds to a
310       string representation of an integer value when cast. A value of None (default)
311       causes the latest version on the server to be used.
312    '''
313    svn = whichsvn()
314    if not svn: return
315    if version:
316        verstr = '-r' + str(version)
317    else:
318        verstr = '-rHEAD'
319    cmd = [svn,'update',fpath,verstr,
320           '--non-interactive',
321           '--accept','theirs-conflict','--force']
322    if svnVersionNumber() >= 1.6:
323        cmd += ['--trust-server-cert']
324    if proxycmds: cmd += proxycmds
325    s = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
326    out,err = s.communicate()
327    if err:
328        print(60*"=")
329        print ("****** An error was noted, see below *********")
330        print(60*"=")
331        print err
332        sys.exit()
333
334def svnUpgrade(fpath=os.path.split(__file__)[0]):
335    '''This reformats subversion files, which may be needed if an upgrade of subversion is
336    done.
337
338    :param str fpath: path to repository dictionary, defaults to directory where
339       the current file is located
340    '''
341    svn = whichsvn()
342    if not svn: return
343    cmd = [svn,'upgrade',fpath,'--non-interactive']
344    if proxycmds: cmd += proxycmds
345    s = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
346    out,err = s.communicate()
347    if err:
348        print("svn upgrade did not happen (this is probably OK). Messages:")
349        print err
350           
351def svnUpdateProcess(version=None,projectfile=None,branch=None):
352    '''perform an update of GSAS-II in a separate python process'''
353    if not projectfile:
354        projectfile = ''
355    else:
356        projectfile = os.path.realpath(projectfile)
357        print 'restart using',projectfile
358    if branch:
359        version = branch
360    elif not version:
361        version = ''
362    else:
363        version = str(version)
364    # start the upgrade in a separate interpreter (avoids loading .pyd files)
365    subprocess.Popen([sys.executable,__file__,projectfile,version])
366    sys.exit()
367
368def svnSwitchDir(rpath,filename,baseURL,loadpath=None,verbose=True):
369    '''This performs a switch command to move files between subversion trees.
370    Note that if the files were previously downloaded,
371    the switch command will update the files to the newest version.
372   
373    :param str rpath: path to locate files, relative to the GSAS-II
374      installation path (defaults to path2GSAS2)
375    :param str URL: the repository URL
376    :param str loadpath: the prefix for the path, if specified. Defaults to path2GSAS2
377    :param bool verbose: if True (default) diagnostics are printed
378    '''
379    svn = whichsvn()
380    if not svn: return
381    URL = baseURL[:]
382    if baseURL[-1] != '/':
383        URL = baseURL + '/' + filename
384    else:
385        URL = baseURL + filename
386    if loadpath:
387        fpath = os.path.join(loadpath,rpath,filename)
388    else:
389        fpath = os.path.join(path2GSAS2,rpath,filename)
390    cmd = [svn,'switch',URL,fpath,
391           '--non-interactive','--trust-server-cert',
392           '--accept','theirs-conflict','--force']
393    if svnVersionNumber(svn) > 1.6: cmd += ['--ignore-ancestry']
394    if proxycmds: cmd += proxycmds
395    if verbose: print(u"Loading files to "+fpath+u"\n  from "+URL)
396    s = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
397    out,err = s.communicate()
398    if err:
399        print(60*"=")
400        print ("****** An error was noted, see below *********")
401        print(60*"=")
402        print 'out=',out
403        print 'err=',err
404        return False
405    if verbose:
406        print('=== Output from svn switch'+(43*'='))
407        print(out.strip())
408        print((70*'=')+'\n')
409    return True
410
411def svnInstallDir(URL,loadpath):
412    '''Load a subversion tree into a specified directory
413
414    :param str URL: the repository URL
415    :param str loadpath: path to locate files
416
417    '''
418    svn = whichsvn()
419    if not svn: return
420    cmd = [svn,'co',URL,loadpath,'--non-interactive']
421    if svnVersionNumber() >= 1.6: cmd += ['--trust-server-cert']
422    print("Loading files from "+URL)
423    if proxycmds: cmd += proxycmds
424    s = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
425    out,err = s.communicate()   #this fails too easily
426    if err:
427        print(60*"=")
428        print ("****** An error was noted, see below *********")
429        print(60*"=")
430        print err
431        return False
432    print ("Files installed at: "+loadpath)
433    return True
434           
435def DownloadG2Binaries(g2home,verbose=True):
436    '''Download GSAS-II binaries from appropriate section of the
437    GSAS-II svn repository based on the platform, numpy and Python
438    version
439    '''
440    # convert version numbers as '1.2.3' to integers (1002) and back (to 1.2)
441    fmtver = lambda v: str(v//1000)+'.'+str(v%1000)
442    intver = lambda vs: sum([int(i) for i in vs.split('.')[0:2]]*np.array((1000,1)))
443   
444    if sys.platform == "win32":
445        prefix = 'win'
446    elif sys.platform == "darwin":
447        prefix = 'mac'
448    elif sys.platform == "linux2":
449        prefix = 'linux'
450    else:
451        print(u'Unknown platform: '+sys.platform)
452        raise Exception('Unknown platform')
453    if platform.architecture()[0] == '64bit':
454        bits = '64'
455    else:
456        bits = '32'
457
458    # format current python & numpy versions
459    pyver = 'p{}.{}'.format(*sys.version_info[0:2])
460    npver = 'n{}.{}'.format(*np.__version__.split('.')[0:2])
461    inpver = intver(np.__version__)
462
463    items = [prefix,bits,pyver]
464    bindir = '_'.join(items)
465
466    svn = whichsvn()
467    if not svn:
468        print('**** unable to load files: svn not found ****')
469        return ''
470    # get binaries matching the required type -- other than for the numpy version
471    cmd = [svn, 'list', g2home + '/Binaries/']
472    if proxycmds: cmd += proxycmds
473    p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
474    res,err = p.communicate()
475    versions = {}
476    for d in res.split():
477        if d.startswith(bindir):
478            v = intver(d.rstrip('/').split('_')[3].lstrip('n'))
479            versions[v] = d
480    intVersionsList = sorted(versions.keys())
481    if not intVersionsList:
482        print('No binaries located')
483        return
484    elif inpver < min(intVersionsList):
485        vsel = min(intVersionsList)
486        print('Warning: The current numpy version, {}, is older than\n\tthe oldest dist version, {}'
487              .format(np.__version__,fmtver(vsel)))
488    elif inpver >= max(intVersionsList):
489        vsel = max(intVersionsList)
490        if verbose: print(
491                'FYI: The current numpy version, {}, is newer than the newest dist version {}'
492                .format(np.__version__,fmtver(vsel)))
493    else:
494        vsel = min(intVersionsList)
495        for v in intVersionsList:
496            if v <= inpver:
497                vsel = v
498            else:
499                if verbose: print(
500                        'FYI: Selecting dist version {} as the current numpy version, {},\n\tis older than the next dist version {}'
501                        .format(fmtver(vsel),np.__version__,fmtver(v)))
502                break
503    distdir = g2home + '/Binaries/' + versions[vsel]
504    # switch reset command: distdir = g2home + '/trunk/bindist'
505    svnSwitchDir('bindist','',distdir,verbose=verbose)
506    return os.path.join(path2GSAS2,'bindist')
507
508def svnTestBranch(loc=None):
509    '''Returns the name of the branch directory if the installation has been switched.
510    Returns none, if not a branch
511    the test 2frame branch. False otherwise
512    '''
513    if loc is None: loc = path2GSAS2
514    svn = whichsvn()
515    if not svn:
516        print('**** unable to load files: svn not found ****')
517        return ''
518    cmd = [svn, 'info', loc]
519    if proxycmds: cmd += proxycmds
520    p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
521    res,err = p.communicate()
522    for l in res.split('\n'):
523        if "Relative URL:" in l: break
524    if "/branch/" in l:
525        return l[l.find("/branch/")+8:].strip()
526    else:
527        return None
528   
529def svnSwitch2branch(branch=None,loc=None,svnHome=None):
530    '''Switch to a subversion branch if specified. Switches to trunk otherwise.
531    '''
532    if svnHome is None: svnHome = g2home
533    svnURL = svnHome + '/trunk'
534    if branch:
535        if svnHome.endswith('/'):
536            svnURL = svnHome[:-1]
537        else:
538            svnURL = svnHome
539        if branch.startswith('/'):
540            svnURL += branch
541        else:
542            svnURL += '/' + branch
543    svnSwitchDir('','',svnURL,loadpath=loc)
544   
545
546def IPyBreak_base():
547    '''A routine that invokes an IPython session at the calling location
548    This routine is only used when debug=True is set in config.py
549    '''
550    savehook = sys.excepthook # save the exception hook
551    try: 
552        from IPython.terminal.embed import InteractiveShellEmbed
553    except ImportError:
554        try:
555            # try the IPython 0.12 approach
556            from IPython.frontend.terminal.embed import InteractiveShellEmbed
557        except ImportError:
558            print 'IPython InteractiveShellEmbed not found'
559            return
560    import inspect
561    ipshell = InteractiveShellEmbed()
562
563    frame = inspect.currentframe().f_back
564    msg   = 'Entering IPython console inside {0.f_code.co_filename} at line {0.f_lineno}\n'.format(frame)
565    ipshell(msg,stack_depth=2) # Go up one level, to see the calling routine
566    sys.excepthook = savehook # reset IPython's change to the exception hook
567
568def exceptHook(*args):
569    '''A routine to be called when an exception occurs. It prints the traceback
570    with fancy formatting and then calls an IPython shell with the environment
571    of the exception location.
572   
573    This routine is only used when debug=True is set in config.py   
574    '''
575    from IPython.core import ultratb
576    if 'win' in sys.platform:
577        ultratb.FormattedTB(call_pdb=False,color_scheme='NoColor')(*args)
578    else:
579        ultratb.FormattedTB(call_pdb=False,color_scheme='LightBG')(*args)
580    try: 
581        from IPython.terminal.embed import InteractiveShellEmbed
582    except ImportError:
583        try:
584            # try the IPython 0.12 approach
585            from IPython.frontend.terminal.embed import InteractiveShellEmbed
586        except ImportError:
587            print 'IPython InteractiveShellEmbed not found'
588            return
589    import inspect
590    frame = inspect.getinnerframes(args[2])[-1][0]
591    msg   = 'Entering IPython console at {0.f_code.co_filename} at line {0.f_lineno}\n'.format(frame)
592    savehook = sys.excepthook # save the exception hook
593    try:
594        InteractiveShellEmbed(banner1=msg)(local_ns=frame.f_locals,global_ns=frame.f_globals)
595    except: # use a different call for IPython 5
596        class c(object): pass
597        pseudomod = c() # create something that acts like a module
598        pseudomod.__dict__ = frame.f_locals
599        InteractiveShellEmbed(banner1=msg)(module=pseudomod,global_ns=frame.f_globals)
600    sys.excepthook = savehook # reset IPython's change to the exception hook
601
602def DoNothing():
603    '''A routine that does nothing. This is called in place of IPyBreak and pdbBreak
604    except when the debug option is set True in config.py
605    '''
606    pass 
607
608IPyBreak = DoNothing
609pdbBreak = DoNothing
610def InvokeDebugOpts():
611    'Called in GSASII.py to set up debug options'
612    if GetConfigValue('debug'):
613        print 'Debug on: IPython: Exceptions and G2path.IPyBreak(); pdb: G2path.pdbBreak()'
614        sys.excepthook = exceptHook
615        import pdb
616        global pdbBreak
617        pdbBreak = pdb.set_trace
618        global IPyBreak
619        IPyBreak = IPyBreak_base
620
621def TestSPG(fpth):
622    '''Test if pyspg.[so,.pyd] can be run from a location in the path
623    '''
624    if not os.path.exists(fpth): return False
625    if not glob.glob(os.path.join(fpth,'pyspg.*')): return False
626    savpath = sys.path[:]
627    sys.path = [fpth]
628    # test to see if a shared library can be used
629    try:
630        import pyspg
631        pyspg.sgforpy('P -1')
632    except Exception as err:
633        print(70*'=')
634        print('Failed to run pyspg in {}\nerror: {}'.format(fpth,err))
635        print(70*'=')
636        sys.path = savpath
637        return False
638    sys.path = savpath
639    return True
640   
641# see if a directory for local modifications is defined. If so, stick that in the path
642if os.path.exists(os.path.expanduser('~/.G2local/')):
643    sys.path.insert(0,os.path.expanduser('~/.G2local/'))
644    import glob
645    fl = glob.glob(os.path.expanduser('~/.G2local/GSASII*.py*'))
646    files = ""
647    prev = None
648    for f in sorted(fl): # make a list of files, dropping .pyc files where a .py exists
649        f = os.path.split(f)[1]
650        if os.path.splitext(f)[0] == prev: continue
651        prev = os.path.splitext(f)[0]
652        if files: files += ", "
653        files += f
654    if files:
655        print("*"*75)
656        print("Warning: the following source files are locally overridden in "+os.path.expanduser('~/.G2local/'))
657        print("  "+files)
658        print("*"*75)
659
660BinaryPathLoaded = False
661def SetBinaryPath():
662    '''
663    Add location of GSAS-II shared libraries (binaries: .so or .pyd files) to path
664   
665    This routine must be executed after GSASIIpath is imported and before any other
666    GSAS-II imports are done.
667    '''
668    # do this only once no matter how many times it is called
669    global BinaryPathLoaded
670    if BinaryPathLoaded: return
671    BinaryPathLoaded = True
672    binpath = None
673    for loc in os.path.abspath(sys.path[0]),os.path.abspath(os.path.split(__file__)[0]):
674        # Look at bin directory (created by a local compile) before standard dist
675        # that at the top of the path
676        for d in 'bin','bindist':
677            if not d: continue
678            fpth = os.path.join(loc,d)
679            if TestSPG(fpth):
680                binpath = fpth
681                break       
682        if binpath: break
683    if binpath:                                            # were GSAS-II binaries found
684        sys.path.insert(0,binpath)
685        print('GSAS-II binary directory: {}'.format(binpath))
686    else:                                                  # try loading them
687        print('Attempting to download GSAS-II binary files...')
688        try:
689            binpath = DownloadG2Binaries(g2home)
690        except AttributeError:   # this happens when building in Read The Docs
691            print('Problem with download')
692        if binpath and TestSPG(binpath):
693            print('GSAS-II binary directory: {}'.format(binpath))
694            sys.path.insert(0,binpath)
695        # this must be imported before anything that imports any .pyd/.so file for GSASII
696        else:
697            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
698            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
699            # patch: use old location based on the host OS and the python version, 
700            # path is relative to location of the script that is called as well as this file
701            bindir = None
702            if sys.platform == "win32":
703                if platform.architecture()[0] == '64bit':
704                    bindir = 'binwin64-%d.%d' % sys.version_info[0:2]
705                else:
706                    bindir = 'binwin%d.%d' % sys.version_info[0:2]
707            elif sys.platform == "darwin":
708                if platform.architecture()[0] == '64bit':
709                    bindir = 'binmac64-%d.%d' % sys.version_info[0:2]
710                else:
711                    bindir = 'binmac%d.%d' % sys.version_info[0:2]
712                #if platform.mac_ver()[0].startswith('10.5.'):
713                #    bindir += '_10.5'
714            elif sys.platform == "linux2":
715                if platform.architecture()[0] == '64bit':
716                    bindir = 'binlinux64-%d.%d' % sys.version_info[0:2]
717                else:
718                    bindir = 'binlinux%d.%d' % sys.version_info[0:2]
719            for loc in os.path.abspath(sys.path[0]),os.path.abspath(os.path.split(__file__)[0]):
720            # Look at bin directory (created by a local compile) before standard dist
721            # that at the top of the path
722                fpth = os.path.join(loc,bindir)
723                binpath = fpth
724                if TestSPG(fpth):
725                    sys.path.insert(0,binpath)
726                    print('\n'+75*'*')
727                    print('  Warning. Using an old-style GSAS-II binary library. This is unexpected')
728                    print('  and will break in future GSAS-II versions. Please contact toby@anl.gov')
729                    print('  so we can learn what is not working on your installation.')
730                    print('GSAS-II binary directory: {}'.format(binpath))
731                    print(75*'*')
732                    break
733            else:
734            # end patch
735            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
736            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
737                print(75*'*')
738                print('Use of GSAS-II binary directory {} failed!'.format(binpath))
739                print(75*'*')
740                raise Exception,"**** ERROR GSAS-II binary libraries not found, GSAS-II cannot run ****"
741
742    # add the data import and export directory to the search path
743    newpath = os.path.join(path2GSAS2,'imports')
744    if newpath not in sys.path: sys.path.append(newpath)
745    newpath = os.path.join(path2GSAS2,'exports')
746    if newpath not in sys.path: sys.path.append(newpath)
747
748    # setup read of config.py, if present
749    global configDict
750    try:
751        import config
752        configDict = config.__dict__
753        import inspect
754        vals = [True for i in inspect.getmembers(config) if '__' not in i[0]]
755        print str(len(vals))+' values read from config file '+os.path.abspath(config.__file__)
756    except ImportError:
757        configDict = {'Clip_on':True}
758    except Exception as err:
759        print("Error importing config.py file: "+str(err))
760        configDict = {'Clip_on':True}
761
762if __name__ == '__main__':
763    '''What follows is called to update (or downdate) GSAS-II in a separate process.
764    '''
765    import time
766    time.sleep(1) # delay to give the main process a chance to exit
767    # perform an update and restart GSAS-II
768    project,version = sys.argv[1:3]
769    loc = os.path.dirname(__file__)
770    if version == 'trunk':
771        svnSwitch2branch('')
772    elif '/' in version:
773        svnSwitch2branch(version)
774    elif version:
775        print("Regress to version "+str(version))
776        svnUpdateDir(loc,version=version)
777    else:
778        print("Update to current version")
779        svnUpdateDir(loc)
780    ex = sys.executable
781    if sys.platform == "darwin": # mac requires pythonw which is not always reported as sys.executable
782        if os.path.exists(ex+'w'): ex += 'w'
783    if project:
784        print("Restart GSAS-II with project file "+str(project))
785        subprocess.Popen([ex,os.path.join(loc,'GSASII.py'),project])
786    else:
787        print("Restart GSAS-II without a project file ")
788        subprocess.Popen([ex,os.path.join(loc,'GSASII.py')])
789    print 'exiting update process'
790    sys.exit()
Note: See TracBrowser for help on using the repository browser.