Commit c1913218 authored by Claudio Scafuri's avatar Claudio Scafuri 💬
Browse files

partial code restructuring

parent a06ae165
NAME_SRV=felmaster
NAME = felmaster-srv
MAIN = FelMaster.py
DIRNAME = $(NAME:-srv=)
MODNAME = $(MAIN:.py=)
PY_FILES += $(wildcard src/*.py)
default: bin/${NAME_SRV} ${PY_FILES}
@cp ${PY_FILES} bin/${NAME_SRV}
default: bin ${PY_FILES}
@cp ${PY_FILES} bin/${DIRNAME}
@echo "#!/usr/bin/env python\nimport sys\nsys.path.append('${DIRNAME}')\nfrom ${MODNAME} import main\nif __name__ == '__main__':\n main()\n" > bin/${NAME}
@chmod +x bin/${NAME} bin/${DIRNAME}/${MAIN}
bin/${NAME_SRV}:
@test -d $@ || mkdirhier $@
bin:
@test -d $@ || mkdir -p $@/${DIRNAME}
clean:
@rm -fr bin/ src/*~
.PHONY: clean
.PHONY: clean
\ No newline at end of file
1.0
40.0
3.0
268.0
235.0
0.0
1.0
0.0
0.0
1.0
0.0
0.0
0.0
0.0
1.2295
2.0
10.0
2.0
25.0
10.0
250.0
3.0
0.0
0.0
-0.3
-1.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
1.2295
1.2295
1.2295
1.2295
1.0
10.0
10.0
10.0
250.0
250.0
250.0
250.0
2.0
3.0
3.0
3.0
0.0
40.0
2.0
370.0
275.0
0.0
1.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.9007123
2.0
20.0
0.0
10.704
0.0
267.6
3.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.90082
0.90082
0.90082
0.90082
0.90082
0.90082
0.90082
1.0
20.0
20.0
20.0
20.0
20.0
20.0
267.6
267.6
267.6
267.6
267.6
267.6
267.6
2.0
3.0
3.0
3.0
3.0
3.0
3.0
This diff is collapsed.
'''
Created on May 18, 2020
@author: claudio
'''
import scipy.interpolate
class compressor_calc(object):
'''
Class for calculating compressor position depending on
OPA wavelenght.
Loads calibartion table from file, The file is in the form of two columns:
lamdabda postion
Lamda: [nm], postion :[mm], data privded by Laser group
Suggested file name and location:
/runtime/servers/etc/fel01/compressor_position.txt
The calibration tabel must be already in correct format: complete rows,
lambda sorted in ascending order.
'''
def __init__(self, filename):
dly = scipy.genfromtxt(filename)
sh = dly.shape
_lmb = dly[0:sh[0], 0]
_dt = dly[0:sh[0], 1]
#create inetrpolator
self._lambda_min = _lmb[0]
self._lambda_max = _lmb[sh[0] - 1]
self._comp = scipy.interpolate.InterpolatedUnivariateSpline(_lmb, _dt)
def get_position(self, wavelength):
'''
Calculate compressor postion. Used for tests and internally
@param wavelength: seed laser wavelength in [nm]
@return: position [mm]
'''
if wavelength < self._lambda_min or wavelength > self._lambda_max:
raise ValueError('lambda out of range')
pos = self._comp(wavelength).item(0)
return pos
def get_min_lambda(self):
'''
@return: minimum usable lambda
'''
return self._lambda_min
def get_max_lambda(self):
'''
@return: maximum usable lambda
'''
return self._lambda_max
# ---------------- end of former externa modula opacalc -------------------
\ No newline at end of file
import numpy
import scipy.interpolate
class delay_shifter_calc(object):
'''
Class for calculating delay line compensation for different
OPA wavelenghts.
Loads calibartion table from file, The file is in the form of two columns:
lamdabda delay
Lamda: [nm], delay:[ps], data privded by Laser group
Suggested file name and location:
/runtime/servers/etc/fel01/opa_delay.txt
The calibration tabel must be already in correct format: complete rows,
lambda sorted in ascending order.
'''
def __init__(self, filename):
dly = scipy.genfromtxt(filename)
sh = dly.shape
_lmb = dly[0:sh[0], 0]
_dt = dly[0:sh[0], 1]
#create inetrpolator
self._lambda_min = _lmb[0]
self._lambda_max = _lmb[sh[0] - 1]
self._cal = scipy.interpolate.InterpolatedUnivariateSpline(_lmb, _dt)
def get_abs_delay(self, wavelength):
'''
Calculate absoulte delay. Used for tests and internally
@param wavelength: seed laser wavelength in [nm]
@return: absolute delay in [ps]
'''
if wavelength < self._lambda_min or wavelength > self._lambda_max:
raise ValueError('lambda out of range')
dly = self._cal(wavelength)
return dly
def get_compensation_delay(self, initial_wavelength, final_wavelength):
'''
Calculate correwction delay.
@param initial_wavelength: actual seed laser wavelength in [nm]
@param final_wavelength: new seed laser wavelength in [nm]
@return: delay compensation in [ps]
@raise ValueError: if one of the two wavelenghts is out of range
'''
#print 'get_compensation_delay iw :',initial_wavelength,' fw :',final_wavelength,self._lambda_min,self._lambda_max
if initial_wavelength < self._lambda_min or initial_wavelength > self._lambda_max:
raise ValueError('initial wavelength out of range')
if final_wavelength < self._lambda_min or final_wavelength > self._lambda_max:
raise ValueError('final wavelength out of range')
#dly_i = self._cal(initial_wavelength)
#dly_f = self._cal(final_wavelength)
dly_i = self._cal(numpy.array([initial_wavelength]))
dly_f = self._cal(numpy.array([final_wavelength]))
retval = (dly_f - dly_i)
return retval
def get_min_lambda(self):
'''
@return: minimum usable lambda
'''
return self._lambda_min
def get_max_lambda(self):
'''
@return: maximum usable lambda
'''
return self._lambda_max
\ No newline at end of file
'''
Created on May 18, 2020
@author: claudio
'''
class harmoncalc(object):
'''
Given the desired FEL wavelegth, this class calculates the required seed
wavelength to be set to the opa (optical paramter amplifier) settings end
the harmin nummber to be used bey the rest of the gap calculation chain
(e.g. FelMaster, SuperGap) seed wavelength are in naonmeters [nm]
'''
def __init__(self, hmin, hmax, lopa_max, lopa_min):
'''
Constructor
@param hmin: minium admissible harmonic - type: int
@param hmax: maximum admissible harmonic - type : int
@param lopa_max : maximum admissible wavelength of seed laser, typical value is 261.0 nm - type : float
@param lopa_min : minimum admissible wavelength of seed laser, typical value is 230.0 nm - type : float
'''
if hmin >= hmax or hmin <= 0 or hmax <= 1:
raise ValueError('harmonic number range invalid')
if lopa_max <= lopa_min or lopa_min < 0.0:
raise ValueError('lambda seed (opa) range invalid')
self.hmin = int(hmin)
self.hmax = int(hmax)
self.lopa_max = float(lopa_max)
self.lopa_min = float(lopa_min)
#calulate fel limits
self.lFEL_max = self.lopa_max / float(self.hmin)
self.lFEL_min = self.lopa_min / float(self.hmax)
def set_limits(self, hmin, hmax, lopa_max, lopa_min):
'''
@param hmin: minium admissible harmonic - type: int
@param hmax: maximum admissible harmonic - type : int
@param lopa_max : maximum admissible wavelength of seed laser, typical value is 261.0 nm - type : float
@param lopa_min : minimum admissible wavelength of seed laser, typical value is 230.0 nm - type : float
'''
if hmin >= hmax or hmin <= 0 or hmax <= 1:
raise ValueError('harmonic number range invalid')
if lopa_max <= lopa_min or lopa_min < 0.0:
raise ValueError('lambda seed (opa) range invalid')
self.hmin = int(hmin)
self.hmax = int(hmax)
self.lopa_max = float(lopa_max)
self.lopa_min = float(lopa_min)
#calulate fel limits
self.lFEL_max = self.lopa_max / float(self.hmin)
self.lFEL_min = self.lopa_min / float(self.hmax)
def get_fel_max(self):
'''
@return: maximum FEL wavelength
'''
return self.lFEL_max
def get_fel_min(self):
'''
@return: absolute minimum FEL wavelength
'''
return self.lFEL_min
def calculate(self, lfel):
'''
Calculate harmonic number and lambda seed. Use low limit for lseed
@param lfel: desired FEL wavelegth, Nan if no solution is feasible
@return : harmonic number , wavelength of lambda seed for OPA
Raise ValueError excpetion if lambda is out of range or no solution is feasible
'''
if lfel < self.lFEL_min or lfel > self.lFEL_max:
raise ValueError('lambda out of range')
hnlow = self.hmin
go_up = True
feasible = True
#loop up - get lower harmonic limit
while go_up and feasible:
lmin = self.lopa_min / float(hnlow)
lmax = self.lopa_max / float(hnlow)
#lmin_next = self.lopa_min / (hnlow + 1)
lmax_next = self.lopa_max / (hnlow + 1)
if (lfel <= lmax and lfel >= lmin) or hnlow == (self.hmax - 1):
go_up = False
if lfel < lmin and lfel > lmax_next and lmax_next < lmin:
raise ValueError('no feasible solution')
if lfel < lmin:
hnlow += 1
if lfel > lmax:
hnlow -= 1
#second pass , start from highes harmonic and loop down
hnhigh = self.hmax
go_down = True
while go_down and feasible:
lmin = self.lopa_min / hnhigh
lmax = self.lopa_max / hnhigh
#lmin_next = self.lopa_min / (hnhigh - 1)
lmax_next = self.lopa_max / (hnhigh - 1)
if (lfel <= lmax and lfel >= lmin) or hnhigh == (self.hmin + 1):
go_down = False
if lmin > lfel > lmax_next and lmax_next < lmin:
raise ValueError('no feasible solution')
if lfel < lmin:
hnhigh += 1
if lfel > lmax:
hnhigh -= 1
harmon = []
lopa = []
hn = hnlow
while hn <= hnhigh:
harmon.append(hn)
lopa.append(hn * lfel)
hn += 1
return harmon, lopa
def get_limits(self):
'''
returns the limits used for harmonic calculations
@return: hmin: minium admissible harmonic, hmax: maximum admissible harmonic,
lopa_max : maximum admissible wavelength of seed laser,
lopa_min : minimum admissible wavelength of seed laser
'''
return self.hmin, self.hmax, self.lopa_max, self.lopa_min
\ No newline at end of file
'''
Created on May 18, 2020
@author: claudio
'''
import tango
class SpectroMeter():
'''
handle operations on padres spetrometer
use try/except around any call!
percent: witdh of acceptable window, in percent of spectrometer span
maxorder: maximum diffraction order to be used (3)
'''
def __init__(self, logger, pespname, ccdname, percent=30.0, maxorder=3):
if percent < 0.0 or percent > 100.0:
raise Exception
self.pesp = tango.DeviceProxy(pespname)
self.ccd = tango.DeviceProxy(ccdname)
self.perc = percent
self.hlimit = float('Nan')
self.llimit = float('Nan')
self.maxorder = maxorder
self.hw = float('Nan')
self.wspan = float('Nan')
self.lw = float('Nan')
self.difforder = float('Nan')
self.wavecentre = float('Nan')
self.pspan = float('Nan')
self.hwperc = float('Nan')
self.lwperc = float('Nan')
# self.read_from_device()
self.logger = logger
self.logger.debug('SpetroMeter.__init__ done')
def read_from_device(self):
'''
read all necessary from psetremeter and calculates limits
'''
grating = self.pesp.grating
if grating == 'G1 LE-Grating':
self.hlimit = 100.0
self.llimit = 24.0
if grating == 'G2 HE-Grating':
self.hlimit = 27.0
self.llimit = 6.7
p2m = self.ccd.Pixel2micron
self.wavecentre = self.pesp.wavelength
span = self.pesp.wavelengthspan
self.wspan = -span * p2m # window span in nm - calculated
self.hw = self.wavecentre + self.wspan / 2.0
self.lw = self.wavecentre - self.wspan / 2.0
self.difforder = self.pesp.diffractionorder
self.pspan = ((self.perc / 100.) * self.wspan) / 2
self.hwperc = self.wavecentre + self.pspan
self.lwperc = self.wavecentre - self.pspan
def calc_diff_order(self, w):
'''
calculate optimal diffraction order for wavalength
'''
n = 1
while n <= self.maxorder:
high = self.hlimit / n
low = self.llimit / n
if high >= w >= low:
return n
n += 1
return -1 # raise exception ?
def diff_order_ok(self, w, n):
'''
given wavelenght w and oredr n, returnrs true if they are comapatible
'''
high = self.hlimit / n
low = self.llimit / n
if w <= high and w >= low:
return True
else:
return False
def set_diff_order(self, n):
self.pesp.diffractionorder = n
def is_in_window(self, w):
'''
check if the requested wavalength is in the window defined by perc
'''
if self.hwperc >= w >= self.lwperc:
return True
return False
def set_new_wcentre(self, w):
'''
does most of the work...
true if movement started
false if no move is needed
'''
self.read_from_device() # update values
if self.is_in_window(w):
self.logger.debug('SpetroMeter.set_new_wcentre(): ok - no movement')
return False
# check diff order
if not self.diff_order_ok(w, self.difforder):
n = self.calc_diff_order(w)
if n < 1:
raise ValueError('no valid diffr. order for wavalenght %f' % (w))
self.set_diff_order(n)
# do the real thing...
self.logger.debug('SpetroMeter.set_new_wcentre(): requesting movement')
self.pesp.wavelength = w
self.logger.debug('SpetroMeter.set_new_wcentre(): movement done')
# print '===spectrometer===> self.pesp.wavelength=', w
return True
'''
Created on May 18, 2020
@author: claudio
'''
import tango as PyTango
import time
......
from __future__ import print_function
from opacalc import *
import harmoncalc
import pylab
opa = harmoncalc(3,20,380,280,280)
opa = harmoncalc.harmoncalc(3,20,380,280)
start=20.0;
stop=100.0;
step = 0.25
......@@ -14,10 +14,10 @@ for l in L:
res = opa.calculate(l)
print (l,'\t', end='')
for i in range (len(res[0])):
n=str(res[0][i])
l=str(res[1][i])
msg=n+'|'+l
print( msg,end='\t')
n=str(res[0][i])
l=str(res[1][i])
msg=n+'|'+l
print( msg,end='\t')
print('')
......@@ -4,13 +4,13 @@ Created on Oct 22, 2012
@author: claudio
'''
import unittest
import FelMaster
import compressor_calc
class Test(unittest.TestCase):
def setUp(self):
self.opa = FelMaster.compressor_calc('../etc/fel01/Compressor_300_365-FEL01.txt')
self.opa = compressor_calc.compressor_calc('../etc/fel01/Compressor_300_365-FEL01.txt')
def tearDown(self):
......
......@@ -4,13 +4,13 @@ Created on Oct 22, 2012
@author: claudio
'''
import unittest
import FelMaster
import delay_shifter_calc
class Test(unittest.TestCase):
def setUp(self):
self.opa = FelMaster.delay_shifter_calc('../etc/fel01/Relative_delay_300_365-FEL01.txt')
self.opa = delay_shifter_calc.delay_shifter_calc('../etc/fel01/Relative_delay_300_365-FEL01.txt')
def tearDown(self):
pass
......
......@@ -3,14 +3,14 @@ Created on Oct 16, 2012
@author: claudio
'''
import FelMaster
import harmoncalc
import unittest
class Test(unittest.TestCase):
def setUp(self):
self.opa = FelMaster.harmoncalc(4, 12, 269.0, 228.0)
self.opa = harmoncalc.harmoncalc(4, 12, 269.0, 228.0)
lmin = self.opa.get_fel_min()
lmax = self.opa.get_fel_max()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment