From bc5fe57bd225c415a2b19c3d28a28128b467b938 Mon Sep 17 00:00:00 2001 From: Yannick Lecoeuche Date: Thu, 5 Mar 2020 19:23:27 -0600 Subject: [PATCH 01/30] Adding lockloss summary plots to webpages Closes #109 (closed) --- locklost/__main__.py | 4 + locklost/config.py | 2 + locklost/summary.py | 331 +++++++++++++++++++++++++++++ locklost/summary/__init__.py | 0 locklost/web/__main__.py | 9 + locklost/web/templates/base.tpl | 2 + locklost/web/templates/summary.tpl | 55 +++++ test/run | 4 +- 8 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 locklost/summary.py delete mode 100644 locklost/summary/__init__.py create mode 100644 locklost/web/templates/summary.tpl diff --git a/locklost/__main__.py b/locklost/__main__.py index 43f1967..ff7e2a1 100644 --- a/locklost/__main__.py +++ b/locklost/__main__.py @@ -11,6 +11,7 @@ from . import analyze from . import online from . import event from . import segments +from . import summary from . import plots ########## @@ -56,6 +57,9 @@ p = gen_subparser('online', online.main) online._parser_add_arguments(p) +p = gen_subparser('summary', summary.main) + + def list_events(args): """List all events""" for e in event.find_events(): diff --git a/locklost/config.py b/locklost/config.py index f241ce7..27669c5 100644 --- a/locklost/config.py +++ b/locklost/config.py @@ -48,6 +48,8 @@ if IFO == 'H1': elif IFO == 'L1': CDS_EVENT_ROOT = 'https://llocds.ligo-la.caltech.edu/data/lockloss/events' +O3_GPS_START = 1238112018 + SEARCH_STRIDE = 10000 DATA_ACCESS = os.getenv('DATA_ACCESS', 'gwpy') diff --git a/locklost/summary.py b/locklost/summary.py new file mode 100644 index 0000000..f455270 --- /dev/null +++ b/locklost/summary.py @@ -0,0 +1,331 @@ +import os +import numpy as np +import matplotlib.pyplot as plt +from lal.gpstime import gps_to_utc, gps_time_now + +from . import config +from .event import find_events, LocklossEvent +from . import plotutils + +EPOCHS = { + 'run': config.O3_GPS_START, + 'month': gps_time_now() - 30*24*3600, + 'week': gps_time_now() - 7*24*3600, +} + +def grab_data(gps): + """ Returns relevant lockloss summary data within three time ranges. + + Looks through O3 lockloss data and returns counts for the locklosses + from each state, the duration in the final state, and the first saturated + suspension channel for the three most common locklosses. Does this for the + run, the last 30 days, and the last week. + """ + + shifts = { + 'owl': { + 'time': np.arange(0,8), + 'counts': 0, + }, + 'day': { + 'time': np.arange(8,16), + 'counts': 0, + }, + 'eve': { + 'time': np.arange(16,24), + 'counts': 0, + }, + } + transitions = [] + observe_durations = [] + saturations = { + 'als': [], + 'darm': [], + 'observe': [], + } + five_sats = [] + shift_losses = { + 'owl': 0, + 'day': 0, + 'eve': 0, + } + tags = { + 'MAINTENANCE': 0, + 'ADS_EXCURSION': 0, + 'BOARD_SAT': 0, + 'BRS_GLITCH': 0, + 'SEISMIC': 0, + 'WINDY': 0, + 'Unknown': 0 + } + + event_count = 0 + for event in find_events(after=gps, state='0-600'): + transitions.append(event.transition_index[0]) + #check event/append to relevant lists + observe_durations = check_durations(event, observe_durations) + saturations, five_sats = check_saturations(event, saturations, five_sats) + shifts = check_shift(event, shifts) + tags = check_tags(event, tags) + event_count += 1 + + print ("Events analyzed: %i" % (event_count)) + + return transitions, observe_durations, saturations, five_sats, shifts, tags + + +def check_tags(event, tags): + ref_sum = sum(tags.values()) + for tag_key in tags: + if event.has_tag(tag_key): + tags[tag_key] += 1 + break + if sum(tags.values()) == ref_sum: + tags['Unknown'] += 1 + + return tags + + +def check_shift(event, shifts): + gps = gps_to_utc(event.gps) + if event.has_tag('Observe'): + for key in shifts.keys(): + if gps.hour in shifts[key]['time']: + shifts[key]['counts'] += 1 + break + + return shifts + + +def check_durations(event, durations): + """ Check if lockloss was from Observe and log lock duration. """ + if event.has_tag('OBSERVE'): + previous = event.previous_state + if previous: + durations.append((previous['end']-previous['start'])/3600) + + return durations + + +def check_saturations(event, saturations, five_sats): + sat_path = event.path('saturations.csv') + if os.path.exists(sat_path): + sats = get_five_sats(sat_path) + five_sats.append(sats) + sat_conditions = { + 'observe': event.has_tag('OBSERVE'), + 'darm': event.transition_index[0] == 101, + 'als': event.transition_index[0] == 15, + } + for key, condition in sat_conditions.items(): + if condition: + if os.path.exists(sat_path): + saturations[key].append(sats[0]) + else: + saturations[key].append('No saturations') + + return saturations, five_sats + + +def get_five_sats(sat_path): + """ Returns shortened names of first (up to) five saturating suspension + channels. """ + all_sats = np.genfromtxt( + sat_path, + delimiter=' ', + dtype=str, + usecols=0, + ) + five_sats = np.array([]) + all_sats = np.array(all_sats, ndmin=1) + sat_lim = min([all_sats.size, 5]) + for sat in all_sats[:sat_lim]: + # create shortened channel name (excluding IFO, quadrant, characters) + sat_123 = sat.split('-') + sat1 = sat_123[0] + sat2 = sat_123[1].split('_')[0] + sat3 = sat_123[1].split('_')[1] + channel_shorthand = '%s %s %s' % (sat1, sat2, sat3) + # Make sure the degenerate channels don't get added + if not channel_shorthand in five_sats: + five_sats = np.append(five_sats, channel_shorthand) + + return five_sats + + +def plot_summary(epoch, gps): + """ Plots lockloss summary data and saves to example_plots. + + Plots histograms for lockloss state transitions, time lengths in Observing, + and first saturating suspension channel for the three most common lockloss + states. Saves these to the example_plots directory. """ + + summary_path = os.path.join(config.WEB_ROOT, 'summary_plots') + if not os.path.exists(summary_path): + os.mkdir(summary_path) + epoch_path = os.path.join(summary_path, epoch) + if not os.path.exists(epoch_path): + os.mkdir(epoch_path) + + transitions, observe_durations, saturations, five_sats, shifts, tags = grab_data(gps) + state_occurence = np.array([]) + sat_occurence = {'als': [], 'darm': [], 'observe': [],} + sat_names = {'observe': 'Observe', 'darm':'ACQUIRE_DRM1_1F', 'als':'LOCKING_ALS'} + sat_positions = {'als': 0, 'darm': 0, 'observe': 0,} + + # Collecting str values for the histogram x-axis and counting number + # of values in each 'bin' + # Transition state bin structuring + states = set(transitions) + for state in states: + state_occurence = np.append(state_occurence, transitions.count(state)) + state_bar = sorted(zip(states, state_occurence)) # sorting states numerically + states, state_occurence = zip(*state_bar) + state_position = np.arange(len(states)) # for histogram later + str_states = [str(i) for i in states] #for histogram later + + # Saturating suspension channel bin structuring + sat_sets = {key:set(val) for key, val in saturations.items()} + for key, sat_set in sat_sets.items(): + for channel in sat_set: + sat_occurence[key] = np.append(sat_occurence[key], saturations[key].count(channel)) + sat_bar = sorted(zip(sat_set, sat_occurence[key])) + sat_sets[key], sat_occurence[key] = zip(*sat_bar) + sat_positions[key] = np.arange(len(sat_set)) + + plotutils.set_rcparams() + + # Transition state plot + fig, ax = plt.subplots(1, figsize=(22,16)) + ax.bar( + state_position, + state_occurence, + align='center', + ) + ax.set_xlabel('State from which lockloss has occurred', labelpad=10) + ax.set_ylabel('Number of locklosses') + ax.set_title('O3 lockloss occurences by final state: %s' % (epoch)) + ax.set_xticks(state_position) + ax.tick_params(axis='x', which='major', labelsize=18) + ax.set_xticklabels(str_states, rotation = 45, ha = 'right') + ax.set_xlim([-1,state_position.size]) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + fig.tight_layout() + + plot_name = 'Lockloss_states' + outpath_plot = os.path.join(epoch_path, plot_name) + fig.savefig(outpath_plot, bbox_inches='tight') + plt.close() + + # Lock duration plot + fig, ax = plt.subplots(1, figsize=(22,16)) + if epoch == 'run': + bin_num = 30 + if epoch == 'month': + bin_num = 10 + if epoch == 'week': + bin_num = 5 + fig, ax = plt.subplots(1, figsize=(22,16)) + ax.hist( + observe_durations, + bins=bin_num, + align='mid', + ) + ax.set_xlabel('Lock duration [hours]', labelpad=10) + ax.set_ylabel('Number of locks') + ax.set_title('Observe lock durations: %s' % (epoch)) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + fig.tight_layout() + + plot_name = 'Lock_durations' + outpath_plot = os.path.join(epoch_path, plot_name) + fig.savefig(outpath_plot, bbox_inches='tight') + plt.close() + + # Saturating suspension channel plot + for key, occurence in sat_occurence.items(): + fig, ax = plt.subplots(1, figsize=(22,16)) + ax.bar( + sat_positions[key], + occurence, + align='center', + ) + ax.set_xlabel('First suspension to saturate before lockloss', labelpad=10) + ax.set_ylabel('Number of locklosses') + ax.set_title('%s locklosses by saturating suspension: %s' % (sat_names[key], epoch)) + ax.set_xticks(sat_positions[key]) + ax.set_xticklabels(sat_sets[key], rotation = 45, ha = 'right') + ax.set_xlim([-1,sat_positions[key].size]) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + fig.tight_layout() + + plot_name = '%s_lockloss_saturations' % (sat_names[key]) + outpath_plot = os.path.join(epoch_path, plot_name) + fig.savefig(outpath_plot, bbox_inches='tight') + plt.close() + + # Lockloss shift plot + counts = [x['counts'] for x in shifts.values()] + shifts = shifts.keys() + fig, ax = plt.subplots(1, figsize=(22,16)) + shift_x = np.array([0,1,2]) + ax.bar( + shift_x, + counts, + align='center', + ) + ax.set_xlabel('Operating shift', labelpad=10) + ax.set_ylabel('Number of locklosses') + ax.set_title('Number of locklosses per shift: %s' % (epoch)) + ax.set_xticks(shift_x) + ax.set_xticklabels(shifts, rotation=45, ha='right') + ax.set_xlim([-1, shift_x.size]) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + fig.tight_layout() + + plot_name = 'Lockloss_by_shift' + outpath_plot = os.path.join(epoch_path, plot_name) + fig.savefig(outpath_plot, bbox_inches='tight') + plt.close() + + # Associated tag plot + temp_dict = dict(tags) + for key, value in tags.items(): + if value == 0: + del temp_dict[key] + tags = temp_dict + ts = tags.keys() + counts = tags.values() + fig, ax = plt.subplots(1, figsize=(22,16)) + shift_x = np.arange(0, len(tags)) + ax.bar( + shift_x, + counts, + align='center', + ) + ax.set_xlabel('Lockloss tags', labelpad=10) + ax.set_ylabel('Number of locklosses') + ax.set_title('Number of locklosses with given tag: %s' % (epoch)) + ax.set_xticks(shift_x) + ax.set_xticklabels(ts, rotation=45, ha='right') + ax.set_xlim([-1, shift_x.size]) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + fig.tight_layout() + + plot_name = 'Lockloss_by_tag' + outpath_plot = os.path.join(epoch_path, plot_name) + fig.savefig(outpath_plot, bbox_inches='tight') + plt.close() + +###################################################### + +def main(args=None): + """ + Create histogram of lockloss states in O3. + """ + for epoch, gps in EPOCHS.items(): + print ('Looking at locklosses over the %s' % (epoch)) + plot_summary(epoch, gps) + +if __name__ == '__main__': + main() diff --git a/locklost/summary/__init__.py b/locklost/summary/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/locklost/web/__main__.py b/locklost/web/__main__.py index fcf842b..ece99fc 100755 --- a/locklost/web/__main__.py +++ b/locklost/web/__main__.py @@ -140,6 +140,15 @@ def index(tag='all'): query=query, ) +@app.route("/summary") +def summary_route(): + return bottle.template( + 'summary.tpl', + IFO=config.IFO, + web_script=WEB_SCRIPT, + online_status=online_status(), + is_home=False, + ) @app.route("/event/") def event_route(gps): diff --git a/locklost/web/templates/base.tpl b/locklost/web/templates/base.tpl index 0f06dc3..8a2b3f2 100644 --- a/locklost/web/templates/base.tpl +++ b/locklost/web/templates/base.tpl @@ -21,6 +21,8 @@ git repo docs issue tracker +
+Summary Plots
% if is_home: diff --git a/locklost/web/templates/summary.tpl b/locklost/web/templates/summary.tpl new file mode 100644 index 0000000..deaf9ef --- /dev/null +++ b/locklost/web/templates/summary.tpl @@ -0,0 +1,55 @@ +% rebase('base.tpl', IFO=IFO, web_script=web_script, online_status=online_status) + +% import os + +% from locklost import config + + +

