Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,17 @@ on: push
jobs:
tests:
name: Test
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
# Check out repo
- uses: actions/checkout@v3
- name: Setup python
uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.9"

- name: Qt5 defaults
run: |
sudo apt install qt5-default
python-version: ${{ matrix.python-version }}

- name: Install pymosa
run: |
Expand All @@ -27,7 +24,9 @@ jobs:
plugin_online_monitor pymosa/online_monitor

- name: Headless display setup
uses: pyvista/setup-headless-display-action@v1
uses: pyvista/setup-headless-display-action@v3
with:
qt: true

- name: Test
run: pytest -s -v
run: pytest -s -v
1 change: 0 additions & 1 deletion VERSION

This file was deleted.

8 changes: 1 addition & 7 deletions pymosa/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
# http://stackoverflow.com/questions/17583443/what-is-the-correct-way-to-share-package-version-with-setup-py-and-the-package
from pkg_resources import get_distribution, DistributionNotFound

try:
__version__ = get_distribution('pymosa').version
except DistributionNotFound:
__version__ = '(local)'
__version__ = "1.0.0"
13 changes: 13 additions & 0 deletions pymosa/constellation_pymosa/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from constellation.core.logging import setup_cli_logging
from constellation.core.satellite import SatelliteArgumentParser
from pymosa_satellite import Pymosa

def main(args=None):
parser = SatelliteArgumentParser()
args = vars(parser.parse_args(args))
setup_cli_logging(args.pop("level"))
s = Pymosa(**args)
s.run_satellite()

if __name__ == "__main__":
main()
12 changes: 12 additions & 0 deletions pymosa/constellation_pymosa/pymosa_conf.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[satellites]

[satellites.Pymosa]
run_number = "None" # Base run number, will be automatically increased; if none is given, generate filename
output_folder = "None" # Output folder for the telescope data; if none is given, the current working directory is used
m26_configuration_file = "None" # Configuration file for Mimosa26 sensors, default: 'm26_config/m26_threshold_8.yaml'
m26_jtag_configuration = true # Send Mimosa26 configuration via JTAG, default: True
no_data_timeout = 30 # No data timeout after which the scan will be aborted, in seconds; if 0, the timeout is disabled
scan_timeout = 0 # Timeout after which the scan will be stopped, in seconds; if 0, the timeout is disabled; use Ctrl-C to stop run
max_triggers = 0 # Maximum number of triggers; if 0, there is no limit on the number of triggers; use Ctrl-C to stop run
send_data = 'tcp://127.0.0.1:8500' # TCP address to which the telescope data is send; to allow incoming connections on all interfaces use 0.0.0.0
enabled_m26_channels = "None" # Enabled RX channels, eg. ["M26_RX1", "M26_RX2", "M26_RX6"]; default None (=all planes)
127 changes: 127 additions & 0 deletions pymosa/constellation_pymosa/pymosa_satellite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
from constellation.core.configuration import Configuration
from constellation.core.satellite import Satellite
import time
from constellation.core.cmdp import MetricsType
from constellation.core.fsm import SatelliteState
from constellation.core.monitoring import schedule_metric
import os
import yaml
import pymosa
from pymosa.m26 import m26
import logging
from pymosa.m26_raw_data import save_configuration_dict
from time import sleep, strftime, time
from tqdm import tqdm
from typing import Any

class Pymosa(Satellite):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def do_initializing(self, config: Configuration) -> None:
# Open Mimosa26 std. configuration
pymosa_path = os.path.dirname(pymosa.__file__)
with open(os.path.join(pymosa_path, 'm26_configuration.yaml'), 'r') as f:
self.yaml_config = yaml.safe_load(f)
# overwrite some configuration variables with toml config
configuration = config.get_dict()
if configuration["run_number"] == "None":
configuration["run_number"] = None
if configuration["output_folder"] == "None":
configuration["output_folder"] = None
if configuration["m26_configuration_file"] == "None":
configuration["m26_configuration_file"] = None
if configuration["enabled_m26_channels"] == "None":
configuration["enabled_m26_channels"] = None
for key in configuration.keys():
self.yaml_config[key] = configuration[key]
# Create telescope object and load hardware configuration
self.telescope = m26(conf=None) # None: use default hardware configuration
return "init done"

def do_launching(self):
# Initialize telescope hardware and set up parameters
self.telescope.init(init_conf=self.yaml_config)
return "launching done"

def do_run(self, payload=None) -> None:
self._pre_run()
with self.telescope.access_file():
save_configuration_dict(self.telescope.raw_data_file.h5_file, 'configuration', self.telescope.telescope_conf)
with self.telescope.readout(enabled_m26_channels=self.telescope.enabled_m26_channels):
got_data = False
start = time()
while not self.stop_scan and not self._state_thread_evt.is_set():
sleep(1.0)
if not got_data:
if self.telescope.m26_readout.data_words_per_second()[0] > 0:
got_data = True
logging.info('Taking data...')
if self.telescope.max_triggers:
self.pbar = tqdm(total=self.telescope.max_triggers, ncols=80)
else:
self.pbar = tqdm(total=self.telescope.scan_timeout, ncols=80)
else:
triggers = self.telescope.dut['TLU']['TRIGGER_COUNTER']
try:
if self.telescope.max_triggers:
self.pbar.update(triggers - self.pbar.n)
else:
self.pbar.update(time() - start - self.pbar.n)
except ValueError:
pass
if self.telescope.max_triggers and triggers >= self.telescope.max_triggers:
self.stop_scan = True
self.pbar.close()
logging.info('Trigger limit was reached: %i' % self.telescope.max_triggers)
logging.info('Total amount of triggers collected: %d', self.telescope.dut['TLU']['TRIGGER_COUNTER'])
self.logger.removeHandler(self.fh)
logging.info('Data Output Filename: %s', self.telescope.run_filename + '.h5')
self.telescope.analyze()
return "running done"

def do_landing(self):
# Close the resources
self.telescope.close()
return "landing done"

def _pre_run(self):
self.stop_scan = False
# signal.signal(signal.SIGINT, self.telescope._signal_handler)
logging.info('Press Ctrl-C to stop run')

# check for filename that is not in use
while True:
if not self.telescope.output_filename and self.telescope.run_number:
filename = 'run_' + str(self.telescope.run_number) + '_' + self.telescope.run_id

else:
if self.telescope.output_filename:
filename = self.telescope.output_filename
else:
filename = strftime("%Y%m%d-%H%M%S") + '_' + self.telescope.run_id
if filename in [os.path.splitext(f)[0] for f in os.listdir(self.telescope.working_dir) if os.path.isfile(os.path.join(self.telescope.working_dir, f))]:
if not self.telescope.output_filename and self.telescope.run_number:
self.telescope.run_number += 1 # increase run number and try again
continue
else:
raise IOError("Filename %s already exists." % filename)
else:
self.telescope.run_filename = os.path.join(self.telescope.working_dir, filename)
break

# set up logger
self.fh = logging.FileHandler(self.telescope.run_filename + '.log')
self.fh.setLevel(logging.DEBUG)
FORMAT = '%(asctime)s [%(name)-17s] - %(levelname)-7s %(message)s'
self.fh.setFormatter(logging.Formatter(FORMAT))
self.logger = logging.getLogger()
self.logger.addHandler(self.fh)
self.telescope.dut['TLU']['TRIGGER_COUNTER'] = 0

@schedule_metric("", MetricsType.LAST_VALUE, 1)
def trigger_number(self) -> Any:
if self.fsm.current_state_value == SatelliteState.RUN:
return self.telescope.dut['TLU']['TRIGGER_COUNTER']
else:
return None
3 changes: 2 additions & 1 deletion pymosa/m26_readout.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import datetime
from time import sleep, time, mktime
from threading import Thread, Event, Lock, Condition
from collections import deque, Iterable
from collections import deque
from collections.abc import Iterable
import sys

import numpy as np
Expand Down
43 changes: 43 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[build-system]
requires = ["setuptools >= 61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "pymosa"
dynamic = ["version"]
license = { "text" = "MIT License" }
readme = {file = "README.md", content-type = "text/markdown"}
requires-python = ">=3.9"
authors = [
{name = "Ivan Caicedo", email="[email protected]"},
{name ="Yannick Dieter", email="[email protected]"},
{name ="Toko Hirono", email="[email protected]"},
{name ="Jens Janssen", email="[email protected]"},
{name ="David-Leon Pohl", email="[email protected]"},
]

dependencies = [
"basil_daq>=3.0.0,<4.0.0",
"bitarray>=0.8.1",
"matplotlib",
"numba",
"numpy",
"online_monitor>=0.6.0",
"pymosa_mimosa26_interpreter>=1.0.0",
"pyyaml",
"tables",
"tqdm"
]

[project.scripts]
pymosa = "pymosa.m26:main"
pymosa_monitor = "pymosa.online_monitor.start_pymosa_online_monitor:main"

[project.urls]
"Repository" = 'https://github.com/SiLab-Bonn/pymosa'

[tool.setuptools.dynamic]
version = {attr = "pymosa.__version__"}

[tool.setuptools]
packages = ["pymosa"]
11 changes: 0 additions & 11 deletions requirements.txt

This file was deleted.

5 changes: 0 additions & 5 deletions setup.cfg

This file was deleted.

37 changes: 0 additions & 37 deletions setup.py

This file was deleted.

Loading