Skip to content
Snippets Groups Projects
models.py 6.26 KiB
Newer Older
Brian Moe's avatar
Brian Moe committed
from django.db import models
from django.core.urlresolvers import reverse

Brian Moe's avatar
Brian Moe committed
import datetime
import thread
import string
Brian Moe's avatar
Brian Moe committed
import os
Brian Moe's avatar
Brian Moe committed

# XXX ER2.utils.  utils is in project directory.  ugh.
from utils import posixToGpsTime

from django.conf import settings
import pytz, time

SERVER_TZ = pytz.timezone(settings.TIME_ZONE)

# Let's say we start here on schema versions
#
# 1.0 -> 1.1   changed EventLog.comment from CharField(length=200) -> TextField
#
schema_version = "1.1"
Brian Moe's avatar
Brian Moe committed
class User(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField()
    principal = models.CharField(max_length=100)
    dn = models.CharField(max_length=100)
    unixid = models.CharField(max_length=25)

    class Meta:
        ordering = ["name"]

    def __unicode__(self):
        return self.name


class Group(models.Model):
    name = models.CharField(max_length=20)
    managers = models.ManyToManyField(User)
    def __unicode__(self):
        return self.name

class Label(models.Model):
    name = models.CharField(max_length=20, unique=True)
    # XXX really, does this belong here? probably not.
    defaultColor = models.CharField(max_length=20, unique=False, default="black")
    def __unicode__(self):
        return self.name
Brian Moe's avatar
Brian Moe committed

class Event(models.Model):
    ANALYSIS_TYPE_CHOICES = (
        ("LM",  "LowMass"),
        ("HM",  "HighMass"),
        ("GRB", "GRB"),
        ("RD",  "Ringdown"),
        ("OM",  "Omega"),
        ("Q",   "Q"),
        ("X",   "X"),
        ("CWB", "CWB"),
Brian Moe's avatar
Brian Moe committed
        ("MBTA", "MBTAOnline"),
        ("HWINJ", "HardwareInjection"),
Brian Moe's avatar
Brian Moe committed
    )
    submitter = models.ForeignKey(User)
    created = models.DateTimeField(auto_now_add=True)
    group = models.ForeignKey(Group)
    uid = models.CharField(max_length=20, default="")  # XXX deprecated.  should be removed.
Brian Moe's avatar
Brian Moe committed
    analysisType = models.CharField(max_length=20, choices=ANALYSIS_TYPE_CHOICES)
Brian Moe's avatar
Brian Moe committed
    instruments = models.CharField(max_length=20, default="")
    nevents = models.PositiveIntegerField(null=True)
Brian Moe's avatar
Brian Moe committed
    far = models.FloatField(null=True)
Brian Moe's avatar
Brian Moe committed
    likelihood = models.FloatField(null=True)

    # NOT from coinc_event, but so, so common.
    #   Note that the semantics for this is different depending
    #   on search type, so in some sense, querying on this may
    #   be considered, umm, wrong?  But it is a starting point.
    gpstime = models.PositiveIntegerField(null=True)
    labels = models.ManyToManyField(Label, through="Labelling")

    class Meta:
        ordering = ["-id"]

        if self.group.name == "Test":
            return "T%04d" % self.id
        elif self.analysisType == "HWINJ":
            return "H%04d" % self.id
Brian Moe's avatar
Brian Moe committed
    def weburl(self):
        return "https://ldas-jobs.phys.uwm.edu/gracedb/data/%s" % self.graceid()
Brian Moe's avatar
Brian Moe committed

    def wikiurl(self):
        return "https://www.lsc-group.phys.uwm.edu/twiki/bin/view/Sandbox/%s" % self.graceid()
Brian Moe's avatar
Brian Moe committed

    def clusterurl(self):
        #return "pcdev1.phys.uwm.edu:/archive/gracedb/data/%s" % self.graceid()
        return "file://pcdev1.phys.uwm.edu/archive/gracedb/data/%s" % self.graceid()
    def datadir(self, general=False):
        # Move to this.  Not the (more) ad hoc crap that's floating around.
        if general:
            subdir = "general"
        else:
            subdir = "private"
        return os.path.join(settings.GRACEDB_DATA_DIR, self.graceid(), subdir)
    def ligoApproved(self):
        return self.approval_set.filter(approvingCollaboration='L').count()

    def virgoApproved(self):
        return self.approval_set.filter(approvingCollaboration='V').count()
Brian Moe's avatar
Brian Moe committed

    def reportingLatency(self):
        if self.gpstime:
            dt = self.created
            if not dt.tzinfo:
                dt = SERVER_TZ.localize(dt)
            posix_time = time.mktime(dt.timetuple())
            gps_time = int(posixToGpsTime(posix_time))
            return gps_time - self.gpstime

    def neighbors(self, delta=5):
        if not self.gpstime:
            return []
        if self.group.name == 'Test':
            nearby = Event.objects.filter(group__name='Test')
        else:
            nearby = Event.objects.exclude(group__name='Test')
        nearby = nearby.filter(gpstime__range=(self.gpstime-delta, self.gpstime+delta))
        nearby = nearby.exclude(id=self.id)
        nearby = nearby.order_by('gpstime')
        return nearby

    @classmethod
    def getTypeLabel(cls, code):
        for key, label in cls.ANALYSIS_TYPE_CHOICES:
            if (key == code) or (code == label):
                return label
        raise KeyError("Unknown analysis type code: %s" % code)

Brian Moe's avatar
Brian Moe committed
    @classmethod
    def getByGraceid(cls, id):
        e = cls.objects.get(id=int(id[1:]))
        if (id[0] == "T") and (e.group.name == "Test"):
            return e
        if (id[0] == "H") and (e.analysisType == "HWINJ"):
            return e
        if (id[0] == "G"):
            return e
        raise cls.DoesNotExist()
    def __unicode__(self):
        return self.graceid()

Brian Moe's avatar
Brian Moe committed
class EventLog(models.Model):
    class Meta:
        ordering = ["-created"]
    event = models.ForeignKey(Event, null=False)
    created = models.DateTimeField(auto_now_add=True)
    issuer = models.ForeignKey(User)
    filename = models.CharField(max_length=100, default="")
    comment = models.TextField(null=False)
Brian Moe's avatar
Brian Moe committed

    def fileurl(self):
        if self.filename:
            return reverse('file', args=[self.event.graceid(), self.filename])
            #return os.path.join(self.event.weburl(), 'private', self.filename)
Brian Moe's avatar
Brian Moe committed
        else:
            return None

    def hasImage(self):
        # XXX hacky
        return self.filename and self.filename[-3:].lower() in ['png','gif','jpg']

class Labelling(models.Model):
    event = models.ForeignKey(Event)
    label = models.ForeignKey(Label)
    creator = models.ForeignKey(User)
    created = models.DateTimeField(auto_now_add=True)

# XXX Deprecated?  Is this used *anywhere*?
# Appears to only be used in models.py.  Here and Event class as approval_set
Brian Moe's avatar
Brian Moe committed
class Approval(models.Model):
    COLLABORATION_CHOICES = ( ('L','LIGO'), ('V','Virgo'), )
    approver = models.ForeignKey(User)
    created = models.DateTimeField(auto_now_add=True)
    approvedEvent = models.ForeignKey(Event, null=False)
    approvingCollaboration = models.CharField(max_length=1, choices=COLLABORATION_CHOICES)