summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOnderwaater <onderwaa@esrf.fr>2015-12-14 09:24:29 +0100
committerOnderwaater <onderwaa@esrf.fr>2015-12-14 09:24:29 +0100
commit9bea7cc3ffa0ab6263054c39fa2db7b413a191c0 (patch)
tree0ebe81446225f4bb16b709d5e4e61102d9388dac
parentcf74ea2a392e1904efc78774caa57d8f63a6656a (diff)
python3 support + old style connections removal + bugfix in limits
-rw-r--r--binoculars/__init__.py6
-rw-r--r--binoculars/backend.py2
-rw-r--r--binoculars/backends/bm25.py5
-rw-r--r--binoculars/backends/bm32.py14
-rw-r--r--binoculars/backends/example.py2
-rw-r--r--binoculars/backends/id03.py26
-rw-r--r--binoculars/backends/id03_xu.py20
-rw-r--r--binoculars/backends/sixs.py8
-rwxr-xr-xbinoculars/dispatcher.py17
-rw-r--r--binoculars/fit.py34
-rwxr-xr-xbinoculars/main.py3
-rwxr-xr-xbinoculars/space.py33
-rwxr-xr-xbinoculars/util.py74
-rwxr-xr-xscripts/binoculars34
-rwxr-xr-xscripts/binoculars-fitaid52
-rwxr-xr-xscripts/binoculars-gui89
-rwxr-xr-xscripts/binoculars-processgui7
-rwxr-xr-xscripts/binoculars-server36
18 files changed, 272 insertions, 190 deletions
diff --git a/binoculars/__init__.py b/binoculars/__init__.py
index 4ed0103..82734bb 100644
--- a/binoculars/__init__.py
+++ b/binoculars/__init__.py
@@ -1,9 +1,9 @@
+from __future__ import print_function, with_statement, division
+
import os
import sys
# for scripted useage
-
-
def run(args):
'''Parameters
args: string
@@ -205,7 +205,7 @@ def fitspace(space, function, guess=None):
Examples:
>>> fit = binoculars.fitspace(space, 'lorentzian')
- >>> print fit.summary
+ >>> print(fit.summary)
I: 1.081e-07 +/- inf
loc: 0.3703 +/- inf
gamma: 0.02383 +/- inf
diff --git a/binoculars/backend.py b/binoculars/backend.py
index c2e5d5a..7c54a3e 100644
--- a/binoculars/backend.py
+++ b/binoculars/backend.py
@@ -5,7 +5,7 @@ class ProjectionBase(util.ConfigurableObject):
def parse_config(self, config):
super(ProjectionBase, self).parse_config(config)
res = config.pop('resolution') # or just give 1 number for all dimensions
- self.config.limits = util.parse_pairs(config.pop('limits', None)) # Optional, set the limits of the space object in projected coordinates. Syntax is same as numpy e.g. '0.3:-0.6, -1:5, :'
+ self.config.limits = util.parse_pairs(config.pop('limits', None)) # Optional, set the limits of the space object in projected coordinates. Syntax is same as numpy e.g. 'limits = [:0,-1:,:], [0:,:-1,:], [:0,:-1,:], [0:,-1:,:]'
labels = self.get_axis_labels()
if not self.config.limits is None:
for lim in self.config.limits:
diff --git a/binoculars/backends/bm25.py b/binoculars/backends/bm25.py
index d9e8adc..06d3bbf 100644
--- a/binoculars/backends/bm25.py
+++ b/binoculars/backends/bm25.py
@@ -21,7 +21,6 @@ author: Dominik Kriegner (dominik.kriegner@gmail.com)
import sys
import os
-import itertools
import glob
import numpy
import xrayutilities as xu
@@ -177,7 +176,7 @@ class EH2SCD(EDFInput):
pwidth2=self.config.pixelsize[0],
distance=1e-10,
roi=roi)
- print('{:>20} {:>9} {:>10} {:>9} {:>9} {:>9}'.format(' ', 'Mu', 'Theta', 'CCD_Y', 'CCD_X', 'CCD_Z'))
+ print(('{:>20} {:>9} {:>10} {:>9} {:>9} {:>9}'.format(' ', 'Mu', 'Theta', 'CCD_Y', 'CCD_X', 'CCD_Z')))
def process_image(self, image):
# motor positions
@@ -205,7 +204,7 @@ class EH2SCD(EDFInput):
# normalization
data = image.data / mon / transm
- print('{:>20} {:9.4f} {:10.4f} {:9.1f} {:9.1f} {:9.1f}'.format(os.path.split(image.filename)[-1] ,mu, th, cty, ctx, ctz))
+ print(('{:>20} {:9.4f} {:10.4f} {:9.1f} {:9.1f} {:9.1f}'.format(os.path.split(image.filename)[-1] ,mu, th, cty, ctx, ctz)))
# masking
intensity = self.apply_mask(data, self.config.xmask, self.config.ymask)
diff --git a/binoculars/backends/bm32.py b/binoculars/backends/bm32.py
index cf03d3f..993ad5c 100644
--- a/binoculars/backends/bm32.py
+++ b/binoculars/backends/bm32.py
@@ -1,10 +1,16 @@
import sys
import os
-import itertools
import glob
import numpy
import time
+#python3 support
+PY3 = sys.version_info > (3,)
+if PY3:
+ pass
+else:
+ from itertools import izip as zip
+
try:
from PyMca import specfilewrapper, EdfFile, SixCircle, specfile
except ImportError:
@@ -192,7 +198,7 @@ class BM32Input(backend.InputBase):
pointparams = self.get_point_params(scan, job.firstpoint, job.lastpoint) # 2D array of diffractometer angles + mon + transm
images = self.get_images(scan, job.firstpoint, job.lastpoint) # iterator!
- for pp, image in itertools.izip(pointparams, images):
+ for pp, image in zip(pointparams, images):
yield self.process_image(scanparams, pp, image)
util.statuseol()
except Exception as exc:
@@ -277,7 +283,7 @@ class BM32Input(backend.InputBase):
uccdtagline = scan.header('M')[0].split()[-1]
UCCD = os.path.dirname(uccdtagline).split(os.sep)
except:
- print 'warning: UCCD tag not found, use imagefolder for proper file specification'
+ print('warning: UCCD tag not found, use imagefolder for proper file specification')
UCCD = []
pattern = self._get_pattern(UCCD)
matches = self.find_edfs(pattern)
@@ -377,7 +383,7 @@ class EH1(BM32Input):
def get_point_params(self, scan, first, last):
sl = slice(first, last+1)
- DEL, OME, ALF, BET, CHI, PHI, MON, TRANSM = range(8)
+ DEL, OME, ALF, BET, CHI, PHI, MON, TRANSM = list(range(8))
params = numpy.zeros((last - first + 1, 8)) # gamma delta theta chi phi mu mon transm
params[:, CHI] = 0 #scan.motorpos('CHI')
params[:, PHI] = 0 #scan.motorpos('PHI')
diff --git a/binoculars/backends/example.py b/binoculars/backends/example.py
index c763eb8..d79bb52 100644
--- a/binoculars/backends/example.py
+++ b/binoculars/backends/example.py
@@ -78,7 +78,7 @@ class Input(backend.InputBase):
aai = numpy.linspace(0, numpy.random.random() * 20, 100)
aomega = numpy.linspace(0, numpy.random.random() * 20, 100)
for af, delta, ai, omega in zip(aaf, adelta, aai, aomega):
- print 'af: {0}, delta: {1}, ai: {2}, omega: {3}'.format(af, delta, ai, omega)
+ print('af: {0}, delta: {1}, ai: {2}, omega: {3}'.format(af, delta, ai, omega))
# caculating the angles per pixel. The values specified in the configuration file
# can be used for calculating these values
diff --git a/binoculars/backends/id03.py b/binoculars/backends/id03.py
index 9389517..a388348 100644
--- a/binoculars/backends/id03.py
+++ b/binoculars/backends/id03.py
@@ -5,12 +5,18 @@ import glob
import numpy
import time
+#python3 support
+PY3 = sys.version_info > (3,)
+if PY3:
+ pass
+else:
+ from itertools import izip as zip
+
try:
from PyMca import specfilewrapper, EdfFile, SixCircle, specfile
except ImportError:
from PyMca5.PyMca import specfilewrapper, EdfFile, SixCircle, specfile
-
from .. import backend, errors, util
@@ -290,7 +296,7 @@ class ID03Input(backend.InputBase):
yield backend.Job(scan=scanno, firstpoint=firstpoint+s.start, lastpoint=firstpoint+s.stop-1, weight=s.stop-s.start)
else: # scanlength is unknown
step = int(self.config.target_weight / 1.4)
- for start, stop in itertools.izip(itertools.count(0, step), itertools.count(step, step)):
+ for start, stop in zip(itertools.count(0, step), itertools.count(step, step)):
if self.wait_for_points(scanno, stop, timeout=self.config.timeout):
stop = self.get_scan(scanno).lines()
yield backend.Job(scan=scanno, firstpoint=start, lastpoint=stop-1, weight=stop-start)
@@ -307,7 +313,7 @@ class ID03Input(backend.InputBase):
pointparams = self.get_point_params(scan, job.firstpoint, job.lastpoint) # 2D array of diffractometer angles + mon + transm
images = self.get_images(scan, job.firstpoint, job.lastpoint) # iterator!
- for pp, image in itertools.izip(pointparams, images):
+ for pp, image in zip(pointparams, images):
yield self.process_image(scanparams, pp, image)
util.statuseol()
except Exception as exc:
@@ -418,7 +424,7 @@ class ID03Input(backend.InputBase):
filename = os.path.basename(file).split('.')[0]
scan, point, image = filename.split('_')[-3:]
scan, point, image = int(scan), int(point), int(image)
- if scan == scanno and point not in ret.keys():
+ if scan == scanno and point not in list(ret.keys()):
ret[point] = file
except ValueError:
continue
@@ -480,7 +486,7 @@ class ID03Input(backend.InputBase):
uccdtagline = scanheaderC[0]
UCCD = os.path.split(uccdtagline.split()[-1])
except:
- print 'warning: UCCD tag not found, use imagefolder for proper file specification'
+ print('warning: UCCD tag not found, use imagefolder for proper file specification')
UCCD = []
pattern = self._get_pattern(UCCD)
matches = self.find_edfs(pattern, zapscanno)
@@ -499,7 +505,7 @@ class ID03Input(backend.InputBase):
uccdtagline = scan.header('UCCD')[0]
UCCD = os.path.split(os.path.dirname(uccdtagline.split()[-1]))
except:
- print 'warning: UCCD tag not found, use imagefolder for proper file specification'
+ print('warning: UCCD tag not found, use imagefolder for proper file specification')
UCCD = []
pattern = self._get_pattern(UCCD)
matches = self.find_edfs(pattern, scan.number())
@@ -595,7 +601,7 @@ class EH1(ID03Input):
def get_point_params(self, scan, first, last):
sl = slice(first, last+1)
- GAM, DEL, TH, CHI, PHI, MU, MON, TRANSM, HRX, HRY = range(10)
+ GAM, DEL, TH, CHI, PHI, MU, MON, TRANSM, HRX, HRY = list(range(10))
params = numpy.zeros((last - first + 1, 10)) # gamma delta theta chi phi mu mon transm
params[:, CHI] = scan.motorpos('Chi')
params[:, PHI] = scan.motorpos('Phi')
@@ -712,7 +718,7 @@ class EH2(ID03Input):
def get_point_params(self, scan, first, last):
sl = slice(first, last+1)
- GAM, DEL, TH, CHI, PHI, MU, MON, TRANSM = range(8)
+ GAM, DEL, TH, CHI, PHI, MU, MON, TRANSM = list(range(8))
params = numpy.zeros((last - first + 1, 8)) # gamma delta theta chi phi mu mon transm
params[:, CHI] = scan.motorpos('Chi')
params[:, PHI] = scan.motorpos('Phi')
@@ -808,7 +814,7 @@ class GisaxsDetector(ID03Input):
def get_point_params(self, scan, first, last):
sl = slice(first, last+1)
- CCDY, CCDZ, TH, CHI, PHI, MU, MON, TRANSM = range(8)
+ CCDY, CCDZ, TH, CHI, PHI, MU, MON, TRANSM = list(range(8))
params = numpy.zeros((last - first + 1, 8)) # gamma delta theta chi phi mu mon transm
params[:, CHI] = scan.motorpos('Chi')
params[:, PHI] = scan.motorpos('Phi')
@@ -834,7 +840,7 @@ class GisaxsDetector(ID03Input):
filename = os.path.basename(file).split('.')[0]
scan, point = filename.split('_')[-2:]
scan, point = int(scan), int(point)
- if scan == scanno and point not in ret.keys():
+ if scan == scanno and point not in list(ret.keys()):
ret[point] = file
except ValueError:
continue
diff --git a/binoculars/backends/id03_xu.py b/binoculars/backends/id03_xu.py
index d8c3fe0..a10f617 100644
--- a/binoculars/backends/id03_xu.py
+++ b/binoculars/backends/id03_xu.py
@@ -13,13 +13,19 @@ author: Dominik Kriegner (dominik.kriegner@gmail.com)
import sys
import os
-import itertools
import glob
import numpy
import xrayutilities as xu
from PyMca import specfile
+#python3 support
+PY3 = sys.version_info > (3,)
+if PY3:
+ pass
+else:
+ import itertools import izip as zip
+
try:
from PyMca import specfilewrapper, EdfFile
except ImportError:
@@ -87,7 +93,7 @@ class ID03Input(backend.InputBase):
pointparams = self.get_point_params(scan, job.firstpoint, job.lastpoint) # 1D array of diffractometer angles + mon + transm
images = self.get_images(scan, job.firstpoint, job.lastpoint) # iterator!
- for pp, image in itertools.izip(pointparams, images):
+ for pp, image in zip(pointparams, images):
yield self.process_image(scanparams, pp, image)
def parse_config(self, config):
@@ -125,7 +131,7 @@ class ID03Input(backend.InputBase):
filename = os.path.basename(file).split('.')[0]
scan, point, image = filename.split('_')[-3:]
scan, point, image = int(scan), int(point), int(image)
- if scan == scanno and point not in ret.keys():
+ if scan == scanno and point not in list(ret.keys()):
ret[point] = file
except ValueError:
continue
@@ -149,7 +155,7 @@ class ID03Input(backend.InputBase):
uccdtagline = scan.header('UCCD')[0]
UCCD = os.path.split(os.path.dirname(uccdtagline.split()[-1]))
except:
- print 'warning: UCCD tag not found, use imagefolder for proper file specification'
+ print('warning: UCCD tag not found, use imagefolder for proper file specification')
UCCD = []
pattern = self._get_pattern(UCCD)
matches = self.find_edfs(pattern, scan.number())
@@ -211,13 +217,13 @@ class EH2(ID03Input):
# distance sdd-600 corresponds to distance of the detector chip from
# the gamR rotation axis (rest is handled by the translations ty and
# gamT (along z))
- print('{:>9} {:>10} {:>9} {:>9}'.format('Mu', 'Theta', 'Delta', 'Gamma'))
+ print(('{:>9} {:>10} {:>9} {:>9}'.format('Mu', 'Theta', 'Delta', 'Gamma')))
def process_image(self, scanparams, pointparams, image):
mu, theta, chi, phi, delta, gamma, mon, transm = pointparams
wavelength, UB = scanparams
data = image / mon / transm
- print('{:9.4f} {:10.4f} {:9.4f} {:9.4f}'.format(mu, theta, delta, gamma))
+ print(('{:9.4f} {:10.4f} {:9.4f} {:9.4f}'.format(mu, theta, delta, gamma)))
# recalculate detector translation (which should be saved!)
gamT = self.ty * numpy.tan(numpy.radians(gamma))
@@ -233,7 +239,7 @@ class EH2(ID03Input):
def get_point_params(self, scan, first, last):
sl = slice(first, last+1)
- MU, TH, CHI, PHI, DEL, GAM, MON, TRANSM = range(8)
+ MU, TH, CHI, PHI, DEL, GAM, MON, TRANSM = list(range(8))
params = numpy.zeros((last - first + 1, 8))
# Mu, Theta, Chi, Phi, Delta, Gamma, MON, transm
params[:, CHI] = scan.motorpos('Chi')
diff --git a/binoculars/backends/sixs.py b/binoculars/backends/sixs.py
index 57fff05..4e47166 100644
--- a/binoculars/backends/sixs.py
+++ b/binoculars/backends/sixs.py
@@ -41,6 +41,10 @@ from networkx import DiGraph, dijkstra_path
from .. import backend, errors, util
+if PY3:
+ from functools import reduce
+else:
+ from itertools import izip as zip
class realspace(backend.ProjectionBase):
# scalars: mu, theta, [chi, phi, "omitted"] delta, gamR, gamT, ty, wavelength
@@ -269,7 +273,7 @@ def dataframes(hfile, data_path=None):
}
# now instantiate the pytables objects
- for key, value in data_path.iteritems():
+ for key, value in data_path.items():
child = scan_data._f_get_child(value)
dataframe[key] = child
@@ -311,7 +315,7 @@ def rotation_axes(graph, nodes):
def zip_with(f, *coll):
- return itertools.starmap(f, itertools.izip(*coll))
+ return itertools.starmap(f, zip(*coll))
def rotation_matrix(values, axes):
diff --git a/binoculars/dispatcher.py b/binoculars/dispatcher.py
index 83b4ee8..7a05043 100755
--- a/binoculars/dispatcher.py
+++ b/binoculars/dispatcher.py
@@ -1,3 +1,4 @@
+import sys
import os
import time
import itertools
@@ -6,6 +7,8 @@ import multiprocessing
from . import util, errors, space
+#python3 support
+PY3 = sys.version_info > (3,)
class Destination(object):
type = filename = overwrite = value = config = limits = None
@@ -151,14 +154,14 @@ class Local(ReentrantBase):
self.config.ncores = multiprocessing.cpu_count()
def process_jobs(self, jobs):
- if self.config.ncores == 1: # note: SingleCore will be marginally faster
- imap = itertools.imap
+ if self.config.ncores == 1 and not PY3: # note: SingleCore will be marginally faster
+ map = itertools.imap
else:
pool = multiprocessing.Pool(self.config.ncores)
- imap = pool.imap_unordered
+ map = pool.imap_unordered
configs = (self.prepare_config(job) for job in jobs)
- for result in imap(self.main.get_reentrant(), configs):
+ for result in map(self.main.get_reentrant(), configs):
yield result
def sum(self, results):
@@ -311,7 +314,7 @@ class Oar(ReentrantBase):
try:
os.remove(f)
except Exception as e:
- print "unable to remove {0}: {1}".format(f, e)
+ print("unable to remove {0}: {1}".format(f, e))
errorfn = []
@@ -323,7 +326,7 @@ class Oar(ReentrantBase):
errormsg = fp.read()
if len(errormsg) > 0:
errorfn.append(errorfilename)
- print 'Critical error: OAR Job {0} failed with the following error: \n{1}'.format(jobid, errormsg)
+ print('Critical error: OAR Job {0} failed with the following error: \n{1}'.format(jobid, errormsg))
if len(errorfn) > 0:
- print 'Warning! {0} job(s) failed. See above for the details or the error log files: {1}'.format(len(errorfn), ', '.join(errorfn))
+ print('Warning! {0} job(s) failed. See above for the details or the error log files: {1}'.format(len(errorfn), ', '.join(errorfn)))
diff --git a/binoculars/fit.py b/binoculars/fit.py
index 028b8e5..a9333ad 100644
--- a/binoculars/fit.py
+++ b/binoculars/fit.py
@@ -133,7 +133,7 @@ def rot3d(x, y, z, th, ph):
def get_class_by_name(name):
options = {}
- for k, v in globals().iteritems():
+ for k, v in globals().items():
if isinstance(v, type) and issubclass(v, FitBase):
options[k.lower()] = v
if name.lower() in options:
@@ -145,7 +145,9 @@ def get_class_by_name(name):
# fitting functions
class Lorentzian1D(PeakFitBase):
@staticmethod
- def func((x, ), (I, loc, gamma, slope, offset)):
+ def func(xxx_todo_changeme, xxx_todo_changeme1):
+ (x, ) = xxx_todo_changeme
+ (I, loc, gamma, slope, offset) = xxx_todo_changeme1
return I / ((x - loc)**2 + gamma**2) + offset + x * slope
def set_guess(self, maximum, argmax, linparams):
@@ -155,7 +157,9 @@ class Lorentzian1D(PeakFitBase):
class Lorentzian1DNoBkg(PeakFitBase):
@staticmethod
- def func((x, ), (I, loc, gamma)):
+ def func(xxx_todo_changeme2, xxx_todo_changeme3):
+ (x, ) = xxx_todo_changeme2
+ (I, loc, gamma) = xxx_todo_changeme3
return I / ((x - loc)**2 + gamma**2)
def set_guess(self, maximum, argmax, linparams):
@@ -165,7 +169,9 @@ class Lorentzian1DNoBkg(PeakFitBase):
class PolarLorentzian2Dnobkg(PeakFitBase):
@staticmethod
- def func((x, y), (I, loc0, loc1, gamma0, gamma1, th)):
+ def func(xxx_todo_changeme4, xxx_todo_changeme5):
+ (x, y) = xxx_todo_changeme4
+ (I, loc0, loc1, gamma0, gamma1, th) = xxx_todo_changeme5
a, b = tuple(grid - center for grid, center in zip(rot2d(x, y, th), rot2d(loc0, loc1, th)))
return (I / (1 + (a / gamma0)**2 + (b / gamma1)**2))
@@ -177,7 +183,9 @@ class PolarLorentzian2Dnobkg(PeakFitBase):
class PolarLorentzian2D(PeakFitBase):
@staticmethod
- def func((x, y), (I, loc0, loc1, gamma0, gamma1, th, slope1, slope2, offset)):
+ def func(xxx_todo_changeme6, xxx_todo_changeme7):
+ (x, y) = xxx_todo_changeme6
+ (I, loc0, loc1, gamma0, gamma1, th, slope1, slope2, offset) = xxx_todo_changeme7
a, b = tuple(grid - center for grid, center in zip(rot2d(x, y, th), rot2d(loc0, loc1, th)))
return (I / (1 + (a / gamma0)**2 + (b / gamma1)**2) + x * slope1 + y * slope2 + offset)
@@ -192,7 +200,9 @@ class PolarLorentzian2D(PeakFitBase):
class Lorentzian2D(PeakFitBase):
@staticmethod
- def func((x, y), (I, loc0, loc1, gamma0, gamma1, th, slope1, slope2, offset)):
+ def func(xxx_todo_changeme8, xxx_todo_changeme9):
+ (x, y) = xxx_todo_changeme8
+ (I, loc0, loc1, gamma0, gamma1, th, slope1, slope2, offset) = xxx_todo_changeme9
a, b = tuple(grid - center for grid, center in zip(rot2d(x, y, th), rot2d(loc0, loc1, th)))
return (I / (1 + (a/gamma0)**2) * 1 / (1 + (b/gamma1)**2) + x * slope1 + y * slope2 + offset)
@@ -204,7 +214,9 @@ class Lorentzian2D(PeakFitBase):
class Lorentzian2Dnobkg(PeakFitBase):
@staticmethod
- def func((x, y), (I, loc0, loc1, gamma0, gamma1, th)):
+ def func(xxx_todo_changeme10, xxx_todo_changeme11):
+ (x, y) = xxx_todo_changeme10
+ (I, loc0, loc1, gamma0, gamma1, th) = xxx_todo_changeme11
a, b = tuple(grid - center for grid, center in zip(rot2d(x, y, th), rot2d(loc0, loc1, th)))
return (I / (1 + (a/gamma0)**2) * 1 / (1 + (b/gamma1)**2))
@@ -220,13 +232,17 @@ class Lorentzian(AutoDimensionFit):
class Gaussian1D(PeakFitBase):
@staticmethod
- def func((x,), (loc, I, sigma, offset, slope)):
+ def func(xxx_todo_changeme12, xxx_todo_changeme13):
+ (x,) = xxx_todo_changeme12
+ (loc, I, sigma, offset, slope) = xxx_todo_changeme13
return I * numpy.exp(-((x-loc)/sigma)**2/2) + offset + x * slope
class Voigt1D(PeakFitBase):
@staticmethod
- def func((x, ), (I, loc, sigma, gamma, slope, offset)):
+ def func(xxx_todo_changeme14, xxx_todo_changeme15):
+ (x, ) = xxx_todo_changeme14
+ (I, loc, sigma, gamma, slope, offset) = xxx_todo_changeme15
z = (x - loc + numpy.complex(0, gamma)) / (sigma * numpy.sqrt(2))
return I * numpy.real(scipy.special.wofz(z))/(sigma * numpy.sqrt(2 * numpy.pi)) + offset + x * slope
diff --git a/binoculars/main.py b/binoculars/main.py
index 188427b..6c80f1b 100755
--- a/binoculars/main.py
+++ b/binoculars/main.py
@@ -22,7 +22,8 @@ def parse_commandline_config_option(s):
return section, option, value
-def multiprocessing_main((config, command)): # note the double parenthesis for map() convenience
+def multiprocessing_main(xxx_todo_changeme): # note the double parenthesis for map() convenience
+ (config, command) = xxx_todo_changeme
Main.from_object(config, command)
return config.dispatcher.destination.retrieve()
diff --git a/binoculars/space.py b/binoculars/space.py
index cc9138f..de501d3 100755
--- a/binoculars/space.py
+++ b/binoculars/space.py
@@ -1,10 +1,20 @@
-import itertools
+from __future__ import unicode_literals
+
import numbers
import numpy
import h5py
+import sys
+from itertools import chain
from . import util, errors
+#python3 support
+PY3 = sys.version_info > (3,)
+if PY3:
+ from functools import reduce
+ basestring = (str,bytes)
+else:
+ from itertools import izip as zip
def silence_numpy_errors():
"""Silence numpy warnings about zero division. Normal usage of Space() will trigger these warnings."""
@@ -13,7 +23,7 @@ def silence_numpy_errors():
def sum_onto(a, axis):
"""Numpy convenience. Project all dimensions of an array onto an axis, i.e. apply sum() to all axes except the one given."""
- for i in reversed(range(len(a.shape))):
+ for i in reversed(list(range(len(a.shape)))):
if axis != i:
a = a.sum(axis=i)
return a
@@ -56,7 +66,7 @@ class Axis(object):
return self.imax - self.imin + 1
def __iter__(self):
- return iter(self[index] for index in xrange(len(self)))
+ return iter(self[index] for index in range(len(self)))
def __getitem__(self, key):
if isinstance(key, slice):
@@ -568,7 +578,7 @@ class Space(object):
weights = self.contributions
# get rid of invalid coords
- valid = reduce(numpy.bitwise_and, intertools.chain((numpy.isfinite(t) for t in transcoords)), (weights > 0, ))
+ valid = reduce(numpy.bitwise_and, chain((numpy.isfinite(t) for t in transcoords)), (weights > 0, ))
transcoords = tuple(t[valid] for t in transcoords)
return self.from_image(resolutions, labels, transcoords, intensity[valid], weights[valid])
@@ -582,7 +592,7 @@ class Space(object):
if len(coordinates) != len(self.axes):
raise ValueError('dimension mismatch between coordinates and axes')
- intensity = numpy.nan_to_num(intensity).flatten() # invalids should be handeled by setting weight to 0, this ensures the weights can do that
+ intensity = numpy.nan_to_num(intensity).flatten() # invalids can be handeled by setting weight to 0, this ensures the weights can do that
weights = weights.flatten()
indices = numpy.array(tuple(ax.get_index(coord) for (ax, coord) in zip(self.axes, coordinates)))
@@ -609,11 +619,11 @@ class Space(object):
if limits is not None:
invalid = numpy.zeros(intensity.shape).astype(numpy.bool)
for coord, sl in zip(coordinates, limits):
- if sl.start is None and sl.stop ia not None:
+ if sl.start is None and sl.stop is not None:
invalid += coord > sl.stop
elif sl.start is not None and sl.stop is None:
invalid += coord < sl.start
- elif sl.start is not None and sl.stop os not None:
+ elif sl.start is not None and sl.stop is not None:
invalid += numpy.bitwise_or(coord < sl.start, coord > sl.stop)
if numpy.all(invalid is True):
@@ -657,6 +667,9 @@ class Space(object):
if len(axes) != len(key):
raise ValueError("dimensionality of 'key' does not match dimensionality of Space in HDF5 file {0}".format(file))
key = tuple(ax.get_index(k) for k, ax in zip(key, axes))
+ for index, sl in enumerate(key):
+ if sl.start == sl.stop and sl.start is not None:
+ raise KeyError('key results in empty space')
axes = tuple(ax[k] for k, ax in zip(key, axes) if isinstance(k, slice))
else:
key = Ellipsis
@@ -795,7 +808,7 @@ def sum(spaces):
def verse_sum(verses):
i = iter(M.spaces for M in verses)
- return Multiverse(sum(spaces) for spaces in itertools.izip(*i))
+ return Multiverse(sum(spaces) for spaces in zip(*i))
# hybrid sum() / __iadd__()
@@ -864,7 +877,7 @@ def dstack(spaces, dindices, dlabel, dresolution):
exprs.append('ones_like({0}) * {1}'.format(labels[0], dindex))
transformation = util.transformation_from_expressions(space, exprs)
return space.transform_coordinates(resolutions, labels, transformation)
- return sum(transform(space, dindex) for space, dindex in itertools.izip(spaces, dindices))
+ return sum(transform(space, dindex) for space, dindex in zip(spaces, dindices))
def axis_offset(space, label, offset):
@@ -897,5 +910,5 @@ def make_compatible(spaces):
resmax = tuple(numpy.vstack(tuple(ax.res for ax in space.reorder(ax0).axes) for space in spaces).max(axis=0))
resmin = tuple(numpy.vstack(tuple(ax.res for ax in space.reorder(ax0).axes) for space in spaces).min(axis=0))
if not resmax == resmin:
- print 'Warning: Not all spaces have the same resolution. Resolution will be changed to: {0}'.format(resmax)
+ print('Warning: Not all spaces have the same resolution. Resolution will be changed to: {0}'.format(resmax))
return tuple(space.reorder(ax0).rebin2(resmax) for space in spaces)
diff --git a/binoculars/util.py b/binoculars/util.py
index 30a09cd..4ef8377 100755
--- a/binoculars/util.py
+++ b/binoculars/util.py
@@ -1,9 +1,10 @@
+from __future__ import print_function, division
+
import os
import sys
import gzip
import itertools
import random
-import cPickle as pickle
import inspect
import time
import copy
@@ -11,20 +12,29 @@ import numpy
import contextlib
import argparse
import h5py
-import ConfigParser
import glob
-import errors
-import StringIO
+from . import errors
import struct
import json
import socket
-import StringIO
import binascii
import re
### ARGUMENT HANDLING
+#python3 support
+PY3 = sys.version_info > (3,)
+if PY3:
+ import pickle
+ import io
+ import configparser
+else:
+ import StringIO as io
+ import Queue as queue
+ import cPickle as pickle
+ import ConfigParser as configparser
+
class OrderedOperation(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
oops = getattr(namespace, 'ordered_operations', [])
@@ -115,7 +125,7 @@ def handle_ordered_operations(space, args, auto3to2=False):
space = space.project(projectaxis)
elif command == 'transform':
- labels, resolutions, exprs = zip(*parse_transform_args(opts))
+ labels, resolutions, exprs = list(zip(*parse_transform_args(opts)))
transformation = transformation_from_expressions(space, exprs)
info.append('transformed to {0}'.format(', '.join('{0} = {1}'.format(label, expr) for (label, expr) in zip(labels, exprs))))
space = space.transform_coordinates(resolutions, labels, transformation)
@@ -188,17 +198,17 @@ def get_backends():
def get_projections(module):
- import backend
+ from . import backend
return get_base(module, backend.ProjectionBase)
def get_inputs(module):
- import backend
+ from . import backend
return get_base(module, backend.InputBase)
def get_dispatchers():
- import dispatcher
+ from . import dispatcher
from inspect import isclass
items = dir(dispatcher)
@@ -238,7 +248,7 @@ def get_base(modname, base):
def get_dispatcher_configkeys(classname):
- import dispatcher
+ from . import dispatcher
cls = getattr(dispatcher, classname)
return get_configkeys(cls)
@@ -290,7 +300,7 @@ def parse_configcode(line):
def parse_range(r):
if '-' in r:
a, b = r.split('-')
- return range(int(a), int(b)+1)
+ return list(range(int(a), int(b)+1))
elif r:
return [int(r)]
else:
@@ -387,9 +397,9 @@ class MetaBase(object):
for section in self.sections:
section_dict = {}
attr = getattr(self, section)
- for key in attr.keys():
+ for key in list(attr.keys()):
if isinstance(attr[key], numpy.ndarray): # to be able to include numpy arrays in the serialisation
- sio = StringIO.StringIO()
+ sio = io.StringIO()
numpy.save(sio, attr[key])
sio.seek(0)
section_dict[key] = binascii.b2a_hex(sio.read()) # hex codation is needed to let json work with the string
@@ -402,12 +412,12 @@ class MetaBase(object):
def fromserial(cls, s):
obj = cls()
data = json.loads(s)
- for section in data.keys():
+ for section in list(data.keys()):
section_dict = data[section]
- for key in section_dict.keys():
- if isinstance(section_dict[key], basestring): # find and replace all the numpy serialised objects
+ for key in list(section_dict.keys()):
+ if isinstance(section_dict[key], str): # find and replace all the numpy serialised objects
if section_dict[key].startswith('934e554d505901004600'): # numpy marker
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sio.write(binascii.a2b_hex(section_dict[key]))
sio.seek(0)
section_dict[key] = numpy.load(sio)
@@ -416,10 +426,10 @@ class MetaBase(object):
obj.sections.append(section)
return obj
-# a collection of metadata objects
-class MetaData(object):
+
+class MetaData(object): # a collection of metadata objects
def __init__(self):
self.metas = []
@@ -441,7 +451,7 @@ class MetaData(object):
@classmethod
def fromfile(cls, filename):
- if isinstance(filename, basestring):
+ if isinstance(filename, str):
if not os.path.exists(filename):
raise IOError('Error importing configuration file. filename {0} does not exist'.format(filename))
@@ -453,7 +463,7 @@ class MetaData(object):
metadata = [] # when metadata is not present, proceed without Error
for label in metadata:
meta = MetaBase()
- for section in metadata[label].keys():
+ for section in list(metadata[label].keys()):
group = metadata[label][section]
setattr(meta, section, dict((key, group[key].value) for key in group))
meta.sections.append(section)
@@ -464,12 +474,12 @@ class MetaData(object):
with open_h5py(filename, 'w') as fp:
metadata = fp.create_group('metadata')
for meta in self.metas:
- label = find_unused_label('metasection', metadata.keys())
+ label = find_unused_label('metasection', list(metadata.keys()))
metabase = metadata.create_group(label)
for section in meta.sections:
sectiongroup = metabase.create_group(section)
s = getattr(meta, section)
- for key in s.keys():
+ for key in list(s.keys()):
sectiongroup.create_dataset(key, data=s[key])
def __repr__(self):
@@ -504,7 +514,7 @@ class ConfigFile(MetaBase):
@classmethod
def fromfile(cls, filename):
- if isinstance(filename, basestring):
+ if isinstance(filename, str):
if not os.path.exists(filename):
raise IOError('Error importing configuration file. filename {0} does not exist'.format(filename))
@@ -513,7 +523,7 @@ class ConfigFile(MetaBase):
try:
config = fp['configuration']
if 'command' in config.attrs:
- configobj.command = json.loads(config.attrs['command'])
+ configobj.command = json.loads(config.attrs['command'].decode('utf8'))
for section in config:
if isinstance(config[section], h5py._hl.group.Group): # new
setattr(configobj, section, dict((key, config[section][key].value) for key in config[section]))
@@ -528,7 +538,7 @@ class ConfigFile(MetaBase):
if not os.path.exists(filename):
raise IOError('Error importing configuration file. filename {0} does not exist'.format(filename))
- config = ConfigParser.RawConfigParser()
+ config = configparser.RawConfigParser()
config.read(filename)
for section, option, value in overrides:
@@ -547,7 +557,7 @@ class ConfigFile(MetaBase):
for section in self.sections:
sectiongroup = conf.create_group(section)
s = getattr(self, section)
- for key in s.keys():
+ for key in list(s.keys()):
sectiongroup.create_dataset(key, data=s[key])
def totxtfile(self, filename):
@@ -596,16 +606,16 @@ class ConfigurableObject(object):
else:
self.config = ConfigSection()
try:
- allkeys = config.keys()
+ allkeys = list(config.keys())
self.parse_config(config)
except KeyError as exc:
raise errors.ConfigError("Configuration option {0} is missing from the configuration file. Please specify this option in the configuration file".format(exc))
except Exception as exc:
- missing = set(key for key in allkeys if key not in self.config.__dict__.keys()) - set(config.keys())
+ missing = set(key for key in allkeys if key not in list(self.config.__dict__.keys())) - set(config.keys())
exc.args = errors.addmessage(exc.args, ". Unable to parse configuration option '{0}'. The error can quite likely be solved by modifying the option in the configuration file.".format(','.join(missing)))
raise
for k in config:
- print 'warning: unrecognized configuration option {0} for {1}'.format(k, self.__class__.__name__)
+ print('warning: unrecognized configuration option {0} for {1}'.format(k, self.__class__.__name__))
self.config.class_ = self.__class__
def parse_config(self, config):
@@ -892,7 +902,7 @@ def zpi_load(filename):
def serialize(space, command):
# first 48 bytes contain length of the message, whereby the first 8 give the length of the command, the second 8 the length of the configfile etc..
- message = StringIO.StringIO()
+ message = io.StringIO()
message.write(struct.pack('QQQQQQ', 0, 0, 0, 0, 0, 0))
message.write(command)
@@ -946,7 +956,7 @@ def socket_send(ip, port, mssg):
def socket_recieve(RequestHandler): # pass one the handler to deal with incoming data
def get_msg(length):
- msg = StringIO.StringIO()
+ msg = io.StringIO()
for packet in packet_slicer(length):
p = RequestHandler.request.recv(packet, socket.MSG_WAITALL) # wait for full mssg
msg.write(p)
diff --git a/scripts/binoculars b/scripts/binoculars
index 8080cad..067229b 100755
--- a/scripts/binoculars
+++ b/scripts/binoculars
@@ -32,7 +32,7 @@ def command_info(args):
if args.output:
if len(args.infile) > 1:
- print 'only one space file argument is support with extractconfig -> using the first'
+ print('only one space file argument is support with extractconfig -> using the first')
config = binoculars.util.ConfigFile.fromfile(args.infile[0])
config.totxtfile(args.output)
else:
@@ -40,16 +40,16 @@ def command_info(args):
try:
axes = binoculars.space.Axes.fromfile(f)
except Exception as e:
- print '{0}: unable to load Space: {1!r}'.format(f, e)
+ print(('{0}: unable to load Space: {1!r}'.format(f, e)))
else:
- print '{0} \n{1!r}'.format(f, axes)
+ print(('{0} \n{1!r}'.format(f, axes)))
if args.config:
try:
config = binoculars.util.ConfigFile.fromfile(f)
except Exception as e:
- print '{0}: unable to load util.ConfigFile: {1!r}'.format(f, e)
+ print(('{0}: unable to load util.ConfigFile: {1!r}'.format(f, e)))
else:
- print '{!r}'.format(config)
+ print(('{!r}'.format(config)))
# CONVERT
@@ -70,7 +70,7 @@ def command_convert(args):
if args.infile.endswith('.zpi'):
if not args.read_trusted_zpi:
- print 'error: .zpi files are unsafe, use --read-trusted-zpi to open'
+ print('error: .zpi files are unsafe, use --read-trusted-zpi to open')
sys.exit(1)
space = binoculars.util.zpi_load(args.infile)
else:
@@ -84,15 +84,15 @@ def command_convert(args):
if ext == '.edf':
binoculars.util.space_to_edf(space, args.outfile)
- print 'saved at {0}'.format(args.outfile)
+ print('saved at {0}'.format(args.outfile))
elif ext == '.txt':
binoculars.util.space_to_txt(space, args.outfile)
- print 'saved at {0}'.format(args.outfile)
+ print('saved at {0}'.format(args.outfile))
elif ext == '.hdf5':
space.tofile(args.outfile)
- print 'saved at {0}'.format(args.outfile)
+ print('saved at {0}'.format(args.outfile))
else:
sys.stderr.write('unknown extension {0}, unable to save!\n'.format(ext))
@@ -136,7 +136,7 @@ def command_plot(args):
fitdata = None
if args.fit:
fit = binoculars.fit.get_class_by_name(args.fit)(space, guess)
- print fit
+ print(fit)
if fit.success:
fitdata = fit.fitdata
@@ -241,7 +241,7 @@ def command_fit(args):
fit = fitclass(newspace, guess)
paramnames = fit.parameters
- print fit
+ print(fit)
if fit.success:
fitlabel.append(numpy.mean([start, stop]))
parameters.append(fit.result)
@@ -255,7 +255,7 @@ def command_fit(args):
fit = None
guess = None
- print guess
+ print(guess)
if args.savepdf or args.savefile:
if len(newspace.get_masked().compressed()):
@@ -273,7 +273,7 @@ def command_fit(args):
info.append('sliced in {0} from {1} to {2}'.format(axlabel, left, right))
pyplot.suptitle('{0}'.format(' '.join(info)))
- pyplot.savefig(filename.next())
+ pyplot.savefig(next(filename))
pyplot.close()
parameters = numpy.vstack(n for n in parameters).T
@@ -293,11 +293,11 @@ def command_fit(args):
if args.savefile:
root, ext = os.path.split(args.savefile)
pyplot.savefig('{0}_summary{1}'.format(root, ext))
- print 'saved at {0}_summary{1}'.format(root, ext)
+ print('saved at {0}_summary{1}'.format(root, ext))
filename = '{0}_summary{1}'.format(root, '.txt')
else:
pyplot.savefig('{0}_summary.pdf'.format(os.path.splitext(args.infile)[0]))
- print 'saved at {0}_summary.pdf'.format(os.path.splitext(args.infile)[0])
+ print('saved at {0}_summary.pdf'.format(os.path.splitext(args.infile)[0]))
filename = '{0}_summary.txt'.format(os.path.splitext(args.infile)[0])
file = open(filename, 'w')
@@ -321,7 +321,7 @@ def command_process(args):
# SUBCOMMAND ARGUMENT HANDLING
def usage(msg=''):
- print """usage: binoculars COMMAND ...
+ print("""usage: binoculars COMMAND ...
{1}
available commands:
@@ -332,7 +332,7 @@ available commands:
process data crunching / binning
run binoculars COMMAND --help more info on that command
-""".format(sys.argv[0], msg)
+""".format(sys.argv[0], msg))
sys.exit(1)
diff --git a/scripts/binoculars-fitaid b/scripts/binoculars-fitaid
index 648f2dc..01e8b6a 100755
--- a/scripts/binoculars-fitaid
+++ b/scripts/binoculars-fitaid
@@ -410,7 +410,7 @@ class TableWidget(QtGui.QWidget):
if rodkey == label:
self.table.removeRow(index)
self.database.delete_rod(rodkey)
- print 'removed: {0}'.format(rodkey)
+ print('removed: {0}'.format(rodkey))
def setlength(self, y, x=1):
if x == 1:
@@ -457,7 +457,7 @@ class FitData(object):
def create_rod(self, rodkey, spacename):
with h5py.File(self.filename, 'a') as db:
- if rodkey not in db.keys():
+ if rodkey not in list(db.keys()):
db.create_group(rodkey)
db[rodkey].attrs['filename'] = spacename
self.axdict[rodkey] = binoculars.space.Axes.fromfile(spacename)
@@ -468,19 +468,19 @@ class FitData(object):
def rods(self):
with h5py.File(self.filename, 'a') as db:
- rods = db.keys()
+ rods = list(db.keys())
return rods
def copy(self, oldkey, newkey):
with h5py.File(self.filename, 'a') as db:
- if oldkey in db.keys():
+ if oldkey in list(db.keys()):
db.copy(db[oldkey], db, name=newkey)
@property
def filelist(self):
filelist = []
with h5py.File(self.filename, 'a') as db:
- for key in db.iterkeys():
+ for key in db.keys():
filelist.append(db[key].attrs['filename'])
return filelist
@@ -596,7 +596,7 @@ class RodData(FitData):
except KeyError:
db[self.rodkey][self.slicekey].create_group('attrs')
group = db[self.rodkey][self.slicekey]['attrs']
- if key in group.keys():
+ if key in list(group.keys()):
return numpy.ma.array(group[key][index], mask=group[mkey][index])
else:
return None
@@ -604,36 +604,36 @@ class RodData(FitData):
def all_attrkeys(self):
with h5py.File(self.filename, 'a') as db:
group = db[self.rodkey][self.slicekey]['attrs']
- return group.keys()
+ return list(group.keys())
def all_from_key(self, key):
mkey = 'mask{0}'.format(key)
axes = self.axdict[self.rodkey]
with h5py.File(self.filename, 'a') as db:
group = db[self.rodkey][self.slicekey]['attrs']
- if key in group.keys():
+ if key in list(group.keys()):
return binoculars.space.get_axis_values(axes, self.axis, self.resolution), numpy.ma.array(group[key], mask=numpy.array(group[mkey]))
def load_loc(self, index):
loc = list()
with h5py.File(self.filename, 'a') as db:
+ count = itertools.count()
+ key = 'guessloc{0}'.format(next(count))
+ while self.load_sliceattr(index, key) != None:
+ loc.append(self.load_sliceattr(index, key))
+ key = 'guessloc{0}'.format(next(count))
+ if len(loc) > 0:
+ return loc
+ else:
count = itertools.count()
- key = 'guessloc{0}'.format(count.next())
+ key = 'loc{0}'.format(next(count))
while self.load_sliceattr(index, key) != None:
loc.append(self.load_sliceattr(index, key))
- key = 'guessloc{0}'.format(count.next())
- if len(loc) > 0:
- return loc
- else:
- count = itertools.count()
- key = 'loc{0}'.format(count.next())
- while self.load_sliceattr(index, key) != None:
- loc.append(self.load_sliceattr(index, key))
- key = 'loc{0}'.format(count.next())
- if len(loc) > 0:
- return loc
- else:
- return None
+ key = 'loc{0}'.format(next(count))
+ if len(loc) > 0:
+ return loc
+ else:
+ return None
def save_loc(self, index, loc):
for i, value in enumerate(loc):
@@ -704,7 +704,7 @@ class FitWidget(QtGui.QWidget):
self.canvas.draw()
def fit(self, index, space, function):
- print index
+ print(index)
if not len(space.get_masked().compressed()) == 0:
loc = self.database.load_loc(index)
if loc:
@@ -714,7 +714,7 @@ class FitWidget(QtGui.QWidget):
fit.fitdata.mask = space.get_masked().mask
self.database.save_data(index, 'fit', fit.fitdata)
params = list(line.split(':')[0] for line in fit.summary.split('\n'))
- print fit.result, fit.variance
+ print(fit.result, fit.variance)
for key, value in zip(params, fit.result):
self.database.save_sliceattr(index, key, value)
for key, value in zip(params, fit.variance):
@@ -922,7 +922,7 @@ class IntegrateWidget(QtGui.QWidget):
interdata[key].mask = numpy.zeros_like(interdata[key])
self.database.save_data(index, 'inter', interdata)
except Exception as e:
- print 'Warning error interpolating slice {0}: {1}'.format(index, e.message)
+ print('Warning error interpolating slice {0}: {1}'.format(index, e.message))
intensity = numpy.array([])
bkg = numpy.array([])
@@ -939,7 +939,7 @@ class IntegrateWidget(QtGui.QWidget):
self.database.save_sliceattr(index, 'sf', structurefactor)
self.database.save_sliceattr(index, 'nisf', nistructurefactor)
- print 'Structurefactor {0}: {1}'.format(index, structurefactor)
+ print('Structurefactor {0}: {1}'.format(index, structurefactor))
def intkey(self, coords, axes):
diff --git a/scripts/binoculars-gui b/scripts/binoculars-gui
index ae2cd67..2b60fee 100755
--- a/scripts/binoculars-gui
+++ b/scripts/binoculars-gui
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import sys
import os
@@ -8,9 +9,7 @@ import json
import itertools
import signal
import subprocess
-import Queue
import socket
-import SocketServer
import threading
import matplotlib.figure
import matplotlib.image
@@ -19,6 +18,14 @@ from mpl_toolkits.mplot3d import Axes3D
from PyQt4 import QtGui, QtCore, Qt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg, NavigationToolbar2QTAgg
+#python3 support
+PY3 = sys.version_info > (3,)
+if PY3:
+ import socketserver
+ import queue
+else:
+ import SocketServer as socketserver
+ import Queue as queue
def set_src():
import sys
@@ -268,7 +275,7 @@ class Window(QtGui.QMainWindow):
self.tab_widget = QtGui.QTabWidget(self)
self.tab_widget.setTabsClosable(True)
- QtCore.QObject.connect(self.tab_widget, QtCore.SIGNAL("tabCloseRequested(int)"), self.tab_widget.removeTab)
+ self.tab_widget.tabCloseRequested.connect(self.tab_widget.removeTab)
self.statusbar = QtGui.QStatusBar()
@@ -342,15 +349,13 @@ class Window(QtGui.QMainWindow):
fname = dialog.selectedFiles()
if not fname:
return
- for index, name in enumerate(fname):
+ for name in fname:
try:
widget = self.tab_widget.currentWidget()
- if index == fname.count() - 1:
- widget.addspace(str(name), True)
- else:
- widget.addspace(str(name), False)
+ widget.addspace(str(name), True)
except Exception as e:
- QtGui.QMessageBox.critical(self, 'Import spaces', 'Unable to import space {}: {}'.format(str(name), e))
+ raise
+ #QtGui.QMessageBox.critical(self, 'Import spaces', 'Unable to import space {}: {}'.format(str(name), e))
def exportspace(self):
widget = self.tab_widget.currentWidget()
@@ -405,11 +410,11 @@ class Window(QtGui.QMainWindow):
def open_server(self, startq=True):
if len(self.threads) != 0:
- print 'Server already running'
+ print('Server already running')
else:
HOST, PORT = socket.gethostbyname(socket.gethostname()), 0
- self.q = Queue.Queue()
+ self.q = queue.Queue()
server = ThreadedTCPServer((HOST, PORT), SpaceTCPHandler)
server.q = self.q
@@ -430,11 +435,11 @@ class Window(QtGui.QMainWindow):
updater.start()
if not startq:
- print 'GUI server started running at ip {0} and port {1}.'.format(self.ip, self.port)
+ print(('GUI server started running at ip {0} and port {1}.'.format(self.ip, self.port)))
def kill_server(self):
if len(self.threads) == 0:
- print 'No server running.'
+ print('No server running.')
else:
self.threads = []
self.kill_subprocess()
@@ -466,7 +471,7 @@ class Window(QtGui.QMainWindow):
class UpdateThread(QtCore.QThread):
- fq = Queue.Queue()
+ fq = queue.Queue()
data_found = QtCore.pyqtSignal(object)
def run(self):
@@ -488,11 +493,11 @@ class UpdateThread(QtCore.QThread):
next(delay)
-class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
+class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
-class SpaceTCPHandler(SocketServer.BaseRequestHandler):
+class SpaceTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
command, config, metadata, axes, photons, contributions = binoculars.util.socket_recieve(self)
space = binoculars.space.Space(binoculars.space.Axes.fromarray(axes))
@@ -540,15 +545,15 @@ class ProjectWidget(QtGui.QWidget):
self.lin = QtGui.QRadioButton('lin', self)
self.lin.setChecked(False)
- QtCore.QObject.connect(self.lin, QtCore.SIGNAL("toggled(bool)"), self.plot)
+ self.lin.toggled.connect(self.plot)
self.log = QtGui.QRadioButton('log', self)
self.log.setChecked(True)
- QtCore.QObject.connect(self.log, QtCore.SIGNAL("toggled(bool)"), self.plot)
+ self.log.toggled.connect(self.plot)
self.loglog = QtGui.QRadioButton('loglog', self)
self.loglog.setChecked(False)
- QtCore.QObject.connect(self.loglog, QtCore.SIGNAL("toggled(bool)"), self.plot)
+ self.loglog.toggled.connect(self.plot)
self.loggroup = QtGui.QButtonGroup(self)
self.loggroup.addButton(self.lin)
@@ -557,19 +562,19 @@ class ProjectWidget(QtGui.QWidget):
self.swap_axes = QtGui.QCheckBox('ax', self)
self.swap_axes.setChecked(False)
- QtCore.QObject.connect(self.swap_axes, QtCore.SIGNAL("stateChanged(int)"), self.plot)
+ self.swap_axes.stateChanged.connect(self.plot)
self.samerange = QtGui.QCheckBox('same', self)
self.samerange.setChecked(False)
- QtCore.QObject.connect(self.samerange, QtCore.SIGNAL("stateChanged(int)"), self.update_colorbar)
+ self.samerange.stateChanged.connect(self.update_colorbar)
self.legend = QtGui.QCheckBox('legend', self)
self.legend.setChecked(True)
- QtCore.QObject.connect(self.legend, QtCore.SIGNAL("stateChanged(int)"), self.plot)
+ self.legend.stateChanged.connect(self.plot)
self.threed = QtGui.QCheckBox('3d', self)
self.threed.setChecked(False)
- QtCore.QObject.connect(self.threed, QtCore.SIGNAL("stateChanged(int)"), self.plot)
+ self.threed.stateChanged.connect(self.plot)
self.auto_update = QtGui.QCheckBox('auto', self)
self.auto_update.setChecked(True)
@@ -580,10 +585,11 @@ class ProjectWidget(QtGui.QWidget):
self.datarange.setLow(0)
self.datarange.setHigh(self.datarange.maximum())
self.datarange.setTickPosition(QtGui.QSlider.TicksBelow)
- QtCore.QObject.connect(self.datarange, QtCore.SIGNAL('sliderMoved(int)'), self.update_colorbar)
+ self.datarange.sliderMoved.connect(self.update_colorbar)
self.table = TableWidget(filelist)
- QtCore.QObject.connect(self.table, QtCore.SIGNAL('selectionError'), self.selectionerror)
+ self.table.selectionError.connect(self.selectionerror)
+ self.table.plotaxesChanged.connect(self.plotaxes_changed)
self.key = key
self.projection = projection
@@ -595,9 +601,8 @@ class ProjectWidget(QtGui.QWidget):
self.button_refresh.clicked.connect(self.table.select)
self.limitwidget = LimitWidget(self.table.plotaxes)
- QtCore.QObject.connect(self.limitwidget, QtCore.SIGNAL("keydict"), self.update_key)
- QtCore.QObject.connect(self.limitwidget, QtCore.SIGNAL("rangechange"), self.update_figure_range)
- QtCore.QObject.connect(self.table, QtCore.SIGNAL('plotaxesChanged'), self.plotaxes_changed)
+ self.limitwidget.keydict.connect(self.update_key)
+ self.limitwidget.rangechange.connect(self.update_figure_range)
self.initUI()
@@ -832,7 +837,7 @@ class ProjectWidget(QtGui.QWidget):
spaces = tuple(self.table.getspace(selected_filename) for selected_filename in self.table.selection)
newspace = binoculars.space.sum(binoculars.space.make_compatible(spaces))
newspace.tofile(filename)
- map(self.table.remove, self.table.selection)
+ list(map(self.table.remove, self.table.selection))
self.table.addspace(filename, True)
except Exception as e:
QtGui.QMessageBox.critical(self, 'Merge', 'Unable to merge the meshes. {}'.format(e))
@@ -985,13 +990,13 @@ class SpaceContainer(QtGui.QTableWidgetItem):
else:
if key == None:
key = Ellipsis
- return self.space[key]
+ return self.space[key]
def get_ax(self):
if self.space == None:
- return binoculars.space.Axes.fromfile(self.label)
+ return binoculars.space.Axes.fromfile(self.label)
else:
- return self.space.axes
+ return self.space.axes
def add_to_space(space):
if self.space == None:
@@ -1001,6 +1006,9 @@ class SpaceContainer(QtGui.QTableWidgetItem):
self.space += space
class TableWidget(QtGui.QWidget):
+ selectionError = QtCore.pyqtSignal(str, name = 'Selection Error')
+ plotaxesChanged = QtCore.pyqtSignal(binoculars.space.Axes, name = 'plot axes changed')
+
def __init__(self, filelist = [],parent=None):
super(TableWidget, self).__init__(parent)
@@ -1049,14 +1057,14 @@ class TableWidget(QtGui.QWidget):
def remove(self, filename):
self.table.removeRow(self.filelist.index(filename))
self.select()
- print 'removed: {0}'.format(filename)
+ print(('removed: {0}'.format(filename)))
def select(self):
axes = self.plotaxes
if len(axes) > 0:
- self.emit(QtCore.SIGNAL('plotaxesChanged'), axes)
+ self.plotaxesChanged.emit(axes)
else:
- self.emit(QtCore.SIGNAL('selectionError'), 'no spaces selected or spaces with non identical labels selected')
+ self.selectionError.emit('no spaces selected or spaces with non identical labels selected')
@property
def selection(self):
@@ -1092,6 +1100,9 @@ class TableWidget(QtGui.QWidget):
return iter(self.table.item(index, 1) for index in range(self.table.rowCount()))
class LimitWidget(QtGui.QWidget):
+ keydict = QtCore.pyqtSignal(dict, name = "keydict")
+ rangechange = QtCore.pyqtSignal(list, name = "rangechange")
+
def __init__(self, axes, parent=None):
super(LimitWidget, self).__init__(parent)
self.initUI(axes)
@@ -1163,9 +1174,9 @@ class LimitWidget(QtGui.QWidget):
self.update_lines()
for slider in self.sliders:
- QtCore.QObject.connect(slider, QtCore.SIGNAL('sliderMoved(int)'), self.update_lines)
+ slider.sliderMoved.connect(self.update_lines)
for slider in self.sliders:
- QtCore.QObject.connect(slider, QtCore.SIGNAL('sliderReleased()'), self.send_signal)
+ slider.sliderReleased.connect(self.send_signal)
for line in self.leftindicator:
line.editingFinished.connect(self.update_sliders_left)
@@ -1192,7 +1203,7 @@ class LimitWidget(QtGui.QWidget):
self.leftindicator[index].setText(str(self.axes[index][slider.low()]))
self.rightindicator[index].setText(str(self.axes[index][slider.high()]))
key = list((float(str(left.text())), float(str(right.text()))) for left, right in zip(self.leftindicator, self.rightindicator))
- self.emit(QtCore.SIGNAL('rangechange'), key)
+ self.rangechange.emit(key)
def send_signal(self):
signal = {}
@@ -1204,7 +1215,7 @@ class LimitWidget(QtGui.QWidget):
project.append(ax.label)
signal['project'] = project
signal['key'] = key
- self.emit(QtCore.SIGNAL('keydict'), signal)
+ self.keydict.emit(signal)
def update_sliders_left(self):
for ax, left, right , slider in zip(self.axes, self.leftindicator, self.rightindicator, self.sliders):
diff --git a/scripts/binoculars-processgui b/scripts/binoculars-processgui
index c3a8f1a..3127cd6 100755
--- a/scripts/binoculars-processgui
+++ b/scripts/binoculars-processgui
@@ -107,7 +107,8 @@ class Window(QtGui.QMainWindow):
def removeConf(self):
self.ListCommand.removeRow(self.ListCommand.currentRow())
- def Add_To_Liste(self, (command, cfg)):
+ def Add_To_Liste(self, xxx_todo_changeme):
+ (command, cfg) = xxx_todo_changeme
row = self.ListCommand.rowCount()
index = self.tab_widget.currentIndex()
filename = self.tab_widget.tabText(index)
@@ -137,11 +138,11 @@ class Window(QtGui.QMainWindow):
pd.setValue(index)
cfg = self.ListCommand.item(index, 1).cfg
command = self.ListCommand.item(index, 0).command
- print cfg
+ print(cfg)
progress(cfg, command)
self.ListCommand.clear()
self.ListCommand.setRowCount(0)
- except BaseException, e:
+ except BaseException as e:
#cfg = self.ListCommand.item(index,1).cfg
#print cfg
QtGui.QMessageBox.about(self, "Error", "There was an error processing one of the scans: {0}".format(e))
diff --git a/scripts/binoculars-server b/scripts/binoculars-server
index d947ea3..354a899 100755
--- a/scripts/binoculars-server
+++ b/scripts/binoculars-server
@@ -11,14 +11,20 @@ interrupted.
'''
import socket
import threading
-import SocketServer
import time
import sys
import traceback
import json
import os
-import Queue
+#python3 support
+PY3 = sys.version_info > (3,)
+if PY3:
+ import socketserver
+ import queue
+else:
+ import SocketServer as socketserver
+ import Queue as queue
def set_src():
import sys
@@ -36,25 +42,25 @@ except ImportError:
import binoculars.util
-class ProcessTCPHandler(SocketServer.BaseRequestHandler):
+class ProcessTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
input = self.request.recv(1024)
if input.startswith('test'):
- print 'Recieved test request'
+ print('Recieved test request')
self.request.sendall('Connection succesful')
else:
try:
job = json.loads(input)
parsed, result = parse_job(job)
if parsed:
- print 'Recieved command: {0}. Job is added to queue.\nNumber of jobs left in queue: {1}'.format(job['command'], self.server.q.qsize())
+ print('Recieved command: {0}. Job is added to queue.\nNumber of jobs left in queue: {1}'.format(job['command'], self.server.q.qsize()))
response = 'Job added to queue'
self.server.q.put(job)
else:
response = result
except:
- print 'Could not parse the job: {0}'.format(input)
- print traceback.format_exc()
+ print('Could not parse the job: {0}'.format(input))
+ print(traceback.format_exc())
response = 'Error: Job could not be added to queue'
finally:
self.request.sendall(response)
@@ -63,7 +69,7 @@ class ProcessTCPHandler(SocketServer.BaseRequestHandler):
def parse_job(job):
try:
overrides = []
- for key in job.keys():
+ for key in list(job.keys()):
if not key in ['command', 'configfilename']:
section_key, value = job[key].split('=')
section, key = section_key.split(':')
@@ -84,21 +90,21 @@ def process(run_event, ip, port, q):
command = str(job['command'])
configfilename = job['configfilename']
overrides = parse_job(job)[1] # [1] are the succesfully parsed jobs
- print 'Start processing: {0}'.format(command)
+ print('Start processing: {0}'.format(command))
try:
configobj = binoculars.util.ConfigFile.fromtxtfile(configfilename, overrides=overrides)
if binoculars.util.parse_bool(configobj.dispatcher['send_to_gui']):
configobj.dispatcher['host'] = ip
configobj.dispatcher['port'] = port
binoculars.main.Main.from_object(configobj, [command])
- print 'Succesfully finished processing: {0}.'.format(command)
+ print('Succesfully finished processing: {0}.'.format(command))
except Exception as exc:
errorfilename = 'error_{0}.txt'.format(command)
- print 'An error occured for scan {0}. For more information see {1}'.format(command, errorfilename)
+ print('An error occured for scan {0}. For more information see {1}'.format(command, errorfilename))
with open(errorfilename, 'w') as fp:
traceback.print_exc(file=fp)
finally:
- print 'Number of jobs left in queue: {0}'.format(q.qsize())
+ print('Number of jobs left in queue: {0}'.format(q.qsize()))
if __name__ == '__main__':
if len(sys.argv) > 1:
@@ -108,7 +114,7 @@ if __name__ == '__main__':
ip = None
port = None
- q = Queue.Queue()
+ q = queue.Queue()
binoculars.util.register_python_executable(os.path.join(os.path.dirname(__file__), 'binoculars.py'))
@@ -120,11 +126,11 @@ if __name__ == '__main__':
process_thread = threading.Thread(target=process, args=(run_event, ip, port, q))
process_thread.start()
- server = SocketServer.TCPServer((HOST, PORT), ProcessTCPHandler)
+ server = socketserver.TCPServer((HOST, PORT), ProcessTCPHandler)
server.q = q
ip, port = server.server_address
- print 'Process server started running at ip {0} and port {1}. Interrupt server with Ctrl-C'.format(ip, port)
+ print('Process server started running at ip {0} and port {1}. Interrupt server with Ctrl-C'.format(ip, port))
try:
server.serve_forever()
except KeyboardInterrupt: