Skip to content
Snippets Groups Projects
Commit 519024fe authored by Jean-Baptiste Bayle's avatar Jean-Baptiste Bayle
Browse files

First attempt to simulate hexagon

parent 0d4aec35
No related branches found
No related tags found
1 merge request!116Resolve "Implement basic structure for the hexagon experiment"
......@@ -7,3 +7,4 @@ from .meta import __author__
from .meta import __email__
from .instrument import Instrument
from .hexagon import Hexagon
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Simulation of the Hexagon experiment [1].
Reference:
[1] Yamamoto, K., Vorndamme, C., Hartwig, O., Staab, M., Schwarze, T. S., & Heinzel, G. (2021).
Experimental verification of intersatellite clock synchronization at LISA performance levels.
https://doi.org/10.1103/PhysRevD.105.042009
Authors:
...
Jean-Baptiste Bayle <j2b.bayle@gmail.com>
"""
import numpy as np
from . import noises
class Hexagon():
"""Represent the Hexagon instrument.
Args:
size (int): numer of samples in the simulation
dt (float): sampling period [s]
primary_laser_asd (float): ASD of primary laser 1 [Hz/sqrt(Hz)]
locked_laser_asd (float): ASD added to locked lasers 2 & 3 [Hz/sqrt(Hz)]
"""
INDICES = [1, 2, 3]
BEATNOTES = [12, 23, 31]
def __init__(self,
size=100, dt=1 / (80e6/2**17/10/6/3),
primary_laser_asd=100,
locked_laser_asd=60,
offset_freqs='default',
central_freq=2.816E14):
self.size = int(size)
self.dt = float(dt)
self.fs = 1.0 / self.dt
self.duration = self.size * self.dt
self.time = np.linspace(0, self.duration-self.dt, self.size)
self.primary_laser_asd = primary_laser_asd
self.locked_laser_asd = locked_laser_asd
self.central_freq = float(central_freq)
if offset_freqs == 'default':
self.offset_freqs = {1: 0.0, 2: 15E6, 3: 7E6}
else:
self.offset_freqs = offset_freqs
# initialize single-laser-related attributes
self.laser_noises = None
self.carrier_flucuations = None
self.carrier_offsets = None
# initialize beatnote-related attributes
self.carrier_beatnote = None
self.carrier_beatnote_offsets = None
self.carrier_beatnote_fluctuations = None
# initialize signal-combination attributes
self.three_signal_combination = None
def simulate(self):
"""Run a simulation, and generate all intermediary signals.
Args:
"""
self.laser_noises = np.empty((self.size, 3)) # (size, laser) [Hz]
# Laser 1 is free-running
self.laser_noises[:, 0] = noises.laser(self.fs, self.size, self.primary_laser_asd)
# Laser 2 replicated laser 1 with added locking noise
self.laser_noises[:, 1] = self.laser_noises[:, 0] \
+ noises.white(self.fs, self.size, self.locked_laser_asd)
# Laser 3 replicated laser 1 with added locking noise
self.laser_noises[:, 2] = self.laser_noises[:, 0] \
+ noises.white(self.fs, self.size, self.locked_laser_asd)
# Carrier beams
self.carrier_flucuations = self.laser_noises # (size, laser) [Hz]
self.carrier_offsets = np.array(
[[self.offset_freqs[index] for index in self.INDICES]]
) # (size, laser) [Hz]
# Compute beatnotes
# Convention is from paper: beatnote ij is beam j - beam i
self.carrier_beatnote_offsets = np.stack([
self.carrier_offsets[:, int(str(ij)[1]) - 1] - self.carrier_offsets[:, int(str(ij)[0]) - 1]
for ij in self.BEATNOTES
], axis=-1) # (size, beatnote) [Hz]
self.carrier_beatnote_fluctuations = np.stack([
self.carrier_flucuations[:, int(str(ij)[1]) - 1] - self.carrier_flucuations[:, int(str(ij)[0]) - 1]
for ij in self.BEATNOTES
], axis=-1) # (size, beatnote) [Hz]
self.carrier_beatnote = self.carrier_beatnote_offsets + self.carrier_beatnote_fluctuations
# Three-signal combination
self.three_signal_combination = self.carrier_beatnote[:,0] \
+ self.carrier_beatnote[:,1] + self.carrier_beatnote[:,2]
\ No newline at end of file
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# pylint: disable=missing-module-docstring
import pytest
from lisainstrument import Hexagon
def test_run():
"""Test that simulations can run."""
hex = Hexagon()
hex.simulate()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment