Пример #1
0
 def print_segments(flag, table=False, caption=None):
     """Print the contents of a `SegmentList` in HTML
     """
     if isinstance(flag, DataQualityFlag):
         flag = flag.active
     dtype = float(abs(flag)).is_integer() and int or float
     if table:
         headers = [
             'GPS start', 'GPS end', 'UTC start', 'UTC end', 'Duration [s]'
         ]
         data = []
         for seg in flag:
             data.append([
                 dtype(seg[0]),
                 dtype(seg[1]),
                 from_gps(seg[0]).strftime('%B %d %Y %H:%M:%S.%f')[:-3],
                 from_gps(seg[1]).strftime('%B %d %Y %H:%M:%S.%f')[:-3],
                 dtype(abs(seg)),
             ])
         return gwhtml.table(headers,
                             data,
                             id='state-information',
                             caption=caption)
     else:
         segwizard = StringIO()
         flag.write(segwizard, format='segwizard', coltype=dtype)
         return markup.oneliner.pre(segwizard.getvalue())
Пример #2
0
    def write_state_html(self, state):
        """Write the HTML for the given state of this `GuardianTab`
        """
        page = self.scaffold_plots(state=state)

        page.div(class_='row')
        page.div(class_='col-md-12')

        # get segment data
        groups = type(self.modes)((idx, name) for idx, name in
                                  self.modes.items() if idx % 10 == 0)
        modes = type(self.modes)(
            (idx, name) for idx, name in self.modes.items() if
            not name.startswith('*'))
        headers = ['Index', 'Name', 'Active seconds',
                   'Hours', '%']
        prefix = self.ifo.lower()
        for flags, title, id in zip(
                [groups, modes],
                ['Top-level mode information', 'Detailed mode information'],
                ['%s-top-level-mode' % prefix, '%s-detailed-mode' % prefix]):
            page.h1(title)
            data = []
            pc = float(abs(state.active) / 100.)
            tots = 0
            toth = 0
            totp = 0
            for idx, name in flags.items():
                flag = get_segments(self.segmenttag % idx,
                                    state.active, query=False).copy()
                actives = abs(flag.active)
                activeh = actives / 3600.
                try:
                    activep = actives / pc
                except ZeroDivisionError:
                    activep = 0
                tots += actives
                toth += activeh
                totp += activep
                data.append([str(idx), name.strip('*'), '%.1f' % actives,
                             '%.1f' % activeh, '%.1f' % activep])
            data.append(['<strong>%s</strong>' % x for x in [
                '', 'Total:', '%.1f' % tots, '%.1f' % toth, '%.1f' % totp]])
            page.add(str(html.table(
                headers, data, id=id,
                caption="%s observatory mode statistics as recorded in "
                        "<samp>%s</samp>" % (title.split()[0], self.channel))))
        return super(ParentTab, self).write_state_html(state, plots=False,
                                                       pre=page)
Пример #3
0
 def print_segments(flag, table=False, caption=None):
     """Print the contents of a `SegmentList` in HTML
     """
     if isinstance(flag, DataQualityFlag):
         flag = flag.active
     dtype = float(abs(flag)).is_integer() and int or float
     if table:
         headers = ['GPS start', 'GPS end', 'UTC start', 'UTC end',
                    'Duration [s]']
         data = []
         for seg in flag:
             data.append([
                 dtype(seg[0]),
                 dtype(seg[1]),
                 from_gps(seg[0]).strftime('%B %d %Y %H:%M:%S.%f')[:-3],
                 from_gps(seg[1]).strftime('%B %d %Y %H:%M:%S.%f')[:-3],
                 dtype(abs(seg)),
             ])
         return gwhtml.table(headers, data, id='state-information',
                             caption=caption)
     else:
         segwizard = StringIO()
         flag.write(segwizard, format='segwizard', coltype=dtype)
         return markup.oneliner.pre(segwizard.getvalue())
Пример #4
0
    def write_state_html(self, state):
        """Build HTML summary of watchdog trips
        """
        # find one example of each channel, and get the bits
        hepichannel = get_channel(HEPI_LATCH_CHANNEL %
                                  (self.ifo, self.chambers[1]))
        hepimask = hepichannel.bits + ['HEPI Unknown']
        if self.chambers == HAMs:
            isichannels = [
                get_channel(HAM_ISI_LATCH_CHANNEL %
                            (self.ifo, self.chambers[0]))
            ]
            isimask = isichannels[0].bits + ['ISI Unknown']
        else:
            isichannels = [
                get_channel(BSC_ST1_LATCH_CHANNEL %
                            (self.ifo, self.chambers[0])),
                get_channel(BSC_ST2_LATCH_CHANNEL %
                            (self.ifo, self.chambers[0]))
            ]
            isimask = (isichannels[0].bits + ['ISI ST1 Unknown'] +
                       isichannels[1].bits + ['ISI ST2 Unknown'])
        mask = hepimask + isimask

        # count trips
        count = {}
        for _, chamber, trigger, _ in self.trips:
            key = (chamber, trigger)
            try:
                count[key] += 1
            except KeyError:
                count[key] = 1

        page = markup.page()

        # build summary table
        page.div(class_='well')
        chambertype = self.chambers[0][:-1]
        id_ = '{}-{}'.format(self.ifo.lower(), chambertype.lower())
        page.table(class_='table table-condensed table-hover watchdog',
                   id_=id_)
        page.caption("Number of watch-dog trips per %s chamber (column) and "
                     "trigger (row)" % (chambertype))
        page.thead()
        # add headers
        page.tr(class_='header')
        for th in ['WD'] + self.chambers + ['Sub-total']:
            page.th(th)
        page.tr.close()
        page.thead.close()

        # add rows
        page.tbody()
        totals = numpy.zeros((len(mask), len(self.chambers) + 1), dtype=int)
        rows = []
        for i, bit in enumerate(mask):
            class_ = []
            if (i == len(hepimask)
                    or i == len(hepimask + isichannels[0].bits)):
                class_.append('tdiv')
            if re_no_count.match(bit):
                class_.append('ignore')
            if class_:
                page.tr(class_=' '.join(class_))
            else:
                page.tr()
            page.th(bit)
            for j, chamber in enumerate(self.chambers):
                try:
                    c = count[(chamber, bit)]
                except KeyError:
                    c = 0
                    pass
                page.td(c or '-')
                # exclude IOP from total
                if not re_no_count.match(bit):
                    totals[i][j] = c
            # add row total
            totals[i][-1] = totals[i].sum()
            page.th(str(totals[i][-1]))
            page.tr.close()
        page.tbody.close()

        # add totals
        page.thead()
        page.tr(class_='header')
        page.th('Totals')
        for i in range(totals.shape[1]):
            page.th(str(totals[:, i].sum()))
        page.tr.close()
        page.thead.close()
        page.table.close()
        page.button('Export to CSV',
                    class_='btn btn-default btn-table',
                    onclick="exportTableToCSV('{name}.csv', '{name}')".format(
                        name=id_))
        page.div.close()

        # build trip groups
        self.trips.sort(key=lambda x: (x[0], x[2] in mask and (mask).index(x[
            2]) or 1000, x[3] is None))
        groups = OrderedDict()
        j = 0
        for i in range(len(self.trips)):
            if i == 0:
                j = i
                groups[j] = []
                continue
            t = self.trips[i][0]
            t2 = self.trips[i - 1][0]
            if (t - t2) < self.window:
                groups[j].append(i)
            else:
                j = i
                groups[j] = []

        # build trip table
        page.h1('Trip list')
        page.div(class_='well')

        utc = tz.gettz('UTC')
        if self.ifo in ['H1', 'C1', 'P1']:
            localzone = tz.gettz('America/Los_Angeles')
        elif self.ifo in ['L1']:
            localzone = tz.gettz('America/Chicago')
        elif self.ifo in ['K1']:
            localzone = tz.gettz('Asia/Tokyo')
        else:
            localzone = tz.gettz('Europe/Berlin')
        headers = [
            'GPS time', 'UTC time', 'Local time', 'Chamber', 'Trigger', 'Plot',
            'Associated'
        ]
        rows = []
        for id in groups:
            t, chamber, trigger, plot = self.trips[id]
            t2 = Time(t, format='gps', scale='utc')
            tlocal = Time(
                t2.datetime.replace(tzinfo=utc).astimezone(localzone),
                format='datetime',
                scale='utc')
            rows.append([t, t2.iso, tlocal.iso, chamber, trigger])
            if plot:
                rows[-1].append(
                    markup.oneliner.a('[Click here]',
                                      href=plot.href,
                                      class_='fancybox plot',
                                      **{'data-fancybox-group': '1'}))
            else:
                rows[-1].append('-')
            assoc = []
            for id2 in groups[id]:
                t2, chamber2, trigger2, plot2 = self.trips[id2]
                dt = t2 - t
                tag = '%s %s (+%.2fs)' % (chamber2, trigger2, dt)
                if plot2:
                    assoc.append(
                        markup.oneliner.a(tag,
                                          href=plot2.href,
                                          class_='fancybox plot',
                                          **{'data-fancybox-group': '1'}))
                else:
                    assoc.append(tag)
            if assoc:
                rows[-1].append('<br>'.join(assoc))
            else:
                rows[-1].append('-')
        page.add(
            str(
                html.table(
                    headers,
                    rows,
                    caption=
                    ('List of %s watch-dog trips in interval [%d .. %d) - '
                     'trips are considered \'associated\' if they fall within '
                     '%s seconds of each other.' %
                     (chambertype, self.start, self.end, self.window)))))

        wdp = []
        for i, p in enumerate(self.plots):
            if 'WATCHDOG_TRIP' in p.href:
                wdp.append(i)
        for idx in wdp[::-1]:
            self.plots.pop(idx)

        # write trips to data file
        tripfile = os.path.join(self.path, 'trips.dat')
        with open(tripfile, 'w') as f:
            for id in groups:
                t, chamber, cause, _ = self.trips[id]
                if cause in hepimask:
                    stage = 'HEPI'
                elif self.chambers == HAMs:
                    stage = 'ISI'
                elif cause in isichannels[0].bits:
                    stage = 'ISI1'
                else:
                    stage = 'ISI2'
                cause = cause.replace(' ', '_')
                print(t, chamber, stage, cause, file=f)
        page.p()
        page.add('The list of trips can be downloaded ')
        page.a('here.',
               href=tripfile,
               alt=os.path.basename(tripfile),
               title='Trip data')
        page.p.close()

        page.div.close()

        # write to file
        idx = self.states.index(state)
        with open(self.frames[idx], 'w') as fobj:
            fobj.write(str(page))
        return self.frames[idx]
Пример #5
0
    def write_state_html(self, state):
        """Write the '#main' HTML content for this tab.

        For now, this function just links all the plots in a 2-column
        format.
        """
        page = markup.page()

        # link data
        if self.subplots:
            page.hr(class_='row-divider')
            page.h1('Sub-plots')
            layout = get_mode() == Mode.week and [7] or [4]
            plist = [p for p in self.subplots if p.state in [state, None]]
            page.add(str(self.scaffold_plots(plots=plist, state=state,
                                             layout=layout)))

        page.hr(class_='row-divider')
        page.div(class_='row')
        page.div(class_='col-md-12')
        channels = sorted(
            (c2 for c in self.get_channels(
                 'timeseries', 'statevector', 'spectrum', 'spectrogram', 'odc',
                 new=False) for c2 in split_channel_combination(c)),
            key=str,
        )
        if len(channels):
            page.h1('Channel information')
            headers = ['Channel', 'Type', 'Frametype', 'Sample rate', 'Units']
            data = []
            for channel in channels:
                # format CIS url and type
                if channel.frametype:
                    ftype = '<samp>%s</samp>' % channel.frametype
                else:
                    ftype = 'Unknown'
                for desc, regex in FRAMETYPE_REGEX.items():
                    if regex.match(str(channel.frametype)):
                        ftype += ' <small>[%s]</small>' % desc
                        break
                if re.search(r'\.[a-z]+\Z', channel.name):
                    name, ctype = channel.name.rsplit('.', 1)
                    c2 = get_channel(name)
                    ctype = ctype in ['rms'] and ctype.upper() or ctype.title()
                else:
                    c2 = channel
                    ctype = 'Raw'
                c = '<samp>%s</samp>' % str(channel)
                if c2.url:
                    link = markup.oneliner.a(c, href=c2.url,
                                             target='_blank')
                else:
                    link = c

                # format sameple rate
                if channel.sample_rate is None:
                    rate = 'Unknown'
                elif isclose(channel.sample_rate.value, 1/60.):
                    rate = '1/60 %s' % channel.sample_rate.unit
                elif channel.sample_rate.value.is_integer():
                    rate = '{0}{1:s}'.format(int(channel.sample_rate.value),
                                             channel.sample_rate._unitstr)
                else:
                    rate = str(channel.sample_rate)
                # format unit
                if hasattr(channel, 'bits'):
                    unit = '-'
                else:
                    unit = str(channel.unit) if channel.unit else 'Unknown'
                data.append([link, ctype, ftype, rate, unit])
            page.add(str(gwhtml.table(
                headers, data, id='channel-information',
                caption="Channels used to generate data on this page")))

        allflags = sorted(set([
            (f, p) for plot in filter(
                lambda p: p.data == 'segments' and p.type != 'guardian',
                self.plots)
            for (f, p) in plot.padding.items()]), key=lambda x: x[0])
        if len(allflags):
            re_int_decimal = re.compile(r'\.00(?=(\s|\%))')
            page.h1('Segment information')
            # make summary table
            headers = ['Name', 'Defined duration [s]', 'Active duration [s]',
                       'Padding', 'Description']
            data = []
            pc = float(abs(self.span) / 100.)
            if pc.is_integer():
                pc = int(pc)
            for flag, padding in allflags:
                if padding == (0, 0):
                    padding = None
                flag = get_segments(flag, [self.span], query=False,
                                    padding={flag: padding})
                try:
                    valid = '%.2f (%.2f%%)' % (abs(flag.known),
                                               abs(flag.known) / pc)
                except ZeroDivisionError:
                    valid = '0 (0%)'
                    active = '0 (0%)'
                else:
                    active = '%.2f (%.2f%%)' % (abs(flag.active),
                                                abs(flag.active) / pc)
                valid = re_int_decimal.sub('', valid)
                active = re_int_decimal.sub('', active)
                data.append(['<samp>%s</samp>' % flag.name, valid, active,
                             padding and str(padding) or '-',
                             flag.description or ''])
            page.add(str(gwhtml.table(
                headers, data, id='segment-information',
                caption="The following flags were used in "
                        "the above data. This list does not include state "
                        "information or combinations of flags. Percentages "
                        "are calculated relative to the total duration of "
                        "%s seconds." % (pc * 100))))

            # print segment lists
            page.div(class_='panel-group', id="accordion")
            for i, (flag, padding) in enumerate(allflags):
                flag = get_segments(flag, [self.span], query=False,
                                    padding={flag: padding})
                page.div(class_='panel well panel-primary')
                page.div(class_='panel-heading')
                page.a(href='#flag%d' % i, **{'data-toggle': 'collapse',
                                              'data-parent': '#accordion'})
                page.h4('<samp>%s</samp>' % flag.name, class_='panel-title')
                page.a.close()
                page.div.close()
                page.div(id_='flag%d' % i, class_='panel-collapse collapse')
                page.div(class_='panel-body')
                # write segment summary
                page.p('This flag was defined and had a known state during '
                       'the following segments:')
                page.add(str(self.print_segments(flag.known)))
                # write segment table
                page.p('This flag was active during the following segments:')
                page.add(str(self.print_segments(flag.active)))

                page.div.close()
                page.div.close()
                page.div.close()
            page.div.close()

        # write state information
        page.add(str(self.write_state_information(state)))

        page.div.close()
        page.div.close()

        return super(DataTab, self).write_state_html(state, plots=True,
                                                     pre=self.foreword,
                                                     post=page)
Пример #6
0
    def write_state_html(self, state):
        """Write the '#main' HTML content for this tab.

        For now, this function just links all the plots in a 2-column
        format.
        """
        page = markup.page()

        # link data
        if self.subplots:
            page.hr(class_='row-divider')
            page.h1('Sub-plots')
            layout = get_mode() == Mode.week and [7] or [4]
            plist = [p for p in self.subplots if p.state in [state, None]]
            page.add(
                str(
                    self.scaffold_plots(plots=plist,
                                        state=state,
                                        layout=layout)))

        page.hr(class_='row-divider')
        page.div(class_='row')
        page.div(class_='col-md-12')
        channels = sorted(
            (c2 for c in self.get_channels('timeseries',
                                           'statevector',
                                           'spectrum',
                                           'spectrogram',
                                           'odc',
                                           new=False)
             for c2 in split_channel_combination(c)),
            key=str,
        )
        if len(channels):
            page.h1('Channel information')
            headers = ['Channel', 'Type', 'Frametype', 'Sample rate', 'Units']
            data = []
            for channel in channels:
                # format CIS url and type
                if channel.frametype:
                    ftype = '<samp>%s</samp>' % channel.frametype
                else:
                    ftype = 'Unknown'
                for desc, regex in FRAMETYPE_REGEX.items():
                    if regex.match(str(channel.frametype)):
                        ftype += ' <small>[%s]</small>' % desc
                        break
                if re.search(r'\.[a-z]+\Z', channel.name):
                    name, ctype = channel.name.rsplit('.', 1)
                    c2 = get_channel(name)
                    ctype = ctype in ['rms'] and ctype.upper() or ctype.title()
                else:
                    c2 = channel
                    ctype = 'Raw'
                c = '<samp>%s</samp>' % str(channel)
                if c2.url:
                    link = markup.oneliner.a(c, href=c2.url, target='_blank')
                else:
                    link = c

                # format sameple rate
                if channel.sample_rate is None:
                    rate = 'Unknown'
                elif isclose(channel.sample_rate.value, 1 / 60.):
                    rate = '1/60 %s' % channel.sample_rate.unit
                elif channel.sample_rate.value.is_integer():
                    rate = '{0}{1:s}'.format(int(channel.sample_rate.value),
                                             channel.sample_rate._unitstr)
                else:
                    rate = str(channel.sample_rate)
                # format unit
                if hasattr(channel, 'bits'):
                    unit = '-'
                else:
                    unit = str(channel.unit) if channel.unit else 'Unknown'
                data.append([link, ctype, ftype, rate, unit])
            page.add(
                str(
                    gwhtml.table(
                        headers,
                        data,
                        id='channel-information',
                        caption="Channels used to generate data on this page"))
            )

        allflags = sorted(set([(f, p) for plot in filter(
            lambda p: p.data == 'segments' and p.type != 'guardian',
            self.plots) for (f, p) in plot.padding.items()]),
                          key=lambda x: x[0])
        if len(allflags):
            re_int_decimal = re.compile(r'\.00(?=(\s|\%))')
            page.h1('Segment information')
            # make summary table
            headers = [
                'Name', 'Defined duration [s]', 'Active duration [s]',
                'Padding', 'Description'
            ]
            data = []
            pc = float(abs(self.span) / 100.)
            if pc.is_integer():
                pc = int(pc)
            for flag, padding in allflags:
                if padding == (0, 0):
                    padding = None
                flag = get_segments(flag, [self.span],
                                    query=False,
                                    padding={flag: padding})
                try:
                    valid = '%.2f (%.2f%%)' % (abs(
                        flag.known), abs(flag.known) / pc)
                except ZeroDivisionError:
                    valid = '0 (0%)'
                    active = '0 (0%)'
                else:
                    active = '%.2f (%.2f%%)' % (abs(
                        flag.active), abs(flag.active) / pc)
                valid = re_int_decimal.sub('', valid)
                active = re_int_decimal.sub('', active)
                data.append([
                    '<samp>%s</samp>' % flag.name, valid, active,
                    padding and str(padding) or '-', flag.description or ''
                ])
            page.add(
                str(
                    gwhtml.table(
                        headers,
                        data,
                        id='segment-information',
                        caption="The following flags were used in "
                        "the above data. This list does not include state "
                        "information or combinations of flags. Percentages "
                        "are calculated relative to the total duration of "
                        "%s seconds." % (pc * 100))))

            # print segment lists
            page.div(class_='panel-group', id="accordion")
            for i, (flag, padding) in enumerate(allflags):
                flag = get_segments(flag, [self.span],
                                    query=False,
                                    padding={flag: padding})
                page.div(class_='panel well panel-primary')
                page.div(class_='panel-heading')
                page.a(href='#flag%d' % i,
                       **{
                           'data-toggle': 'collapse',
                           'data-parent': '#accordion'
                       })
                page.h4('<samp>%s</samp>' % flag.name, class_='panel-title')
                page.a.close()
                page.div.close()
                page.div(id_='flag%d' % i, class_='panel-collapse collapse')
                page.div(class_='panel-body')
                # write segment summary
                page.p('This flag was defined and had a known state during '
                       'the following segments:')
                page.add(str(self.print_segments(flag.known)))
                # write segment table
                page.p('This flag was active during the following segments:')
                page.add(str(self.print_segments(flag.active)))

                page.div.close()
                page.div.close()
                page.div.close()
            page.div.close()

        # write state information
        page.add(str(self.write_state_information(state)))

        page.div.close()
        page.div.close()

        return super(DataTab, self).write_state_html(state,
                                                     plots=True,
                                                     pre=self.foreword,
                                                     post=page)
Пример #7
0
Файл: tabs.py Проект: tjma12/vet
    def write_state_html(self, state):
        """Write the content of inner HTML for the given state
        """
        def format_result(res):
            fmt = '%d' if (
                res.value < 0.01 or
                (res.unit == Unit('%') and res.value > 99.99)) else '%.2f'
            return ''.join([fmt % res.value, str(res.unit)])

        def add_config_entry(page, title, entry):
            page.tr()
            page.th(title)
            page.td(entry)
            page.tr.close()

        # write results table
        performance = [(
            str(m),
            format_result(r),
            m.description.split('\n')[0],
        ) for (m, r) in self.results[state].items()]
        pre = markup.page()
        pre.p(self.foreword)
        pre.h4('Flag performance summary', class_='mt-4')
        pre.add(
            str(
                gwhtml.table(['Metric', 'Result', 'Description'],
                             performance,
                             id=self.title)))
        pre.h2('Figures of Merit', class_='mt-4 mb-2')
        # write configuration table
        post = markup.page()
        post.h2('Analysis configuration', class_='mt-4')
        post.div()
        post.table(class_='table table-sm table-hover')
        add_config_entry(post, 'Flags', '<br>'.join(list(map(str,
                                                             self.flags))))
        if len(self.flags) > 1 and self.intersection:
            add_config_entry(post, 'Flag combination',
                             'Intersection (logical AND)')
        elif len(self.flags) > 1:
            add_config_entry(post, 'Flag combination', 'Union (logical OR)')
        add_config_entry(
            post, 'Analysis start time', '%s (%s)' %
            (str(Time(float(self.start), format='gps',
                      scale='utc').iso), self.start))
        add_config_entry(
            post, 'Analysis end time', '%s (%s)' %
            (str(Time(float(self.end), format='gps',
                      scale='utc').iso), self.end))
        add_config_entry(post, 'Event trigger channel', str(self.channel))
        add_config_entry(post, 'Event trigger generator', str(self.etg))
        post.table.close()
        post.div.close()
        post.h2('Segment information', class_='mt-4')
        post.div(class_='mt-2', id="accordion")
        for i, flag in enumerate([self.metaflag] + self.flags):
            flag = get_segments(flag,
                                state.active,
                                query=False,
                                padding=self.padding).copy()
            post.div(class_='card border-info mb-1 shadow-sm')
            post.div(class_='card-header text-white bg-info')
            if i == 0:
                title = self.intersection and 'Intersection' or 'Union'
            elif self.labels[i - 1] != str(flag):
                title = '%s (%s)' % (flag.name, self.labels[i - 1])
            else:
                title = flag.name
            post.a(title,
                   class_='card-link cis-link collapsed',
                   href='#flag%d' % i,
                   **{
                       'data-toggle': 'collapse',
                       'aria-expanded': 'false'
                   })
            post.div.close()  # card-header
            post.div(id_='flag%d' % i,
                     class_='collapse',
                     **{'data-parent': '#accordion'})
            post.div(class_='card-body')
            # write segment summary
            post.p('This flag was defined and had a known state during '
                   'the following segments:')
            post.add(self.print_segments(flag.known))
            # write segment table
            post.p('This flag was active during the following segments:')
            post.add(self.print_segments(flag.active))
            post.div.close()  # card-body
            post.div.close()  # collapse
            post.div.close()  # card
        post.div.close()

        # then write standard data tab
        return super(get_tab('default'), self).write_state_html(state,
                                                                plots=True,
                                                                pre=pre,
                                                                post=post)
