From 8577b776dfac2d01a3c2134ba63cec03fb07ce43 Mon Sep 17 00:00:00 2001
From: ahmedk <karim.ahmed@xfel.eu>
Date: Thu, 5 Sep 2024 13:53:07 +0200
Subject: [PATCH] Remove report service directory

---
 reportservice/README.md          | 129 -------
 reportservice/automatic_run.py   |  89 -----
 reportservice/build_dc_report.sh |  17 -
 reportservice/manual_run.py      |  89 -----
 reportservice/messages.py        |   3 -
 reportservice/report_conf.yaml   | 640 -------------------------------
 reportservice/report_service.py  | 432 ---------------------
 7 files changed, 1399 deletions(-)
 delete mode 100644 reportservice/README.md
 delete mode 100644 reportservice/automatic_run.py
 delete mode 100755 reportservice/build_dc_report.sh
 delete mode 100644 reportservice/manual_run.py
 delete mode 100644 reportservice/messages.py
 delete mode 100644 reportservice/report_conf.yaml
 delete mode 100644 reportservice/report_service.py

diff --git a/reportservice/README.md b/reportservice/README.md
deleted file mode 100644
index b0a3d83d2..000000000
--- a/reportservice/README.md
+++ /dev/null
@@ -1,129 +0,0 @@
-Offline Calibration Reportservice
-=================================
-
-The Reportserivce is a service responsible for handling requests (manual or automatic triggers)
-for generating the DetectorCharacterization reports based on the requested configurations.
-
-The Reportservice mainly consists of a service, clients and YAML configuration.
-The service keeps on listening to any ZMQ requests with a given configurations.
-Then based on these configurations, it produces slurm jobs (through xfel-calibrate command line) to generate *.png plots of calibration configurations over time.
-
-Finally these generated plots are pushed on to DetectorCharacterization(DC) remote repository and displayed on the ReadTheDocs(RTD).
-
-
-Configuration
--------------
-
-It is important to know the machine name and the port, where the reportservice is running, for successful connection.
-
-Starting the Service
---------------------
-
-The reportservice is a python script that can run through:
-
-    ```bash
-    python reportservice.py
-    ```
-
-The available command line arguments are:
-
-* --report-conf: The path for the main report configuration yaml file.
-* --log-file: The path for the log file.
-* --mode: The mode for running the service. Choices are sim[simulation], local and prod[production].
-* --logging: The required logs to be written. Choices are INFO, DEBUG and Error.
-
-Modes:
-
-*prod* is the production mode working on the max-exfl-cal001 as xcal user for generating the DC report through RTD
-and it should generate a very generalized DC report for the available detectors with information useful for most of the detector experts and users.
-
-*local* is the mode used for generating figures locally without uploading the DC report on RTD or pushing figures
-to the git repository, rather generated figures are copied to the local repository and depending on the
-given report-fmt(report format) argument an html or a pdf is generated in doc/_build/
-of the report service out folder (repo-local).
-
-*sim* is a simulation mode, which is mostly used for debugging purposes and tool development without generating any reports locally or over RTD.
-This mode make sure not to do any git interactions and it only works on running the notebooks for generating figures in the out-folder without further work.
-
-Report Configuration(report-conf):
-
-*report_conf.yaml* is the configuration file, which contains all the required information
-for operating and connecting to the reportservice.
-
-The global information holds the path to the DetectorCharacterization main tool for displaying the plots.
-Also, the information over the server (reportservice.py) and the time for automatic triggers for updating DC plots.
-
-```YAML
-    Global
-        git:
-            repo-local: "/gpfs/exfel/data/scratch/<username>/DetectorCharacterization/"
-            figures-remote: "http://<username>:<git-access-tocken>@git.xfel.eu/gitlab/detectors/DetectorCharacterization.git"
-            server-port: "tcp:<host-name>:<port-address>"
-
-        report_service:
-            report-service:
-            port: <port-address>
-            bind-to: tcp://*
-            job-db: ./reportservice_jobs.sqlite
-            job-update-interval: 30
-            job-timeout: 12000
-```
-
-The YAML configuration file can be modified with all the available parameters, responsible for generating the required plots and DC report on RTD.
-
-
-```YAML
-    <instrument>:
-        <detector>:
-            det-type:
-
-            start-date:
-            nconstants:
-            end-date:
-
-            constants:
-                - "Noise"
-                - "Offset"
-
-            modules:
-
-            bias-voltages:
-
-            mem-cells:
-
-            out-folder:
-            cal-db-timeout: 180000
-            cal-db-interface: "<cal-db-host-port>"
-```
-
-Triggering the service
----------------------
-
-To use the service and generate a DC report corresponding to the report_conf.yaml.
-The service can be triggered through two processes:
-
-Automatic Launch:
-
-    This is a similar script to reportservice.py that needs to be run using:
-
-    ```bash
-    python automatic_run.py
-    ```
-* --config-file: The path for the configuration file* --log-file: The path for the log file.
-* --logging: The required logs to be written. Choices are INFO, DEBUG and Error
-* --log-file: The path for the log file.
-
-Manual Launch:
-
-    This manual launch script is currently used for debugging purposes, only.
-
-    The available command line arguments are:
-
-* --config-file: The path for the configuration file
-* --instrument: A selected list of instruments to generate a report for. This instrument must be in the report_conf.yaml. The default for this argument is ['all]
-* --overwrite-conf: A bool for indicating a new report configuration file(conf-file) should be sent instead of the default report_conf.yaml,
-which is used by report_service.py from the start.
-* --log-file: The path for the log file.
-* --report-fmt: The output DC report format. Choices are pdf or html
-* --upload: A bool for uploading the figure to out-folder of the report service(repo-local) and generating a report. Default is False
-* --logging: The required log mode to be used. Choices are INFO, DEBUG and Error
diff --git a/reportservice/automatic_run.py b/reportservice/automatic_run.py
deleted file mode 100644
index dc3b71564..000000000
--- a/reportservice/automatic_run.py
+++ /dev/null
@@ -1,89 +0,0 @@
-import argparse
-import asyncio
-import logging
-from datetime import datetime, timedelta
-
-import yaml
-import zmq
-import zmq.asyncio
-from dateutil import parser, tz
-
-
-async def auto_run(cfg, timeout=3000):
-    """
-    Run the report service automatically depending on the scheduled times
-    in the run_time list, read from the config yaml file (report_conf.yaml)
-    """
-
-    # time index that points at a timestamp, when the next
-    # report service run takes place.
-    tidx = 0
-
-    # list of timestamps for the report service runs
-    run_time = cfg['GLOBAL']['run-on']
-    request = {}
-    request['req'] = ['all']
-    request['upload'] = True
-    request['report-fmt'] = 'html'
-    for i, ti in enumerate(run_time):
-        run_time[i] = parser.parse(ti)
-
-    while True:
-
-        time_now = datetime.utcnow().replace(tzinfo=tz.tzutc())
-        sched_time = run_time[tidx]
-
-        if sched_time.tzinfo is None:
-            sched_time = sched_time.replace(tzinfo=tz.tzutc())
-
-        # do automatic-run.
-        if time_now > sched_time:
-            con = zmq.asyncio.Context()
-            sock = con.socket(zmq.REQ)
-            port = cfg['GLOBAL']['server-port']
-            sock.SNDTIMEO = timeout
-            sock.RCVTIMEO = timeout
-            sock.connect(port)
-            await sock.send_pyobj(request)
-            msg = await sock.recv_pyobj()
-            logging.info('{} Automatic Run'.format(msg))
-
-            # Changing run_time to the sametime next week
-            run_time[tidx] = sched_time + timedelta(weeks=1)
-
-            tidx = tidx + 1 if tidx != len(run_time)-1 else 0
-
-        # check every 10mins, if there is
-        # a need for an automatic-run.
-        await asyncio.sleep(3000)
-
-
-arg_parser = argparse.ArgumentParser(description='Automatic Launch')
-arg_parser.add_argument('--config-file', type=str,
-                        default='./report_conf.yaml',
-                        help='config file path with reportservice port. '
-                             'Default=./report_conf.yaml')
-arg_parser.add_argument('--log-file', type=str, default='./report.log',
-                        help='The report log file path. Default=./report.log')
-arg_parser.add_argument('--logging', type=str, default="INFO",
-                        help='logging modes: INFO, DEBUG or ERROR. '
-                             'Default=INFO',
-                        choices=['INFO', 'DEBUG', 'ERROR'])
-
-if __name__ == "__main__":
-    args = vars(arg_parser.parse_args())
-    conf_file = args["config_file"]
-    with open(conf_file, "r") as f:
-        cfg = yaml.load(f.read(), Loader=yaml.FullLoader)
-
-    logfile = args["log_file"]
-    fmt = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
-
-    logging.basicConfig(filename=logfile, filemode='a+',
-                        level=getattr(logging, args['logging']),
-                        format='%(levelname)-6s: %(asctime)s %(message)s',
-                        datefmt='%Y-%m-%d %H:%M:%S')
-
-    loop = asyncio.get_event_loop()
-    loop.run_until_complete(auto_run(cfg))
-    loop.close()
diff --git a/reportservice/build_dc_report.sh b/reportservice/build_dc_report.sh
deleted file mode 100755
index cc40a6e46..000000000
--- a/reportservice/build_dc_report.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-# the path to doc folder with a Makefile
-dc_folder=$1
-report_fmt=$2
-
-echo "Running with the following parameters:"
-echo "DC folder path: $dc_folder"
-echo "DC Report format should be: report_fmt"
-
-if [ "${report_fmt}" == "pdf" ]
-then
-    make latexpdf -C "${dc_folder}"
-elif [ "${report_fmt}" == "html" ]
-then
-    make html -C "${dc_folder}"
-fi
diff --git a/reportservice/manual_run.py b/reportservice/manual_run.py
deleted file mode 100644
index df7ab40f7..000000000
--- a/reportservice/manual_run.py
+++ /dev/null
@@ -1,89 +0,0 @@
-import argparse
-import logging
-
-import yaml
-import zmq
-
-
-def manual_run(request, cfg):
-    """
-    Run the report service manually from any machine
-    and provide the requested configuration for
-    reports generation.
-
-    :param request: a dictionary for generating reports for the
-                     requested Instruments. This dict consists
-                     of two keys. A upload boolean key for defining
-                     the fate of the generated plots
-                     (pushed to the DC repo. or staying locally)
-                     and a key request which can either be a list
-                     of requested Instruments names e.g ['SPB'] or ['all']
-                     for generating reports, or dict or new requested
-                     configuration.
-
-    """
-
-
-    port = cfg['GLOBAL']['server-port']
-    con = zmq.Context()
-    socket = con.socket(zmq.REQ)
-    socket.connect(port)
-    socket.send_pyobj(request)
-    msg = socket.recv_pyobj()
-    logging.info('{} Manual Run'.format(msg))
-
-
-arg_parser = argparse.ArgumentParser(description='Manual Launch')
-arg_parser.add_argument('--instrument', default=['all'], nargs='+',
-                        help='Select the requested instruments. '
-                             'Default=\"all\", which can be used for selecting'
-                             ' all instruments.')
-arg_parser.add_argument('--config-file', type=str,
-                        default='./report_conf.yaml',
-                        help='path to report configuration file '
-                             'Default=./report_conf.yaml')
-arg_parser.add_argument('--upload', action='store_true',
-                        help='Required for uploading the generated figures.'
-                             'Default=False. '
-                             'Note: THIS HAS NO EFFECT IN SIM MODE!')
-arg_parser.set_defaults(upload=False)
-arg_parser.add_argument('--overwrite-conf', action='store_true',
-                        help='A flag for using a different config file than'
-                             'what is used by the running report_service.'
-                             'Default=False, type=str.')
-arg_parser.set_defaults(overwrite_conf=False)
-arg_parser.add_argument('--report-fmt', default='html',
-                        type=str, choices=['pdf', 'html'],
-                        help='If available in the report service running mode,'
-                             ' this can configure the report format '
-                             'to be html or pdf. Default=html '
-                             'Note: THIS HAS NO EFFECT IN PROD AND SIM MODES!')
-arg_parser.add_argument('--log-file', type=str, default='./report.log',
-                        help='The report log file path. Default=./report.log')
-arg_parser.add_argument('--logging', type=str, default="INFO",
-                        help='logging modes: INFO, DEBUG or ERROR. '
-                             'Default=INFO',
-                        choices=['INFO', 'DEBUG', 'ERROR'])
-
-if __name__ == "__main__":
-    args = vars(arg_parser.parse_args())
-    conf_file = args["config_file"]
-    with open(conf_file, "r") as f:
-        cfg = yaml.load(f.read(), Loader=yaml.FullLoader)
-
-    logfile = args["log_file"]
-    fmt = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
-
-    logging.basicConfig(filename=logfile, filemode='a+',
-                        level=getattr(logging, args['logging']),
-                        format='%(levelname)-6s: %(asctime)s %(message)s',
-                        datefmt='%Y-%m-%d %H:%M:%S')
-
-    request = {'upload': args["upload"],
-               'report-fmt': args["report_fmt"]}
-
-    if args["overwrite_conf"]:
-        request['req'] = cfg
-    else:
-        request['req'] = args["instrument"]
-    manual_run(request, cfg)
diff --git a/reportservice/messages.py b/reportservice/messages.py
deleted file mode 100644
index a4723c162..000000000
--- a/reportservice/messages.py
+++ /dev/null
@@ -1,3 +0,0 @@
-class Errors:
-    REQUEST_MALFORMED = "FAILED: request {} is malformed, please contact det-support@xfel.eu"
-    INSTRUMENT_NOT_FOUND = "FAILED: Instrument {} is not known!, please contact det-support@xfel.eu"
diff --git a/reportservice/report_conf.yaml b/reportservice/report_conf.yaml
deleted file mode 100644
index 9c517865c..000000000
--- a/reportservice/report_conf.yaml
+++ /dev/null
@@ -1,640 +0,0 @@
-GLOBAL:
-    git:
-        repo-local: "/gpfs/exfel/data/scratch/xcal/calibration/DetectorCharacterization/"
-        figures-remote: "http://git@git.xfel.eu/gitlab/detectors/DetectorCharacterization.git"
-    server-port: "tcp://max-exfl-cal001:5566"
-
-    run-on:
-        - Monday 08:30:00 UTC
-
-    report-service:
-        port: 5566
-        bind-to: tcp://*
-        allowed-ips:
-        job-db: ./reportservice_jobs.sqlite
-        job-update-interval: 30
-        job-timeout: 12000
-
-SPB:
-    AGIPD1M1:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB2"
-        modules:
-            - "AGIPD1M1"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        constants:
-            - "Noise"
-            - "SlopesFF"
-            - "SlopesPC"
-            - "Offset"
-        dclass: "AGIPD"
-        submodules: "0-16"
-        bias-voltage:
-            - 300
-            - 500
-        memory-cells:
-            - 128
-            - 176
-            - 250
-        acquisition-rate:
-            - 1.1
-            - 2.2
-            - 4.5
-        gain-setting:
-            - 0
-            - 1
-            - 2
-        photon-energy: 9.2
-        separate-plot:
-            - "gain_setting"
-        parameter-names:
-            - "bias_voltage"
-            - "acquisition_rate"
-            - "memory_cells"
-        spShape:
-            - 64
-            - 64
-        gain-titles:
-            - "High gain"
-            - "Medium gain"
-            - "Low gain"
-        x-labels:
-            - "Acquisition rate"
-            - "Memory cells"
-        sp-name: "ASICs id"
-        nMemToShow: 32
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-    JUNGFRAU:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        constants:
-            - "Noise"
-            - "Offset"
-            - "RelativeGain"
-        dclass: "jungfrau"
-        nMemToShow: 16
-        modules:
-            - "Jungfrau_M035"
-            - "Jungfrau_M203"
-            - "Jungfrau_M221"
-            - "Jungfrau_M275"
-            - "Jungfrau_M273"
-            - "Jungfrau_M267"
-        bias-voltage:
-            - 90
-            - 180
-        memory-cells:
-            - 1
-            - 16
-        pixels-x:
-            - 1024
-        pixels-y:
-            - 512
-            - 1024
-        temperature:
-            - 291
-        integration-time:
-            - 4.96
-            - 50
-            - 250
-        gain-setting:
-            - 0
-            - 1
-            - 2
-        separate-plot:
-            - "integration_time"
-            - "gain_setting"
-            - "memory_cells"
-        parameter-names:
-            - "bias_voltage"
-            - "integration_time"
-            - "pixels_x"
-            - "pixels_y"
-            - "temperature"
-            - "memory_cells"
-        spShape:
-            - 256
-            - 64
-        gain-titles:
-            - "High gain"
-            - "Medium gain"
-            - "Low gain"
-        x-labels:
-            - "Sensor Temperature"
-            - "Integration Time"
-        sp-name: "Supercolumn 256*64"
-        photon-energy: 9.2
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-MID:
-    AGIPD1M2:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB2"
-        modules:
-            - "AGIPD1M2"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        constants:
-            - "Noise"
-            - "SlopesFF"
-            - "SlopesPC"
-            - "Offset"
-        dclass: "AGIPD"
-        submodules: "0-16"
-        bias-voltage:
-            - 300
-            - 500
-        memory-cells:
-            - 128
-            - 176
-            - 250
-        acquisition-rate:
-            - 1.1
-            - 2.2
-            - 4.5
-        gain-setting:
-            - 0
-            - 1
-            - 2
-        photon-energy: 9.2
-        separate-plot:
-            - "gain_setting"
-        parameter-names:
-            - "bias_voltage"
-            - "acquisition_rate"
-            - "memory_cells"
-        spShape:
-            - 64
-            - 64
-        gain-titles:
-            - "High gain"
-            - "Medium gain"
-            - "Low gain"
-        x-labels:
-            - "Acquisition rate"
-            - "Memory cells"
-        sp-name: "ASICs id"
-        nMemToShow: 32
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-    EPIX:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        dclass: "ePix100"
-        nMemToShow: 1
-        modules:
-            - "ePix100_M15"
-            - "ePix100_M18"
-        constants:
-            - "Noise"
-            - "Offset"
-        bias-voltage:
-            - 200
-        temperature:
-            - 288
-        integration-time:
-            - 1
-            - 50
-        photon-energy: 9.2
-        separate-plot:
-            - "integration_time"
-        parameter-names:
-            - "bias_voltage"
-            - "integration_time"
-            - "temperature"
-            - "in_vacuum"
-        spShape:
-            - 354
-            - 96
-        x-labels:
-            - "Sensor Temperature"
-            - "Integration Time"
-        sp-name: "ASICs id"
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-
-FXE:
-    LPD1M1:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB2"
-        modules:
-            - "LPD1M1"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        constants:
-            - "Noise"
-            - "SlopesFF"
-            - "SlopesCI"
-            - "Offset"
-        dclass: "LPD"
-        submodules: "0-16"
-        bias-voltage:
-            - 250
-            - 500
-        memory-cells:
-            - 1
-            - 128
-            - 512
-        gain-setting:
-            - 0
-            - 1
-            - 2
-        photon-energy: 9.2
-        separate-plot:
-            - "gain_setting"
-        parameter-names:
-            - "bias_voltage"
-            - "memory_cells"
-        spShape:
-            - 64
-            - 64
-        gain-titles:
-            - "High gain"
-            - "Medium gain"
-            - "Low gain"
-        x-labels:
-            - "Memory cells"
-        sp-name: "ASICs id"
-        nMemToShow: 32
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-    JUNGFRAU:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        constants:
-            - "Noise"
-            - "Offset"
-            - "RelativeGain"
-        dclass: "jungfrau"
-        modules:
-            - "Jungfrau_M233"
-            - "Jungfrau_M125"
-            - "Jungfrau_M260"
-        bias-voltage:
-            - 90
-            - 180
-        memory-cells:
-            - 1
-            - 16
-        pixels-x:
-            - 1024
-        pixels-y:
-            - 512
-            - 1024
-        temperature:
-            - 291
-        integration-time:
-            - 4.96
-            - 50
-            - 250
-        gain-setting:
-            - 0
-            - 1
-            - 2
-        separate-plot:
-            - "integration_time"
-            - "gain_setting"
-            - "memory_cells"
-        parameter-names:
-            - "bias_voltage"
-            - "integration_time"
-            - "pixels_x"
-            - "pixels_y"
-            - "temperature"
-            - "memory_cells"
-        spShape:
-            - 256
-            - 64
-        gain-titles:
-            - "High gain"
-            - "Medium gain"
-            - "Low gain"
-        nMemToShow: 1
-        x-labels:
-            - "Sensor Temperature"
-            - "Integration Time"
-        sp-name: "Supercolumn 256*64"
-        photon-energy: 9.2
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-DETLAB:
-    FASTCCD:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        constants:
-            - "Noise"
-            - "Offset"
-        dclass: "CCD"
-        nMemToShow: 1
-        modules:
-            - "fastCCD1"
-        bias-voltage:
-            - 79
-        temperature:
-            - 235
-            - 216
-            - 245
-        integration-time:
-            - 1
-            - 50
-        gain-setting:
-            - 0
-            - 1
-            - 2
-            - 8
-        pixels-x:
-            - 1934
-        pixels-y:
-            - 960
-        separate-plot:
-            - "integration_time"
-            - "gain_setting"
-            - "temperature"
-        parameter-names:
-            - "bias_voltage"
-            - "integration_time"
-            - "pixels_x"
-            - "pixels_y"
-            - "gain_setting"
-            - "temperature"
-        spShape:
-            - 967
-            - 10
-        gain-titles:
-            - "gain 0x"
-            - "gain 1x"
-            - "gain 2x"
-            - "gain 8x"
-        x-labels:
-            - "Sensor Temperature"
-            - "Integration Time"
-        sp-name: "Supercolumn 967*10"
-        photon-energy: 9.2
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-
-SCS:
-    FASTCCD:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        constants:
-            - "Noise"
-            - "Offset"
-        dclass: "CCD"
-        nMemToShow: 1
-        modules:
-            - "fastCCD1"
-        bias-voltage:
-            - 79
-        temperature:
-            - 235
-            - 216
-            - 245
-        integration-time:
-            - 1
-            - 50
-        gain-setting:
-            - 0
-            - 1
-            - 2
-            - 8
-        pixels-x:
-            - 1934
-        pixels-y:
-            - 960
-        separate-plot:
-            - "integration_time"
-            - "gain_setting"
-            - "temperature"
-        parameter-names:
-            - "bias_voltage"
-            - "integration_time"
-            - "pixels_x"
-            - "pixels_y"
-            - "gain_setting"
-            - "temperature"
-        spShape:
-            - 967
-            - 10
-        gain-titles:
-            - "gain 0x"
-            - "gain 1x"
-            - "gain 2x"
-            - "gain 8x"
-        x-labels:
-            - "Sensor Temperature"
-            - "Integration Time"
-        sp-name: "Supercolumn 967*10"
-        photon-energy: 9.2
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-SQS:
-    PNCCD:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        constants:
-            - "Noise"
-            - "Offset"
-        dclass: "CCD"
-        nMemToShow: 1
-        modules:
-            - "PnCCD1"
-        bias-voltage:
-            - 300
-        temperature:
-            - 235
-        integration-time:
-            - 1
-            - 50
-        gain-setting:
-            - 0
-        pixels-x:
-            - 1024
-        pixels-y:
-            - 1024
-        separate-plot:
-            - "integration_time"
-            - "temperature"
-        parameter-names:
-            - "bias_voltage"
-            - "integration_time"
-            - "pixels_x"
-            - "pixels_y"
-            - "gain_setting"
-            - "temperature"
-        spShape:
-            - 256
-            - 256
-        x-labels:
-            - "Sensor Temperature"
-            - "Integration Time"
-        sp-name: "Supercolumn 256*256"
-        photon-energy: 9.2
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-HED:
-    EPIX:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        dclass: "ePix100"
-        nMemToShow: 1
-        modules:
-            - "ePix100_M16"
-            - "ePix100_M17"
-        constants:
-            - "Noise"
-            - "Offset"
-        bias-voltage:
-            - 200
-        temperature:
-            - 288
-        integration-time:
-            - 1
-            - 50
-        photon-energy: 9.2
-        separate-plot:
-            - "integration_time"
-        parameter-names:
-            - "bias_voltage"
-            - "integration_time"
-            - "temperature"
-            - "in_vacuum"
-        spShape:
-            - 354
-            - 96
-        x-labels:
-            - "Sensor Temperature"
-            - "Integration Time"
-        sp-name: "superpixel id"
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
-
-    JUNGFRAU:
-        det-type:
-            - "GENERIC"
-            - "STATS_FROM_DB"
-        start-date: "2019-01-01"
-        end-date: "NOW"
-        nconstants: 20
-        constants:
-            - "Noise"
-            - "Offset"
-            - "RelativeGain"
-        dclass: "jungfrau"
-        nMemToShow: 1
-        modules:
-            - "Jungfrau_M039"
-            - "Jungfrau_M266"
-        bias-voltage:
-            - 90
-            - 180
-        memory-cells:
-            - 1
-            - 16
-        pixels-x:
-            - 1024
-        pixels-y:
-            - 512
-            - 1024
-        temperature:
-            - 291
-        integration-time:
-            - 4.96
-            - 50
-            - 250
-        gain-setting:
-            - 0
-            - 1
-            - 2
-        separate-plot:
-            - "integration_time"
-            - "gain_setting"
-            - "memory_cells"
-        parameter-names:
-            - "bias_voltage"
-            - "integration_time"
-            - "pixels_x"
-            - "pixels_y"
-            - "temperature"
-            - "memory_cells"
-        spShape:
-            - 256
-            - 64
-        gain-titles:
-            - "High gain"
-            - "Medium gain"
-            - "Low gain"
-        x-labels:
-            - "Sensor Temperature"
-            - "Integration Time"
-        sp-name: "Supercolumn 256*64"
-        photon-energy: 9.2
-        use-existing: "''"
-        out-folder: "/gpfs/exfel/data/scratch/xcal/report_service/tmp/{instrument}/{detector}/"
-        cal-db-timeout: 180000
-        cal-db-interface: "tcp://max-exfl-cal001:8015#8025"
diff --git a/reportservice/report_service.py b/reportservice/report_service.py
deleted file mode 100644
index 0e3da7e7c..000000000
--- a/reportservice/report_service.py
+++ /dev/null
@@ -1,432 +0,0 @@
-import argparse
-import asyncio
-import copy
-import glob
-import logging
-import os
-import subprocess
-from asyncio.subprocess import PIPE
-
-import yaml
-import zmq
-import zmq.asyncio
-from git import InvalidGitRepositoryError, Repo
-from messages import Errors
-
-loop = asyncio.get_event_loop()
-
-
-def init_config_repo(config):
-    """ Make sure the configuration repo. is present and up-to-data
-
-    :param config: the configuration defined in the `config-repo` section
-    """
-    os.makedirs(config['repo-local'], exist_ok=True)
-
-    try:
-        # Check if it is a git-repo.
-        repo = Repo(config['repo-local'])
-    except InvalidGitRepositoryError:
-        # clone the repo.
-        repo = Repo.clone_from(config['figures-remote'],
-                               config['repo-local'])
-        logging.info("Cloning the repository")
-    try:
-        # make sure it is updated
-        repo.remote().pull()
-    except Exception as e:
-        logging.error(e)
-        # update the head of local repository as the remote's
-        repo.remote().fetch()
-        repo.git.reset('--hard', 'origin/master')
-        # then make sure
-        repo.remote().pull()
-    logging.info("Config repo is initialized")
-
-
-async def parse_output(output):
-
-    joblist = []
-    for line in output.split('\n'):
-        if 'Submitted' in line:
-            joblist.append(line.split()[2])
-    logging.info('joblist: {}'.format(joblist))
-    return joblist
-
-
-async def wait_jobs(joblist):
-
-    counter = 0
-    while True:
-        found_jobs = set()
-        output = subprocess.check_output(['squeue']).decode('utf8')
-        for line in output.split("\n"):
-            for job in joblist:
-                if str(job) in line:
-                    found_jobs.add(job)
-        if not found_jobs:
-            logging.info('Jobs are finished')
-            break
-        await asyncio.sleep(10)
-        counter += 10
-
-
-async def get_run_base(instr_name, det_name, detector):
-
-    run_base = ['xfel-calibrate'] + detector['det-type']
-
-    for key, item in detector.items():
-
-        if key in ['det-type']:
-            continue
-
-        run_base += ['--{}'.format(str(key))]
-        if not isinstance(item, list):
-            if key == 'out-folder':
-                item = detector['out-folder'].format(instrument=instr_name,
-                                                     detector=det_name)
-            run_base += [str(item).replace(' ', '\ ')]
-        else:
-            for val in item:
-                run_base += [str(val).replace(' ', '\ ')]
-
-    return run_base
-
-
-async def del_folder(fpath):
-    """ Delete temporary folders e.g. the out-folder of new generated
-        plots.
-
-    :param fpath: the folder path that needs to be deleted.
-    """
-    cmd = ["rm", "-rf", fpath]
-    await asyncio.subprocess.create_subprocess_shell(" ".join(cmd))
-    logging.info('temp file {} has been deleted'.format(fpath))
-
-
-async def copy_files(f, path, sem):
-    """ Copying with concurrency limitation
-
-    :param f: the main file with its current path.
-    :param path: the path, where f is copied to.
-    :param sem: Semaphore is a variable that controls
-                access to common resources.
-                sem can be give a None value, to indicate
-                a copy of low numbers of file e.g. 1 file.
-    """
-    if sem:
-        async with sem:
-            cmd = ["rsync", "-a", f, path]
-            await asyncio.subprocess.create_subprocess_shell(" ".join(cmd))
-    else:
-        cmd = ["rsync", "-a", f, path]
-        await asyncio.subprocess.create_subprocess_shell(" ".join(cmd))
-
-
-async def build_dc_report(dc_folder, report_fmt):
-    """
-    Generating a DC report (latex or html) using maxwell nodes.
-    With the supported inputs a slurm job is submitted to sphinx-build
-    pdf or html depending on mode of the report_service.
-    html for prod mode and pdf or html for local mode depending
-    on the chosen report_fmt
-
-    :param dc_folder: the local DC folder path with figures and rst files
-    :param report_fmt: the expected report format(html or pdf)
-    """
-    temp_path = "{}/temp/build_dc_report/".format(os.getcwd())
-    os.makedirs(temp_path, exist_ok=True)
-
-    # launching a slurm job and assigning the bash script to it.
-    sprof = os.environ.get("XFELCALSLURM", "exfel")
-    launcher_command = "sbatch -t 24:00:00 --mem 500G --requeue " \
-                       "--output {temp_path}/slurm-%j.out"
-    srun_base = launcher_command.format(
-                temp_path=temp_path) + " -p {}".format(sprof)
-    srun_base = srun_base.split()
-
-    srun_base += [os.path.abspath("./build_dc_report.sh"),
-                  os.path.abspath("{}/doc".format(dc_folder)),
-                  report_fmt]
-    logging.info("Building DC report submission: {}".format(srun_base))
-    output = subprocess.check_output(srun_base).decode('utf8')
-
-    jobid = None
-    for line in output.split("\n"):
-        if "Submitted batch job " in line:
-            jobid = line.split(" ")[3]
-    logging.info("Submitted job for building a report: {}".format(jobid))
-
-    await asyncio.wait_for(wait_jobs([jobid]), timeout=7200)  # timeout=2hours
-    # delete folder only after the pending slurm jobs finishes
-    await del_folder("{}/slurm-{}.out".format(temp_path, jobid))
-
-
-async def push_figures(repo_master, addf):
-    """ Upload new figures
-
-    :param repo_master: the local git-repository.
-    :param addf: the generated figures to be added.
-    """
-
-    repo = Repo(repo_master)
-
-    add_tries = 0
-    while add_tries < 10:
-        try:
-            repo.index.add(addf)
-            add_tries = 10
-        except Exception as e:
-            logging.error(str(e))
-            await asyncio.sleep(2)
-            add_tries += 1
-    repo.index.commit("Add {} new figures".format(len(addf)))
-    repo.remote().push()
-    logging.info('Pushed to git')
-
-
-async def server_runner(conf_file, mode):
-    """
-    The main server loop. After pulling the latest changes
-    of the DC project, it awaits receiving configurations
-    on how to generate the requested reports.
-
-    Depending on receiving a conf yaml file or a list of
-    instruments, the server proceeds by generating figures.
-    Figures are copied to the corresponding folder in the
-    DC project and an add-commit-push is performed to
-    update the remote project and build reports that can
-    be accessed through ReadTheDocs.
-    """
-    with open(conf_file, "r") as f:
-        config = yaml.load(f.read(), Loader=yaml.FullLoader)
-
-    # perform git-dir checks and pull the project
-    # for updates only in production mode.
-    if mode != 'sim':
-        init_config_repo(config['GLOBAL']['git'])
-
-    logging.info("Report service started in mode: {}".format(mode))
-
-    logging.info("report service port: {}:{}"
-                        .format(config['GLOBAL']['report-service']['bind-to'],
-                                config['GLOBAL']['report-service']['port']))
-
-    context = zmq.asyncio.Context()
-    socket = context.socket(zmq.REP)
-
-    socket.bind("{}:{}".format(config['GLOBAL']['report-service']['bind-to'],
-                               config['GLOBAL']['report-service']['port']))
-
-    while True:
-        response = await socket.recv_pyobj()
-        await socket.send_pyobj('Build DC reports through -->')
-        logging.info("response: {} with uploading: {} and report format: {}"
-                     .format(response['req'],
-                             response['upload'],
-                             response['report-fmt']))
-
-        # Check if response is a list or a dict.
-        # if list, it should either have instrument names or ['all'].
-        # if dict, it should acquire the details of the requested reports
-        # for generation. As it will be used instead of report_conf.yaml
-
-        # reports config file
-        req_cfg = {}
-
-        # Validate the type of 'requested' response.
-        if isinstance(response['req'], dict):
-            req_cfg = response['req']
-        elif isinstance(response['req'], list):
-            if len(response['req']) == 1 and response['req'][0] == 'all':
-                req_cfg = config
-            else:
-                req_cfg['GLOBAL'] = config['GLOBAL']
-                for instr in response['req']:
-                    try:
-                        req_cfg[instr] = config[instr]
-                    except:
-                        logging.error(
-                                Errors.INSTRUMENT_NOT_FOUND.format(instr))
-                        continue
-        else:
-            logging.error(Errors.REQUEST_MALFORMED.format(response['req']))
-            continue
-
-        # No interaction with DC repository (local or remote)
-        # is allowed if sim mode.
-        if mode == 'sim':
-            req_cfg['GLOBAL']['upload'] = False
-            req_cfg['GLOBAL']['report-fmt'] = False
-        else:
-            # boolean for pushing to DC git repo.
-            req_cfg['GLOBAL']['upload'] = response['upload']
-            if mode == 'prod':
-                req_cfg['GLOBAL']['report-fmt'] = 'html'
-            else:
-                req_cfg['GLOBAL']['report-fmt'] = response['report-fmt']
-        logging.info('Requested Configuration: {}'.format(req_cfg))
-
-        async def do_action(cfg, service_mode):
-
-            logging.info('Run plot production')
-            local_repo = cfg['GLOBAL']['git']['repo-local']
-            fig_local = '{}/figures'.format(local_repo)
-            jobs_timeout = cfg['GLOBAL']['report-service'].get('job-timeout',
-                                                               3600)
-            all_new_files = []
-
-            for instr_name, instrument in cfg.items():
-
-                if instr_name == "GLOBAL":
-                    continue
-
-                launched_jobs = []
-                for det_name, det_conf in instrument.items():
-
-                    logging.info('Process detector: {}'.format(det_name))
-                    logging.debug('Config information: {}'.format(det_conf))
-
-                    run_base = await get_run_base(instr_name,
-                                                  det_name,
-                                                  det_conf)
-                    try:
-                        output = await asyncio.create_subprocess_shell(
-                                 " ".join(run_base), stdout=PIPE, stderr=PIPE)
-
-                        launched_jobs.append(output.communicate())
-
-                        logging.info('Submission information: {}:'
-                                                    .format(run_base))
-                    except Exception as e:
-                        logging.error('Submission failed: {}'.format(e))
-                        exit(1)
-
-                outputs = await asyncio.gather(*launched_jobs)
-
-                job_list = []
-                for output in outputs:
-                    if output[0]:
-                        logging.info('Submission Output: {}'
-                                     .format(output[0].decode('utf8')))
-                    if output[1]:
-                        logging.error('Submission Error: {}'
-                                      .format(output[1].decode('utf8')))
-                    job_list += await parse_output(output[0].decode('utf8'))
-
-                try:
-                    await asyncio.wait_for(wait_jobs(job_list),
-                                           timeout=jobs_timeout)
-                    logging.info('All jobs are finished')
-                except asyncio.TimeoutError:
-                    logging.error('Jobs have timed-out!')
-                    logging.error('{}/temp has not been deleted.'.format(
-                                  os.path.dirname(os.path.abspath(__file__))))
-
-                # Avoid copying files if upload bool is False
-                # to avoid causing local git repository errors.
-                if cfg['GLOBAL']['upload']:
-                    # Copy all plots
-                    for det_name, det_conf in instrument.items():
-
-                        out_folder = det_conf['out-folder'].format(
-                                              instrument=instr_name,
-                                              detector=det_name)
-
-                        figures = glob.glob("{}/*png".format(out_folder))
-
-                        det_new_files = {}
-
-                        for f in figures:
-                            const = f.split('/')[-1].split('_')[0]
-                            fpath = '{}/{}/{}/{}'.format(fig_local, instr_name,
-                                                         det_name, const)
-
-                            os.makedirs(fpath, exist_ok=True)
-                            det_new_files[f] = fpath
-
-                            # Set concurrency limitation.
-                            # 50 have been chosen by trial
-                            # Note: This is not the max limitation.
-                            sem = asyncio.Semaphore(50)
-                            all_new_files.append(
-                                '{}/{}'.format(fpath, f.split('/')[-1]))
-
-                        await asyncio.gather(*[copy_files(k, v, sem)
-                                               for k, v in det_new_files.items()])  # noqa
-
-                        logging.info('{} figures of {} are copied into {}'
-                                     .format(len(figures), det_name,
-                                             fig_local))
-
-            if cfg['GLOBAL']['upload']:
-                try:
-                    report_fmt = cfg['GLOBAL']['report-fmt']
-                    # Remove sensitive information from the config file.
-                    del cfg['GLOBAL']
-                    # Write the requested cfg.yaml before pushing all figures.
-                    with open('{}/report_conf.yaml'.format(
-                                                  fig_local), 'w') as outfile:
-                        yaml.dump(cfg, outfile, default_flow_style=False)
-
-                    if service_mode == 'prod':
-                        # add report_con.yaml in the list of files added to the
-                        # new git commit before pushing to remote
-                        all_new_files.append('{}/report_conf.yaml'
-                                             .format(fig_local))
-                        asyncio.ensure_future(push_figures(local_repo,
-                                                           all_new_files))
-                    # build either html or pdf depending on the running mode
-                    # of the report_service and requested report format.
-                    asyncio.ensure_future(build_dc_report(local_repo,
-                                                          report_fmt))  # noqa
-                except Exception as upload_e:
-                    logging.error("upload failed: {}".format(upload_e))
-
-                # TODO:delete out-folder
-                #try:
-                #    asyncio.ensure_future(del_folder(out_folder))
-                #except:
-                #    logging.error(str(e))
-
-            logging.info('Generating requested plots is finished!')
-            logging.info('=======================================')
-
-            return
-
-        try:
-            asyncio.ensure_future(do_action(copy.copy(req_cfg),
-                                            mode))
-        except Exception as e:  # actions that fail are only error logged
-            logging.error(str(e))
-            break
-
-arg_parser = argparse.ArgumentParser(description='Start the report service')
-arg_parser.add_argument('--config-file', type=str,
-                        default='./report_conf.yaml',
-                        help='config file path with '
-                             'reportservice port. '
-                             'Default=./report_conf.yaml')
-arg_parser.add_argument('--mode', type=str, default="sim", choices=['sim', 'prod', 'local'])
-arg_parser.add_argument('--log-file', type=str, default='./report.log',
-                        help='The report log file path. Default=./report.log')
-arg_parser.add_argument('--logging', type=str, default="INFO",
-                        help='logging modes: INFO, DEBUG or ERROR. '
-                             'Default=INFO',
-                    	choices=['INFO', 'DEBUG', 'ERROR'])
-
-if __name__ == "__main__":
-    args = vars(arg_parser.parse_args())
-    conf_file = args["config_file"]
-
-    logfile = args["log_file"]
-    fmt = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
-
-    logging.basicConfig(filename=logfile, filemode='a+',
-                        level=getattr(logging, args['logging']),
-                        format='%(levelname)-6s: %(asctime)s %(message)s',
-                        datefmt='%Y-%m-%d %H:%M:%S')
-    mode = args["mode"]
-    loop = asyncio.get_event_loop()
-    loop.run_until_complete(server_runner(conf_file, mode))
-    loop.close()
-- 
GitLab