source: trunk/GSASIIpath.py @ 3025

Last change on this file since 3025 was 3025, checked in by toby, 4 years ago

work on installation issues

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 30.5 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: 3025 $"
70      that is set by subversion when the file is retrieved from subversion.
71
72    Place ``GSASIIpath.SetVersionNumber("$Revision: 3025 $")`` 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/','--non-interactive', '--trust-server-cert']
477    if proxycmds: cmd += proxycmds
478    if verbose:
479        print('Running svn command')
480        for item in cmd: print item,
481        print ""
482    p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
483    res,err = p.communicate()
484    versions = {}
485    for d in res.split():
486        if d.startswith(bindir):
487            v = intver(d.rstrip('/').split('_')[3].lstrip('n'))
488            versions[v] = d
489    intVersionsList = sorted(versions.keys())
490    if not intVersionsList:
491        print('No binaries located')
492        return
493    elif inpver < min(intVersionsList):
494        vsel = min(intVersionsList)
495        print('Warning: The current numpy version, {}, is older than\n\tthe oldest dist version, {}'
496              .format(np.__version__,fmtver(vsel)))
497    elif inpver >= max(intVersionsList):
498        vsel = max(intVersionsList)
499        if verbose: print(
500                'FYI: The current numpy version, {}, is newer than the newest dist version {}'
501                .format(np.__version__,fmtver(vsel)))
502    else:
503        vsel = min(intVersionsList)
504        for v in intVersionsList:
505            if v <= inpver:
506                vsel = v
507            else:
508                if verbose: print(
509                        'FYI: Selecting dist version {} as the current numpy version, {},\n\tis older than the next dist version {}'
510                        .format(fmtver(vsel),np.__version__,fmtver(v)))
511                break
512    distdir = g2home + '/Binaries/' + versions[vsel]
513    # switch reset command: distdir = g2home + '/trunk/bindist'
514    svnSwitchDir('bindist','',distdir,verbose=verbose)
515    return os.path.join(path2GSAS2,'bindist')
516
517# def svnTestBranch(loc=None):
518#     '''Returns the name of the branch directory if the installation has been switched.
519#     Returns none, if not a branch
520#     the test 2frame branch. False otherwise
521#     '''
522#     if loc is None: loc = path2GSAS2
523#     svn = whichsvn()
524#     if not svn:
525#         print('**** unable to load files: svn not found ****')
526#         return ''
527#     cmd = [svn, 'info', loc]
528#     if proxycmds: cmd += proxycmds
529#     p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
530#     res,err = p.communicate()
531#     for l in res.split('\n'):
532#         if "Relative URL:" in l: break
533#     if "/branch/" in l:
534#         return l[l.find("/branch/")+8:].strip()
535#     else:
536#         return None
537   
538def svnSwitch2branch(branch=None,loc=None,svnHome=None):
539    '''Switch to a subversion branch if specified. Switches to trunk otherwise.
540    '''
541    if svnHome is None: svnHome = g2home
542    svnURL = svnHome + '/trunk'
543    if branch:
544        if svnHome.endswith('/'):
545            svnURL = svnHome[:-1]
546        else:
547            svnURL = svnHome
548        if branch.startswith('/'):
549            svnURL += branch
550        else:
551            svnURL += '/' + branch
552    svnSwitchDir('','',svnURL,loadpath=loc)
553   
554
555def IPyBreak_base(userMsg=None):
556    '''A routine that invokes an IPython session at the calling location
557    This routine is only used when debug=True is set in config.py
558    '''
559    savehook = sys.excepthook # save the exception hook
560    try: 
561        from IPython.terminal.embed import InteractiveShellEmbed
562    except ImportError:
563        try:
564            # try the IPython 0.12 approach
565            from IPython.frontend.terminal.embed import InteractiveShellEmbed
566        except ImportError:
567            print 'IPython InteractiveShellEmbed not found'
568            return
569    import inspect
570    ipshell = InteractiveShellEmbed()
571
572    frame = inspect.currentframe().f_back
573    msg   = 'Entering IPython console inside {0.f_code.co_filename} at line {0.f_lineno}\n'.format(frame)
574    if userMsg: msg += userMsg
575    ipshell(msg,stack_depth=2) # Go up one level, to see the calling routine
576    sys.excepthook = savehook # reset IPython's change to the exception hook
577
578def exceptHook(*args):
579    '''A routine to be called when an exception occurs. It prints the traceback
580    with fancy formatting and then calls an IPython shell with the environment
581    of the exception location.
582   
583    This routine is only used when debug=True is set in config.py   
584    '''
585    from IPython.core import ultratb
586    if 'win' in sys.platform:
587        ultratb.FormattedTB(call_pdb=False,color_scheme='NoColor')(*args)
588    else:
589        ultratb.FormattedTB(call_pdb=False,color_scheme='LightBG')(*args)
590    try: 
591        from IPython.terminal.embed import InteractiveShellEmbed
592    except ImportError:
593        try:
594            # try the IPython 0.12 approach
595            from IPython.frontend.terminal.embed import InteractiveShellEmbed
596        except ImportError:
597            print 'IPython InteractiveShellEmbed not found'
598            return
599    import inspect
600    frame = inspect.getinnerframes(args[2])[-1][0]
601    msg   = 'Entering IPython console at {0.f_code.co_filename} at line {0.f_lineno}\n'.format(frame)
602    savehook = sys.excepthook # save the exception hook
603    try:
604        InteractiveShellEmbed(banner1=msg)(local_ns=frame.f_locals,global_ns=frame.f_globals)
605    except: # use a different call for IPython 5
606        class c(object): pass
607        pseudomod = c() # create something that acts like a module
608        pseudomod.__dict__ = frame.f_locals
609        InteractiveShellEmbed(banner1=msg)(module=pseudomod,global_ns=frame.f_globals)
610    sys.excepthook = savehook # reset IPython's change to the exception hook
611
612def DoNothing():
613    '''A routine that does nothing. This is called in place of IPyBreak and pdbBreak
614    except when the debug option is set True in config.py
615    '''
616    pass 
617
618IPyBreak = DoNothing
619pdbBreak = DoNothing
620def InvokeDebugOpts():
621    'Called in GSASII.py to set up debug options'
622    if GetConfigValue('debug'):
623        print 'Debug on: IPython: Exceptions and G2path.IPyBreak(); pdb: G2path.pdbBreak()'
624        sys.excepthook = exceptHook
625        import pdb
626        global pdbBreak
627        pdbBreak = pdb.set_trace
628        global IPyBreak
629        IPyBreak = IPyBreak_base
630
631def TestSPG(fpth):
632    '''Test if pyspg.[so,.pyd] can be run from a location in the path
633    '''
634    if not os.path.exists(fpth): return False
635    if not glob.glob(os.path.join(fpth,'pyspg.*')): return False
636    savpath = sys.path[:]
637    sys.path = [fpth]
638    # test to see if a shared library can be used
639    try:
640        import pyspg
641        pyspg.sgforpy('P -1')
642    except Exception as err:
643        print(70*'=')
644        print('Failed to run pyspg in {}\nerror: {}'.format(fpth,err))
645        print(70*'=')
646        sys.path = savpath
647        return False
648    sys.path = savpath
649    return True
650   
651# see if a directory for local modifications is defined. If so, stick that in the path
652if os.path.exists(os.path.expanduser('~/.G2local/')):
653    sys.path.insert(0,os.path.expanduser('~/.G2local/'))
654    import glob
655    fl = glob.glob(os.path.expanduser('~/.G2local/GSASII*.py*'))
656    files = ""
657    prev = None
658    for f in sorted(fl): # make a list of files, dropping .pyc files where a .py exists
659        f = os.path.split(f)[1]
660        if os.path.splitext(f)[0] == prev: continue
661        prev = os.path.splitext(f)[0]
662        if files: files += ", "
663        files += f
664    if files:
665        print("*"*75)
666        print("Warning: the following source files are locally overridden in "+os.path.expanduser('~/.G2local/'))
667        print("  "+files)
668        print("*"*75)
669
670BinaryPathLoaded = False
671def SetBinaryPath(printInfo=True):
672    '''
673    Add location of GSAS-II shared libraries (binaries: .so or .pyd files) to path
674   
675    This routine must be executed after GSASIIpath is imported and before any other
676    GSAS-II imports are done.
677    '''
678    # do this only once no matter how many times it is called
679    global BinaryPathLoaded
680    if BinaryPathLoaded: return
681    try:
682        inpver = intver(np.__version__)
683    except AttributeError: # happens on building docs
684        return
685    binpath = None
686    binprfx = GetBinaryPrefix()
687    for loc in os.path.abspath(sys.path[0]),os.path.abspath(os.path.split(__file__)[0]):
688        # Look at bin directory (created by a local compile) before looking for standard dist files
689        searchpathlist = [os.path.join(loc,'bin')]
690        # also look for matching binary dist in loc/AllBinaries
691        versions = {}
692        for d in glob.glob(os.path.join(loc,'AllBinaries',binprfx+'*')):
693            v = intver(d.rstrip('/').split('_')[3].lstrip('n'))
694            versions[v] = d
695        searchpathlist = [os.path.join(loc,'bin')]
696        vmin = None
697        vmax = None
698        for v in sorted(versions.keys()):
699            if v <= inpver:
700                vmin = v
701            elif v > inpver:
702                vmax = v
703                break
704        if vmin in versions:
705            searchpathlist.append(versions[vmin])
706        if vmax in versions:
707            searchpathlist.append(versions[vmax])
708        searchpathlist.append(os.path.join(loc,'bindist'))
709        for fpth in searchpathlist:
710            if TestSPG(fpth):
711                binpath = fpth
712                break       
713        if binpath: break
714    if binpath:                                            # were GSAS-II binaries found
715        sys.path.insert(0,binpath)
716        if printInfo:
717            print('GSAS-II binary directory: {}'.format(binpath))
718        BinaryPathLoaded = True
719    else:                                                  # try loading them
720        if printInfo:
721            print('Attempting to download GSAS-II binary files...')
722        try:
723            binpath = DownloadG2Binaries(g2home)
724        except AttributeError:   # this happens when building in Read The Docs
725            if printInfo:
726                print('Problem with download')
727        if binpath and TestSPG(binpath):
728            if printInfo:
729                print('GSAS-II binary directory: {}'.format(binpath))
730            sys.path.insert(0,binpath)
731            BinaryPathLoaded = True
732        # this must be imported before anything that imports any .pyd/.so file for GSASII
733        else:
734            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
735            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
736            # patch: use old location based on the host OS and the python version, 
737            # path is relative to location of the script that is called as well as this file
738            BinaryPathLoaded = True
739            bindir = None
740            if sys.platform == "win32":
741                if platform.architecture()[0] == '64bit':
742                    bindir = 'binwin64-%d.%d' % sys.version_info[0:2]
743                else:
744                    bindir = 'binwin%d.%d' % sys.version_info[0:2]
745            elif sys.platform == "darwin":
746                if platform.architecture()[0] == '64bit':
747                    bindir = 'binmac64-%d.%d' % sys.version_info[0:2]
748                else:
749                    bindir = 'binmac%d.%d' % sys.version_info[0:2]
750                #if platform.mac_ver()[0].startswith('10.5.'):
751                #    bindir += '_10.5'
752            elif sys.platform == "linux2":
753                if platform.architecture()[0] == '64bit':
754                    bindir = 'binlinux64-%d.%d' % sys.version_info[0:2]
755                else:
756                    bindir = 'binlinux%d.%d' % sys.version_info[0:2]
757            for loc in os.path.abspath(sys.path[0]),os.path.abspath(os.path.split(__file__)[0]):
758            # Look at bin directory (created by a local compile) before standard dist
759            # that at the top of the path
760                fpth = os.path.join(loc,bindir)
761                binpath = fpth
762                if TestSPG(fpth):
763                    sys.path.insert(0,binpath)
764                    if printInfo:
765                        print('\n'+75*'*')
766                        print('  Warning. Using an old-style GSAS-II binary library. This is unexpected')
767                        print('  and will break in future GSAS-II versions. Please contact toby@anl.gov')
768                        print('  so we can learn what is not working on your installation.')
769                        print('GSAS-II binary directory: {}'.format(binpath))
770                        print(75*'*')
771                    break
772            else:
773            # end patch
774            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
775            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
776                if printInfo:
777                    print(75*'*')
778                    print('Use of GSAS-II binary directory {} failed!'.format(binpath))
779                    print(75*'*')
780                raise Exception,"**** ERROR GSAS-II binary libraries not found, GSAS-II cannot run ****"
781
782    # add the data import and export directory to the search path
783    newpath = os.path.join(path2GSAS2,'imports')
784    if newpath not in sys.path: sys.path.append(newpath)
785    newpath = os.path.join(path2GSAS2,'exports')
786    if newpath not in sys.path: sys.path.append(newpath)
787
788    # setup read of config.py, if present
789    global configDict
790    try:
791        import config
792        configDict = config.__dict__
793        import inspect
794        vals = [True for i in inspect.getmembers(config) if '__' not in i[0]]
795        if printInfo:
796            print str(len(vals))+' values read from config file '+os.path.abspath(config.__file__)
797    except ImportError:
798        configDict = {'Clip_on':True}
799    except Exception as err:
800        if printInfo:
801            print("Error importing config.py file: "+str(err))
802        configDict = {'Clip_on':True}
803
804if __name__ == '__main__':
805    '''What follows is called to update (or downdate) GSAS-II in a separate process.
806    '''
807    import time
808    time.sleep(1) # delay to give the main process a chance to exit
809    # perform an update and restart GSAS-II
810    project,version = sys.argv[1:3]
811    loc = os.path.dirname(__file__)
812    if version == 'trunk':
813        svnSwitch2branch('')
814    elif '/' in version:
815        svnSwitch2branch(version)
816    elif version:
817        print("Regress to version "+str(version))
818        svnUpdateDir(loc,version=version)
819    else:
820        print("Update to current version")
821        svnUpdateDir(loc)
822    ex = sys.executable
823    if sys.platform == "darwin": # mac requires pythonw which is not always reported as sys.executable
824        if os.path.exists(ex+'w'): ex += 'w'
825    if project:
826        print("Restart GSAS-II with project file "+str(project))
827        subprocess.Popen([ex,os.path.join(loc,'GSASII.py'),project])
828    else:
829        print("Restart GSAS-II without a project file ")
830        subprocess.Popen([ex,os.path.join(loc,'GSASII.py')])
831    print 'exiting update process'
832    sys.exit()
Note: See TracBrowser for help on using the repository browser.