Пример #8
0
    def write_state_html(self, state):
        """Write the HTML for the given state of this `GuardianTab`
        """
        page = self.scaffold_plots(state=state)

        page.div(class_='row')
        page.div(class_='col-md-12')
        page.h2('%s state transitions' % self.node, class_='mt-4 mb-4')
        page.add(
            html.alert(  # add dismissable alert
                'For all of the following data, "Unknown" simply labels any '
                'state in this node that was not chosen for display, and does '
                'not mean that the state was unrecognised by the Guardian '
                'system. Transitions from an "Unkown" state are not listed in '
                'the table below, but are included in the totals.',
                context=self.ifo.lower()))

        # draw table
        id_ = '{}-state-transitions'.format(self.ifo.lower())
        page.table(class_='table table-sm table-hover transitions mt-2',
                   id_=id_)
        page.caption('Transitions into each state (row) from each other '
                     'state (column). Only those states named in the '
                     'configuration are shown, but the \'Total\' includes '
                     'transitions from any and all states. A dash '
                     '(\'&mdash;\') indicates no transitions from '
                     'the given state.')
        page.thead()
        page.tr()
        for th in ['State'] + list(self.grdstates.values()) + ['Total']:
            page.th(th)
        page.tr.close()
        page.thead.close()
        page.tbody()
        for i, bit in enumerate(self.transstates):
            page.tr()
            name = self.grdstates[bit].strip('*')
            page.th(name)
            for j, bit2 in enumerate(self.grdstates):
                if i == j:
                    page.td('&mdash;', class_='ignore')
                    continue
                count = len([t for t in self.transitions[bit] if t[1] == bit2])
                if count:
                    page.td(str(count))
                else:
                    page.td('&mdash;')
            page.th(str(len(self.transitions[bit])))
            page.tr.close()
        page.tbody.close()
        page.table.close()
        page.button('Export to CSV',
                    class_='btn btn-outline-secondary btn-table mt-2',
                    **{
                        'data-table-id': id_,
                        'data-filename': '%s.csv' % id_
                    })
        page.div.close()  # col-md-12
        page.div.close()  # row

        # summarise each state
        page.div(class_='row')
        page.div(class_='col-md-12')
        page.h2('State details', class_='mt-4 mb-2')
        page.div(id='accordion')
        for i, bit in enumerate(self.grdstates):
            name = self.grdstates[bit].strip('*')
            page.div(class_='card border-info mb-1 shadow-sm', id=str(bit))
            # heading
            page.div(class_='card-header text-white bg-info')
            page.a('%s [%d]' % (name, bit),
                   href='#collapse-%d' % bit,
                   class_='card-link cis-link collapsed',
                   **{
                       'data-toggle': 'collapse',
                       'aria-expandedt': 'false'
                   })
            page.div.close()  # card-header

            # body
            page.div(id='collapse-%d' % bit,
                     class_='collapse',
                     **{'data-parent': '#accordion'})
            page.div(class_='card-body')

            # print transitions
            headers = [
                'Transition GPS time', 'UTC time', 'Local time',
                'Transition from', 'Exited to'
            ]
            data = []
            if self.ifo in ['H1', 'C1', 'P1']:
                localzone = tz.gettz('America/Los_Angeles')
            elif self.ifo in ['L1']:
                localzone = tz.gettz('America/Chicago')
            elif self.ifo in ['K1']:
                localzone = tz.gettz('Asia/Tokyo')
            else:
                localzone = tz.gettz('Europe/Berlin')
            for t, from_, to_ in self.transitions[bit]:
                t2 = Time(t, format='gps', scale='utc')
                tlocal = Time(
                    t2.datetime.replace(tzinfo=UTC).astimezone(localzone),
                    format='datetime',
                    scale='utc')
                data.append(
                    (t, t2.iso, tlocal.iso,
                     '%s [%d]' % (self.grdstates.get(from_, 'Unknown'), from_),
                     '%s [%d]' % (self.grdstates.get(to_, 'Unknown'), to_)))
            page.add(
                str(
                    html.table(headers,
                               data,
                               id='%s-guardian-%s' %
                               (self.ifo.lower(), str(bit)),
                               caption="Transitions for %s %r state" %
                               (self.node, name))))

            # print segments
            flag = get_segments(self.segmenttag % name,
                                state.active,
                                query=False).copy()
            livetime = abs(flag.active)
            try:
                duty = abs(flag.active) / float(abs(flag.known)) * 100.
            except ZeroDivisionError:
                duty = 0
            page.p('This state was active for %.2f seconds (%.2f%%) during '
                   'the following segments:' % (livetime, duty))
            page.add(str(self.print_segments(flag)))
            page.div.close()  # card-body
            page.div.close()  # collapse
            page.div.close()  # card
        page.div.close()  # accordion
        page.div.close()  # col-md-12
        page.div.close()  # row

        return super(DataTab, self).write_state_html(state,
                                                     plots=False,
                                                     pre=page)
