151 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
# -*- coding: utf-8 -*-
 | 
						|
############################################################################
 | 
						|
# Copyright (C) GFZ Potsdam                                                #
 | 
						|
# All rights reserved.                                                     #
 | 
						|
#                                                                          #
 | 
						|
# GNU Affero General Public License Usage                                  #
 | 
						|
# This file may be used under the terms of the GNU Affero                  #
 | 
						|
# Public License version 3.0 as published by the Free Software Foundation  #
 | 
						|
# and appearing in the file LICENSE included in the packaging of this      #
 | 
						|
# file. Please review the following information to ensure the GNU Affero   #
 | 
						|
# Public License version 3.0 requirements will be met:                     #
 | 
						|
# https://www.gnu.org/licenses/agpl-3.0.html.                              #
 | 
						|
############################################################################
 | 
						|
 | 
						|
import sys
 | 
						|
import json
 | 
						|
import datetime
 | 
						|
import argparse
 | 
						|
import zmq
 | 
						|
import seiscomp.datamodel, seiscomp.core, seiscomp.io
 | 
						|
 | 
						|
 | 
						|
VERSION = "0.1 (2024.066)"
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    parser = argparse.ArgumentParser()
 | 
						|
 | 
						|
    parser.set_defaults(
 | 
						|
        address="tcp://localhost:3333",
 | 
						|
        sample_rate=100,
 | 
						|
        gain=1.0,
 | 
						|
        network="XX",
 | 
						|
        station="{channel:05d}",
 | 
						|
        location="",
 | 
						|
        channel="HSF"
 | 
						|
    )
 | 
						|
 | 
						|
    parser.add_argument("--version",
 | 
						|
        action="version",
 | 
						|
        version="%(prog)s " + VERSION
 | 
						|
    )
 | 
						|
 | 
						|
    parser.add_argument("-a", "--address",
 | 
						|
        help="ZeroMQ address (default %(default)s)"
 | 
						|
    )
 | 
						|
 | 
						|
    parser.add_argument("-r", "--sample-rate",
 | 
						|
        type = int,
 | 
						|
        help = "sample rate (default %(default)s)"
 | 
						|
    )
 | 
						|
 | 
						|
    parser.add_argument("-g", "--gain",
 | 
						|
        type=float,
 | 
						|
        help="gain (default %(default)s)"
 | 
						|
    )
 | 
						|
 | 
						|
    parser.add_argument("-n", "--network",
 | 
						|
        help="network code (default %(default)s)"
 | 
						|
    )
 | 
						|
 | 
						|
    parser.add_argument("-s", "--station",
 | 
						|
        help="station code template (default %(default)s)"
 | 
						|
    )
 | 
						|
 | 
						|
    parser.add_argument("-l", "--location",
 | 
						|
        help="location code (default %(default)s)"
 | 
						|
    )
 | 
						|
 | 
						|
    parser.add_argument("-c", "--channel",
 | 
						|
        help="channel code (default %(default)s)"
 | 
						|
    )
 | 
						|
 | 
						|
    args = parser.parse_args()
 | 
						|
 | 
						|
    sock = zmq.Context().socket(zmq.SUB)
 | 
						|
    sock.connect(args.address)
 | 
						|
    sock.setsockopt(zmq.SUBSCRIBE, b"")
 | 
						|
 | 
						|
    header = json.loads(sock.recv().decode("utf-8"))
 | 
						|
 | 
						|
    inv = seiscomp.datamodel.Inventory()
 | 
						|
 | 
						|
    resp = seiscomp.datamodel.ResponsePAZ_Create()
 | 
						|
    resp.setType("A")
 | 
						|
    resp.setGain(args.gain * header["sensitivities"][0]["factor"] / header["dataScale"])
 | 
						|
    resp.setGainFrequency(0)
 | 
						|
    resp.setNormalizationFactor(1)
 | 
						|
    resp.setNormalizationFrequency(0)
 | 
						|
    resp.setNumberOfZeros(0)
 | 
						|
    resp.setNumberOfPoles(0)
 | 
						|
    inv.add(resp)
 | 
						|
 | 
						|
    sensor = seiscomp.datamodel.Sensor_Create()
 | 
						|
    sensor.setName(header["instrument"])
 | 
						|
    sensor.setDescription(header["instrument"])
 | 
						|
    sensor.setUnit(header["sensitivities"][0]["unit"])
 | 
						|
    sensor.setResponse(resp.publicID())
 | 
						|
    inv.add(sensor)
 | 
						|
 | 
						|
    datalogger = seiscomp.datamodel.Datalogger_Create()
 | 
						|
    datalogger.setDescription(header["instrument"])
 | 
						|
    datalogger.setGain(1)
 | 
						|
    datalogger.setMaxClockDrift(0)
 | 
						|
    deci = seiscomp.datamodel.Decimation()
 | 
						|
    deci.setSampleRateNumerator(args.sample_rate)
 | 
						|
    deci.setSampleRateDenominator(1)
 | 
						|
    datalogger.add(deci)
 | 
						|
    inv.add(datalogger)
 | 
						|
 | 
						|
    net = seiscomp.datamodel.Network_Create()
 | 
						|
    net.setCode(args.network)
 | 
						|
    net.setDescription(header["experiment"])
 | 
						|
    net.setStart(seiscomp.core.Time.FromYearDay(datetime.datetime.utcnow().year, 1))
 | 
						|
    inv.add(net)
 | 
						|
 | 
						|
    for roi in header["roiTable"]:
 | 
						|
        for c in range(roi["roiStart"], roi["roiEnd"] + 1, roi["roiDec"]):
 | 
						|
            sta = seiscomp.datamodel.Station_Create()
 | 
						|
            sta.setCode(eval("f'''" + args.station + "'''", {"channel": c}))
 | 
						|
            sta.setDescription("DAS channel %d" % c)
 | 
						|
            sta.setStart(net.start())
 | 
						|
            net.add(sta)
 | 
						|
 | 
						|
            loc = seiscomp.datamodel.SensorLocation_Create()
 | 
						|
            loc.setCode(args.location)
 | 
						|
            loc.setStart(net.start())
 | 
						|
            sta.add(loc)
 | 
						|
 | 
						|
            cha = seiscomp.datamodel.Stream_Create()
 | 
						|
            cha.setCode(args.channel)
 | 
						|
            cha.setStart(net.start())
 | 
						|
            cha.setGain(args.gain * header["sensitivities"][0]["factor"] / header["dataScale"])
 | 
						|
            cha.setGainUnit(header["sensitivities"][0]["unit"])
 | 
						|
            cha.setGainFrequency(0)
 | 
						|
            cha.setSensor(sensor.publicID())
 | 
						|
            cha.setDatalogger(datalogger.publicID())
 | 
						|
            loc.add(cha)
 | 
						|
 | 
						|
    ar = seiscomp.io.XMLArchive()
 | 
						|
    ar.create("-")
 | 
						|
    ar.setFormattedOutput(True)
 | 
						|
    ar.writeObject(inv)
 | 
						|
    ar.close()
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    main()
 | 
						|
 |