示例#1
0
 def run(self, keep: bool, upload: bool, assume_clean: bool,
         sensor_plot: bool, plot_audio: bool) -> None:
     submission_hash = str(config["sauron.test_submission_hash"])
     output_dir = config.get_output_dir(submission_hash)
     args = SubmissionRunnerArgs(
         dark=None,
         local=not upload,
         overwrite=True,
         keep_frames=False,
         store_to=None,
         assume_clean=assume_clean,
         sensor_plot=sensor_plot,
         plot_audio=plot_audio,
         halt_after_acquisition=False,
         ignore_prior=True,
     )
     with Valar() as db:
         SauronxLock().lock(None)
         try:
             # these will get shut down afterward
             audio = SauronxAudio()
             audio.start()
             b = Board()
             b.init()
             ss = SubmissionRunner(args, db, audio, b)
             ss.run(submission_hash, True)
             if not keep:
                 shutil.rmtree(output_dir, ignore_errors=True)
         finally:
             SauronxLock().unlock(ignore_warning=True)
示例#2
0
 def log(self) -> None:
     parser = argparse.ArgumentParser(
         description="Show the recent history of submissions on this Sauron."
     )
     self._parse_args(parser)
     lookup = LookupTools()
     with Valar():
         lookup.history()
示例#3
0
 def lookup(self) -> None:
     parser = argparse.ArgumentParser(
         description="List something in Valar",
         usage=
         "sauronx lookup [users|experiments|submissions|history|batteries|assays|templates|configs|stimuli|audio_files|sensors|plates|runs|plate_types|saurons|locations]",
     )
     parser.add_argument("what", help="What to list")
     args = self._parse_args(parser)
     with Valar():
         getattr(LookupTools(), args.what)()
示例#4
0
    def update(
        self, text: str,
        when: datetime.datetime = datetime.datetime.now()) -> None:
        with Valar() as valar:
            import valarpy.model as model

            conf = model.SauronConfigs(
                datetime_changed=when,
                description=text,
                sauron=config.sauron_id,
                created=datetime.datetime.now(),
            )
            conf.save()
        print(Fore.BLUE + "Created new sauron_config {}".format(conf.id))
示例#5
0
 def run(
     self,
     hashes: List[str],
     dark: Optional[int],
     local: bool,
     overwrite: bool,
     keep_frames: bool,
     store_to: Optional[str],
     assume_clean: bool,
     sensor_plot: bool,
     plot_audio: bool,
     halt_after_acquisition: bool,
     ignore_prior: bool,
     keep_lock: bool,
 ) -> None:
     args = SubmissionRunnerArgs(
         dark=dark,
         local=local,
         overwrite=overwrite,
         keep_frames=keep_frames,
         store_to=store_to,
         assume_clean=assume_clean,
         sensor_plot=sensor_plot,
         plot_audio=plot_audio,
         halt_after_acquisition=halt_after_acquisition,
         ignore_prior=ignore_prior,
     )
     SauronxLock().lock(None)
     try:
         b = Board()
         b.init()
         audio = SauronxAudio()
         audio.start()
         with Valar() as db:
             ss = SubmissionRunner(args, db, audio, b)
             for i, h in enumerate(hashes):
                 # TODO datetime_started only applies to the first hash. Is this really what we want?
                 self._log_start(args.local, h)
                 # we don't need a new process for the last run
                 ss.run(h, i == len(hashes) - 1)
                 self._log_finish(args.local, h, halt_after_acquisition)
     finally:
         if not keep_lock:
             SauronxLock().unlock(ignore_warning=True)
示例#6
0
 def __init__(
     self,
     submission_hash: Optional[str],
     db: Optional[Valar] = None,
     acquisition_start: bool = False,
     ignore_warnings: bool = False,
 ) -> None:
     """If submission_hash is None, don't try to access submission_obj or status_obj or call update_status."""
     self.db = None  # type: Valar
     self._internal_db = None  # type: bool
     self.submission_hash = None  # type: Optional[str]
     self.submission_obj = None  # type: Submissions
     self.sauron_obj = None  # type: Saurons
     self.status_obj = None  # type: Optional[SubmissionRecords]
     self._internal_db = db is None  # don't close if it was built outside
     self.ignore_warnings = ignore_warnings
     self.acquisition_start = acquisition_start
     self.submission_hash = submission_hash
     if self.submission_hash is not None:
         processing_list = ProcessingList.now()
         if self.submission_hash in processing_list:
             warn_user(
                 "Refusing to touch {}:".format(submission_hash),
                 "Another SauronX process appears to be handling it.",
                 "If this is wrong, run 'sauronx clear {}' to continue.".
                 format(submission_hash),
             )
             raise LockedError(
                 "Refusing to touch {}: Another SauronX process appears to be handling it."
                 .format(submission_hash))
     if db is None:
         self.db = Valar()
     else:
         self.db = db
     try:
         if "connection.notification.slack_info_file" in config:
             with open(
                     str(config["connection.notification.slack_info_file"]),
                     "r") as file:
                 self._slack_hook = file.readline()
                 self._slack_user_dict = json.loads(file.readline())
     except Exception:
         warn_user("Failed to call notification")
         logger.error("Failed to call notification", exc_info=True)