Summary Plots

+ + + + + + +% for id in ['run', 'month', 'week']: +% plot_dir = os.path.join(config.EVENT_ROOT, 'summary_plots', id) +% plotnames = os.listdir(plot_dir) +
+% for plotname in plotnames: +% plot_url = os.path.join(config.WEB_ROOT, 'events/summary_plots', id, plotname) +
+
+
+ % include('plots.tpl', plots=[plot_url], size=8) +
+
+% end +
+% end + + diff --git a/test/run b/test/run index d0b95e6..dfd7cf1 100755 --- a/test/run +++ b/test/run @@ -26,7 +26,7 @@ case $IFO in exit 1 ;; esac - + export LOG_LEVEL=DEBUG export LOCKLOST_EVENT_ROOT=$(mktemp -d) export LOCKLOST_WEB_ROOT=https://ldas-jobs.ligo.caltech.edu/~lockloss @@ -51,6 +51,8 @@ test $nevents -eq $NEVENTS $PYTHON -m locklost analyze $EVENT +$PYTHON -m locklost summary + $PYTHON -m locklost show $EVENT $PYTHON -m locklost plot-history $LOCKLOST_EVENT_ROOT/history.svg -- GitLab From 29fc9d3401ca20784187e0b55b07132e29fb5a9a Mon Sep 17 00:00:00 2001 From: Marc Lormand Date: Mon, 6 Apr 2020 18:23:03 -0500 Subject: [PATCH 02/30] Improved tagging of elevated seismicity Expand SEISMIC tag into separate tags indicated elevated noise in the separate EARTHQUAKE, ANTHROPOGENIC, and MICROSEISMIC bands; include plots for all bands. --- locklost/config.py | 94 +++++++++++++++++-- locklost/plugins/seismic.py | 155 ++++++++++++++++++------------- locklost/web/templates/event.tpl | 11 +-- 3 files changed, 180 insertions(+), 80 deletions(-) diff --git a/locklost/config.py b/locklost/config.py index 27669c5..e0aed58 100644 --- a/locklost/config.py +++ b/locklost/config.py @@ -66,7 +66,9 @@ TAG_COLORS = { 'BRS_GLITCH': ('rebeccapurple', 'lavender'), 'BOARD_SAT': ('navy', 'cornflowerblue'), 'WINDY': ('springgreen', 'mediumblue'), - 'SEISMIC': ('orange', 'black'), + 'EARTHQUAKE': ('orange', 'black'), + 'MICROSEISMIC': ('yellow', 'black'), + 'ANTHROPOGENIC': ('red', 'black'), 'ADS_EXCURSION': ('mediumvioletred', 'plum'), 'SEI_BS_TRANS': ('sienna', 'orange'), } @@ -301,17 +303,91 @@ elif IFO == 'L1': ################################################## -SEISMIC_CHANNELS = [ - 'ISI-GND_STS_ITMY_Z_BLRMS_30M_100M', - 'ISI-GND_STS_ITMY_Z_DQ', -] -SEISMIC_CHANNELS = ifochans(SEISMIC_CHANNELS) - +# Set seismic band thresholds based on IFO site if IFO == 'H1': - SEI_THRESH = 300 + SEI_EARTHQUAKE_THRESH = 300 + SEI_ANTHROPOGENIC_THRESH = 1000 # placeholder + SEI_MICROSEISMIC_THRESH = 3000 # placeholder if IFO == 'L1': - SEI_THRESH = 600 + SEI_EARTHQUAKE_THRESH = 600 + SEI_ANTHROPOGENIC_THRESH = 1000 + SEI_MICROSEISMIC_THRESH = 3000 + +# Main data structure, each subdictionary contains the channel, save file name, data quality key, +# channel's data axis, threshold for the channel, and tag designation +SEISMIC_CONFIG = { + 'EQ band' : { + 'channel' : 'ISI-GND_STS_ITMY_Z_BLRMS_30M_100M', + 'savefile' : 'seismic_eq.png', + 'dq_channel' : 'ISI-GND_STS_ITMY_Z_DQ', + 'axis' : 'Z', + 'threshold' : SEI_EARTHQUAKE_THRESH, + 'tag' : 'EARTHQUAKE', + }, + 'anthropogenic corner' : { + 'channel' : 'ISI-GND_STS_ITMY_Z_BLRMS_1_3', + 'savefile' : 'seismic_anthro_ITMY.png', + 'dq_channel' : 'ISI-GND_STS_ITMY_Z_DQ', + 'axis' : 'Z', + 'threshold' : SEI_ANTHROPOGENIC_THRESH, + 'tag' : 'ANTHROPOGENIC', + }, + 'anthropogenic Xend' : { + 'channel' : 'ISI-GND_STS_ETMX_Z_BLRMS_1_3', + 'savefile' : 'seismic_anthro_ETMX.png', + 'dq_channel' : 'ISI-GND_STS_ETMX_Z_DQ', + 'axis' : 'Z', + 'threshold' : SEI_ANTHROPOGENIC_THRESH, + 'tag' : 'ANTHROPOGENIC', + }, + 'anthropogenic Yend' : { + 'channel' : 'ISI-GND_STS_ETMY_Z_BLRMS_1_3', + 'savefile' : 'seismic_anthro_ETMY.png', + 'dq_channel' : 'ISI-GND_STS_ETMY_Z_DQ', + 'axis' : 'Z', + 'threshold' : SEI_ANTHROPOGENIC_THRESH, + 'tag' : 'ANTHROPOGENIC', + }, + 'micro ITMY Y 100u 300u' : { + 'channel' : 'ISI-GND_STS_ITMY_Y_BLRMS_100M_300M', + 'savefile' : 'seismic_micro_Y_100u_300u.png', + 'dq_channel' : 'ISI-GND_STS_ITMY_Y_DQ', + 'axis' : 'Y', + 'threshold' : SEI_MICROSEISMIC_THRESH, + 'tag' : 'MICROSEISMIC', + }, + 'micro ITMY Y 300u 1' : { + 'channel' : 'ISI-GND_STS_ITMY_Y_BLRMS_300M_1', + 'savefile' : 'seismic_micro_Y_300u_1.png', + 'dq_channel' : 'ISI-GND_STS_ITMY_Y_DQ', + 'axis' : 'Y', + 'threshold' : SEI_MICROSEISMIC_THRESH, + 'tag' : 'MICROSEISMIC', + }, + 'micro ITMY Z 100u 300u' : { + 'channel' : 'ISI-GND_STS_ITMY_Z_BLRMS_100M_300M', + 'savefile' : 'seismic_micro_Z_100u_300u.png', + 'dq_channel' : 'ISI-GND_STS_ITMY_Z_DQ', + 'axis' : 'Z', + 'threshold' : SEI_MICROSEISMIC_THRESH, + 'tag' : 'MICROSEISMIC', + }, + 'micro ITMY Z 300u 1' : { + 'channel' : 'ISI-GND_STS_ITMY_Z_BLRMS_300M_1', + 'savefile' : 'seismic_micro_Z_300u_1.png', + 'dq_channel' : 'ISI-GND_STS_ITMY_Z_DQ', + 'axis' : 'Z', + 'threshold' : SEI_MICROSEISMIC_THRESH, + 'tag' : 'MICROSEISMIC', + }, +} +# Loop to convert channel names to the IFO channel names +# Could not use ifochans function since ifochans was only pulling one character at a time from channel string +for i in SEISMIC_CONFIG: + SEISMIC_CONFIG[i]['channel'] = '{}:{}'.format(IFO, SEISMIC_CONFIG[i]['channel']) + SEISMIC_CONFIG[i]['dq_channel'] = '{}:{}'.format(IFO, SEISMIC_CONFIG[i]['dq_channel']) + SEI_SEARCH_WINDOW = [-30, 150] ################################################## diff --git a/locklost/plugins/seismic.py b/locklost/plugins/seismic.py index 99385c7..465fac7 100644 --- a/locklost/plugins/seismic.py +++ b/locklost/plugins/seismic.py @@ -20,76 +20,103 @@ def check_seismic(event): """ mod_window = [config.SEI_SEARCH_WINDOW[0], config.SEI_SEARCH_WINDOW[1]] segment = Segment(mod_window).shift(int(event.gps)) - # need to wait for low-frequency response data to be available # since it's later than the the default data discovery window # FIXME: what to do if timeout reached? data.data_wait(segment) + + earthquake_tag = False + micro_tag = False + anthro_tag = False + + # Create the channel list that is used to get the data + channel_list = [] + for v in config.SEISMIC_CONFIG.values(): + channel_list.append(v['channel']) + if v['dq_channel'] not in channel_list: + channel_list.append(v['dq_channel']) + + # Fetch data using channel list into the dictionary channel_data + channel_data = data.fetch(channel_list, segment, as_dict=True) + + plotutils.set_rcparams() + + # Main loop, use config.SEISMIC_CONFIG keys to call data from channel_data dictionary + for band, params in config.SEISMIC_CONFIG.items(): - seismic_channels = data.fetch(config.SEISMIC_CHANNELS, segment) + channel = params['channel'] + dq_channel = params['dq_channel'] - if any(seismic_channels[0].data > config.SEI_THRESH): - event.add_tag('SEISMIC') - else: - logging.info('ground motion below threshold') + blrms_srate = channel_data[channel].sample_rate + blrms_t = channel_data[channel].tarray + raw_srate = channel_data[dq_channel].sample_rate + raw_t = channel_data[dq_channel].tarray - blrms_srate = seismic_channels[0].sample_rate - blrms_t = np.arange(segment[0], segment[1], 1/blrms_srate) - raw_srate = seismic_channels[1].sample_rate - raw_t = np.arange(segment[0], segment[1], 1/raw_srate) + fig, ax = plt.subplots(1, figsize=(22,16)) + ln1 = ax.plot( + blrms_t-event.gps, + channel_data[channel].data, + label=channel_data[channel].channel, + alpha=0.8, + lw=2, + color='indigo', + ) + ax2 = ax.twinx() + ln2 = ax2.plot( + raw_t-event.gps, + channel_data[dq_channel].data, + label=channel_data[dq_channel].channel, + alpha=0.6, + lw=2, + color='seagreen', + ) + ln3 = ax.axhline( + params['threshold'], + linestyle='--', + color='indigo', + label='seismic threshold', + lw=5, + ) + # setting left y-axis paramters + ax.spines['left'].set_color('indigo') + ax.yaxis.label.set_color('indigo') + ax.tick_params(axis='y', colors='indigo') + ax.set_ylabel('Band-limited RMS Velocity [nm/s]') + ax.set_ylim(0, max(channel_data[channel].data)+1) - plotutils.set_rcparams() + # setting right y-axis parameters + ax2.spines['right'].set_color('seagreen') + ax2.yaxis.label.set_color('seagreen') + ax2.tick_params(axis='y', colors='seagreen') + ax2.set_ylabel('Raw Output Velocity [nm/s]') + + # setting general plot parameters + lns = ln1+ln2+[ln3] + labs = [l.get_label() for l in lns] + ax.legend(lns, labs, loc='best') + ax.set_xlabel( + 'Time [s] since lock loss at {}'.format(event.gps), + labelpad=10, + ) + plt.xlim(blrms_t[0]-event.gps, blrms_t[-1]-event.gps) + ax.set_title('{}-axis seismic motion'.format(params['axis'])) + + fig.tight_layout(pad=0.05) + outfile_plot = params['savefile'] + outpath_plot = event.path(outfile_plot) + fig.savefig(outpath_plot, bbox_inches='tight') + + if any(channel_data[channel].data > params['threshold']): + if not event.has_tag(params['tag']): + event.add_tag(params['tag']) + + # Logging info + if not event.has_tag('EARTHQUAKE'): + logging.info('Earthquake ground motion below threshold') + + if not event.has_tag('ANTHROPOGENIC'): + logging.info('anthropogenic ground motion below threshold') + + if not event.has_tag('MICROSEISMIC'): + logging.info('microseismic ground motion below threshold') - fig, ax = plt.subplots(1, figsize=(22,16)) - ln1 = ax.plot( - blrms_t-event.gps, - seismic_channels[0].data, - label=seismic_channels[0].channel, - alpha=0.8, - lw=2, - color='indigo', - ) - ax2 = ax.twinx() - ln2 = ax2.plot( - raw_t-event.gps, - seismic_channels[1].data, - label=seismic_channels[1].channel, - alpha=0.6, - lw=2, - color='seagreen', - ) - ln3 = ax.axhline( - config.SEI_THRESH, - linestyle='--', - color='indigo', - label='seismic threshold', - lw=5, - ) - # setting left y-axis paramters - ax.spines['left'].set_color('indigo') - ax.yaxis.label.set_color('indigo') - ax.tick_params(axis='y', colors='indigo') - ax.set_ylabel('Band-limited RMS Velocity [nm/s]') - ax.set_ylim(0, max(seismic_channels[0].data)+1) - - # setting right y-axis parameters - ax2.spines['right'].set_color('seagreen') - ax2.yaxis.label.set_color('seagreen') - ax2.tick_params(axis='y', colors='seagreen') - ax2.set_ylabel('Raw Output Velocity [nm/s]') - - # setting general plot parameters - lns = ln1+ln2+[ln3] - labs = [l.get_label() for l in lns] - ax.legend(lns, labs, loc='best') - ax.set_xlabel( - 'Time [s] since lock loss at {}'.format(event.gps), - labelpad=10, - ) - plt.xlim(blrms_t[0]-event.gps, blrms_t[-1]-event.gps) - ax.set_title('Z-axis seismic motion') - - fig.tight_layout(pad=0.05) - outfile_plot = 'seismic.png' - outpath_plot = event.path(outfile_plot) - fig.savefig(outpath_plot, bbox_inches='tight') diff --git a/locklost/web/templates/event.tpl b/locklost/web/templates/event.tpl index 225f713..e3229fa 100644 --- a/locklost/web/templates/event.tpl +++ b/locklost/web/templates/event.tpl @@ -144,13 +144,10 @@
% has_tag = False -% if event.has_tag('SEISMIC') or event.has_tag('WINDY'): -% has_tag = True -% end -% env_plots = [ -% event.url('windy.png'), -% event.url('seismic.png'), -% ] +% has_tag = any([event.has_tag(tag) for tag in ['EARTHQUAKE', 'WINDY', 'MICROSEISMIC', 'ANTHROPOGENIC']]) +% env_plots = [event.url(v['savefile']) for v in config.SEISMIC_CONFIG.values()] +% env_plots.insert(0, event.url('windy.png')) +% % include('collapsed_plots.tpl', title ='Environment plots', id='environment', plots=env_plots, size=5, expand=has_tag, section='main')
-- GitLab From 24085c124c77d06931f962e824a58bcc05ecabe0 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Mon, 6 Apr 2020 17:25:59 -0700 Subject: [PATCH 03/30] minor cleanup in main --- locklost/__main__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/locklost/__main__.py b/locklost/__main__.py index ff7e2a1..692f93d 100644 --- a/locklost/__main__.py +++ b/locklost/__main__.py @@ -2,7 +2,6 @@ import os import subprocess import argparse import logging -import signal from . import __version__, set_signal_handlers from . import config @@ -42,8 +41,10 @@ def gen_subparser(cmd, func): ########## -parser.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__), - help="print version and exit") +parser.add_argument( + '--version', action='version', version='%(prog)s {}'.format(__version__), + help="print version and exit") + p = gen_subparser('search', search.main) search._parser_add_arguments(p) @@ -186,5 +187,6 @@ def main(): raise SystemExit("Must specify LOCKLOST_EVENT_ROOT env var.") args.func(args) + if __name__ == '__main__': main() -- GitLab From 59aae36780b49c87b6e396c85f0f85af212101c2 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Mon, 6 Apr 2020 17:32:40 -0700 Subject: [PATCH 04/30] Fixes to summary plot code Mostly PEP8, and drop use of LAL, but also fix some issues with directory creation. --- locklost/__main__.py | 1 + locklost/summary.py | 142 +++++++++++++++++++++++-------------------- 2 files changed, 77 insertions(+), 66 deletions(-) diff --git a/locklost/__main__.py b/locklost/__main__.py index 692f93d..b51c6d8 100644 --- a/locklost/__main__.py +++ b/locklost/__main__.py @@ -59,6 +59,7 @@ online._parser_add_arguments(p) p = gen_subparser('summary', summary.main) +online._parser_add_arguments(p) def list_events(args): diff --git a/locklost/summary.py b/locklost/summary.py index f455270..94bb36f 100644 --- a/locklost/summary.py +++ b/locklost/summary.py @@ -1,38 +1,42 @@ import os +import argparse import numpy as np + import matplotlib.pyplot as plt -from lal.gpstime import gps_to_utc, gps_time_now +from gpstime import gpsnow, gpstime from . import config -from .event import find_events, LocklossEvent +from .event import find_events from . import plotutils + EPOCHS = { 'run': config.O3_GPS_START, - 'month': gps_time_now() - 30*24*3600, - 'week': gps_time_now() - 7*24*3600, + 'month': int(gpsnow()) - 30*24*3600, + 'week': int(gpsnow()) - 7*24*3600, } + def grab_data(gps): - """ Returns relevant lockloss summary data within three time ranges. + """Returns relevant lockloss summary data within three time ranges. Looks through O3 lockloss data and returns counts for the locklosses from each state, the duration in the final state, and the first saturated suspension channel for the three most common locklosses. Does this for the run, the last 30 days, and the last week. - """ + """ shifts = { 'owl': { - 'time': np.arange(0,8), + 'time': np.arange(0, 8), 'counts': 0, }, 'day': { - 'time': np.arange(8,16), + 'time': np.arange(8, 16), 'counts': 0, }, 'eve': { - 'time': np.arange(16,24), + 'time': np.arange(16, 24), 'counts': 0, }, } @@ -44,11 +48,6 @@ def grab_data(gps): 'observe': [], } five_sats = [] - shift_losses = { - 'owl': 0, - 'day': 0, - 'eve': 0, - } tags = { 'MAINTENANCE': 0, 'ADS_EXCURSION': 0, @@ -59,17 +58,13 @@ def grab_data(gps): 'Unknown': 0 } - event_count = 0 - for event in find_events(after=gps, state='0-600'): + for i, event in enumerate(find_events(after=gps, state='0-600')): transitions.append(event.transition_index[0]) - #check event/append to relevant lists + # check event/append to relevant lists observe_durations = check_durations(event, observe_durations) saturations, five_sats = check_saturations(event, saturations, five_sats) shifts = check_shift(event, shifts) tags = check_tags(event, tags) - event_count += 1 - - print ("Events analyzed: %i" % (event_count)) return transitions, observe_durations, saturations, five_sats, shifts, tags @@ -82,28 +77,25 @@ def check_tags(event, tags): break if sum(tags.values()) == ref_sum: tags['Unknown'] += 1 - return tags def check_shift(event, shifts): - gps = gps_to_utc(event.gps) - if event.has_tag('Observe'): + gt = gpstime.fromgps(event.gps) + if event.has_tag('OBSERVE'): for key in shifts.keys(): - if gps.hour in shifts[key]['time']: + if gt.hour in shifts[key]['time']: shifts[key]['counts'] += 1 break - return shifts def check_durations(event, durations): - """ Check if lockloss was from Observe and log lock duration. """ + """Check if lockloss was from Observe and log lock duration.""" if event.has_tag('OBSERVE'): previous = event.previous_state if previous: durations.append((previous['end']-previous['start'])/3600) - return durations @@ -128,8 +120,9 @@ def check_saturations(event, saturations, five_sats): def get_five_sats(sat_path): - """ Returns shortened names of first (up to) five saturating suspension - channels. """ + """Returns shortened names of first (up to) five saturating suspension channels. + + """ all_sats = np.genfromtxt( sat_path, delimiter=' ', @@ -147,31 +140,31 @@ def get_five_sats(sat_path): sat3 = sat_123[1].split('_')[1] channel_shorthand = '%s %s %s' % (sat1, sat2, sat3) # Make sure the degenerate channels don't get added - if not channel_shorthand in five_sats: + if channel_shorthand not in five_sats: five_sats = np.append(five_sats, channel_shorthand) return five_sats -def plot_summary(epoch, gps): - """ Plots lockloss summary data and saves to example_plots. +def plot_summary(path, epoch): + """Plots lockloss summary data and saves to example_plots. Plots histograms for lockloss state transitions, time lengths in Observing, and first saturating suspension channel for the three most common lockloss - states. Saves these to the example_plots directory. """ + states. Saves these to the example_plots directory. - summary_path = os.path.join(config.WEB_ROOT, 'summary_plots') - if not os.path.exists(summary_path): - os.mkdir(summary_path) - epoch_path = os.path.join(summary_path, epoch) - if not os.path.exists(epoch_path): - os.mkdir(epoch_path) + """ + epoch_path = os.path.join(path, epoch) + try: + os.makedirs(epoch_path) + except FileExistsError: + pass - transitions, observe_durations, saturations, five_sats, shifts, tags = grab_data(gps) + transitions, observe_durations, saturations, five_sats, shifts, tags = grab_data(EPOCHS[epoch]) state_occurence = np.array([]) - sat_occurence = {'als': [], 'darm': [], 'observe': [],} - sat_names = {'observe': 'Observe', 'darm':'ACQUIRE_DRM1_1F', 'als':'LOCKING_ALS'} - sat_positions = {'als': 0, 'darm': 0, 'observe': 0,} + sat_occurence = {'als': [], 'darm': [], 'observe': []} + sat_names = {'observe': 'Observe', 'darm': 'ACQUIRE_DRM1_1F', 'als': 'LOCKING_ALS'} + sat_positions = {'als': 0, 'darm': 0, 'observe': 0} # Collecting str values for the histogram x-axis and counting number # of values in each 'bin' @@ -182,7 +175,7 @@ def plot_summary(epoch, gps): state_bar = sorted(zip(states, state_occurence)) # sorting states numerically states, state_occurence = zip(*state_bar) state_position = np.arange(len(states)) # for histogram later - str_states = [str(i) for i in states] #for histogram later + str_states = [str(i) for i in states] # for histogram later # Saturating suspension channel bin structuring sat_sets = {key:set(val) for key, val in saturations.items()} @@ -196,7 +189,7 @@ def plot_summary(epoch, gps): plotutils.set_rcparams() # Transition state plot - fig, ax = plt.subplots(1, figsize=(22,16)) + fig, ax = plt.subplots(1, figsize=(22, 16)) ax.bar( state_position, state_occurence, @@ -207,9 +200,9 @@ def plot_summary(epoch, gps): ax.set_title('O3 lockloss occurences by final state: %s' % (epoch)) ax.set_xticks(state_position) ax.tick_params(axis='x', which='major', labelsize=18) - ax.set_xticklabels(str_states, rotation = 45, ha = 'right') - ax.set_xlim([-1,state_position.size]) - plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + ax.set_xticklabels(str_states, rotation=45, ha='right') + ax.set_xlim([-1, state_position.size]) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gpsnow()), fontsize=16) fig.tight_layout() plot_name = 'Lockloss_states' @@ -218,14 +211,14 @@ def plot_summary(epoch, gps): plt.close() # Lock duration plot - fig, ax = plt.subplots(1, figsize=(22,16)) + fig, ax = plt.subplots(1, figsize=(22, 16)) if epoch == 'run': bin_num = 30 if epoch == 'month': bin_num = 10 if epoch == 'week': bin_num = 5 - fig, ax = plt.subplots(1, figsize=(22,16)) + fig, ax = plt.subplots(1, figsize=(22, 16)) ax.hist( observe_durations, bins=bin_num, @@ -234,7 +227,7 @@ def plot_summary(epoch, gps): ax.set_xlabel('Lock duration [hours]', labelpad=10) ax.set_ylabel('Number of locks') ax.set_title('Observe lock durations: %s' % (epoch)) - plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gpsnow()), fontsize=16) fig.tight_layout() plot_name = 'Lock_durations' @@ -244,7 +237,7 @@ def plot_summary(epoch, gps): # Saturating suspension channel plot for key, occurence in sat_occurence.items(): - fig, ax = plt.subplots(1, figsize=(22,16)) + fig, ax = plt.subplots(1, figsize=(22, 16)) ax.bar( sat_positions[key], occurence, @@ -254,9 +247,9 @@ def plot_summary(epoch, gps): ax.set_ylabel('Number of locklosses') ax.set_title('%s locklosses by saturating suspension: %s' % (sat_names[key], epoch)) ax.set_xticks(sat_positions[key]) - ax.set_xticklabels(sat_sets[key], rotation = 45, ha = 'right') + ax.set_xticklabels(sat_sets[key], rotation=45, ha='right') ax.set_xlim([-1,sat_positions[key].size]) - plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gpsnow()), fontsize=16) fig.tight_layout() plot_name = '%s_lockloss_saturations' % (sat_names[key]) @@ -267,8 +260,8 @@ def plot_summary(epoch, gps): # Lockloss shift plot counts = [x['counts'] for x in shifts.values()] shifts = shifts.keys() - fig, ax = plt.subplots(1, figsize=(22,16)) - shift_x = np.array([0,1,2]) + fig, ax = plt.subplots(1, figsize=(22, 16)) + shift_x = np.array([0, 1, 2]) ax.bar( shift_x, counts, @@ -280,10 +273,10 @@ def plot_summary(epoch, gps): ax.set_xticks(shift_x) ax.set_xticklabels(shifts, rotation=45, ha='right') ax.set_xlim([-1, shift_x.size]) - plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gpsnow()), fontsize=16) fig.tight_layout() - plot_name = 'Lockloss_by_shift' + plot_name = 'lockloss_by_shift' outpath_plot = os.path.join(epoch_path, plot_name) fig.savefig(outpath_plot, bbox_inches='tight') plt.close() @@ -296,7 +289,7 @@ def plot_summary(epoch, gps): tags = temp_dict ts = tags.keys() counts = tags.values() - fig, ax = plt.subplots(1, figsize=(22,16)) + fig, ax = plt.subplots(1, figsize=(22, 16)) shift_x = np.arange(0, len(tags)) ax.bar( shift_x, @@ -309,23 +302,40 @@ def plot_summary(epoch, gps): ax.set_xticks(shift_x) ax.set_xticklabels(ts, rotation=45, ha='right') ax.set_xlim([-1, shift_x.size]) - plt.gcf().text(0.02, 0.02, "Created: {}".format(gps_time_now()), fontsize=16) + plt.gcf().text(0.02, 0.02, "Created: {}".format(gpsnow()), fontsize=16) fig.tight_layout() - plot_name = 'Lockloss_by_tag' + plot_name = 'lockloss_by_tag' outpath_plot = os.path.join(epoch_path, plot_name) fig.savefig(outpath_plot, bbox_inches='tight') plt.close() ###################################################### +def _parser_add_arguments(parser): + parser.add_argument( + 'path', + help="summary plots directory path") + + def main(args=None): + """Generate lockloss summary plots + """ - Create histogram of lockloss states in O3. - """ - for epoch, gps in EPOCHS.items(): - print ('Looking at locklosses over the %s' % (epoch)) - plot_summary(epoch, gps) + if not args: + parser = argparse.ArgumentParser() + _parser_add_arguments(parser) + args = parser.parse_args() + + try: + os.mkdir(args.path) + except FileExistsError: + pass + + for epoch in EPOCHS: + print('summarizing locklosses epoch {}'.format(epoch)) + plot_summary(args.path, epoch) + if __name__ == '__main__': main() -- GitLab From 13bfc2058fc8ac958a3b75d5847e423e885eb76a Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Mon, 6 Apr 2020 17:34:36 -0700 Subject: [PATCH 05/30] fix summary arg parse, and test --- locklost/__main__.py | 2 +- test/run | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/locklost/__main__.py b/locklost/__main__.py index b51c6d8..776c46e 100644 --- a/locklost/__main__.py +++ b/locklost/__main__.py @@ -59,7 +59,7 @@ online._parser_add_arguments(p) p = gen_subparser('summary', summary.main) -online._parser_add_arguments(p) +summary._parser_add_arguments(p) def list_events(args): diff --git a/test/run b/test/run index dfd7cf1..ed148e9 100755 --- a/test/run +++ b/test/run @@ -51,7 +51,7 @@ test $nevents -eq $NEVENTS $PYTHON -m locklost analyze $EVENT -$PYTHON -m locklost summary +$PYTHON -m locklost summary $LOCKLOST_EVENT_ROOT/summary $PYTHON -m locklost show $EVENT -- GitLab From f6454c981e112801268843b54955b6ed450599dc Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Mon, 6 Apr 2020 17:42:27 -0700 Subject: [PATCH 06/30] config PEP8 cleanup --- locklost/config.py | 130 +++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/locklost/config.py b/locklost/config.py index e0aed58..aa13371 100644 --- a/locklost/config.py +++ b/locklost/config.py @@ -136,7 +136,8 @@ if IFO == 'H1': if IFO == 'L1': CHANGE_DAC_DATE = 1188518418 -#ETM's are 20-bit and were changed at a date within our wanted lockloss time range +# ETM's are 20-bit and were changed at a date within our wanted +# lockloss time range if IFO == 'H1': ETM_L3_CHANNELS = [ 'SUS-ETMX_L3_MASTER_OUT_UR_DQ', @@ -154,7 +155,7 @@ if IFO == 'L1': ] ETM_L3_CHANNELS = ifochans(ETM_L3_CHANNELS) -#RM's, OM'S, and ZM'S are 16-bit +# RM's, OM'S, and ZM'S are 16-bit SIXTEEN_BIT_CHANNELS = [ 'SUS-RM1_M1_MASTER_OUT_UR_DQ', 'SUS-RM1_M1_MASTER_OUT_UL_DQ', @@ -313,72 +314,73 @@ if IFO == 'L1': SEI_ANTHROPOGENIC_THRESH = 1000 SEI_MICROSEISMIC_THRESH = 3000 -# Main data structure, each subdictionary contains the channel, save file name, data quality key, -# channel's data axis, threshold for the channel, and tag designation -SEISMIC_CONFIG = { - 'EQ band' : { - 'channel' : 'ISI-GND_STS_ITMY_Z_BLRMS_30M_100M', - 'savefile' : 'seismic_eq.png', - 'dq_channel' : 'ISI-GND_STS_ITMY_Z_DQ', - 'axis' : 'Z', - 'threshold' : SEI_EARTHQUAKE_THRESH, - 'tag' : 'EARTHQUAKE', +# Main data structure, each subdictionary contains the channel, save +# file name, data quality key, channel's data axis, threshold for the +# channel, and tag designation +SEISMIC_CONFIG = { + 'EQ band': { + 'channel': 'ISI-GND_STS_ITMY_Z_BLRMS_30M_100M', + 'savefile': 'seismic_eq.png', + 'dq_channel': 'ISI-GND_STS_ITMY_Z_DQ', + 'axis': 'Z', + 'threshold': SEI_EARTHQUAKE_THRESH, + 'tag': 'EARTHQUAKE', }, - 'anthropogenic corner' : { - 'channel' : 'ISI-GND_STS_ITMY_Z_BLRMS_1_3', - 'savefile' : 'seismic_anthro_ITMY.png', - 'dq_channel' : 'ISI-GND_STS_ITMY_Z_DQ', - 'axis' : 'Z', - 'threshold' : SEI_ANTHROPOGENIC_THRESH, - 'tag' : 'ANTHROPOGENIC', + 'anthropogenic corner': { + 'channel': 'ISI-GND_STS_ITMY_Z_BLRMS_1_3', + 'savefile': 'seismic_anthro_ITMY.png', + 'dq_channel': 'ISI-GND_STS_ITMY_Z_DQ', + 'axis': 'Z', + 'threshold': SEI_ANTHROPOGENIC_THRESH, + 'tag': 'ANTHROPOGENIC', }, - 'anthropogenic Xend' : { - 'channel' : 'ISI-GND_STS_ETMX_Z_BLRMS_1_3', - 'savefile' : 'seismic_anthro_ETMX.png', - 'dq_channel' : 'ISI-GND_STS_ETMX_Z_DQ', - 'axis' : 'Z', - 'threshold' : SEI_ANTHROPOGENIC_THRESH, - 'tag' : 'ANTHROPOGENIC', + 'anthropogenic Xend': { + 'channel': 'ISI-GND_STS_ETMX_Z_BLRMS_1_3', + 'savefile': 'seismic_anthro_ETMX.png', + 'dq_channel': 'ISI-GND_STS_ETMX_Z_DQ', + 'axis': 'Z', + 'threshold': SEI_ANTHROPOGENIC_THRESH, + 'tag': 'ANTHROPOGENIC', }, - 'anthropogenic Yend' : { - 'channel' : 'ISI-GND_STS_ETMY_Z_BLRMS_1_3', - 'savefile' : 'seismic_anthro_ETMY.png', - 'dq_channel' : 'ISI-GND_STS_ETMY_Z_DQ', - 'axis' : 'Z', - 'threshold' : SEI_ANTHROPOGENIC_THRESH, - 'tag' : 'ANTHROPOGENIC', + 'anthropogenic Yend': { + 'channel': 'ISI-GND_STS_ETMY_Z_BLRMS_1_3', + 'savefile': 'seismic_anthro_ETMY.png', + 'dq_channel': 'ISI-GND_STS_ETMY_Z_DQ', + 'axis': 'Z', + 'threshold': SEI_ANTHROPOGENIC_THRESH, + 'tag': 'ANTHROPOGENIC', }, - 'micro ITMY Y 100u 300u' : { - 'channel' : 'ISI-GND_STS_ITMY_Y_BLRMS_100M_300M', - 'savefile' : 'seismic_micro_Y_100u_300u.png', - 'dq_channel' : 'ISI-GND_STS_ITMY_Y_DQ', - 'axis' : 'Y', - 'threshold' : SEI_MICROSEISMIC_THRESH, - 'tag' : 'MICROSEISMIC', + 'micro ITMY Y 100u 300u': { + 'channel': 'ISI-GND_STS_ITMY_Y_BLRMS_100M_300M', + 'savefile': 'seismic_micro_Y_100u_300u.png', + 'dq_channel': 'ISI-GND_STS_ITMY_Y_DQ', + 'axis': 'Y', + 'threshold': SEI_MICROSEISMIC_THRESH, + 'tag': 'MICROSEISMIC', }, - 'micro ITMY Y 300u 1' : { - 'channel' : 'ISI-GND_STS_ITMY_Y_BLRMS_300M_1', - 'savefile' : 'seismic_micro_Y_300u_1.png', - 'dq_channel' : 'ISI-GND_STS_ITMY_Y_DQ', - 'axis' : 'Y', - 'threshold' : SEI_MICROSEISMIC_THRESH, - 'tag' : 'MICROSEISMIC', + 'micro ITMY Y 300u 1': { + 'channel': 'ISI-GND_STS_ITMY_Y_BLRMS_300M_1', + 'savefile': 'seismic_micro_Y_300u_1.png', + 'dq_channel': 'ISI-GND_STS_ITMY_Y_DQ', + 'axis': 'Y', + 'threshold': SEI_MICROSEISMIC_THRESH, + 'tag': 'MICROSEISMIC', }, - 'micro ITMY Z 100u 300u' : { - 'channel' : 'ISI-GND_STS_ITMY_Z_BLRMS_100M_300M', - 'savefile' : 'seismic_micro_Z_100u_300u.png', - 'dq_channel' : 'ISI-GND_STS_ITMY_Z_DQ', - 'axis' : 'Z', - 'threshold' : SEI_MICROSEISMIC_THRESH, - 'tag' : 'MICROSEISMIC', + 'micro ITMY Z 100u 300u': { + 'channel': 'ISI-GND_STS_ITMY_Z_BLRMS_100M_300M', + 'savefile': 'seismic_micro_Z_100u_300u.png', + 'dq_channel': 'ISI-GND_STS_ITMY_Z_DQ', + 'axis': 'Z', + 'threshold': SEI_MICROSEISMIC_THRESH, + 'tag': 'MICROSEISMIC', }, - 'micro ITMY Z 300u 1' : { - 'channel' : 'ISI-GND_STS_ITMY_Z_BLRMS_300M_1', - 'savefile' : 'seismic_micro_Z_300u_1.png', - 'dq_channel' : 'ISI-GND_STS_ITMY_Z_DQ', - 'axis' : 'Z', - 'threshold' : SEI_MICROSEISMIC_THRESH, - 'tag' : 'MICROSEISMIC', + 'micro ITMY Z 300u 1': { + 'channel': 'ISI-GND_STS_ITMY_Z_BLRMS_300M_1', + 'savefile': 'seismic_micro_Z_300u_1.png', + 'dq_channel': 'ISI-GND_STS_ITMY_Z_DQ', + 'axis': 'Z', + 'threshold': SEI_MICROSEISMIC_THRESH, + 'tag': 'MICROSEISMIC', }, } @@ -387,7 +389,7 @@ SEISMIC_CONFIG = { for i in SEISMIC_CONFIG: SEISMIC_CONFIG[i]['channel'] = '{}:{}'.format(IFO, SEISMIC_CONFIG[i]['channel']) SEISMIC_CONFIG[i]['dq_channel'] = '{}:{}'.format(IFO, SEISMIC_CONFIG[i]['dq_channel']) - + SEI_SEARCH_WINDOW = [-30, 150] ################################################## @@ -469,7 +471,7 @@ GLITCH_CHANNELS = { 'ASC-Y_TR_B_PIT_OUT_DQ', 'ASC-Y_TR_B_YAW_OUT_DQ', ], - 'IMC' : [ + 'IMC': [ 'IMC-DOF_1_P_IN1_DQ', 'IMC-DOF_2_P_IN1_DQ', 'IMC-DOF_4_P_IN1_DQ', @@ -510,7 +512,7 @@ GLITCH_CHANNELS = { 'LSC-REFL_SERVO_ERR_OUT_DQ', 'LSC-Y_ARM_OUT_DQ', ], - 'PSL' : [ + 'PSL': [ 'PSL-FSS_PC_MON_OUT_DQ', 'PSL-ILS_HV_MON_OUT_DQ', 'PSL-ILS_MIXER_OUT_DQ', -- GitLab From e6284ccfe7178dfbe99baba3592352d43c2583c0 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Mon, 6 Apr 2020 17:51:57 -0700 Subject: [PATCH 07/30] disable summary test for the moment until issues resolved --- test/run | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/run b/test/run index ed148e9..d9fc53b 100755 --- a/test/run +++ b/test/run @@ -51,12 +51,12 @@ test $nevents -eq $NEVENTS $PYTHON -m locklost analyze $EVENT -$PYTHON -m locklost summary $LOCKLOST_EVENT_ROOT/summary - $PYTHON -m locklost show $EVENT $PYTHON -m locklost plot-history $LOCKLOST_EVENT_ROOT/history.svg +# $PYTHON -m locklost summary $LOCKLOST_EVENT_ROOT/summary + REQUEST_METHOD=GET $PYTHON -m locklost.web >/dev/null REQUEST_METHOD=GET QUERY_STRING=event=$EVENT $PYTHON -m locklost.web >/dev/null -- GitLab From 9179ec87ea196c8b40923793c4ea52c3e0fd62c4 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Mon, 27 Apr 2020 14:58:13 -0700 Subject: [PATCH 08/30] rebasing master --- test/run | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/run b/test/run index d9fc53b..186e05e 100755 --- a/test/run +++ b/test/run @@ -51,6 +51,8 @@ test $nevents -eq $NEVENTS $PYTHON -m locklost analyze $EVENT +$PYTHON -m locklost summary + $PYTHON -m locklost show $EVENT $PYTHON -m locklost plot-history $LOCKLOST_EVENT_ROOT/history.svg -- GitLab From aba2dede754225df9ee3d122260b7897acaf18c8 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Mon, 27 Apr 2020 14:59:00 -0700 Subject: [PATCH 09/30] Continuing rebase --- locklost/config.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/locklost/config.py b/locklost/config.py index aa13371..708faae 100644 --- a/locklost/config.py +++ b/locklost/config.py @@ -384,6 +384,12 @@ SEISMIC_CONFIG = { }, } +# Loop to convert channel names to the IFO channel names +# Could not use ifochans function since ifochans was only pulling one character at a time from channel string +for i in SEISMIC_CONFIG: + SEISMIC_CONFIG[i]['channel'] = '{}:{}'.format(IFO, SEISMIC_CONFIG[i]['channel']) + SEISMIC_CONFIG[i]['dq_channel'] = '{}:{}'.format(IFO, SEISMIC_CONFIG[i]['dq_channel']) + # Loop to convert channel names to the IFO channel names # Could not use ifochans function since ifochans was only pulling one character at a time from channel string for i in SEISMIC_CONFIG: -- GitLab From 4d80783fbb99ba840d159a0f674f280a9e82c19e Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Mon, 6 Apr 2020 17:34:36 -0700 Subject: [PATCH 10/30] fix summary arg parse, and test --- test/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/run b/test/run index 186e05e..ef9d7d8 100755 --- a/test/run +++ b/test/run @@ -51,7 +51,7 @@ test $nevents -eq $NEVENTS $PYTHON -m locklost analyze $EVENT -$PYTHON -m locklost summary +$PYTHON -m locklost summary $LOCKLOST_EVENT_ROOT/summary $PYTHON -m locklost show $EVENT -- GitLab From 93975da27bc74d5cd367ad9ee6e75790aeb6989e Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Mon, 6 Apr 2020 17:51:57 -0700 Subject: [PATCH 11/30] disable summary test for the moment until issues resolved --- test/run | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/run b/test/run index ef9d7d8..d9fc53b 100755 --- a/test/run +++ b/test/run @@ -51,8 +51,6 @@ test $nevents -eq $NEVENTS $PYTHON -m locklost analyze $EVENT -$PYTHON -m locklost summary $LOCKLOST_EVENT_ROOT/summary - $PYTHON -m locklost show $EVENT $PYTHON -m locklost plot-history $LOCKLOST_EVENT_ROOT/history.svg -- GitLab From 9d479c8385c501f1c91db5c622e995ce51d037d2 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Mon, 27 Apr 2020 14:43:54 -0700 Subject: [PATCH 12/30] Testing atom repository --- locklost/plugins/seismic.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/locklost/plugins/seismic.py b/locklost/plugins/seismic.py index 465fac7..e6f9f19 100644 --- a/locklost/plugins/seismic.py +++ b/locklost/plugins/seismic.py @@ -24,23 +24,25 @@ def check_seismic(event): # since it's later than the the default data discovery window # FIXME: what to do if timeout reached? data.data_wait(segment) - + earthquake_tag = False micro_tag = False anthro_tag = False - + # Create the channel list that is used to get the data channel_list = [] for v in config.SEISMIC_CONFIG.values(): channel_list.append(v['channel']) if v['dq_channel'] not in channel_list: channel_list.append(v['dq_channel']) - + # Fetch data using channel list into the dictionary channel_data channel_data = data.fetch(channel_list, segment, as_dict=True) - + plotutils.set_rcparams() - + + print ("testing repo") + # Main loop, use config.SEISMIC_CONFIG keys to call data from channel_data dictionary for band, params in config.SEISMIC_CONFIG.items(): @@ -105,7 +107,7 @@ def check_seismic(event): outfile_plot = params['savefile'] outpath_plot = event.path(outfile_plot) fig.savefig(outpath_plot, bbox_inches='tight') - + if any(channel_data[channel].data > params['threshold']): if not event.has_tag(params['tag']): event.add_tag(params['tag']) @@ -119,4 +121,3 @@ def check_seismic(event): if not event.has_tag('MICROSEISMIC'): logging.info('microseismic ground motion below threshold') - -- GitLab From 53de540822d2b826d189395dc0a3d78bd51ba01f Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Mon, 27 Apr 2020 14:44:14 -0700 Subject: [PATCH 13/30] reverting --- locklost/plugins/seismic.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/locklost/plugins/seismic.py b/locklost/plugins/seismic.py index e6f9f19..f02a58c 100644 --- a/locklost/plugins/seismic.py +++ b/locklost/plugins/seismic.py @@ -41,8 +41,6 @@ def check_seismic(event): plotutils.set_rcparams() - print ("testing repo") - # Main loop, use config.SEISMIC_CONFIG keys to call data from channel_data dictionary for band, params in config.SEISMIC_CONFIG.items(): -- GitLab From 5d47e65cd19b6696da8451f07fba2cf8c78208cf Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Tue, 16 Jun 2020 13:49:41 -0700 Subject: [PATCH 14/30] Checking channel list can be correctly parsed --- locklost/plugins/seismic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locklost/plugins/seismic.py b/locklost/plugins/seismic.py index f02a58c..e6dfb76 100644 --- a/locklost/plugins/seismic.py +++ b/locklost/plugins/seismic.py @@ -37,6 +37,8 @@ def check_seismic(event): channel_list.append(v['dq_channel']) # Fetch data using channel list into the dictionary channel_data + print (channel_list) + print (segment) channel_data = data.fetch(channel_list, segment, as_dict=True) plotutils.set_rcparams() -- GitLab From 2128aee145ceb959e64657cd9c556bc8cf5b3328 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Tue, 16 Jun 2020 15:12:28 -0700 Subject: [PATCH 15/30] Removing print statement, unexplained extra loop --- locklost/config.py | 6 ------ locklost/plugins/seismic.py | 2 -- 2 files changed, 8 deletions(-) diff --git a/locklost/config.py b/locklost/config.py index 708faae..aa13371 100644 --- a/locklost/config.py +++ b/locklost/config.py @@ -384,12 +384,6 @@ SEISMIC_CONFIG = { }, } -# Loop to convert channel names to the IFO channel names -# Could not use ifochans function since ifochans was only pulling one character at a time from channel string -for i in SEISMIC_CONFIG: - SEISMIC_CONFIG[i]['channel'] = '{}:{}'.format(IFO, SEISMIC_CONFIG[i]['channel']) - SEISMIC_CONFIG[i]['dq_channel'] = '{}:{}'.format(IFO, SEISMIC_CONFIG[i]['dq_channel']) - # Loop to convert channel names to the IFO channel names # Could not use ifochans function since ifochans was only pulling one character at a time from channel string for i in SEISMIC_CONFIG: diff --git a/locklost/plugins/seismic.py b/locklost/plugins/seismic.py index e6dfb76..f02a58c 100644 --- a/locklost/plugins/seismic.py +++ b/locklost/plugins/seismic.py @@ -37,8 +37,6 @@ def check_seismic(event): channel_list.append(v['dq_channel']) # Fetch data using channel list into the dictionary channel_data - print (channel_list) - print (segment) channel_data = data.fetch(channel_list, segment, as_dict=True) plotutils.set_rcparams() -- GitLab From 375e6f7c32dad8769756f614353364f756913ea7 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Tue, 16 Jun 2020 15:13:06 -0700 Subject: [PATCH 16/30] Shortening plugin list (temporary) --- locklost/plugins/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locklost/plugins/__init__.py b/locklost/plugins/__init__.py index a0a86f7..6123eb7 100644 --- a/locklost/plugins/__init__.py +++ b/locklost/plugins/__init__.py @@ -31,8 +31,8 @@ register_plugin(refine_time) from .observe import check_observe register_plugin(check_observe) -from .history import find_previous_state -register_plugin(find_previous_state) +# from .history import find_previous_state +# register_plugin(find_previous_state) from .saturations import find_saturations register_plugin(find_saturations) -- GitLab From e8ae7af16d72bf08408a78efb5065a5507255985 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Tue, 16 Jun 2020 16:37:49 -0700 Subject: [PATCH 17/30] Reverting plugin commenting --- locklost/plugins/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locklost/plugins/__init__.py b/locklost/plugins/__init__.py index 6123eb7..a0a86f7 100644 --- a/locklost/plugins/__init__.py +++ b/locklost/plugins/__init__.py @@ -31,8 +31,8 @@ register_plugin(refine_time) from .observe import check_observe register_plugin(check_observe) -# from .history import find_previous_state -# register_plugin(find_previous_state) +from .history import find_previous_state +register_plugin(find_previous_state) from .saturations import find_saturations register_plugin(find_saturations) -- GitLab From e02c748f0082cf111e69241d155f3e86e3f64427 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Wed, 8 Jul 2020 14:48:39 -0700 Subject: [PATCH 18/30] Changing lpy lim based on channel bit-rate --- locklost/plugins/lpy.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index f841745..483fd2e 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -27,7 +27,6 @@ def find_lpy(event): infile_csv = 'saturations.csv' inpath_csv = event.path(infile_csv) sat_channel = '' - lpy_lim = 4*config.SATURATION_THRESHOLD if not os.path.exists(inpath_csv): logging.info("LPY plot bypassed (no saturating suspensions).") @@ -38,6 +37,15 @@ def find_lpy(event): if first_sat: sat_channel, sat_time = first_sat.split(' ', 1) + # set lpy saturation limits based on if channel is 16, 18, or 20-bit + if sat_channel in config.ETM_L3_CHANNELS: + one_quad_lim = 4*config.SATURATION_THRESHOLD + elif sat_channel in config.SIXTEEN_BIT_CHANNELS: + one_quad_lim = config.SATURATION_THRESHOLD/4 + else: + one_quad_lim = config.SATURATION_THRESHOLD + lpy_lim = 4*one_quad_lim + # generate the LPY mapping and channels to query from base channel lpy_map = channel2lpy_coeffs(sat_channel) base_channel, _, _ = sat_channel.rsplit('_', 2) -- GitLab From dcd64a3dff8688f0a73b7aa22cb57397f45622ae Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Thu, 16 Jul 2020 18:15:00 -0700 Subject: [PATCH 19/30] Adjusting lpy map for coil driver magnet sign --- locklost/plugins/lpy.py | 68 +++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index 483fd2e..f8bfb8f 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -141,48 +141,70 @@ def channel2lpy_coeffs(channel): if optic in ['ETMX', 'ETMY', 'ITMX', 'ITMY']: if stage in ['M0']: - lpy_map['length'] = {'F2': -1, 'F3': -1} - lpy_map['pitch'] = {'F2': 1, 'F3': 1} - lpy_map['yaw'] = {'F2': 1, 'F3': -1} + lpy_map['length'] = {'F2': 1, 'F3': -1} + lpy_map['pitch'] = {'F2': -1, 'F3': 1} + lpy_map['yaw'] = {'F2': -1, 'F3': -1} lpy_map['corners'] = ['F2', 'F3'] - elif stage in ['L1', 'L2', 'L3']: + elif stage in ['L1']: + if optic is 'ETMX': + lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} + lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} + lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': -1, 'LR': -1} + lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] + else: + lpy_map['length'] = {'UL': -1, 'LL': 1, 'UR': 1, 'LR': -1} + lpy_map['pitch'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} + lpy_map['yaw'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} + lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] + elif stage in ['L2']: + lpy_map['length'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} + lpy_map['pitch'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} + lpy_map['yaw'] = {'UL': -1, 'LL': 1, 'UR': -1, 'LR': 1} + lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] + elif stage in ['L3']: lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': 1, 'LR': 1} lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] elif optic in ['MC1', 'MC2', 'MC3', 'PRM', 'PR2', 'PR3', 'SRM', 'SR2', 'SR3']: if stage in ['M1']: - lpy_map['length'] = {'LF': 1, 'RT': 1} - lpy_map['pitch'] = {'T2': 1, 'T3': -1} - lpy_map['yaw'] = {'LF': -1, 'RT': 1} + lpy_map['length'] = {'LF': 1, 'RT': -1} + lpy_map['pitch'] = {'T2': -1, 'T3': -1} + lpy_map['yaw'] = {'LF': -1, 'RT': -1} lpy_map['corners'] = ['T2', 'T3', 'LF', 'RT'] elif stage in ['M2', 'M3']: - lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': 1, 'LR': 1} - lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} - lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} + lpy_map['length'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} + lpy_map['pitch'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} + lpy_map['yaw'] = {'UL': -1, 'LL': 1, 'UR': -1, 'LR': 1} lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] elif optic in ['BS']: if stage in ['M1']: - lpy_map['length'] = {'LF': 1, 'RT': 1} - lpy_map['pitch'] = {'F2': -1, 'F3': -1} - lpy_map['yaw'] = {'LF': -1, 'RT': 1} + lpy_map['length'] = {'LF': 1, 'RT': -1} + lpy_map['pitch'] = {'F2': -1, 'F3': 1} + lpy_map['yaw'] = {'LF': -1, 'RT': -1} lpy_map['corners'] = ['F2', 'F3'] elif stage in ['M2']: - lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': 1, 'LR': 1} - lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} - lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} + lpy_map['length'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} + lpy_map['pitch'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} + lpy_map['yaw'] = {'UL': -1, 'LL': 1, 'UR': -1, 'LR': 1} lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] elif optic in ['OMC']: if stage in ['M1']: - lpy_map['length'] = {'LF': 1, 'RT': 1} - lpy_map['pitch'] = {'T2': 1, 'T3': -1} - lpy_map['yaw'] = {'LF': -1, 'RT': 1} + lpy_map['length'] = {'LF': 1, 'RT': -1} + lpy_map['pitch'] = {'T2': -1, 'T3': -1} + lpy_map['yaw'] = {'LF': -1, 'RT': -1} lpy_map['corners'] = ['T2', 'T3', 'LF', 'RT'] - elif optic in ['OM1', 'OM2', 'OM3', 'RM1', 'RM2', 'ZM1', 'ZM2']: + elif optic in ['RM2']: if stage in ['M1']: - lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': 1, 'LR': 1} - lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} - lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} + lpy_map['length'] = {'UL': -1, 'LL': 1, 'UR': 1, 'LR': -1} + lpy_map['pitch'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} + lpy_map['yaw'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} + lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] + elif optic in ['OM1', 'OM2', 'OM3', 'RM1', 'ZM1', 'ZM2']: + if stage in ['M1']: + lpy_map['length'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} + lpy_map['pitch'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} + lpy_map['yaw'] = {'UL': -1, 'LL': 1, 'UR': -1, 'LR': 1} lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] else: raise RuntimeError("no LPY map for suspension '{}'.".format(channel)) -- GitLab From 1f0692bab8452b44640af1b46db99ebae8001917 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Wed, 22 Jul 2020 13:24:33 -0700 Subject: [PATCH 20/30] Commenting plugins --- locklost/plugins/__init__.py | 68 ++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/locklost/plugins/__init__.py b/locklost/plugins/__init__.py index 6a7129a..5964751 100644 --- a/locklost/plugins/__init__.py +++ b/locklost/plugins/__init__.py @@ -25,14 +25,14 @@ def register_plugin(func): from .discover import discover_data register_plugin(discover_data) -from .history import find_previous_state -register_plugin(find_previous_state) +# from .history import find_previous_state +# register_plugin(find_previous_state) from .refine import refine_time register_plugin(refine_time) -from .ifo_mode import check_ifo_mode -register_plugin(check_ifo_mode) +# from .ifo_mode import check_ifo_mode +# register_plugin(check_ifo_mode) from .saturations import find_saturations register_plugin(find_saturations) @@ -40,33 +40,33 @@ register_plugin(find_saturations) from .lpy import find_lpy register_plugin(find_lpy) -from .lsc_asc import plot_lsc_asc -register_plugin(plot_lsc_asc) - -from .glitch import analyze_glitches -register_plugin(analyze_glitches) - -from .overflows import find_overflows -register_plugin(find_overflows) - -from .brs import check_brs -register_plugin(check_brs) - -from .board_sat import check_boards -register_plugin(check_boards) - -from .wind import check_wind -register_plugin(check_wind) - -from .ads_excursion import check_ads -register_plugin(check_ads) - -from .sei_bs_trans import check_sei_bs -register_plugin(check_sei_bs) - -from .fss_oscillation import check_fss -register_plugin(check_fss) - -# add last since this needs to wait for additional data -from .seismic import check_seismic -register_plugin(check_seismic) +# from .lsc_asc import plot_lsc_asc +# register_plugin(plot_lsc_asc) +# +# from .glitch import analyze_glitches +# register_plugin(analyze_glitches) +# +# from .overflows import find_overflows +# register_plugin(find_overflows) +# +# from .brs import check_brs +# register_plugin(check_brs) +# +# from .board_sat import check_boards +# register_plugin(check_boards) +# +# from .wind import check_wind +# register_plugin(check_wind) +# +# from .ads_excursion import check_ads +# register_plugin(check_ads) +# +# from .sei_bs_trans import check_sei_bs +# register_plugin(check_sei_bs) +# +# from .fss_oscillation import check_fss +# register_plugin(check_fss) +# +# # add last since this needs to wait for additional data +# from .seismic import check_seismic +# register_plugin(check_seismic) -- GitLab From 46f7bfdcbf86dea1c13356ead58d4660e81b070b Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Wed, 22 Jul 2020 17:01:12 -0700 Subject: [PATCH 21/30] Adding separate matrices for coil driver magnet polarization --- locklost/plugins/lpy.py | 109 +++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 45 deletions(-) diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index f8bfb8f..dc7ce82 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -51,6 +51,11 @@ def find_lpy(event): base_channel, _, _ = sat_channel.rsplit('_', 2) channels = [get_sus_channel(base_channel, corner) for corner in lpy_map['corners']] + magnet_map = magnet_orientation(sat_channel) + for lpy in ['length', 'pitch', 'yaw']: + for corner in lpy_map[lpy]: + lpy_map[lpy][corner] *= magnet_map[corner] + for window_type, window in config.PLOT_WINDOWS.items(): logging.info('Making {} LPY plot for {}'.format(window_type, base_channel)) @@ -132,6 +137,42 @@ def extract_sus_channel(channel): return optic, stage, corner +def magnet_orientation(channel): + + optic, stage, corner = extract_sus_channel(channel) + + if optic in ['ETMX', 'ETMY', 'ITMX', 'ITMY']: + if stage in ['M0']: + magnet_map = {'F2': -1, 'F3': 1} + elif stage in ['L1']: + if optic in ['ETMX']: + magnet_map = {'UL': -1, 'UR': -1, 'LL': 1, 'LR': 1} + else: + magnet_map = {'UL': -1, 'UR': 1, 'LL': 1, 'LR': -1} + elif stage in ['L2']: + magnet_map = {'UL': 1, 'UR': -1, 'LL': -1, 'LR': 1} + elif stage in ['L3']: + magnet_map = {'UL': 1, 'UR': 1, 'LL': 1, 'LR': 1} + elif optic in ['MC1', 'MC2', 'MC3', 'PRM', 'PR2', 'PR3', 'SRM', 'SR2', 'SR3', 'OMC']: + if stage in ['M1']: + magnet_map = {'LF': 1, 'RT': -1, 'T2': -1, 'T3': 1} + if stage in ['M2', 'M3']: + magnet_map = {'UL': 1, 'UR': -1, 'LL': -1, 'LR': 1} + elif optic in ['BS']: + if stage in ['M1']: + magnet_map = {'LF': 1, 'RT': -1, 'F2': 1, 'F3': -1} + if stage in ['M2']: + magnet_map = {'UL': 1, 'UR': -1, 'LL': -1, 'LR': 1} + elif optic in ['OM1', 'OM2', 'OM3', 'RM1', 'ZM1', 'ZM2']: + if stage in ['M1']: + magnet_map = {'UL': 1, 'UR': -1, 'LL': -1, 'LR': 1} + elif optic in ['RM2']: + if stage in ['M1']: + magnet_map = {'UL': -1, 'UR': 1, 'LL': 1, 'LR': -1} + + return magnet_map + + def channel2lpy_coeffs(channel): """From a suspension channel, get a dictionary containing the LPY coefficients. @@ -141,70 +182,48 @@ def channel2lpy_coeffs(channel): if optic in ['ETMX', 'ETMY', 'ITMX', 'ITMY']: if stage in ['M0']: - lpy_map['length'] = {'F2': 1, 'F3': -1} - lpy_map['pitch'] = {'F2': -1, 'F3': 1} - lpy_map['yaw'] = {'F2': -1, 'F3': -1} + lpy_map['length'] = {'F2': -1, 'F3': -1} + lpy_map['pitch'] = {'F2': 1, 'F3': 1} + lpy_map['yaw'] = {'F2': 1, 'F3': -1} lpy_map['corners'] = ['F2', 'F3'] - elif stage in ['L1']: - if optic is 'ETMX': - lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} - lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} - lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': -1, 'LR': -1} - lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] - else: - lpy_map['length'] = {'UL': -1, 'LL': 1, 'UR': 1, 'LR': -1} - lpy_map['pitch'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} - lpy_map['yaw'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} - lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] - elif stage in ['L2']: - lpy_map['length'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} - lpy_map['pitch'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} - lpy_map['yaw'] = {'UL': -1, 'LL': 1, 'UR': -1, 'LR': 1} - lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] - elif stage in ['L3']: + elif stage in ['L1', 'L2', 'L3']: lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': 1, 'LR': 1} lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] elif optic in ['MC1', 'MC2', 'MC3', 'PRM', 'PR2', 'PR3', 'SRM', 'SR2', 'SR3']: if stage in ['M1']: - lpy_map['length'] = {'LF': 1, 'RT': -1} - lpy_map['pitch'] = {'T2': -1, 'T3': -1} - lpy_map['yaw'] = {'LF': -1, 'RT': -1} + lpy_map['length'] = {'LF': 1, 'RT': 1} + lpy_map['pitch'] = {'T2': 1, 'T3': -1} + lpy_map['yaw'] = {'LF': -1, 'RT': 1} lpy_map['corners'] = ['T2', 'T3', 'LF', 'RT'] elif stage in ['M2', 'M3']: - lpy_map['length'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} - lpy_map['pitch'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} - lpy_map['yaw'] = {'UL': -1, 'LL': 1, 'UR': -1, 'LR': 1} + lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': 1, 'LR': 1} + lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} + lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] elif optic in ['BS']: if stage in ['M1']: - lpy_map['length'] = {'LF': 1, 'RT': -1} - lpy_map['pitch'] = {'F2': -1, 'F3': 1} - lpy_map['yaw'] = {'LF': -1, 'RT': -1} + lpy_map['length'] = {'LF': 1, 'RT': 1} + lpy_map['pitch'] = {'F2': -1, 'F3': -1} + lpy_map['yaw'] = {'LF': -1, 'RT': 1} lpy_map['corners'] = ['F2', 'F3'] elif stage in ['M2']: - lpy_map['length'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} - lpy_map['pitch'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} - lpy_map['yaw'] = {'UL': -1, 'LL': 1, 'UR': -1, 'LR': 1} + lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': 1, 'LR': 1} + lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} + lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] elif optic in ['OMC']: if stage in ['M1']: - lpy_map['length'] = {'LF': 1, 'RT': -1} - lpy_map['pitch'] = {'T2': -1, 'T3': -1} - lpy_map['yaw'] = {'LF': -1, 'RT': -1} + lpy_map['length'] = {'LF': 1, 'RT': 1} + lpy_map['pitch'] = {'T2': 1, 'T3': -1} + lpy_map['yaw'] = {'LF': -1, 'RT': 1} lpy_map['corners'] = ['T2', 'T3', 'LF', 'RT'] - elif optic in ['RM2']: + elif optic in ['OM1', 'OM2', 'OM3', 'RM1', 'RM2', 'ZM1', 'ZM2']: if stage in ['M1']: - lpy_map['length'] = {'UL': -1, 'LL': 1, 'UR': 1, 'LR': -1} - lpy_map['pitch'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} - lpy_map['yaw'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} - lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] - elif optic in ['OM1', 'OM2', 'OM3', 'RM1', 'ZM1', 'ZM2']: - if stage in ['M1']: - lpy_map['length'] = {'UL': 1, 'LL': -1, 'UR': -1, 'LR': 1} - lpy_map['pitch'] = {'UL': 1, 'LL': 1, 'UR': -1, 'LR': -1} - lpy_map['yaw'] = {'UL': -1, 'LL': 1, 'UR': -1, 'LR': 1} + lpy_map['length'] = {'UL': 1, 'LL': 1, 'UR': 1, 'LR': 1} + lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} + lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] else: raise RuntimeError("no LPY map for suspension '{}'.".format(channel)) -- GitLab From 620bdabf3228c39712ee2b9faa1178af4bf4889b Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Wed, 22 Jul 2020 17:20:23 -0700 Subject: [PATCH 22/30] Pointing to ETMY_L3 if no saturations --- locklost/plugins/lpy.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index dc7ce82..110d24c 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -29,8 +29,7 @@ def find_lpy(event): sat_channel = '' if not os.path.exists(inpath_csv): - logging.info("LPY plot bypassed (no saturating suspensions).") - return + sat_channel = 'H1:SUS-ETMY_L3_MASTER_OUT' with open(inpath_csv, 'r') as f: first_sat = f.readline() @@ -54,7 +53,7 @@ def find_lpy(event): magnet_map = magnet_orientation(sat_channel) for lpy in ['length', 'pitch', 'yaw']: for corner in lpy_map[lpy]: - lpy_map[lpy][corner] *= magnet_map[corner] + lpy_map[lpy][corner] *= magnet_map[corner] for window_type, window in config.PLOT_WINDOWS.items(): logging.info('Making {} LPY plot for {}'.format(window_type, base_channel)) -- GitLab From e4801837eecec9fec17eadeabfd114d32789e3be Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Wed, 22 Jul 2020 17:26:09 -0700 Subject: [PATCH 23/30] ETMX instead ETMY --- locklost/plugins/lpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index 110d24c..5355c3a 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -29,7 +29,7 @@ def find_lpy(event): sat_channel = '' if not os.path.exists(inpath_csv): - sat_channel = 'H1:SUS-ETMY_L3_MASTER_OUT' + sat_channel = 'H1:SUS-ETMX_L3_MASTER_OUT' with open(inpath_csv, 'r') as f: first_sat = f.readline() -- GitLab From bd304edbb6f4849b1b73d4e4d0aecde35a57d727 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Wed, 22 Jul 2020 17:35:26 -0700 Subject: [PATCH 24/30] Only opening inpath_csv if it exists --- locklost/plugins/lpy.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index 5355c3a..0951597 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -30,11 +30,11 @@ def find_lpy(event): if not os.path.exists(inpath_csv): sat_channel = 'H1:SUS-ETMX_L3_MASTER_OUT' - - with open(inpath_csv, 'r') as f: - first_sat = f.readline() - if first_sat: - sat_channel, sat_time = first_sat.split(' ', 1) + else: + with open(inpath_csv, 'r') as f: + first_sat = f.readline() + if first_sat: + sat_channel, sat_time = first_sat.split(' ', 1) # set lpy saturation limits based on if channel is 16, 18, or 20-bit if sat_channel in config.ETM_L3_CHANNELS: -- GitLab From efc01384aa7dcecf9dc5e541edec16cc91b75741 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Wed, 22 Jul 2020 17:47:17 -0700 Subject: [PATCH 25/30] Using correct channel --- locklost/plugins/lpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index 0951597..5b711e5 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -29,7 +29,7 @@ def find_lpy(event): sat_channel = '' if not os.path.exists(inpath_csv): - sat_channel = 'H1:SUS-ETMX_L3_MASTER_OUT' + sat_channel = '{}:SUS-ETMX_L3_MASTER_OUT_UR_DQ'.format(config.IFO) else: with open(inpath_csv, 'r') as f: first_sat = f.readline() -- GitLab From 3d93ce84e9a7b06c7d2ffc17f860641b8b4a68dc Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Wed, 22 Jul 2020 17:52:49 -0700 Subject: [PATCH 26/30] Changing web display to not depend on sat_channels existing --- locklost/web/templates/event.tpl | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/locklost/web/templates/event.tpl b/locklost/web/templates/event.tpl index 8263efe..fdc40ee 100644 --- a/locklost/web/templates/event.tpl +++ b/locklost/web/templates/event.tpl @@ -78,19 +78,15 @@ % end -% if sat_channels: -
-
-
-