Пример #9
0
    def write_state_html(self, state):
        """Write the HTML for the given state of this `GuardianTab`
        """
        page = self.scaffold_plots(state=state)

        page.div(class_='row')
        page.div(class_='col-md-12')

        # get segment data
        groups = type(self.modes)(
            (idx, name) for idx, name in self.modes.items() if idx % 10 == 0)
        modes = type(self.modes)((idx, name)
                                 for idx, name in self.modes.items()
                                 if not name.startswith('*'))
        headers = ['Index', 'Name', 'Active seconds', 'Hours', '%']
        prefix = self.ifo.lower()
        for flags, title, id in zip(
            [groups, modes],
            ['Top-level mode information', 'Detailed mode information'],
            ['%s-top-level-mode' % prefix,
             '%s-detailed-mode' % prefix]):
            page.h1(title, class_='mt-4')
            data = []
            pc = float(abs(state.active) / 100.)
            tots = 0
            toth = 0
            totp = 0
            for idx, name in flags.items():
                flag = get_segments(self.segmenttag % idx,
                                    state.active,
                                    query=False).copy()
                actives = abs(flag.active)
                activeh = actives / 3600.
                try:
                    activep = actives / pc
                except ZeroDivisionError:
                    activep = 0
                tots += actives
                toth += activeh
                totp += activep
                data.append([
                    str(idx),
                    name.strip('*'),
                    '%.1f' % actives,
                    '%.1f' % activeh,
                    '%.1f' % activep
                ])
            data.append([
                '<strong>%s</strong>' % x for x in
                ['', 'Total:',
                 '%.1f' % tots,
                 '%.1f' % toth,
                 '%.1f' % totp]
            ])
            page.add(
                str(
                    html.table(
                        headers,
                        data,
                        id=id,
                        caption="%s observatory mode statistics as recorded in "
                        "<samp>%s</samp>" % (title.split()[0], self.channel))))
        return super(ParentTab, self).write_state_html(state,
                                                       plots=False,
                                                       pre=page)
Пример #10
0
    def write_state_html(self, state, pre=None):
        """Write the '#main' HTML content for this `EventTriggerTab`.
        """
        page = markup.page()
        if self.error.get(state, None):
            level, message = self.error[state]
            # no segments, print warning
            page.add(
                html.alert((
                    message,
                    "If you believe this to be an error, please contact %s." %
                    markup.oneliner.a('the DetChar group',
                                      class_='alert-link',
                                      href='mailto:[email protected]'),
                ),
                           context=level,
                           dismiss=False))
        else:
            # otherwise, carry on...
            if pre is not None:
                page.add(str(pre))
            elif self.foreword:
                page.add(str(self.foreword))
            page.add(str(self.scaffold_plots(state=state)))

            # link full results
            if self.url:
                page.hr(class_='row-divider')
                page.div(class_='btn-group')
                page.a('Click here for the full %s results' % self.name,
                       href=self.url,
                       rel='external',
                       target='_blank',
                       class_='btn btn-info btn-xl')
                page.div.close()
                page.hr(class_='row-divider')

            if self.loudest:
                # get triggers
                table = get_triggers(self.channel,
                                     self.plots[0].etg,
                                     state,
                                     query=False)
                if self.filterstr is not None:
                    table = table.filter(self.filterstr)
                tcol = get_time_column(table, self.etg)
                # set table headers
                headers = list(self.loudest['labels']) + ['LDVW Action']
                columns = list(self.loudest['columns'])
                if tcol in columns:
                    headers.insert(1, 'UTC time')
                    date = True
                else:
                    date = False
                # loop over rank columns
                for rank in self.loudest['rank']:
                    try:
                        rankstr = self.loudest['labels'][columns.index(rank)]
                    except ValueError:
                        rankstr = repr(rank)
                    page.h2('Loudest events by %s' % rankstr,
                            class_='mt-4 mb-4')
                    rank = table[rank].argsort()[::-1]
                    loudest = []
                    i = 0
                    dt = self.loudest['dt']
                    while len(loudest) < self.loudest['N'] and i < rank.size:
                        e = table[rank[i]]
                        t = e[tcol]
                        if i == 0 or all(
                                abs((t - e2[tcol])) >= dt for e2 in loudest):
                            loudest.append(e)
                        i += 1
                    data = []
                    for row in loudest:
                        data.append([])
                        for column in columns:
                            data[-1].append('%.3f' % float(row[column]))
                        if date:
                            data[-1].insert(
                                1,
                                from_gps(row[tcol]).strftime(
                                    '%B %d %Y %H:%M:%S.%f')[:-3])
                        data[-1].append(ldvw_qscan(self.channel, data[-1][0]))

                    # construct table
                    times = tuple(row[0] for row in data)
                    launch = ldvw_qscan(self.channel, times)
                    page.add(
                        str(
                            html.table(
                                headers,
                                data,
                                id='%s-loudest-table' % self.etg,
                                caption=(
                                    "%d loudest <samp>%s</samp> (%s) events "
                                    "by %s with minimum %ss separation. %s" %
                                    (self.loudest['N'], self.channel,
                                     self.etg, rankstr, self.loudest['dt'],
                                     str(launch))))))

            if self.subplots:
                page.h1('Sub-plots', class_='mt-4')
                layout = get_mode() == Mode.week and [7] or [4]
                plist = [p for p in self.subplots if p.state in [state, None]]
                page.add(
                    str(
                        self.scaffold_plots(plots=plist,
                                            state=state,
                                            layout=layout)))

                # link full results
                if self.url:
                    page.hr(class_='row-divider')
                    page.div(class_='btn-group')
                    page.a('Click here for the full %s results' % self.name,
                           href=self.url,
                           rel='external',
                           target='_blank',
                           class_='btn btn-info btn-xl')
                    page.div.close()
                    page.hr(class_='row-divider')

            # write state information
            page.add(str(self.write_state_information(state)))

        # write to file
        idx = self.states.index(state)
        with open(self.frames[idx], 'w') as fobj:
            fobj.write(str(page))
        return self.frames[idx]