示例#7
0
 def clean(self) -> None:
     parser = argparse.ArgumentParser(
         description=
         "List SauronX output on this machine and decide whether to delete it"
     )
     parser.add_argument(
         "--auto",
         action="store_true",
         help="Auto-accept each recommendation without prompting")
     parser.add_argument(
         "--skip-ignores",
         action="store_true",
         help="Don’t prompt when the recommendation is to ignore.",
     )
     args, restrictions, options, base_dir = self._data_args(parser)
     with Valar() as db:
         if args.auto:
             DataManager(db).auto_clean(restrictions, options, base_dir)
         else:
             DataManager(db).clean(restrictions, options, base_dir,
                                   args.skip_ignores)
示例#8
0
 def connect(self) -> None:
     """Hidden connection test."""
     with Valar():
         pass
示例#9
0
 def data(self) -> None:
     parser = argparse.ArgumentParser(
         description="List SauronX output on this machine")
     args, restrictions, options, base_dir = self._data_args(parser)
     with Valar() as db:
         DataManager(db).data(restrictions, options, base_dir)
示例#10
0
 def print_info(self, extended: bool = False) -> None:
     with Valar() as valar:
         print()
         self._bannered(
             Style.BRIGHT + "Version information...",
             "Version ".ljust(20, ".") + " " + sauronx_version,
             "Hash ".ljust(20, ".") + " " + git_commit_hash(sauronx_home),
         )
         obj = config.get_sauron_config()
         self._bannered(
             Style.BRIGHT + "Hardware config information...",
             "Date/time changed ".ljust(20, ".") + " " + "{}Z".format(
                 config.sauron_number,
                 obj.datetime_changed.strftime("%Y-%m-%d_%H-%M-%S")),
             "Description ".ljust(20, ".") + " " + obj.description,
         )
         self._bannered(
             Style.BRIGHT + "Video information...",
             "QP ".ljust(20, ".") + " " +
             str(config["sauron.data.video.qp"]),
             "Keyframe interval ".ljust(20, ".") + " " +
             str(config["sauron.data.video.keyframe_interval"]),
             "Preset ".ljust(20, ".") + " " +
             config.get_str("sauron.data.video.preset"),
             "Custom params ".ljust(20, ".") + " " + "; ".join([
                 str(k) + "=" + str(v) for k, v in
                 config["sauron.data.video.extra_x265_params"].items()
             ]),
         )
         self._bannered(
             Style.BRIGHT + "Hardware information...",
             "FPS ".ljust(20, ".") + " " +
             str(config["sauron.hardware.camera.frames_per_second"]),
             "Exposure ".ljust(20, ".") + " " +
             str(config["sauron.hardware.camera.exposure"]),
             "Gain ".ljust(20, ".") + " " +
             str(config["sauron.hardware.camera.gain"]),
             "Gamma ".ljust(20, ".") + " " +
             str(config["sauron.hardware.camera.gamma"]),
             "Black level ".ljust(20, ".") + " " +
             str(config["sauron.hardware.camera.black_level"]),
             "Pre-padding ".ljust(20, ".") + " " + str(config[
                 "sauron.hardware.camera.padding_before_milliseconds"]),
             "Post-padding ".ljust(20, ".") + " " +
             str(config["sauron.hardware.camera.padding_after_milliseconds"]
                 ),
             "Arduino chipset ".ljust(20, ".") + " " +
             config.get_str("sauron.hardware.arduino.chipset"),
             "Sample rate (ms) ".ljust(20, ".") + " " + str(config[
                 "sauron.hardware.sensors.sampling_interval_milliseconds"]),
             "Audio floor (dB) ".ljust(20, ".") + " " +
             str(config["sauron.hardware.stimuli.audio.audio_floor"]),
             "Registered sensors ".ljust(20, ".") + " " +
             "; ".join(config["sauron.hardware.sensors.registry"]),
         )
         self._bannered(
             Style.BRIGHT + "Sauronx config information...",
             "Sauron ".ljust(20, ".") + " " + str(config.sauron_name),
             "Raw frames dir ".ljust(20, ".") + " " +
             config.raw_frames_root,
             "Output dir ".ljust(20, ".") + " " + config.output_dir_root,
             "Trash dir ".ljust(20, ".") + " " + config.trash_dir(),
             "Temp dir ".ljust(20, ".") + " " + config.temp_dir(),
             "Incubation dir ".ljust(20, ".") + " " +
             config.get_incubation_dir(),
             "Prototyping dir ".ljust(20, ".") + " " +
             config.get_prototyping_dir(),
             "Plate types ".ljust(20, ".") + " " +
             "; ".join(config.list_plate_types()),
         )
         if extended:
             self._bannered(
                 Style.BRIGHT + "Environment information...",
                 *[((key + " ").ljust(40, ".") + " " +
                    escape_for_properties(value))
                   for key, value in config.environment_info.items()],
             )
示例#11
0
import datetime
import json
import logging
from enum import Enum
from typing import List, Optional

from pocketutils.full import Tools
from valarpy.Valar import Valar
from pocketutils.core.exceptions import LockedError, RefusingRequestError
from pocketutils.misc.fancy_console import ColorMessages

from loguru import logger

Valar().open()
from valarpy.model import *

from sauronx import datetime_started_raw

from .configuration import config
from .locks import ProcessingList, ProcessingSubmission, SauronxLock


class InterceptHandler(logging.Handler):
    """
    Redirects standard logging to loguru.
    """
    def emit(self, record):
        # Get corresponding Loguru level if it exists
        try:
            level = logger.level(record.levelname).name
        except ValueError: