#!/usr/bin/env python # # Pull the pDAQ hit rates from all stringHub-*.moni files in the specified # directory. # # John Kelley # jkelley@icecube.wisc.edu # #------------------------------------------------- import numpy as np import sys import glob import re import time import datetime import string import json import operator # Naming convention for stringHub moni files FILEPAT = "stringHub-*.moni" # Use HLC? Otherwise use SLC HLC = False #------------------------------------------------- # Rate reporting in the log follows this format: # # DataCollectorMonitor-00A: 2012-04-27 02:11:32.712034: # NumHits: 8761 # RunState: RUNNING # NumTcal: 17 # MainboardId: 12b78d1cea33 # LBMOverflowCount: 0 # AcquisitionLoopCount: 264 # HitRate: 760.1 # HitRateLC: 25.3 # NumMoni: 152 # NumSupernova: 1 # # although field order can be different in older runs!!! # #------------------------------------------------- # MB lookup file NICKNAMES = "nicknames.txt" #------------------------------------------------- if (len(sys.argv) != 2): print("Usage: %s " % (sys.argv[0])) sys.exit(0) dirName = sys.argv[1] m = re.match("daqrun(\d+)", dirName) if m: runNumber = m.group(1) else: print("ERROR: log directory should be daqrun######") sys.exit(1) #------------------------------------------------- # Look up the mbid to position mapping try: f = open(NICKNAMES, "r") except: print("ERROR: couldn't open nicknames file for MBID mapping.") sys.exit(1) nameDict = {} posDict = {} # Skip header f.readline() for line in f.readlines(): vals = line.split() if len(vals) >= 4: mbid = vals[0] name = vals[2] pos = vals[3] nameDict[mbid] = name posDict[mbid] = pos f.close() #------------------------------------------------- # Get the filenames from the directory files = glob.glob(dirName+"/"+FILEPAT) if not files: print("ERROR: couldn't find stringHub log files in directory",dirName,".") sys.exit(1) # Iterate through the files rateDict = {} # TEMP FIX ME rateArr = [] timeArr = [] for fileName in files: try: f = open(fileName, "r") except: print("WARNING: couldn't open file",f,"for reading: skipped!") continue startTime = None foundMoni = False for line in f.readlines(): # Reset on newline m = re.match("^\s*$", line) if m: foundMoni = False continue m = re.match("DataCollectorMonitor-([0-9][0-9][AB]):\s*(.*):", line) if m: timeStr = m.group(2) mbid = "" rate = 0. foundMoni = True continue if foundMoni: m = re.match("\s*MainboardId:\s*([0-9a-f]+)\s*", line) if m: mbid = m.group(1) # Fix mainboard id if not zero-padded (moni bug) if len(mbid) != 12: z = "0"*(12-len(mbid)) mbid = z+mbid continue if not HLC: m = re.match("\s*HitRate:\s*([0-9.]+)\s*", line) else: m = re.match("\s*HitRateLC:\s*([0-9.]+)\s*", line) if m: rate = float(m.group(1)) if mbid in rateDict: rateDict[mbid].append(rate) else: if mbid != "": rateDict[mbid] = [rate] else: print("WARNING: found rate without mbid!") continue f.close() # Calculate median and stddev ratestats = {} for mbid,pos in sorted(posDict.items(), key=operator.itemgetter(1)): if mbid in rateDict: rate_median = np.median(rateDict[mbid]) rate_std = np.std(rateDict[mbid]) poskey = pos.replace("-", ",") ratestats[poskey] = {"rate_hz": rate_median, "stddev_hz": rate_std} # Find longest name for pretty-printing longName = max(nameDict.items(), key=lambda a:len(a[1])) longLen = len(longName[1]) # Save the results as text, sorted by position with open('rates_%s.txt' % runNumber, 'w') as outfile: print("Pos \t%sRate[Hz]\tStdDev[Hz]" % ("Name".ljust(longLen)), file=outfile) for mbid,pos in sorted(posDict.items(), key=operator.itemgetter(1)): poskey = pos.replace("-", ",") if poskey in ratestats: print("%s\t%s\t%.2f\t%.2f" % (pos, nameDict[mbid].ljust(longLen), ratestats[poskey]["rate_hz"], ratestats[poskey]["stddev_hz"]), file=outfile) # Also dump the result as JSON with open('rates_%s.json' % runNumber, 'w') as outfile: json.dump(ratestats, outfile, sort_keys = True, indent = 4, ensure_ascii=False)