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

Last change on this file since 2967 was 2967, checked in by toby, 6 years ago

misc changes for sphinx docs

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