Пример #11
0
Файл: etg.py Проект: gwpy/gwsumm
    def write_state_html(self, state, pre=None):
        """Write the '#main' HTML content for this `EventTriggerTab`.
        """
        page = markup.page()
        if self.error.get(state, None):
            level, message = self.error[state]
            # no segments, print warning
            page.div(class_='alert alert-%s' % level)
            page.p(message)
            page.p("If you believe this to be an error, please contact %s."
                   % markup.oneliner.a('the DetChar group',
                                       class_='alert-link',
                                       href='mailto:[email protected]'))
            page.div.close()
        else:
            # otherwise, carry on...
            if pre is not None:
                page.add(str(pre))
            elif self.foreword:
                page.add(str(self.foreword))
            page.add(str(self.scaffold_plots(state=state)))

            # link full results
            if self.url:
                page.hr(class_='row-divider')
                page.div(class_='btn-group')
                page.a('Click here for the full %s results' % self.name,
                       href=self.url, rel='external', target='_blank',
                       class_='btn btn-default btn-info btn-xl')
                page.div.close()
                page.hr(class_='row-divider')

            if self.loudest:
                # get triggers
                table = get_triggers(self.channel, self.plots[0].etg, state,
                                     query=False)
                if self.filterstr is not None:
                    table = table.filter(self.filterstr)
                tcol = get_time_column(table, self.etg)
                # set table headers
                headers = list(self.loudest['labels'])
                columns = list(self.loudest['columns'])
                if tcol in columns:
                    headers.insert(1, 'UTC time')
                    date = True
                else:
                    date = False
                # loop over rank columns
                for rank in self.loudest['rank']:
                    try:
                        rankstr = self.loudest['labels'][columns.index(rank)]
                    except ValueError:
                        rankstr = repr(rank)
                    page.h2('Loudest events by %s' % rankstr)
                    rank = table[rank].argsort()[::-1]
                    loudest = []
                    i = 0
                    dt = self.loudest['dt']
                    while len(loudest) < self.loudest['N'] and i < rank.size:
                        e = table[rank[i]]
                        t = e[tcol]
                        if i == 0 or all(
                                abs((t - e2[tcol])) >= dt
                                for e2 in loudest):
                            loudest.append(e)
                        i += 1
                    data = []
                    for row in loudest:
                        data.append([])
                        for column in columns:
                            data[-1].append(
                                '%.3f' % float(row[column]))
                        if date:
                            data[-1].insert(
                                1, from_gps(row[tcol]).strftime(
                                       '%B %d %Y %H:%M:%S.%f')[:-3])
                    page.add(str(html.table(
                        headers, data, id='%s-loudest-table' % self.etg,
                        caption=("%d loudest <samp>%s</samp> (%s) events "
                                 "by %s with minimum %ss separation"
                                 % (self.loudest['N'], self.channel, self.etg,
                                    rankstr, self.loudest['dt'])))))

            if self.subplots:
                page.hr(class_='row-divider')
                page.h1('Sub-plots')
                layout = get_mode() == Mode.week and [7] or [4]
                plist = [p for p in self.subplots if p.state in [state, None]]
                page.add(str(self.scaffold_plots(plots=plist, state=state,
                                                 layout=layout)))

                # link full results
                if self.url:
                    page.hr(class_='row-divider')
                    page.div(class_='btn-group')
                    page.a('Click here for the full %s results' % self.name,
                           href=self.url, rel='external', target='_blank',
                           class_='btn btn-default btn-info btn-xl')
                    page.div.close()
                    page.hr(class_='row-divider')

            # write state information
            page.add(str(self.write_state_information(state)))

        # write to file
        idx = self.states.index(state)
        with open(self.frames[idx], 'w') as fobj:
            fobj.write(str(page))
        return self.frames[idx]
Пример #12
0
Файл: sei.py Проект: gwpy/gwsumm
    def write_state_html(self, state):
        """Build HTML summary of watchdog trips
        """
        # find one example of each channel, and get the bits
        hepichannel = get_channel(HEPI_LATCH_CHANNEL
                                  % (self.ifo, self.chambers[1]))
        hepimask = hepichannel.bits + ['HEPI Unknown']
        if self.chambers == HAMs:
            isichannels = [get_channel(HAM_ISI_LATCH_CHANNEL
                                       % (self.ifo, self.chambers[0]))]
            isimask = isichannels[0].bits + ['ISI Unknown']
        else:
            isichannels = [get_channel(BSC_ST1_LATCH_CHANNEL
                                       % (self.ifo, self.chambers[0])),
                           get_channel(BSC_ST2_LATCH_CHANNEL
                                       % (self.ifo, self.chambers[0]))]
            isimask = (isichannels[0].bits + ['ISI ST1 Unknown'] +
                       isichannels[1].bits + ['ISI ST2 Unknown'])
        mask = hepimask + isimask

        # count trips
        count = {}
        for _, chamber, trigger, _ in self.trips:
            key = (chamber, trigger)
            try:
                count[key] += 1
            except KeyError:
                count[key] = 1

        page = markup.page()

        # build summary table
        page.div(class_='well')
        chambertype = self.chambers[0][:-1]
        id_ = '{}-{}'.format(self.ifo.lower(), chambertype.lower())
        page.table(
            class_='table table-condensed table-hover watchdog', id_=id_)
        page.caption("Number of watch-dog trips per %s chamber (column) and "
                     "trigger (row)" % (chambertype))
        page.thead()
        # add headers
        page.tr(class_='header')
        for th in ['WD'] + self.chambers + ['Sub-total']:
            page.th(th)
        page.tr.close()
        page.thead.close()

        # add rows
        page.tbody()
        totals = numpy.zeros((len(mask), len(self.chambers) + 1),
                             dtype=int)
        rows = []
        for i, bit in enumerate(mask):
            class_ = []
            if (i == len(hepimask) or
                    i == len(hepimask + isichannels[0].bits)):
                class_.append('tdiv')
            if re_no_count.match(bit):
                class_.append('ignore')
            if class_:
                page.tr(class_=' '.join(class_))
            else:
                page.tr()
            page.th(bit)
            for j, chamber in enumerate(self.chambers):
                try:
                    c = count[(chamber, bit)]
                except KeyError:
                    c = 0
                    pass
                page.td(c or '-')
                # exclude IOP from total
                if not re_no_count.match(bit):
                    totals[i][j] = c
            # add row total
            totals[i][-1] = totals[i].sum()
            page.th(str(totals[i][-1]))
            page.tr.close()
        page.tbody.close()

        # add totals
        page.thead()
        page.tr(class_='header')
        page.th('Totals')
        for i in range(totals.shape[1]):
            page.th(str(totals[:, i].sum()))
        page.tr.close()
        page.thead.close()
        page.table.close()
        page.button(
            'Export to CSV', class_='btn btn-default btn-table',
            onclick="exportTableToCSV('{name}.csv', '{name}')".format(
                name=id_))
        page.div.close()

        # build trip groups
        self.trips.sort(
            key=lambda x: (x[0], x[2] in mask and
                           (mask).index(x[2]) or 1000, x[3] is None))
        groups = OrderedDict()
        j = 0
        for i in range(len(self.trips)):
            if i == 0:
                j = i
                groups[j] = []
                continue
            t = self.trips[i][0]
            t2 = self.trips[i-1][0]
            if (t - t2) < self.window:
                groups[j].append(i)
            else:
                j = i
                groups[j] = []

        # build trip table
        page.h1('Trip list')
        page.div(class_='well')

        utc = tz.gettz('UTC')
        if self.ifo in ['H1', 'C1', 'P1']:
            localzone = tz.gettz('America/Los_Angeles')
        elif self.ifo in ['L1']:
            localzone = tz.gettz('America/Chicago')
        else:
            localzone = tz.gettz('Europe/Berlin')
        headers = ['GPS time', 'UTC time', 'Local time', 'Chamber', 'Trigger',
                   'Plot', 'Associated']
        rows = []
        for id in groups:
            t, chamber, trigger, plot = self.trips[id]
            t2 = Time(t, format='gps', scale='utc')
            tlocal = Time(
                t2.datetime.replace(tzinfo=utc).astimezone(localzone),
                format='datetime', scale='utc')
            rows.append([t, t2.iso, tlocal.iso, chamber, trigger])
            if plot:
                rows[-1].append(markup.oneliner.a(
                    '[Click here]', href=plot.href, class_='fancybox plot',
                    **{'data-fancybox-group': '1'}))
            else:
                rows[-1].append('-')
            assoc = []
            for id2 in groups[id]:
                t2, chamber2, trigger2, plot2 = self.trips[id2]
                dt = t2 - t
                tag = '%s %s (+%.2fs)' % (chamber2, trigger2, dt)
                if plot2:
                    assoc.append(markup.oneliner.a(
                        tag,
                        href=plot2.href,
                        class_='fancybox plot',
                        **{'data-fancybox-group': '1'}
                    ))
                else:
                    assoc.append(tag)
            if assoc:
                rows[-1].append('<br>'.join(assoc))
            else:
                rows[-1].append('-')
        page.add(str(gwhtml.table(
            headers, rows,
            caption=('List of %s watch-dog trips in interval [%d .. %d) - '
                     'trips are considered \'associated\' if they fall within '
                     '%s seconds of each other.'
                     % (chambertype, self.start, self.end, self.window)))))

        wdp = []
        for i, p in enumerate(self.plots):
            if 'WATCHDOG_TRIP' in p.href:
                wdp.append(i)
        for idx in wdp[::-1]:
            self.plots.pop(idx)

        # write trips to data file
        tripfile = os.path.join(self.path, 'trips.dat')
        with open(tripfile, 'w') as f:
            for id in groups:
                t, chamber, cause, _ = self.trips[id]
                if cause in hepimask:
                    stage = 'HEPI'
                elif self.chambers == HAMs:
                    stage = 'ISI'
                elif cause in isichannels[0].bits:
                    stage = 'ISI1'
                else:
                    stage = 'ISI2'
                cause = cause.replace(' ', '_')
                print(t, chamber, stage, cause, file=f)
        page.p()
        page.add('The list of trips can be downloaded ')
        page.a('here.', href=tripfile, alt=os.path.basename(tripfile),
               title='Trip data')
        page.p.close()

        page.div.close()

        # write to file
        idx = self.states.index(state)
        with open(self.frames[idx], 'w') as fobj:
            fobj.write(str(page))
        return self.frames[idx]
