Document Purpose

This document serves as the general procedure and reference for running the Main Injector code.

https://github.com/SSantosLab/Main-Injector

Scope

Main Injector is a python package designed by the SoaresSantosLab team in order to retrieve alerts from LVC GCN and work with those alerts to search for electromagnetic counterparts of gravitational wave events. To use main injector, you have to do three things: setup the SOURCEME file, source the SOURCEME file, and run the listener in the appropriate mode

Setup Main-Injector

To setup Main-Injector, you need to:

  1. Edit SOURCEME file
  2. source SOURCEME file.
  3. Execute listener.py (or any other test)

Execute workflow

The current workflow of Main-Injector is:

  1. listener.py "listens" for LVK alerts from GW Events.
  2. When listener.py gets an alert, it's sent to gwstreamer.py, which is responsible for processing it's content and send important information to slack, emails and cellphones.
    1. gwstreamer.py also initiates recycler.py through a child process. At this point, recyler.py and it's child process is independent from gwstreamer.py and listener.py.
  3. In recyler.py, the setup for strategy and onering is made, running two instances for 'moony' and 'notmoony' sky conditions.

Running tests

  1. From listener.py

    python listener.py --mode test
    
  2. From gwstreamer.py

    cd handler; python gwstreamer.py
    
  3. From recyler.py

    python recycler.py --trigger-id MS181101ab --skymap OUTPUT/TESTING/MS181101ab/PRELIMINARY_0/bayestar.fits.gz --event BNS --official
    
  4. Run Strategy:

    python python/knlc/kn_strategy.py --input-skymap OUPUT/TESTING/MS181101ab/PRELIMINARY_0/bayestar.fits.gz --ouput OUPUT/TESTING/MS181101ab/PRELIMINARY_0 -teff-type moony --kn-type blue --time 584239324
    

Active branches

Branch name Branch info
NotModularMI Currently run on DES machines
hex_factors Elise’s branch for OneRing development
tom
Website
master

Definitions and Acronyms

Term or Acronym Definition or Meaning
GW Gravitational wave
EM Electromagnetic
LVC LIGO, Virgo, and KAGRA comprise the advanced gravitational wave detector network
GCN The General Coordinates Network is a public collaboration platform run by NASA for the astronomy research community to share alerts and rapid communications about high-energy, multimessenger, and transient phenomena. For our purposes, we use GCN notices for GW events to trigger main injector to run
moony vs notmoony Two different strategy codes are run for implementation - one is called moony, one is called notmoony. They are somewhat self explanatory, but the main difference is their implementation in different night sky conditions - moony for nights where the moon is bright, notmoony for nights where the moon is not brightly illuminated
onering OneRing is the observing plan creator to rule them all (as dubbed by Jim and Nora). The original version sorted strategy hexes with a nearest_neighbor function and outputted a json file, but didn’t take much into account. The new version sorts based on Awesomeness Factor, which includes airmass, probability, slew time, moon visibility, rise/set time, and whether the hex is higher or lower priority in order to get a great observing plan json including ras, decs, MJD, and dither.
strategy Takes in a skymap and event type, and splits the skymap into hexes with ras, decs, and probabilities attached. Outputs two .csv strategy files (moony and notmoony) with a bunch of observing strategies based on the event type. These .csvs are used by recycler to pick either LTT (least telescope time) strategy or overall optimal strategy, sorted into hex types, then input into OneRing to create a final observing plan.

Full procedure

  1. Edit SOURCEME file

    The SOURCEME file state as of 01/30/24 on des70.a

    The SOURCEME file state as of 01/30/24 on des70.a

  2. source SOURCEME file.

  3. Execute listener.py to "listen" for LVK alerts from GW Events.

    python listener.py --mode test
    
  4. listener.py instantiates instances of GWStreamer and the EmailBot

  5. listener.py opens the gcn_credentials.yaml file and loads its contents into the variable gcn

    1. If listener.py is in test mode:
      1. Opens a directory of fake GCN alerts, loads them, and passes them to the GWStreamer.handle function
    2. If listener.py is not in test mode:
      1. The gcn_kafka.Consumer calls a gw alert whenever it is received
      2. The consumer instance loads the GCN alert in .json form and passes it to the GWStreamer.handle function
  6. The GWStreamer.handle function processes the GCNs and posts appropriate messages to the email and Slack bots.

    1. If the gcn is not a real streamed alert, then
    2. If the gcn is a real streamed alert, then the end of the GWStreamer.handle function calls recycler.py
  7. In recycler.py, the method run_strategy_and_onering is called twice - one for 'moony' and another for 'notmoony' sky conditions.

    1. 'moony' and 'notmoony' are keywords to be passed to /data/des70.a/data/desgw/O4/Main-Injector/python/knlc/kn_strategy_sims_MI.py to define the T_eff
  8. The method run_strategy_and_onering runs OneRing (which is located in python/OneRing.py). OneRing takes in the inner_hexes and outer_hexes lists (highest and lowest prob hexes) and produces a .json observing plan with ras, decs, dithers, and MJDs

listener.py process Diagram

graph TD
%% D[Edit SOURCEME using vim]-->C[source SOURCEME]

a\\["python listener.py --mode ['observation', 'mock', 'test']"] --> A((GWStreamer)) --> z\\["GWStreamer.handle()"]
a\\["python listener.py --mode ['observation', 'mock', 'test']"]-->B((EmailBot)) -- If listener hits an exception --> AA[Send email]
a\\["python listener.py --mode ['observation', 'mock', 'test']"] --> d\\["open(gcn_credentials.yaml)"] --> e(gcn)

e(gcn) -- If listener.py is in 'mock' or 'observation' mode --> Q((Consumer))--> h(consumer) --> J\\("consumer.subscribe(['igwn.gwalert'])")
J\\("consumer.subscribe(['igwn.gwalert'])")-- while message in consumer.consume() --> KKKKK\\["gcn_alert = json.loads(message.value())"] --> z\\["GWStreamer.handle()"]
e(gcn) -- If listener.py is in 'test' mode --> j[Open a directory of fake GCN alerts] --> PL(fake_gcn_alert) --> z\\("GWStreamer.handle(gcn_alert)")

z\\("GWStreamer.handle(gcn_alert)") --> zz[Conditional tests on gcn_alert for extraneous alerts]
zz[Conditional tests on gcn_alert for extraneous alerts] --> AAAYO((Slackbot))
zz[Conditional tests on gcn_alert for extraneous alerts] --> APPLES((EmailBot))
zz[Conditional tests on gcn_alert for extraneous alerts] --> BOBATEA[recycler.py]
AAAYO((Slackbot)) --> JJJ[Post message]
AAAYO((Slackbot)) --> KOLK[Post skymap]
AAAYO((Slackbot)) --> KOLB[Post moon plot]
APPLES((EmailBot)) --> EML[Send email]

BOBATEA(recycler.py) --> abc[run_strategy_and_onering] --> notmoon(notmoony_strategy)
BOBATEA(recycler.py) --> def[run_strategy_and_onering] --> moon(moony_strategy)

Related Resources, in ascending date order

https://docs.google.com/document/d/1SkDr7k985-WOi1Sq6661qsoW4QOEgdyrEiLRhf3Pr_I/edit#heading=h.7zr8flsrhf69

https://docs.google.com/presentation/d/1DqwVo19-7X_IkcvA9-LZGioE-AlNcDNoc_0AcZBYOTE/edit?usp=sharing

https://docs.google.com/presentation/d/1Mabf7Puh2frbIvmn7ZVsU-bKljlenF_ZE2fFNFFwtSw/edit?usp=sharing