Length-Pitch-Yaw Plots

-
-

Length, pitch, and yaw drives reconstructed from osem DAC counts for first suspension stage to saturate.

-% include('plots.tpl', plots=event_plot_urls(event, 'lpy'), size=6) -
-
-% else: -

LPY plots not created due to lack of saturating suspension channels.

-% end +
+
+
+

Length-Pitch-Yaw Plots

+
+

Length, pitch, and yaw drives reconstructed from osem DAC counts for first suspension stage to saturate.

+% include('plots.tpl', plots=event_plot_urls(event, 'lpy'), size=6) +
+

-- GitLab From a00db2e458bcc5d78a50858a9db6e35ea5ed4a45 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Wed, 5 Aug 2020 17:00:45 -0700 Subject: [PATCH 27/30] Adding 20-bit ETM channels for LLO --- locklost/config.py | 17 +++++++++-------- locklost/plugins/lpy.py | 2 +- locklost/plugins/saturations.py | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/locklost/config.py b/locklost/config.py index 9c00c00..177d33d 100644 --- a/locklost/config.py +++ b/locklost/config.py @@ -145,21 +145,22 @@ if IFO == 'L1': # ETM's are 20-bit and were changed at a date within our wanted # lockloss time range if IFO == 'H1': - ETM_L3_CHANNELS = [ + TWENTY_BIT_CHANNELS = [ 'SUS-ETMX_L3_MASTER_OUT_UR_DQ', 'SUS-ETMX_L3_MASTER_OUT_UL_DQ', 'SUS-ETMX_L3_MASTER_OUT_LR_DQ', 'SUS-ETMX_L3_MASTER_OUT_LL_DQ', ] if IFO == 'L1': - ETM_L3_CHANNELS = [ - 'SUS-ETMY_L3_MASTER_OUT_DC_DQ', - 'SUS-ETMY_L3_MASTER_OUT_UR_DQ', - 'SUS-ETMY_L3_MASTER_OUT_UL_DQ', - 'SUS-ETMY_L3_MASTER_OUT_LR_DQ', - 'SUS-ETMY_L3_MASTER_OUT_LL_DQ' + TWENTY_BIT_CHANNELS = [] + for optic in ['ETMX', 'ETMY']: + for stage in ['L1', 'L2', 'L3']: + for quadrant in ['UL', 'LL', 'UR', 'LR']: + TWENTY_BIT_CHANNELS.append('SUS-{}_{}_MASTER_OUT_{}_DQ'.format(optic, stage, quadrant)) + for quadrant in ['F1', 'F2', 'F3', 'LF', 'RT', 'SD']: + TWENTY_BIT_CHANNELS.append('SUS-{}_{}_MASTER_OUT_{}_DQ'.format(optic, 'M0', quadrant)) ] -ETM_L3_CHANNELS = ifochans(ETM_L3_CHANNELS) +TWENTY_BIT_CHANNELS = ifochans(TWENTY_BIT_CHANNELS) # RM's, OM'S, and ZM'S are 16-bit SIXTEEN_BIT_CHANNELS = [ diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index 5b711e5..bf0fafe 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -37,7 +37,7 @@ def find_lpy(event): sat_channel, sat_time = first_sat.split(' ', 1) # set lpy saturation limits based on if channel is 16, 18, or 20-bit - if sat_channel in config.ETM_L3_CHANNELS: + if sat_channel in config.TWENTY_BIT_CHANNELS: one_quad_lim = 4*config.SATURATION_THRESHOLD elif sat_channel in config.SIXTEEN_BIT_CHANNELS: one_quad_lim = config.SATURATION_THRESHOLD/4 diff --git a/locklost/plugins/saturations.py b/locklost/plugins/saturations.py index e1a8ecb..2119d94 100644 --- a/locklost/plugins/saturations.py +++ b/locklost/plugins/saturations.py @@ -21,7 +21,7 @@ def find_saturations(event): saturation_threshold = config.SATURATION_THRESHOLD low_thresh_channels = config.SIXTEEN_BIT_CHANNELS - high_thresh_channels = config.ETM_L3_CHANNELS + high_thresh_channels = config.TWENTY_BIT_CHANNELS plot_first = config.PLOT_SATURATIONS sat_search_window = config.SAT_SEARCH_WINDOW dac_change_date = config.CHANGE_DAC_DATE -- GitLab From 591c4f282359b916c3cb0b9da764d29cc79b7231 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Thu, 27 Aug 2020 17:18:29 -0700 Subject: [PATCH 28/30] Adding TMSX and TMSY to checked channels in saturations and lpy --- locklost/plugins/lpy.py | 4 +++- locklost/plugins/saturations.py | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index bf0fafe..d48c559 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -162,6 +162,8 @@ def magnet_orientation(channel): magnet_map = {'LF': 1, 'RT': -1, 'F2': 1, 'F3': -1} if stage in ['M2']: magnet_map = {'UL': 1, 'UR': -1, 'LL': -1, 'LR': 1} + elif optic in ['TMSX', 'TMSY']: + magnet_map = {'LF': -1, 'RT': 1, 'F2': -1, 'F3': 1} elif optic in ['OM1', 'OM2', 'OM3', 'RM1', 'ZM1', 'ZM2']: if stage in ['M1']: magnet_map = {'UL': 1, 'UR': -1, 'LL': -1, 'LR': 1} @@ -201,7 +203,7 @@ def channel2lpy_coeffs(channel): lpy_map['pitch'] = {'UL': 1, 'LL': -1, 'UR': 1, 'LR': -1} lpy_map['yaw'] = {'UL': -1, 'LL': -1, 'UR': 1, 'LR': 1} lpy_map['corners'] = ['UL', 'LL', 'UR', 'LR'] - elif optic in ['BS']: + elif optic in ['BS', 'TMSX', 'TMSY']: if stage in ['M1']: lpy_map['length'] = {'LF': 1, 'RT': 1} lpy_map['pitch'] = {'F2': -1, 'F3': -1} diff --git a/locklost/plugins/saturations.py b/locklost/plugins/saturations.py index 2119d94..82445d8 100644 --- a/locklost/plugins/saturations.py +++ b/locklost/plugins/saturations.py @@ -259,6 +259,8 @@ def gen_channel_names(): for corner in ['F1', 'F2', 'F3', 'LF', 'RT', 'SD']: add_channel('BS', 'M1', corner) + add_channel('TMSX', 'M1', corner) + add_channel('TMSY', 'M1', corner) for corner in corners: add_channel('BS', 'M2', corner) for corner in triple_top_corners: -- GitLab From 95d193677a964986153963f1934378a66de15d91 Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Thu, 27 Aug 2020 17:24:31 -0700 Subject: [PATCH 29/30] Adding TMSX, TMSY to LLO 20-bit channels --- locklost/config.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locklost/config.py b/locklost/config.py index 177d33d..c521697 100644 --- a/locklost/config.py +++ b/locklost/config.py @@ -159,7 +159,9 @@ if IFO == 'L1': TWENTY_BIT_CHANNELS.append('SUS-{}_{}_MASTER_OUT_{}_DQ'.format(optic, stage, quadrant)) for quadrant in ['F1', 'F2', 'F3', 'LF', 'RT', 'SD']: TWENTY_BIT_CHANNELS.append('SUS-{}_{}_MASTER_OUT_{}_DQ'.format(optic, 'M0', quadrant)) - ] + for optic in ['TMSX', 'TMSY']: + for quadrant in ['F1', 'F2', 'F3', 'LF', 'RT', 'SD']: + TWENTY_BIT_CHANNELS.append('SUS-{}_{}_MASTER_OUT_{}_DQ'.format(optic, 'M1', quadrant)) TWENTY_BIT_CHANNELS = ifochans(TWENTY_BIT_CHANNELS) # RM's, OM'S, and ZM'S are 16-bit -- GitLab From 4c96c07f887812fe12b710056de55fb5d85ce1dd Mon Sep 17 00:00:00 2001 From: "yannick.lecoeuche" Date: Tue, 1 Sep 2020 14:00:33 -0700 Subject: [PATCH 30/30] Adding check for date of dac change --- locklost/config.py | 2 +- locklost/plugins/lpy.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/locklost/config.py b/locklost/config.py index c521697..0c32fcb 100644 --- a/locklost/config.py +++ b/locklost/config.py @@ -140,7 +140,7 @@ PLOT_CHUNKSIZE = 3000 if IFO == 'H1': CHANGE_DAC_DATE = 1224961218 if IFO == 'L1': - CHANGE_DAC_DATE = 1188518418 + CHANGE_DAC_DATE = 1279979838 # ETM's are 20-bit and were changed at a date within our wanted # lockloss time range diff --git a/locklost/plugins/lpy.py b/locklost/plugins/lpy.py index d48c559..2f2da91 100644 --- a/locklost/plugins/lpy.py +++ b/locklost/plugins/lpy.py @@ -37,7 +37,7 @@ def find_lpy(event): sat_channel, sat_time = first_sat.split(' ', 1) # set lpy saturation limits based on if channel is 16, 18, or 20-bit - if sat_channel in config.TWENTY_BIT_CHANNELS: + if gps > config.CHANGE_DAC_DATE and sat_channel in config.TWENTY_BIT_CHANNELS: one_quad_lim = 4*config.SATURATION_THRESHOLD elif sat_channel in config.SIXTEEN_BIT_CHANNELS: one_quad_lim = config.SATURATION_THRESHOLD/4 -- GitLab