From cb5fb5e5cfe4b2beb9f9a40682a8702f75e4d2dc Mon Sep 17 00:00:00 2001 From: Brian Moe <brian.moe@ligo.org> Date: Mon, 12 Apr 2010 12:35:12 -0500 Subject: [PATCH] Added make_histograms command to gracedb Django management --- gracedb/management/__init__.py | 0 gracedb/management/commands/__init__.py | 0 .../management/commands/make_histograms.py | 165 ++++++++++++++++++ manage.py | 8 + 4 files changed, 173 insertions(+) create mode 100644 gracedb/management/__init__.py create mode 100644 gracedb/management/commands/__init__.py create mode 100644 gracedb/management/commands/make_histograms.py diff --git a/gracedb/management/__init__.py b/gracedb/management/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/gracedb/management/commands/__init__.py b/gracedb/management/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/gracedb/management/commands/make_histograms.py b/gracedb/management/commands/make_histograms.py new file mode 100644 index 000000000..1a47e23b4 --- /dev/null +++ b/gracedb/management/commands/make_histograms.py @@ -0,0 +1,165 @@ + +from django.conf import settings +from django.core.management.base import BaseCommand, NoArgsCommand +from django.db import connection +from django.utils import dateformat + + +from gracedb.gracedb.models import Event + +import os +from datetime import datetime, timedelta +from subprocess import Popen, PIPE, STDOUT + + +DEST_DIR = "/tmp/foo" + + +def analysisTypes(): + cursor = connection.cursor() + cursor.execute(""" + SELECT DISTINCT e.analysisType + FROM gracedb_event e, gracedb_group g + WHERE + (e.group_id <> g.id AND g.name = 'Test') AND + (e.analysisType <> 'HWINJ') + """) + return [x[0] for x in cursor.fetchall()] + + +class Command(NoArgsCommand): + help = "I am the HISTOGRAM MAKER!" + + def handle_noargs(self, **options): + + now = datetime.now() + + start_day = now - timedelta(1) + start_week = now - timedelta(7) + start_month = now - timedelta(30) + + PAST = 91 + now -= timedelta(PAST) + start_day -= timedelta(PAST) + start_week -= timedelta(PAST) + start_month -= timedelta(PAST) + + time_ranges = [(start_day, "day"), (start_week, "week"), (start_month, "month")] + + valid_types = analysisTypes() + + for atype, atype_name in Event.ANALYSIS_TYPE_CHOICES: + if atype not in valid_types: + continue + for start_time, time_range in time_ranges: + try: + label = "Latencies for %s Events" % atype_name + except KeyError: + label = "Bad analysis type: %s" % atype + #labels = [label, "%s previous to %s" % (time_range, str(now))] + labels = [label, "%s previous to %s" % (time_range, dateformat.format(now, settings.DATE_FORMAT))] + d = histogramData(atype, start_time, now) + h = histogramImage(d, labels) + + open(os.path.join(DEST_DIR,"%s-%s.png" % (atype, time_range)),"w").write(h) + +#label = "Latencies for %s Events" % Event.getTypeLabel(atype) +# data = Event.objects.extra(select={"date":"DATE(created)"}) \ +# .values('date','analysisType') \ +# .annotate(count=Count('id')) + +class GnuPlot(object): + def __init__(self, prog=None): + self.p = Popen( + ["/usr/bin/gnuplot"], + executable="/usr/bin/gnuplot", + stdin=PIPE, + stdout=PIPE, + stderr=open('/dev/null','w')) + if prog: + self.set_prog(prog) + + def set_prog(self, prog): + self.p.stdin.write(prog) + + def write_data(self, data): + if isinstance(data, dict): + for key in data: + self.p.stdin.write("%s %s\n" % (key, data[key])) + elif isinstance(data, tuple): + for line in data: + for item in data: + self.p.stdin.write("%s " % data) + self.p.stdin.write("\n") + + def end_data(self, data): + self.p.stdin.write('e\n') + + def close_data(self): + self.p.stdin.close() + + def get_image(self): + self.close_data() + return self.p.stdout.read() # XXX ugh. will it always read the whole thing? + + +def histogramData(atype, start, end): + hist_data = {} + + data = Event.objects.filter(analysisType=atype, + created__range=[start, end]) + + for e in data: + latency = e.reportingLatency() + if latency is None: + continue + if latency in hist_data: + hist_data[latency] += 1 + else: + hist_data[latency] = 1 + return hist_data + + +def histogramImage(data, labels=[], size=(400,200)): + if not data: + data = { 0:0 } + if isinstance(labels, str): + labels = [labels] + elif not isinstance(labels, list): + try: + labels = list(labels) + except TypeError: + labels = [labels] + label_cmds = "" + labeloffset = 1.05 + for label in labels: + labeloffset -= 0.1 + label_cmds += 'set label "%s" at graph .1, %f\n' % (label, labeloffset) + minx, maxx = min(data.keys()), max(data.keys()) + width, height = size + + plotCode = """ + set terminal png size %(width)d, %(height)d + unset xtics + set ytics + set x2tics ( "%(minx)ds" %(minx)d, "%(maxx)ds" %(maxx)d ) + set xtics + set xrange [ 0 : %(maxx)s+10 ] + set yrange [0:] + set boxwidth 0.9 + set style data histograms + set style histogram cluster + set style fill solid 1.0 border lt -1 + %(label_cmds)s + plot "-" notitle with boxes fill + """ % { + "minx" : minx, + "maxx" : maxx, + "label_cmds" : label_cmds, + "width" : width, + "height" : height, + } + g = GnuPlot(plotCode) + g.write_data(data) + return g.get_image() + diff --git a/manage.py b/manage.py index 5e78ea979..b6f360910 100755 --- a/manage.py +++ b/manage.py @@ -1,5 +1,13 @@ #!/usr/bin/env python from django.core.management import execute_manager + +# THIS IS TERRIBLE, but some idiot named the project AND application gracedb. +# Things looking for gracedb.settings fail because they find the app not the proj. +# This also causes things wanting the app having to do gracedb.gracedb.whatever +# all the time, but that mess has already been made. +import sys, os +sys.path.insert(0, os.path.join(os.path.dirname(__file__),'..')) + try: import settings # Assumed to be in the same directory. except ImportError: -- GitLab