Skip to content

Commit b6ab75b

Browse files
committed
scripting: read images from URL, remove raise from try/except
1 parent 90a8cd4 commit b6ab75b

File tree

2 files changed

+90
-26
lines changed

2 files changed

+90
-26
lines changed

GSASII/GSASIIscriptable.py

Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,12 @@ def LoadDictFromProjFile(ProjFile):
219219
G2fil.G2Print ('\n*** Error attempt to open project file that does not exist: \n {}'.
220220
format(ProjFile))
221221
raise IOError('GPX file {} does not exist'.format(ProjFile))
222+
errmsg = ''
222223
try:
223224
Project, nameList = G2stIO.GetFullGPX(ProjFile)
224225
except Exception as msg:
225-
raise IOError(msg)
226+
errmsg = msg
227+
if errmsg: raise IOError(errmsg)
226228
return Project,nameList
227229

228230
def SaveDictToProjFile(Project,nameList,ProjFile):
@@ -269,10 +271,12 @@ def PreSetup(data):
269271
def SetupGeneral(data, dirname):
270272
'''Initialize phase data.
271273
'''
274+
errmsg = ''
272275
try:
273276
G2elem.SetupGeneral(data,dirname)
274277
except ValueError as msg:
275-
raise G2ScriptException(msg)
278+
errmsg = msg
279+
if errmsg: raise G2ScriptException(errmsg)
276280

277281
def make_empty_project(author=None, filename=None):
278282
"""Creates an dictionary in the style of GSASIIscriptable, for an empty
@@ -384,11 +388,30 @@ class G2ImportException(Exception):
384388
class G2ScriptException(Exception):
385389
pass
386390

387-
def import_generic(filename, readerlist, fmthint=None, bank=None):
391+
def import_generic(filename, readerlist, fmthint=None, bank=None,
392+
URL=False, download_loc=None):
388393
"""Attempt to import a filename, using a list of reader objects.
389394
390395
Returns the first reader object which worked."""
391396
# Translated from OnImportGeneric method in GSASII.py
397+
if URL is True:
398+
import requests
399+
fname = os.path.split(filename)[1]
400+
if download_loc is None:
401+
import tempfile
402+
download_loc = tempfile.gettempdir()
403+
elif os.path.isdir(download_loc) and os.path.exists(download_loc):
404+
pass
405+
elif os.path.exists(os.path.dirname(download_loc)):
406+
download_loc,fname = os.path.split(download_loc)
407+
pass
408+
else:
409+
raise G2ScriptException(f"Import error: Cannot download to {download_loc}")
410+
G2fil.G2Print(f'Preparing to download {filename}')
411+
response = requests.get(filename)
412+
filename = os.path.join(download_loc,fname)
413+
open(filename,'wb').write(response.content)
414+
G2fil.G2Print(f'File {filename} written')
392415
primaryReaders, secondaryReaders = [], []
393416
for reader in readerlist:
394417
if fmthint is not None and fmthint not in reader.formatName: continue
@@ -1179,19 +1202,23 @@ def add_simulated_powder_histogram(self, histname, iparams, Tmin, Tmax, Tstep=No
11791202
if wavelength is not None:
11801203
if 'Lam1' in pwdrdata['Instrument Parameters'][0]:
11811204
# have alpha 1,2 here
1205+
errmsg = ''
11821206
try:
11831207
pwdrdata['Instrument Parameters'][0]['Lam1'][0] = float(wavelength[0])
11841208
pwdrdata['Instrument Parameters'][0]['Lam1'][1] = float(wavelength[0])
11851209
pwdrdata['Instrument Parameters'][0]['Lam2'][0] = float(wavelength[1])
11861210
pwdrdata['Instrument Parameters'][0]['Lam2'][1] = float(wavelength[1])
11871211
except:
1188-
raise G2ScriptException("add_simulated_powder_histogram Error: only one wavelength with alpha 1+2 histogram?")
1212+
errmsg = "add_simulated_powder_histogram Error: only one wavelength with alpha 1+2 histogram?"
1213+
if errmsg: raise G2ScriptException(errmsg)
11891214
elif 'Lam' in pwdrdata['Instrument Parameters'][0]:
1215+
errmsg = ''
11901216
try:
11911217
pwdrdata['Instrument Parameters'][0]['Lam'][0] = float(wavelength)
11921218
pwdrdata['Instrument Parameters'][0]['Lam'][1] = float(wavelength)
11931219
except:
1194-
raise G2ScriptException("add_simulated_powder_histogram Error: invalid wavelength?")
1220+
errmsg = "add_simulated_powder_histogram Error: invalid wavelength?"
1221+
if errmsg: raise G2ScriptException(errmsg)
11951222
else:
11961223
raise G2ScriptException("add_simulated_powder_histogram Error: can't set a wavelength for a non-CW dataset")
11971224
self.data[histname] = pwdrdata
@@ -1658,17 +1685,17 @@ def image(self, imageRef):
16581685
if imageRef in self._images():
16591686
return G2Image(self.data[imageRef], imageRef, self)
16601687

1688+
errmsg = ''
16611689
try:
16621690
# imageRef should be an index
16631691
num = int(imageRef)
16641692
imageRef = self._images()[num]
16651693
return G2Image(self.data[imageRef], imageRef, self)
16661694
except ValueError:
1667-
raise Exception("imageRef {} not an object, name or image index in current selected project"
1668-
.format(imageRef))
1695+
errmsg = "imageRef {imageRef} not an object, name or image index in current selected project"
16691696
except IndexError:
1670-
raise Exception("imageRef {} out of range (max={}) in current selected project"
1671-
.format(imageRef,len(self._images())-1))
1697+
errmsg = "imageRef {imageRef} out of range (max={len(self._images())-1)}) in current selected project"
1698+
if errmsg: raise G2ScriptException(errmsg)
16721699

16731700
def images(self):
16741701
"""
@@ -1705,15 +1732,17 @@ def pdf(self, pdfRef):
17051732
if pdfRef in self._pdfs():
17061733
return G2PDF(self.data[pdfRef], pdfRef, self)
17071734

