Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
P
pykat
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
11
Issues
11
List
Boards
Labels
Service Desk
Milestones
Iterations
Requirements
Requirements
List
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
finesse
pykat
Commits
4a3b014d
Commit
4a3b014d
authored
Mar 08, 2018
by
Daniel Brown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updates to IFO classses to fix f1/f2 frequency changes
parent
04271457
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
302 additions
and
95 deletions
+302
-95
pykat/ifo/__init__.py
pykat/ifo/__init__.py
+21
-7
pykat/ifo/aligo/__init__.py
pykat/ifo/aligo/__init__.py
+235
-79
pykat/ifo/aligo/plot.py
pykat/ifo/aligo/plot.py
+46
-9
No files found.
pykat/ifo/__init__.py
View file @
4a3b014d
...
...
@@ -157,7 +157,7 @@ def find_peak(out, detector, minmax='max', debug=False):
import
matplotlib.pyplot
as
plt
plt
.
figure
()
plt
.
plot
(
out
.
x
,
out
[
detector
])
plt
.
semilogy
(
out
.
x
,
out
[
detector
])
plt
.
show
()
print
(
"max: "
)
...
...
@@ -167,6 +167,7 @@ def find_peak(out, detector, minmax='max', debug=False):
if
len
(
_max
)
==
0
and
minmax
==
"max"
:
raise
pkex
.
BasePyKatException
(
"No maximum peaks found in {}"
.
format
(
detector
))
if
len
(
_min
)
==
0
and
minmax
==
"min"
:
raise
pkex
.
BasePyKatException
(
"No minimum peaks found in {}"
.
format
(
detector
))
...
...
@@ -303,7 +304,7 @@ def scan_optics(kat, _optics, _factors, target="phi", xlimits=[-100, 100], steps
kat
.
parse
(
scan_optic_cmds
(
_optics
,
_factors
,
target
=
target
,
xlimits
=
xlimits
,
steps
=
steps
,
relative
=
relative
))
return
kat
.
run
(
cmd_args
=
"-cr=on"
)
return
kat
.
run
(
cmd_args
=
[
"-cr=on"
]
)
def
optical_gain
(
DOF_sig
,
DOF_det
,
f
=
1
,
useDiff
=
True
,
deriv_h
=
1.0e-8
):
"""
...
...
@@ -402,7 +403,7 @@ def scan_demod_phase_cmds(pd_detectors, demod_phase=1, relative=False, xaxis=1,
return
rtn
def
optimise_demod_phase
(
_kat
,
DOF
,
ports
,
debug
=
False
):
def
optimise_demod_phase
(
_kat
,
DOF
,
ports
,
minimise
=
False
,
debug
=
False
):
"""
This will optimise the demodulation phase at each port
provide the largest slope in the detector outputs with respect
...
...
@@ -455,7 +456,7 @@ def optimise_demod_phase(_kat, DOF, ports, debug=False):
if
debug
:
print
(
kat
&
"OPTIMISE"
)
out
=
kat
.
run
()
out
=
kat
.
run
(
cmd_args
=
[
"-cr=on"
]
)
if
debug
:
print
(
out
.
y
)
...
...
@@ -469,6 +470,9 @@ def optimise_demod_phase(_kat, DOF, ports, debug=False):
R
=
np
.
sqrt
(
y1
**
2
+
y2
**
2
)
phi
=
np
.
rad2deg
(
np
.
arctan2
(
y2
,
y1
))
if
minimise
:
phi
+=
90
# All in I quadrature so no
_kat
.
IFO
.
Outputs
[
port
.
name
].
phase
=
phi
...
...
@@ -517,7 +521,7 @@ def mismatch_cavities(base, node):
mmx
[
c1
][
c2
]
=
pykat
.
BeamParam
.
overlap
(
q1x
,
q2x
)
mmy
[
c1
][
c2
]
=
pykat
.
BeamParam
.
overlap
(
q1y
,
q2y
)
return
1
-
mmx
,
1
-
mmy
,
list
(
zip
(
cavs
,
qxs
,
qys
))
return
1
-
mmx
.
astype
(
float
),
1
-
mmy
.
astype
(
float
)
,
list
(
zip
(
cavs
,
qxs
,
qys
))
def
mismatch_scan_RoC
(
base
,
node
,
mirror
,
lower
,
upper
,
steps
):
_kat
=
base
.
deepcopy
()
...
...
@@ -1239,11 +1243,14 @@ class Output(object):
You can add many detectors at a given port, which readout different quadratures or types of transfer functions
or signals.
"""
def
__init__
(
self
,
IFO
,
name
,
nodeNames
,
f
=
None
,
phase
=
0
,
block
=
None
):
def
__init__
(
self
,
IFO
,
name
,
nodeNames
,
f_property_name
=
None
,
phase
=
0
,
block
=
None
):
if
f_property_name
is
not
None
and
not
isinstance
(
f_property_name
,
six
.
string_types
):
raise
Exception
(
"f_property_name should be a property name of a frequency in class {}"
.
format
(
IFO
.
__class__
))
self
.
__IFO
=
IFO
self
.
name
=
name
self
.
nodeNames
=
make_list_copy
(
nodeNames
)
self
.
f
=
f
# demodulation frequency, float
self
.
__f_property_name
=
f_property_name
self
.
phase
=
phase
# demodulation phase for I quadrature, float
self
.
_block
=
block
...
...
@@ -1252,6 +1259,13 @@ class Output(object):
"""For referencing the kat object this DOF is associated with"""
return
self
.
__IFO
.
kat
@
property
def
f
(
self
):
if
self
.
__f_property_name
is
None
:
return
None
return
getattr
(
self
.
__IFO
,
self
.
__f_property_name
)
def
check_nodeName
(
self
):
self
.
nodeName
=
None
...
...
pykat/ifo/aligo/__init__.py
View file @
4a3b014d
...
...
@@ -41,9 +41,6 @@ class ALIGO_IFO(IFO):
def
__init__
(
self
,
kat
,
tuning_keys_list
,
tunings_components_list
):
IFO
.
__init__
(
self
,
kat
,
tuning_keys_list
,
tunings_components_list
)
self
.
_f1
=
np
.
nan
self
.
_f2
=
np
.
nan
self
.
_f3
=
np
.
nan
self
.
_f36M
=
np
.
nan
@
property
...
...
@@ -70,60 +67,30 @@ class ALIGO_IFO(IFO):
@
property
def
f1
(
self
):
return
self
.
_f1
return
self
.
kat
.
mod1
.
f
.
value
@
f1
.
setter
def
f1
(
self
,
value
):
self
.
_f1
=
float
(
value
)
self
.
f36M
=
self
.
f2
-
self
.
f1
# Updating ports
if
hasattr
(
self
,
'LSC_DOFs'
):
for
a
in
self
.
LSC_DOFs
:
if
a
.
port
.
name
[
-
2
:]
==
'f1'
:
a
.
port
.
f
=
self
.
f1
self
.
kat
.
mod1
.
f
.
value
=
value
@
property
def
f2
(
self
):
return
self
.
_f2
return
self
.
kat
.
mod2
.
f
.
value
@
f2
.
setter
def
f2
(
self
,
value
):
self
.
_f2
=
float
(
value
)
self
.
f36M
=
self
.
f2
-
self
.
f1
# Updating ports
if
hasattr
(
self
,
'LSC_DOFs'
):
for
a
in
self
.
LSC_DOFs
:
if
a
.
port
.
name
[
-
2
:]
==
'f2'
:
a
.
port
.
f
=
self
.
f2
@
property
def
f3
(
self
):
return
self
.
_f3
@
f3
.
setter
def
f3
(
self
,
value
):
self
.
_f3
=
float
(
value
)
# Updating ports
if
hasattr
(
self
,
'LSC_DOFs'
):
for
a
in
self
.
LSC_DOFs
:
if
a
.
port
.
name
[
-
2
:]
==
'f3'
:
a
.
port
.
f
=
self
.
f3
self
.
kat
.
mod2
.
f
.
value
=
value
@
property
def
f36M
(
self
):
return
self
.
_f36M
@
f36M
.
setter
def
f36M
(
self
,
value
):
self
.
_f36M
=
float
(
value
)
# Updating ports
if
hasattr
(
self
,
'LSC_DOFs'
):
for
a
in
self
.
LSC_DOFs
:
if
a
.
port
.
name
[
-
4
:]
==
'f36M'
:
a
.
port
.
f
=
self
.
f36M
return
self
.
f2
-
self
.
f1
def
createPorts
(
self
):
# useful ports
self
.
POP_f1
=
Output
(
self
,
"POP_f1"
,
"nPOP"
,
self
.
f1
,
phase
=
101
)
self
.
POP_f2
=
Output
(
self
,
"POP_f2"
,
"nPOP"
,
self
.
f2
,
phase
=
13
)
self
.
REFL_f1
=
Output
(
self
,
"REFL_f1"
,
"nREFL"
,
self
.
f1
,
phase
=
101
)
self
.
REFL_f2
=
Output
(
self
,
"REFL_f2"
,
"nREFL"
,
self
.
f2
,
phase
=
14
)
self
.
POP_f1
=
Output
(
self
,
"POP_f1"
,
"nPOP"
,
"f1"
,
phase
=
101
)
self
.
POP_f2
=
Output
(
self
,
"POP_f2"
,
"nPOP"
,
"f2"
,
phase
=
13
)
self
.
REFL_f1
=
Output
(
self
,
"REFL_f1"
,
"nREFL"
,
"f1"
,
phase
=
101
)
self
.
REFL_f2
=
Output
(
self
,
"REFL_f2"
,
"nREFL"
,
"f2"
,
phase
=
14
)
self
.
AS_DC
=
Output
(
self
,
"AS_DC"
,
"nAS"
)
self
.
POW_BS
=
Output
(
self
,
"PowBS"
,
"nPRBS*"
)
self
.
POW_X
=
Output
(
self
,
"PowX"
,
"nITMX2"
)
...
...
@@ -268,10 +235,19 @@ class ALIGO_IFO(IFO):
This function alters the kat object directly.
"""
self
.
kat
.
remove
(
"lmod1"
,
"mod1"
,
"lmod2"
,
"mod2"
,
"lmod3"
)
# Remove modulators
comps
,
nodes
=
self
.
kat
.
nodes
.
getComponentsBetween
(
self
.
kat
.
L0
.
nodes
[
0
].
name
,
self
.
kat
.
mod2
.
nodes
[
1
].
name
,
getNodes
=
True
)
for
i
,
c
in
enumerate
(
comps
):
if
c
.
name
==
"lmod1"
:
i
-=
1
break
self
.
kat
.
remove
(
"lmod1"
,
"mod1"
,
"lmod2"
,
"mod2"
)
# Remove modulators
# Set output node of laser block to be on the laser
self
.
kat
.
nodes
.
replaceNode
(
self
.
kat
.
L0
,
'n0'
,
'nLaserOut'
)
self
.
kat
.
nodes
.
replaceNode
(
comps
[
i
],
nodes
[
i
][
-
1
].
name
,
'nLaserOut'
)
def
remove_IMC_HAM2
(
self
,
removeIMC
,
removeHAM2
):
"""
For use with files that have the IMC and HAM2 blocks.
...
...
@@ -410,13 +386,15 @@ class ALIGO_IFO(IFO):
Sets the DC offset for this inteferometer.
This function directly alters the tunings of the associated kat object.
DCoffset - degrees of additional DC offset to apply current tunings
"""
_kat
=
self
.
kat
if
DCoffset
is
not
None
:
self
.
DCoffset
=
DCoffset
print
(
"-- applying user-defined DC offset:"
)
vprint
(
verbose
,
"-- applying user-defined DC offset:"
)
tunings
=
self
.
get_tunings
()
...
...
@@ -683,14 +661,14 @@ class ALIGO_IFO(IFO):
self
.
set_REFL_gouy_telescope_phase
(
gouy_REFL_BS
,
gouy_A
,
gouy_B
)
self
.
kat
.
IFO
.
ASC_REFL9A
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL9A"
,
"nREFL_WFS_A"
,
self
.
kat
.
IFO
.
f1
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL9B
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL9B"
,
"nREFL_WFS_B"
,
self
.
kat
.
IFO
.
f1
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL9A
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL9A"
,
"nREFL_WFS_A"
,
"f1"
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL9B
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL9B"
,
"nREFL_WFS_B"
,
"f1"
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL45A
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL45A"
,
"nREFL_WFS_A"
,
self
.
kat
.
IFO
.
f2
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL45B
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL45B"
,
"nREFL_WFS_B"
,
self
.
kat
.
IFO
.
f2
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL45A
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL45A"
,
"nREFL_WFS_A"
,
"f2"
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL45B
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL45B"
,
"nREFL_WFS_B"
,
"f2"
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL36A
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL36A"
,
"nREFL_WFS_A"
,
self
.
kat
.
IFO
.
f36M
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL36B
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL36B"
,
"nREFL_WFS_B"
,
self
.
kat
.
IFO
.
f36M
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL36A
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL36A"
,
"nREFL_WFS_A"
,
"f36M"
,
block
=
"REFL_gouy_tele"
)
self
.
kat
.
IFO
.
ASC_REFL36B
=
Output
(
self
.
kat
.
IFO
,
"ASC_REFL36B"
,
"nREFL_WFS_B"
,
"f36M"
,
block
=
"REFL_gouy_tele"
)
self
.
update
()
...
...
@@ -827,11 +805,6 @@ def make_kat(name="design", katfile=None, verbose = False, debug=False, keepComm
else
:
kat
.
IFO
.
f2
=
5.0
*
kat
.
IFO
.
f1
if
"f3"
in
kat
.
constants
.
keys
():
kat
.
IFO
.
f3
=
float
(
kat
.
constants
[
"f3"
].
value
)
kat
.
IFO
.
f36M
=
kat
.
IFO
.
f2
-
kat
.
IFO
.
f1
# TODO add else here!
# check modultion frequencies
if
(
5
*
kat
.
IFO
.
f1
!=
kat
.
IFO
.
f2
):
...
...
@@ -846,10 +819,10 @@ def make_kat(name="design", katfile=None, verbose = False, debug=False, keepComm
# define ports and signals
# useful ports
kat
.
IFO
.
POP_f1
=
Output
(
kat
.
IFO
,
"POP_f1"
,
"nPOP"
,
kat
.
IFO
.
f1
,
phase
=
101
)
kat
.
IFO
.
POP_f2
=
Output
(
kat
.
IFO
,
"POP_f2"
,
"nPOP"
,
kat
.
IFO
.
f2
,
phase
=
13
)
kat
.
IFO
.
REFL_f1
=
Output
(
kat
.
IFO
,
"REFL_f1"
,
"nREFL"
,
kat
.
IFO
.
f1
,
phase
=
101
)
kat
.
IFO
.
REFL_f2
=
Output
(
kat
.
IFO
,
"REFL_f2"
,
"nREFL"
,
kat
.
IFO
.
f2
,
phase
=
14
)
kat
.
IFO
.
POP_f1
=
Output
(
kat
.
IFO
,
"POP_f1"
,
"nPOP"
,
"f1"
,
phase
=
101
)
kat
.
IFO
.
POP_f2
=
Output
(
kat
.
IFO
,
"POP_f2"
,
"nPOP"
,
"f2"
,
phase
=
13
)
kat
.
IFO
.
REFL_f1
=
Output
(
kat
.
IFO
,
"REFL_f1"
,
"nREFL"
,
"f1"
,
phase
=
101
)
kat
.
IFO
.
REFL_f2
=
Output
(
kat
.
IFO
,
"REFL_f2"
,
"nREFL"
,
"f2"
,
phase
=
14
)
# If we don't have an OMC then we need to attach
# directly to the AS node. Otherwise use OMC refl
...
...
@@ -858,9 +831,9 @@ def make_kat(name="design", katfile=None, verbose = False, debug=False, keepComm
else
:
nAS_RF
=
"nAS"
kat
.
IFO
.
AS_f1
=
Output
(
kat
.
IFO
,
"AS_f1"
,
nAS_RF
,
kat
.
IFO
.
f1
,
phase
=
101
)
kat
.
IFO
.
AS_f2
=
Output
(
kat
.
IFO
,
"AS_f2"
,
nAS_RF
,
kat
.
IFO
.
f2
,
phase
=
14
)
kat
.
IFO
.
AS_f36
=
Output
(
kat
.
IFO
,
"AS_f36"
,
nAS_RF
,
kat
.
IFO
.
f36M
,
phase
=
14
)
kat
.
IFO
.
AS_f1
=
Output
(
kat
.
IFO
,
"AS_f1"
,
nAS_RF
,
"f1"
,
phase
=
101
)
kat
.
IFO
.
AS_f2
=
Output
(
kat
.
IFO
,
"AS_f2"
,
nAS_RF
,
"f2"
,
phase
=
14
)
kat
.
IFO
.
AS_f36
=
Output
(
kat
.
IFO
,
"AS_f36"
,
nAS_RF
,
"f36M"
,
phase
=
14
)
kat
.
IFO
.
AS_DC
=
Output
(
kat
.
IFO
,
"AS_DC"
,
"nAS"
)
kat
.
IFO
.
POW_BS
=
Output
(
kat
.
IFO
,
"PowBS"
,
"nPRBS*"
)
...
...
@@ -868,12 +841,16 @@ def make_kat(name="design", katfile=None, verbose = False, debug=False, keepComm
kat
.
IFO
.
POW_Y
=
Output
(
kat
.
IFO
,
"PowY"
,
"nITMY2"
)
# pretune LSC DOF
kat
.
IFO
.
preARMX
=
DOF
(
kat
.
IFO
,
"ARMX"
,
kat
.
IFO
.
POW_X
,
""
,
"ETMX"
,
1
,
1.0
,
sigtype
=
"z"
)
kat
.
IFO
.
preARMY
=
DOF
(
kat
.
IFO
,
"ARMY"
,
kat
.
IFO
.
POW_Y
,
""
,
"ETMY"
,
1
,
1.0
,
sigtype
=
"z"
)
kat
.
IFO
.
preMICH
=
DOF
(
kat
.
IFO
,
"AS"
,
kat
.
IFO
.
AS_DC
,
""
,
[
"ITMX"
,
"ETMX"
,
"ITMY"
,
"ETMY"
],
[
1
,
1
,
-
1
,
-
1
],
6.0
,
sigtype
=
"z"
)
kat
.
IFO
.
prePRCL
=
DOF
(
kat
.
IFO
,
"PRCL"
,
kat
.
IFO
.
POW_BS
,
""
,
"PRM"
,
1
,
10.0
,
sigtype
=
"z"
)
kat
.
IFO
.
preSRCL
=
DOF
(
kat
.
IFO
,
"SRCL"
,
kat
.
IFO
.
AS_DC
,
""
,
"SRM"
,
1
,
10.0
,
sigtype
=
"z"
)
kat
.
IFO
.
preARMX
=
DOF
(
kat
.
IFO
,
"ARMX"
,
kat
.
IFO
.
POW_X
,
""
,
"ETMX"
,
1
,
1.0
,
sigtype
=
"z"
)
kat
.
IFO
.
preARMY
=
DOF
(
kat
.
IFO
,
"ARMY"
,
kat
.
IFO
.
POW_Y
,
""
,
"ETMY"
,
1
,
1.0
,
sigtype
=
"z"
)
kat
.
IFO
.
preMICH
=
DOF
(
kat
.
IFO
,
"AS"
,
kat
.
IFO
.
AS_DC
,
""
,
[
"ITMX"
,
"ETMX"
,
"ITMY"
,
"ETMY"
],
[
1
,
1
,
-
1
,
-
1
],
6.0
,
sigtype
=
"z"
)
kat
.
IFO
.
prePRCL
=
DOF
(
kat
.
IFO
,
"PRCL"
,
kat
.
IFO
.
POW_BS
,
""
,
"PRM"
,
1
,
10.0
,
sigtype
=
"z"
)
kat
.
IFO
.
preSRCL
=
DOF
(
kat
.
IFO
,
"SRCL"
,
kat
.
IFO
.
AS_DC
,
""
,
"SRM"
,
1
,
10.0
,
sigtype
=
"z"
)
# Used by new pretuning scripts DOFs
kat
.
IFO
.
_preDARM
=
DOF
(
kat
.
IFO
,
"DARM"
,
kat
.
IFO
.
AS_f2
,
"Q"
,
[
"ETMX"
,
"ETMY"
],
[
-
1
,
1
],
1.0
,
sigtype
=
"z"
)
kat
.
IFO
.
_prePRCL
=
DOF
(
kat
.
IFO
,
"PRCL"
,
kat
.
IFO
.
REFL_f1
,
"I"
,
"PRM"
,
1
,
10.0
,
sigtype
=
"z"
)
# control scheme as in [1] Table C.1. Due to Finesse conventions, the overall factor for all but PRCL are multiplied by -1
# compared to the LIGO defintion, to match the same defintion.
kat
.
IFO
.
PRCL
=
DOF
(
kat
.
IFO
,
"PRCL"
,
kat
.
IFO
.
POP_f1
,
"I"
,
"PRM"
,
1
,
100.0
,
sigtype
=
"z"
)
...
...
@@ -937,24 +914,25 @@ def make_kat(name="design", katfile=None, verbose = False, debug=False, keepComm
def
scan_to_precision
(
kat
,
DOF
,
pretune_precision
,
minmax
=
"max"
,
phi
=
0.0
,
precision
=
60.0
):
def
scan_to_precision
(
kat
,
DOF
,
pretune_precision
,
minmax
=
"max"
,
phi
=
0.0
,
precision
=
90.0
,
debug
=
None
):
assert_aligo_ifo_kat
(
kat
)
while
precision
>
pretune_precision
*
DOF
.
scale
:
out
=
scan_DOF
(
kat
,
DOF
,
xlimits
=
[
phi
-
1.5
*
precision
,
phi
+
1.5
*
precision
])
phi
,
precision
=
find_peak
(
out
,
DOF
.
port
.
name
,
minmax
=
minmax
)
phi
,
precision
=
find_peak
(
out
,
DOF
.
port
.
name
,
minmax
=
minmax
,
debug
=
debug
)
return
phi
,
precision
def
pretune
(
_kat
,
pretune_precision
=
1.0e-4
,
verbose
=
False
):
def
pretune
(
_kat
,
pretune_precision
=
1.0e-4
,
verbose
=
False
,
debug
=
{}
):
assert_aligo_ifo_kat
(
_kat
)
# This function needs to apply a bunch of pretunings to the original
# kat and associated IFO object passed in
IFO
=
_kat
.
IFO
print
(
"-- pretuning interferometer to precision {0:2g} deg = {1:2g} m"
.
format
(
pretune_precision
,
pretune_precision
*
_kat
.
lambda0
/
360.0
))
vprint
(
verbose
,
"-- pretuning interferometer to precision {0:2g} deg = {1:2g} m"
.
format
(
pretune_precision
,
pretune_precision
*
_kat
.
lambda0
/
360.0
))
kat
=
_kat
.
deepcopy
()
kat
.
removeBlock
(
"locks"
,
False
)
...
...
@@ -1004,7 +982,7 @@ def pretune(_kat, pretune_precision=1.0e-4, verbose=False):
make_transparent
(
kat
,[
"SRM"
])
phi
,
precision
=
scan_to_precision
(
kat
,
IFO
.
prePRCL
,
pretune_precision
)
phi
=
round
(
phi
/
pretune_precision
)
*
pretune_precision
phi
=
round_to_n
(
phi
,
5
)
phi
=
round_to_n
(
phi
,
5
)
vprint
(
verbose
,
" found max/min at: {} (precision = {:2g})"
.
format
(
phi
,
precision
))
IFO
.
prePRCL
.
apply_tuning
(
phi
)
...
...
@@ -1012,15 +990,193 @@ def pretune(_kat, pretune_precision=1.0e-4, verbose=False):
kat
=
_kat
.
deepcopy
()
kat
.
removeBlock
(
"locks"
,
False
)
phi
,
precision
=
scan_to_precision
(
kat
,
IFO
.
preSRCL
,
pretune_precision
,
phi
=
0
,
precision
=
10
)
phi
,
precision
=
scan_to_precision
(
kat
,
IFO
.
preSRCL
,
pretune_precision
,
phi
=
0
,
debug
=
(
"SRCL"
in
debug
)
)
phi
=
round
(
phi
/
pretune_precision
)
*
pretune_precision
phi
=
round_to_n
(
phi
,
4
)
-
90.0
phi
=
round_to_n
(
phi
,
5
)
-
90.0
vprint
(
verbose
,
" found max/min at: {} (precision = {:2g})"
.
format
(
phi
,
precision
))
IFO
.
preSRCL
.
apply_tuning
(
phi
)
print
(
" ... done"
)
vprint
(
verbose
,
" ... done"
)
def
pretune_2
(
_kat
,
pretune_precision
=
1.0e-4
,
verbose
=
False
,
debug
=
{}):
"""
This will pretune the arms and PRC cavities. This should be used in conjunction with the
pretune_SRCL function after the DC offset has been set.
"""
assert_aligo_ifo_kat
(
_kat
)
# This function needs to apply a bunch of pretunings to the original
# kat and associated IFO object passed in
IFO
=
_kat
.
IFO
vprint
(
verbose
,
"-- pretuning interferometer to precision {0:2g} deg = {1:2g} m"
.
format
(
pretune_precision
,
pretune_precision
*
_kat
.
lambda0
/
360.0
))
kat
=
_kat
.
deepcopy
()
kat
.
removeBlock
(
"locks"
,
False
)
vprint
(
verbose
,
" scanning X arm (maximising power)"
)
make_transparent
(
kat
,
[
"PRM"
,
"SRM"
])
make_transparent
(
kat
,
[
"ITMY"
,
"ETMY"
])
kat
.
BS
.
setRTL
(
0.0
,
1.0
,
0.0
)
# set BS refl. for X arm
phi
,
precision
=
scan_to_precision
(
kat
,
IFO
.
preARMX
,
pretune_precision
)
phi
=
round
(
phi
/
pretune_precision
)
*
pretune_precision
phi
=
round_to_n
(
phi
,
5
)
vprint
(
verbose
,
" found max/min at: {} (precision = {:2g})"
.
format
(
phi
,
precision
))
IFO
.
preARMX
.
apply_tuning
(
phi
)
vprint
(
verbose
,
" scanning Y arm (maximising power)"
)
kat
=
_kat
.
deepcopy
()
kat
.
removeBlock
(
"locks"
,
False
)
make_transparent
(
kat
,[
"PRM"
,
"SRM"
])
make_transparent
(
kat
,[
"ITMX"
,
"ETMX"
])
kat
.
BS
.
setRTL
(
1.0
,
0.0
,
0.0
)
# set BS refl. for Y arm
phi
,
precision
=
scan_to_precision
(
kat
,
IFO
.
preARMY
,
pretune_precision
)
phi
=
round
(
phi
/
pretune_precision
)
*
pretune_precision
phi
=
round_to_n
(
phi
,
5
)
vprint
(
verbose
,
" found max/min at: {} (precision = {:2g})"
.
format
(
phi
,
precision
))
IFO
.
preARMY
.
apply_tuning
(
phi
)
vprint
(
verbose
,
" scanning MICH (minimising power)"
)
kat
=
_kat
.
deepcopy
()
kat
.
removeBlock
(
"locks"
,
False
)
make_transparent
(
kat
,[
"PRM"
,
"SRM"
])
phi
,
precision
=
scan_to_precision
(
kat
,
IFO
.
preMICH
,
pretune_precision
,
minmax
=
"min"
,
precision
=
30.0
)
phi
=
round
(
phi
/
pretune_precision
)
*
pretune_precision
phi
=
round_to_n
(
phi
,
5
)
vprint
(
verbose
,
" found max/min at: {} (precision = {:2g})"
.
format
(
phi
,
precision
))
IFO
.
preMICH
.
apply_tuning
(
phi
,
add
=
True
)
vprint
(
verbose
,
" scanning PRCL (maximising power)"
)
kat
=
_kat
.
deepcopy
()
kat
.
removeBlock
(
"locks"
,
False
)
make_transparent
(
kat
,[
"SRM"
])
phi
,
precision
=
scan_to_precision
(
kat
,
IFO
.
prePRCL
,
pretune_precision
)
phi
=
round
(
phi
/
pretune_precision
)
*
pretune_precision
phi
=
round_to_n
(
phi
,
5
)
vprint
(
verbose
,
" found max/min at: {} (precision = {:2g})"
.
format
(
phi
,
precision
))
IFO
.
prePRCL
.
apply_tuning
(
phi
)
vprint
(
verbose
,
" ... done"
)
def
pretune_SRCL
(
_kat
,
verbose
=
False
,
debug
=
False
):
"""
This pretunes the SRC cavity to find a reasonable operating point.
It works slightly better with distorted interferometer models compared
to just using pretune().
"""
assert_aligo_ifo_kat
(
_kat
)
IFO
=
_kat
.
IFO
vprint
(
verbose
,
" scanning SRCL (finding TEM00 antiresonance)"
)
base1
=
_kat
.
deepcopy
()
# add some detectors to make a metric
base1
.
removeBlock
(
"locks"
,
False
)
base1
.
parse
(
"""
pd Psrm nSRM1
"""
)
base1
.
parse
(
base1
.
IFO
.
SRCL
.
signal
())
# Set some detectors to only see the TEM00 mode
for
n
in
range
(
_kat
.
maxtem
+
1
):
for
m
in
range
(
_kat
.
maxtem
+
1
):
base1
.
detectors
[
base1
.
IFO
.
SRCL
.
signal_name
()].
mask
(
n
,
m
,
int
(
n
==
m
==
0
))
base1
.
Psrm
.
mask
(
n
,
m
,
int
(
n
==
m
==
0
))
...
out
=
pykat
.
ifo
.
scan_DOF
(
base1
,
base1
.
IFO
.
SRCL
,
xlimits
=
[
-
10
,
180
],
steps
=
1000
)
# find resonance tuning
mx_deg_Psrm
=
out
.
x
[
out
[
'Psrm'
].
argmax
()]
c
=
((
mx_deg_Psrm
+
90
)
%
360
)
-
180
out
=
pykat
.
ifo
.
scan_DOF
(
base1
,
base1
.
IFO
.
SRCL
,
xlimits
=
[
c
-
180
,
c
+
180
],
steps
=
1000
)
# A weighting to favour the minimum value between the two SRC resonances
# highlighting the anti-resonance
W_Psrm
=
1
+
np
.
cos
(
np
.
deg2rad
((
out
.
x
-
mx_deg_Psrm
)
*
2
))
# Error signal should be small as well as small amount of power
SRCL_metric
=
abs
(
out
[
"REFL_f2_I"
]
*
out
[
"Psrm"
])
SRCL_metric
/=
SRCL_metric
.
max
()
# favour points further away from resonance
SRCL_metric
+=
W_Psrm
if
debug
:
plt
.
plot
(
out
.
x
,
SRCL_metric
)
plt
.
plot
(
out
.
x
,
out
[
"REFL_f2_I"
])
deg
=
(
out
.
x
[
SRCL_metric
.
argmin
()]
%
360
)
-
180
IFO
.
preSRCL
.
apply_tuning
(
-
deg
)
def
setup
(
base
,
old
=
True
,
DC_offset_pm
=
20
,
verbose
=
False
):
"""
Runs a preparation routine to produce a LIGO model at a resonable operating point.
This uses the pretune2 and pretune_SRCL methods which allow you
"""
assert_aligo_ifo_kat
(
base
)
base
=
base
.
deepcopy
()
base
.
verbose
=
False
base
.
removeBlock
(
'locks'
,
False
)
base
.
removeBlock
(
'errsigs'
,
False
)
base
.
removeBlock
(
'powers'
,
False
)
base
.
phase
=
2
base
.
IFO
.
fix_mirrors
()
kat
=
base
.
deepcopy
()
kat
.
IFO
.
remove_modulators
()
if
old
:
pretune
(
kat
,
pretune_precision
=
1e-3
,
verbose
=
verbose
)
else
:
pretune_2
(
kat
,
pretune_precision
=
1e-3
,
verbose
=
verbose
)
# Apply the tunings to our base kat file
base
.
IFO
.
apply_tunings
(
kat
.
IFO
.
get_tunings
())
base
.
IFO
.
adjust_PRC_length
(
verbose
=
verbose
)
if
verbose
:
pretune_status
(
base
)
base
.
IFO
.
lengths_status
()
# Set DC offset and plot
DCoffset
=
DC_offset_pm
*
1e-12
/
base
.
lambda0
*
180.0
base
.
IFO
.
set_DC_offset
(
DCoffset
=
DCoffset
,
verbose
=
verbose
)
if
not
old
:
pretune_SRCL
(
base
,
verbose
=
verbose
)
errsigs_cmds
=
base
.
IFO
.
add_errsigs_block
()
# Generates a dictionary of the lock values to use
locks
=
generate_locks
(
base
,
verbose
=
verbose
)
# Takes these values and then generates the commands and adds them to
# the lock block of the kat
lock_cmds
=
base
.
IFO
.
add_locks_block
(
locks
,
verbose
=
verbose
)
base
.
SRCL_lock
.
accuracy
/=
10
return
base
def
pretune_status
(
_kat
):
...
...
pykat/ifo/aligo/plot.py
View file @
4a3b014d
...
...
@@ -119,7 +119,7 @@ def error_signals(_kat, xlimits=[-1,1], DOFs=None, plotDOFs=None,
# add in signals for those DOF to plot
for
_
in
dofs
:
if
not
(
not
replaceDOFSignals
and
hasattr
(
kat
,
_
.
signal_name
()
)):
if
replaceDOFSignals
and
not
hasattr
(
kat
,
_
.
signal_name
(
)):
kat
.
parse
(
_
.
signal
())
toShow
=
None
...
...
@@ -158,21 +158,27 @@ def error_signals(_kat, xlimits=[-1,1], DOFs=None, plotDOFs=None,
kat
.
parse
(
scan_cmd
,
addToBlock
=
"SCAN"
)
out
=
kat
.
run
()
out
=
kat
.
run
(
cmd_args
=
[
'-cr=on'
]
)
if
d
.
name
==
"DARM"
and
"DC"
in
d
.
port
.
name
:
DC_Offset
=
kat
.
IFO
.
DCoffsetW
else
:
DC_Offset
=
0
DC_Offset
=
None
# Get a lock offset if used
if
(
d
.
name
+
'_lock'
)
in
_kat
.
commands
:
DC_Offset
=
_kat
.
commands
[
d
.
name
+
'_lock'
].
offset
.
value
if
DC_Offset
is
None
:
DC_Offset
=
0
else
:
DC_Offset
=
float
(
DC_Offset
)
if
toShow
is
None
:
ax
.
plot
(
out
.
x
,
out
[
d
.
signal_name
()]
-
DC_Offset
,
label
=
legend
)
ax
.
plot
(
out
.
x
,
out
[
d
.
signal_name
()]
+
DC_Offset
,
label
=
legend
)
else
:
for
_
in
toShow
:
if
legend
is
None
:
legend
=
_
.
name
ax
.
plot
(
out
.
x
,
out
[
_
.
signal_name
()]
-
DC_Offset
,
label
=
legend
)
ax
.
plot
(
out
.
x
,
out
[
_
.
signal_name
()]
+
DC_Offset
,
label
=
legend
)
ax
.
set_xlim
([
np
.
min
(
out
.
x
),
np
.
max
(
out
.
x
)])
ax
.
set_xlabel
(
"{} [deg]"
.
format
(
d
.
name
))
...
...
@@ -366,5 +372,36 @@ def pow_lsc(kat,xaxis = [-1,1,100]):
Plotting cavity powers and error signals in the same figures. Can be used
to see if error signal zero crossings coincide with power peaks.
'''
pass
raise
NotImplemented
()
def
strain_sensitivity
(
base
,
lower
=
10
,
upper
=
5000
,
steps
=
100
,
ax
=
None
,
plt
=
{}):
"""
Plots strain sensitivity
base - LIGO model
lower, upper, steps - frequency vector
ax - Matplotlib axes to use, if None it creates internally
plt - Dict of keyword arguments to pass to loglog
"""
kat
=
base
.
deepcopy
()
kat
.
removeBlock
(
"locks"
)
kat
.
removeBlock
(
"errsigs"
)
kat
.
parse
(
kat
.
IFO
.
DARM
.
transfer
())
kat
.
parse
(
"qnoisedS NSR 1 $fs nAS"
)
if
ax
is
None
:
ax
=
plt
.
subplot
(
111
)
out
=
kat
.
IFO
.
DARM_h
.
scan_f
(
linlog
=
"log"
,
lower
=
lower
,
upper
=
upper
,
steps
=
steps
)
ax
.
loglog
(
out
.
x
,
abs
(
out
[
"NSR"
]),
**
plt
)
ax
.
set_ylabel
(
"Sensitivity [h/sqrt{Hz}]"
)
ax
.
set_xlabel
(
"Frequency [Hz]"
)
if
ax
is
None
:
plt
.
gcf
().
tight_layout
()
plt
.
show
()
\ No newline at end of file
Write
Preview