#!/usr/bin/env tclshexe package require LDASJob #-- Set job parameters set manager llo set db llo_2 set seggrp L1:IFOLocked set channel L1:LSC-AS_Q set length 180 set window 690086706 ;#-- Initial beginning of window for data to consider #----------------------------------------------------------------------------- # Procedure to retrieve list of segments from the database # Output is an alternating list of start and stop times after "condensing" proc Seglist { seggrp manager db {start 0} } { #-- If user specified a start time, construct that part of the query if { $start > 0 } { set qual "and end_time > $start" } else { set qual "" } #-- Run the job LJrun SeglistJob -manager $manager { getMetaData -returnprotocol http://out.xml -returnformat LIGO_LW -database $db -sqlquery "select start_time,end_time from segment\ where segment_group='$seggrp' $qual\ order by start_time,end_time" } #-- Check whether the job failed if $LJerror { return -code error "Error while retrieving segment list:\ LDAS job failed\n$::SeglistJob(error)" } #-- Make sure there was an output file set nout [llength $::SeglistJob(outputs)] if { $nout == 0 } { return -code error "Error while retrieving segment list:\ no output from LDAS job $::SeglistJob(jobid)" } elseif { $nout > 1 } { return -code error "Error while retrieving segment list:\ more than one output from LDAS job $::SeglistJob(jobid)" } #-- Download the job output to a local file with a unique name set file SeglistJob[clock seconds].xml LJcopy $::SeglistJob(outputs) $file #-- Read the segment information into memory set seglist [exec lwtprint $file -d " "] #-- Delete the file, and the information about the LDAS job file delete $file LJdelete SeglistJob #-- Condense the list of segments set seglist [SeglistCondense $seglist] #-- Return list of segments return $seglist } #----------------------------------------------------------------------------- # Procedure to condense list of segments # Combines segments which are contiguous (or which overlap). Input is an # alternating list of start and stop times; must be sorted by (start,stop) proc SeglistCondense { seglist } { #-- If the list has nothing in it, just return if { [llength $seglist] < 2 } { return {} } set newlist {} set curstart [lindex $seglist 0] set curstop [lindex $seglist 1] foreach {sstart sstop} $seglist { if { $sstart <= $curstop } { #-- Update the current segment if { $sstop > $curstop } { set curstop $sstop } } else { #-- Flush current segment lappend newlist $curstart $curstop set curstart $sstart set curstop $sstop } } #-- Flush the final segment lappend newlist $curstart $curstop return $newlist } #----------------------------------------------------------------------------- # Procedure to construct name of ilwd element containing a channel's data proc mkchannel { chan stime } { regsub -all -- {:} $chan {\:} chalias return "${chalias}::AdcData:$stime:0:Frame" } #----------------------------------------------------------------------------- # Beginning of code for this job #-- Print out parameter values puts "Script started at [clock format [clock seconds]]" puts "Running jobs at $manager" puts "Looking for segments for $seggrp in $db database" puts "Processing $length-second sections of data for $channel" puts "Initial window begins at $window" set havesegs 0 #-- Set this up as an infinite loop, sleeping until data is available while { 1 } { #-- If the "havesegs" flag is cleared, retrieve list of segments if { ! $havesegs } { puts "\nRetrieving list of segments" #-- Get list of segments, catching any error that may occur if [catch {Seglist $seggrp $manager $db $window} seglist] { puts stderr $seglist exit 1 } set last_op "query" } #-- Identify first segment, after the specified beginning window time, #-- that is at least as long as the specified length set usestart -1 foreach {sstart sstop} $seglist { if { $sstop < $window } { continue } if { $sstart < $window } { set sstart $window } set slen [expr {$sstop-$sstart}] if { $slen >= $length } { set usestart $sstart set usestop [expr {$sstart+$length}] break } } #-- Make sure an acceptable segment was found if { $usestart < 0 } { set havesegs 0 #-- Only sleep if last operation was a query if { $last_op == "query" } { puts "\nSleeping until more data is available..." after 120000 } continue } set havesegs 1 set last_op "analysis" #-- Print out the data segment we will use puts "\nProcessing $length seconds of data from $usestart to $usestop" #-- Construct time-range string, accounting for the fact that LDAS expects #-- us to specify an end time which is 1 second before the actual end of #-- the data we want set times "$usestart-[expr {$usestop-1}]" set ch0alias [ mkchannel $channel $usestart ] LJrun job1 -manager $manager { dataPipeline -realtimeratio 0.5 -np 8 ### -dynlib /ldcg_server/dso-test/libldastfclusters.so.0.0.0 -dynlib /ldcg/lib/lalwrapper/libldastfclusters.so -filterparams ($channel,SNGL_BURST,2949120,425984,0.125,16384,65536,1e-22,0.001,1,0,8192,5,0,0,0,0,0,0,0,2,2,3) -subject TFCLUSTERS1401 -datacondtarget mpi -mddapi ligolw -resultname { TFCLUSTERS1401 result } -aliases { x = $ch0alias; } -algorithms { p = psd(x,2048,_,1024,1); intermediate(,mpi,spectrum,PSD of data); m = mean(x); y = sub(x, m); } -framequery { { [string index $channel 0] {} $times Adc($channel) } } } if $LJerror { puts "LDAS job failed! Error message from LDAS:" puts $job1(error) ### Should we exit now, or go on to the next job? ## puts "\nExiting" ## exit 1 } else { puts "LDAS job $job1(jobid) succeeded. Reply message from LDAS:" puts $job1(jobReply) } LJdelete job1 #-- Update the window and try to run another job set window $usestop } ;#-- End of "while" loop