Пример #13
0
Файл: tabs.py Проект: gwpy/vet
    def write_state_html(self, state):
        # write results table
        performance = [(str(m), '%.2f %s' % (r.value, r.unit),
                        m.description.split('\n')[0]) for
                       (m, r) in self.results[state].iteritems()]
        pre = markup.page()
        pre.div(class_='scaffold well')
        pre.strong('Flag performance summary')
        pre.add(str(gwhtml.table(['Metric', 'Result', 'Description'],
                                 performance)))
        pre.div.close()
        pre.h2('Figures of Merit')
        # write configuration table
        post = markup.page()
        def add_config_entry(title, entry):
            post.tr()
            post.th(title)
            post.td(entry)
            post.tr.close()
        post.h2('Analysis configuration')
        post.div()
        post.table(class_='table table-condensed table-hover')
        add_config_entry('Flags', '<br>'.join(map(str, self.flags)))
        if len(self.flags) > 1 and self.intersection:
            add_config_entry('Flag combination', 'Intersection (logical AND)')
        elif len(self.flags) > 1:
            add_config_entry('Flag combination', 'Union (logical OR)')
        add_config_entry('Analysis start time', '%s (%s)' % (
            str(Time(float(self.start), format='gps', scale='utc').iso),
            self.start))
        add_config_entry('Analysis end time', '%s (%s)' % (
            str(Time(float(self.end), format='gps', scale='utc').iso),
            self.end))
        add_config_entry('Event trigger channel', str(self.channel))
        add_config_entry('Event trigger generator', str(self.etg))
        post.table.close()
        post.div.close()
        post.h2('Segment information')
        post.div(class_='panel-group', id="accordion")
        for i, flag in enumerate([self.metaflag] + self.flags):
            flag = get_segments(flag, state.active, query=False,
                                padding=self.padding).copy()
            post.div(class_='panel well panel-primary')
            post.div(class_='panel-heading')
            post.a(href='#flag%d' % i, **{'data-toggle': 'collapse',
                                          'data-parent': '#accordion'})
            if i == 0:
                post.h4(self.intersection and 'Intersection' or 'Union',
                        class_='panel-title')
            elif self.labels[i-1] != str(flag):
                post.h4('%s (%s)' % (flag.name, self.labels[i-1]),
                        class_='panel-title')
            else:
                post.h4(flag.name, class_='panel-title')
            post.a.close()
            post.div.close()
            post.div(id_='flag%d' % i, class_='panel-collapse collapse')
            post.div(class_='panel-body')
            # write segment summary
            post.p('This flag was defined and had a known state during '
                   'the following segments:')
            post.add(self.print_segments(flag.known))
            # write segment table
            post.p('This flag was active during the following segments:')
            post.add(self.print_segments(flag.active))

            post.div.close()
            post.div.close()
            post.div.close()
        post.div.close()

        # then write standard data tab
        return super(get_tab('default'), self).write_state_html(
            state, plots=True, pre=pre, post=post)