#! /usr/local/bin/perl5 # # Implements a daemon type perl script, sending USR2 to running mcstas # process, plus running mcplot. # # # This file is part of the McStas neutron ray-trace simulation package # Copyright (C) 1997-2004, All rights reserved # Risoe National Laborartory, Roskilde, Denmark # Institut Laue Langevin, Grenoble, France # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use Tk; use IPC::Open2; use File::Basename; my $win; my $PID; my @PIDs=(); my $Instrument = "h8_test.out"; my $Timeout = 300; my $Datafile = "mcstas.sim"; my $Format = "McStas"; my $working = 0; my $child = 0; my $McPlot = 0; # Check if we have any input parms: if (@ARGV==0) { # Set up main window: $win = new MainWindow; setup_window($win); MainLoop; } elsif(@ARGV==4) { $PID = $ARGV[0]; $Timeout = $ARGV[1]; $Datafile = $ARGV[2]; $Format = $ARGV[3]; # Split in pieces my $DataFile = basename($Datafile); my $DataDir = dirname($Datafile); print "Monitoring PID $PID in intervals of $Timeout seconds\n"; my $stop = 0; while ($stop == 0) { (kill 0, $PID) || (die "$PID has ended, terminating...\n"); # Sleep for a while... sleep $Timeout; (kill 'USR2', $PID) || (die "Could not send USR2 to $PID\n"); # Replotting in DataDir if ($McPlot == 0) { chdir $DataDir || (die "Could not chdir to $DataDir\n"); $McPlot=open2(READER,WRITER,"mcplot -p$Format --daemon=$PID --wait=$Timeout $DataFile") || (die "Could not spawn mcplot!\n"); } } } else { die "I need 0 or four input parameters:\n1) PID of simulation\n2) re-saving interval in seconds\n3) Output file to plot\n4) Used format\nFurther input parameters will be passed to mcplot (e.g. -gif)"; } sub setup_window { my ($w) = @_; my $f1 = $w->Frame(); my $pid_list; $f1->pack(-fill => 'x'); my $instr_lab = $f1->Label(-text => "Instrument to monitor:", -anchor => 'w', -justify => 'left'); $instr_lab->pack(-side => 'left'); my $instr_entry = $f1->Entry(-textvariable => \$Instrument, -justify => 'right'); $instr_entry->pack(-side => 'right'); my $f2 = $w->Frame(); my $inter_lab = $f2->Label(-text => "Datafile:", -anchor => 'w', -justify => 'left'); $inter_lab->pack(-side => 'left'); my $inter_entry = $f2->Entry(-textvariable => \$Datafile, -justify => 'right'); $inter_entry->pack(-side => 'right'); $f2->pack(-fill => 'x'); my $f3 = $w->Frame(); my $inter_lab = $f3->Label(-text => "Data format:", -anchor => 'w', -justify => 'left'); $inter_lab->pack(-side => 'left'); my $inter_entry = $f3->Entry(-textvariable => \$Format, -justify => 'right'); $inter_entry->pack(-side => 'right'); $f3->pack(-fill => 'x'); my $f4 = $w->Frame(); my $inter_lab = $f4->Label(-text => "Replot interval:", -anchor => 'w', -justify => 'left'); $inter_lab->pack(-side => 'left'); my $inter_entry = $f4->Entry(-textvariable => \$Timeout, -justify => 'right'); $inter_entry->pack(-side => 'right'); $f4->pack(-fill => 'x'); my $f5 = $w->Frame(); my $pid_fetch = $f5->Button(-text => "Fetch PID's", -command => sub { @PIDs = get_pid(); $PID->delete(0,'end'); foreach my $pid (@PIDs) { $PID->insert(0,$pid); } } ); $pid_fetch->pack(-side => 'left'); my $pid_label = $f5->Label(-text => "PID's:"); $pid_label->pack(-side => 'left'); $PID = $f5->Scrolled('Listbox',-height => '2', -scrollbars => 'osoe', -exportselection => 'false')->pack(-side => 'right'); $PID->pack(-side => 'right'); $f5->pack(-fill => 'x'); my $f6 = $w->Frame(); my $start = $f6->Button(-text => "Start", -command => sub { start_it(); } ); $start->pack(-side => 'left'); my $stop = $f6->Button(-text => "Stop", -command => sub { stop_it(); } ); $stop->pack(-side => 'left'); $f6->pack(-fill => 'x'); } sub get_pid{ my $USER=$ENV{'USER'}; my $PIDdata=`ps -u $USER | grep $Instrument | grep -v grep `; #$PIDdata =~ s/ //g; my @List = split('\n',$PIDdata); # Go through the list to get the first numeric element... my ($j, $k); my @sublist; my @final_list; for ($j=0; $j<@List; $j++) { @sublist = split(' ',$List[$j]); $final_list[$j] = $sublist[0]; print "first element is $sublist[0]\n"; } return @final_list; } sub start_it{ if ($working == 0) { # Check what PID to attack: my @pids = $PID->get(0,'end'); my $selected = $PID->curselection()+1; print "Current selection is $selected\n"; my $pid = @pids[$selected-1]+0; # Ensure that we have a PID: if ($pid>0 && (kill 0, $pid)) { print "mcdaemon $pid $Timeout $Datafile $Format &\n"; $child=open(READER,"mcdaemon $pid $Timeout $Datafile $Format|"); print "child process is $child\n"; $working = 1; } } } sub stop_it{ if ($working == 1) { print "Terminating $child\n"; (kill 9, $child); $working = 0; print "Terminating $McPlot\n"; (kill 'TERM', $McPlot); $McPlot=0; } } sub status { my $PID = $_; return (kill 0, $pid); }