diff --git a/python/drawing.svg b/python/drawing.svg
deleted file mode 100644
index 48eaa35..0000000
--- a/python/drawing.svg
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
diff --git a/python/helicalscan.py b/python/helicalscan.py
new file mode 100755
index 0000000..ccffeaa
--- /dev/null
+++ b/python/helicalscan.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python
+# *-----------------------------------------------------------------------*
+# | |
+# | Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
+# | |
+# | Author Thierry Zamofing (thierry.zamofing@psi.ch) |
+# *-----------------------------------------------------------------------*
+'''
+tools to setup and execute a helical scan of a cristal
+#THIS IS JUST TESTING CODE TO SOLVE FINDING THE ROTATION CENTER
+'''
+
+import os, sys, json
+import numpy as np
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+from utilities import *
+
+class HelicalScan:
+ def __init__(self,args):
+ if args.cfg:
+ fh=open(args.cfg,'r')
+ s=fh.read()
+ cfg=json.loads(s, object_hook=ConvUtf8)
+ s=json.dumps(cfg, indent=2, separators=(',', ': '));print(s)
+ else:
+ fn='/tmp/shapepath4'
+ #fn='/home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/data/'+time.strftime('%y-%m-%d-%H_%M_%S')
+ #cfg = {"sequencer": ['gen_grid_points(w=5,h=5,pitch=100,rnd=0.4)', 'sort_points()','gen_prog(file="'+fn+'.prg",host="SAR-CPPM-EXPMX1",mode=1,pt2pt_time=10,cnt=1)', 'plot_gather("'+fn+'.npz")']}
+ #cfg = {"sequencer": ['test_find_rot_ctr()']}
+ cfg = {"sequencer": ['test_find_rot_ctr(n=5. ,per=1. ,phi=24.6 ,bias=2.31,ampl=4.12)']}
+
+ self.cfg=dotdict(cfg)
+ self.args=args
+
+ def run(self):
+ print('args='+str(self.args))
+ print('cfg='+str(self.cfg))
+ #try:
+ # self.points=np.array(self.cfg.points)
+ #except AttributeError:
+ # pass
+ try:
+ sequencer= self.cfg.pop('sequencer')
+ except KeyError:
+ print('no command sequence to execute')
+ else:
+ dryrun=self.args.dryrun
+ for cmd in sequencer:
+ print('>'*5+' '+cmd+' '+'<'*5)
+ if not dryrun:
+ eval('self.' + cmd)
+
+ def meas_rot_ctr(self,y,per=1):
+ # find the amplitude bias and phase of an equidistant sampled sinus
+ # it needs at least 3 measurements e.g. at 0,120 240 deg or 0 90 180 270 deg
+ # per is the number of persiods, default is 1 period =360 deg
+ n=len(y)
+ f = np.fft.fft(y)
+ idx=int(per)
+ bias=np.absolute(f[0]/n)
+ phase=np.angle(f[idx])
+ ampl=np.absolute(f[idx])*2/n
+ return (bias,phase,ampl)
+
+ def test_find_rot_ctr(self,n=3. ,per=1. ,phi=37 ,bias=4.1,ampl=2.4):
+ # find the rotation center, amplitude out of n (niminum 3) measurements
+ # n number of equidistant measurements
+ # per number of periods (full rotation of all measurements nut be a interger value for precise measurements)
+ # phi phase
+ # bias bias value
+ # ampl amplitude
+
+ t = np.arange(n)
+ y=ampl*np.cos(2*np.pi*(per/n*t+phi/360.))+bias
+ sp = np.fft.fft(y)
+ freq = np.fft.fftfreq(t.shape[-1])
+ plt.figure(1)
+ plt.subplot(311)
+ plt.plot(t,y,'b.-')
+ plt.subplot(312)
+ #plt.plot(t, sp.real,'b.-', t, sp.imag,'r.-')
+ plt.step(t, sp.real,'b.-', t, sp.imag,'r.-', where='mid')
+ #plt.stem(t, sp.real,'b-')
+ #plt.plot(freq, sp.real,'b.-', freq, sp.imag,'r.-')
+
+ idx=int(per)
+ bias=np.absolute(sp[0]/n)
+ phase=np.angle(sp[idx])
+ ampl=np.absolute(sp[idx]) * 2 / n
+ print('bias: '+str(bias))
+ print('phase: '+str(phase*360./2/np.pi))
+ print('amplitude: '+str(ampl))
+
+ plt.subplot(313)
+ t2 = np.linspace(0,2*np.pi,64)
+ y2=ampl*np.cos(t2+phase)+bias
+ plt.plot(t2,y2,'g-')
+ plt.stem(t/n*2*np.pi*per,y,'b-')
+
+
+ plt.show()
+ pass
+
+
+if __name__=='__main__':
+ from optparse import OptionParser, IndentedHelpFormatter
+ class MyFormatter(IndentedHelpFormatter):
+ 'helper class for formating the OptionParser'
+
+ def __init__(self):
+ IndentedHelpFormatter.__init__(self)
+
+ def format_epilog(self, epilog):
+ if epilog:
+ return epilog
+ else:
+ return ""
+
+ def parse_args():
+ 'main command line interpreter function'
+ #usage: gpasciiCommunicator.py --host=PPMACZT84 myPowerBRICK.cfg
+ (h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>3 else sys.argv[0])+' '
+ exampleCmd=('-n',
+ '-v15'
+ )
+ epilog=__doc__+'''
+Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n '
+
+ fmt=MyFormatter()
+ parser=OptionParser(epilog=epilog, formatter=fmt)
+
+ parser.add_option('-v', '--verbose', type="int", dest='verbose', help='verbosity bits (see below)', default=0)
+ parser.add_option('-n', '--dryrun', action='store_true', help='dryrun to stdout')
+ parser.add_option('--xy', action='store_true', help='sort x,y instead y,x')
+ parser.add_option('--cfg', help='config file containing json configuration structure')
+
+ (args, other)=parser.parse_args()
+ args.other=other
+
+ sp=HelicalScan(args)
+ sp.run()
+#------------------ Main Code ----------------------------------
+ #ssh_test()
+ ret=parse_args()
+ exit(ret)
diff --git a/python/helicalscan1.svg b/python/helicalscan1.svg
new file mode 100644
index 0000000..0ef3f5a
--- /dev/null
+++ b/python/helicalscan1.svg
@@ -0,0 +1,389 @@
+
+
+
+
diff --git a/python/helicalscan2.svg b/python/helicalscan2.svg
new file mode 100644
index 0000000..cf31eec
--- /dev/null
+++ b/python/helicalscan2.svg
@@ -0,0 +1,478 @@
+
+
+
+