1735+
errmsg = ''
17081736
try:
17091737
# pdfRef should be an index
17101738
num = int(pdfRef)
17111739
pdfRef = self._pdfs()[num]
17121740
return G2PDF(self.data[pdfRef], pdfRef, self)
17131741
except ValueError:
1714-
raise Exception(f"pdfRef {pdfRef} not an object, name or PDF index in current selected project")
1742+
errmsg = f"pdfRef {pdfRef} not an object, name or PDF index in current selected project"
17151743
except IndexError:
1716-
raise Exception(f"pdfRef {pdfRef} out of range (max={len(G2SmallAngle)-1}) in current selected project")
1744+
errmsg = f"pdfRef {pdfRef} out of range (max={len(G2SmallAngle)-1}) in current selected project"
1745+
if errmsg: raise Exception(errmsg)
17171746
def pdfs(self):
17181747
"""
17191748
Returns a list of all the PDFs in the project.
@@ -2066,15 +2095,17 @@ def SAS(self, sasRef):
20662095
if sasRef in self._sasd():
20672096
return G2SmallAngle(self.data[sasRef], sasRef, self)
20682097

2098+
errmsg = ''
20692099
try:
20702100
# sasRef should be an index
20712101
num = int(sasRef)
20722102
sasRef = self._sasd()[num]
20732103
return G2PDF(self.data[sasRef], sasRef, self)
20742104
except ValueError:
2075-
raise Exception(f"sasRef {sasRef} not an object, name or SAS index in current selected project")
2105+
errmsg = f"sasRef {sasRef} not an object, name or SAS index in current selected project"
20762106
except IndexError:
2077-
raise Exception(f"sasRef {sasRef} out of range (max={len(self._sasd())-1}) in current selected project")
2107+
errmsg = "sasRef {sasRef} out of range (max={len(self._sasd())-1}) in current selected project"
2108+
if errmsg: raise Exception(errmsg)
20782109

20792110
def SASs(self):
20802111
"""
@@ -2468,7 +2499,8 @@ def make_var_obj(self, phase=None, hist=None, varname=None, atomId=None,
24682499
return G2obj.G2VarObj(phase, hist, varname, atomId)
24692500

24702501
def add_image(self, imagefile, fmthint=None, defaultImage=None,
2471-
indexList=None, cacheImage=False):
2502+
indexList=None, cacheImage=False,
2503+
URL=False, download_loc=None):
24722504
"""Load an image into a project
24732505
24742506
:param str imagefile: The image file to read, a filename.
@@ -2485,12 +2517,34 @@ def add_image(self, imagefile, fmthint=None, defaultImage=None,
24852517
to be included in the project.
24862518
:param bool cacheImage: When True, the image is cached to save
24872519
in rereading it later. Default is False (no caching).
2488-
2520+
:param bool URL: if True, the contents of imagefile is a URL
2521+
and the file will be downloaded and saved. The file will be
2522+
written in the specified directory (see `download_loc`)
2523+
or a temporary location, if not specified. Note that
2524+
if a temporary location, if the proiject (.gpx) file is
2525+
saved, the image may not be accessible if the .gpx file
2526+
is later reopened. Default is False.
2527+
If URL is specified and the Python requests package is
2528+
not installed, a `ModuleNotFoundError` Exception will occur.
2529+
will occur.
2530+
:param str download_loc: a location or file name where the
2531+
image will be saved. Note that for almost all image types,
2532+
the image cannot be read if the file extension does not
2533+
match what is expected for the format. (This can be determined
2534+
by looking at the importer code; if `strictExtension=True`,
2535+
the extension must be in the `extensionlist` list.)
2536+
If only a directory is specified, the file name will be taken
2537+
from the URL, which will likely cause problems if it does
2538+
not match the needed extension.
2539+
If URL is specified and the default download_loc
2540+
value is used (None), the image will be saved in a temporary
2541+
location that will persist until the OS removes it.
24892542
:returns: a list of :class:`G2Image` object(s) for the added image(s)
24902543
"""
24912544
LoadG2fil()
2492-
imagefile = os.path.abspath(os.path.expanduser(imagefile))
2493-
readers = import_generic(imagefile, Readers['Image'], fmthint=fmthint)
2545+
if not URL: imagefile = os.path.abspath(os.path.expanduser(imagefile))
2546+
readers = import_generic(imagefile, Readers['Image'],
2547+
fmthint=fmthint, URL=URL, download_loc=download_loc)
24942548
objlist = []
24952549
for i,rd in enumerate(readers):
24962550
if indexList is not None and i not in indexList:
@@ -3822,10 +3876,12 @@ def set_refinements(self, refs):
38223876
elif key == 'Instrument Parameters':
38233877
instrument, secondary = self.data['Instrument Parameters']
38243878
for iparam in value:
3879+
errmsg = ''
38253880
try:
38263881
instrument[iparam][2] = True
38273882
except IndexError:
3828-
raise ValueError("Invalid key:", iparam)
3883+
errmsg = f"Invalid key: {iparam}"
3884+
if errmsg: raise ValueError(errmsg)
38293885
else:
38303886
raise ValueError("Unknown key:", key)
38313887
# Fit fixed points after the fact - ensure they are after fixed points
@@ -5335,6 +5391,7 @@ def setHAPentryValue(self, keylist, newvalue):
53355391
def _getBondRest(self,nam):
53365392
if 'Restraints' not in self.proj.data:
53375393
raise G2ScriptException(f"{nam} error: Restraints entry not in data tree")
5394+
errmsg = ''
53385395
try:
53395396
return self.proj.data['Restraints']['data'][self.name]['Bond']
53405397
except:
@@ -5701,13 +5758,14 @@ def RefData(self,hist):
57015758
refinement results and the second element has the contents of
57025759
the histogram tree items.
57035760
'''
5761+
errmsg = ''
57045762
try:
57055763
hist = self.data['histNames'][hist]
57065764
except IndexError:
5707-
raise Exception('Histogram #{} is out of range from the Sequential Refinement'
5708-
.format(hist))
5765+
errmsg = 'Histogram #{hist} is out of range from the Sequential Refinement'
57095766
except TypeError:
57105767
pass
5768+
if errmsg: raise Exception(errmsg)
57115769
if hist not in self.data['histNames']:
57125770
raise Exception('Histogram {} is not included in the Sequential Refinement'
57135771
.format(hist))
@@ -6148,6 +6206,7 @@ def setControl(self,arg,value):
61486206
G2fil.G2Print('Allowed args:\n',[nam for nam,typ in self.findControl('')])
61496207
raise Exception('arg {} not defined in G2Image.setControl'
61506208
.format(arg))
6209+
errmsg = ''
61516210
try:
61526211
if typ == 'int':
61536212
self.data['Image Controls'][arg] = int(value)
@@ -6165,8 +6224,9 @@ def setControl(self,arg,value):
61656224
raise Exception('Unknown type {} for arg {} in G2Image.setControl'
61666225
.format(typ,arg))
61676226
except:
6168-
raise Exception('Error formatting value {} as type {} for arg {} in G2Image.setControl'
6169-
.format(value,typ,arg))
6227+
errmsg = 'Error formatting value {value} as type {typ} for arg {arg} in G2Image.setControl'
6228+
6229+
if errmsg: raise Exception(errmsg)
61706230

61716231
def getControl(self,arg):
61726232
'''Return an Image Controls parameter in the current image.
@@ -6667,7 +6727,7 @@ def GeneratePixelMask(self,esdMul=3.0,ttmin=0.,ttmax=180.,
66676727
Mask is placed into the G2image object where it will be
66686728
accessed during integration. Note that this increases the .gpx file
66696729
size significantly; use :meth:`~G2Image.clearPixelMask` to delete
6670-
this if it need not be saved.
6730+
this, if it need not be saved.
66716731
66726732
This code is based on :func:`GSASIIimage.FastAutoPixelMask`
66736733
but has been modified to recycle expensive computations
@@ -6741,12 +6801,15 @@ def GeneratePixelMask(self,esdMul=3.0,ttmin=0.,ttmax=180.,
67416801
G2fil.G2Print(f'Fast mask: Spots greater or less than {esdMul:.1f} of median abs deviation are masked')
67426802
outMask = np.zeros_like(tam,dtype=bool).ravel()
67436803
TThs = np.linspace(LUtth[0], LUtth[1], numChans, False)
6804+
errmsg = ''
67446805
try:
67456806
fmask.mask(esdMul, tam.ravel(), TA.ravel(),
67466807
Image.ravel(), TThs, outMask, ttmin, ttmax)
67476808
except Exception as msg:
6748-
print('Exception in fmask.mask\n\t',msg)
6749-
raise Exception(msg)
6809+
errmsg = msg
6810+
if errmsg:
6811+
print('Exception in fmask.mask\n\t',errmsg)
6812+
raise Exception(errmsg)
67506813
outMask = outMask.reshape(Image.shape)
67516814
else: # slow search, no sense using cache to save time
67526815
Masks['SpotMask']['SearchMin'] = ttmin

pixi/pixi.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ clean-build = { cmd = "(rm dist/*whl || true) && (rm -r build || true) ", cwd='.
1818
saveversions = { cmd = "python save-versions.py", cwd='../GSASII/install' }
1919
build = { cmd = "python -m build -wnx -vvvv -Cbuild-dir='build'", cwd='../', depends-on = ['clean-build']}
2020
install = { cmd = "pip install dist/*whl --force-reinstall --no-deps" , cwd='../', depends-on=['saveversions', 'build']}
21+
2122
# following contains a rather messy way to get files into bin area
22-
install-editable = { cmd = "pip install -ve . --no-build-isolation; /bin/cp -v $(find ./build -name convcell) ./pixi/.pixi/envs/default/bin/; /bin/cp -v $(find ./build -name LATTIC) ./pixi/.pixi/envs/default/bin/", cwd='../', depends-on=['clean-build', 'saveversions']}
23+
install-editable = { cmd = "pip install -ve . --no-build-isolation; /bin/cp -v $(find ./build -name convcell) ./pixi/.pixi/envs/$PIXI_ENVIRONMENT_NAME/bin/; /bin/cp -v $(find ./build -name LATTIC) ./pixi/.pixi/envs/$PIXI_ENVIRONMENT_NAME/bin/", cwd='../', depends-on=['clean-build', 'saveversions']}
2324

2425
# at present all windows stuff is questionable because flang does not [yet] work for GSAS-II binaries
2526
build-win = { cmd = "python -m build -wnx -vvvv -Cbuild-dir='build'", cwd='../', depends-on = ['clean-build'] , env={CC = 'clang-cl', CXX ='clang-cl'}}

0 commit comments

Comments
 (0)