root/branches/mcstas-1.x/mcformatgui.pl

Revision 2161, 11.8 KB (checked in by pkwi, 4 years ago)

(primarily) Win32 related fixes...

  • Property svn:executable set to *
Line 
1#!/usr/bin/perl
2#     This file is part of the McStas neutron ray-trace simulation package
3#     Copyright (C) 1997-2004, All rights reserved
4#     Risoe National Laborartory, Roskilde, Denmark
5#     Institut Laue Langevin, Grenoble, France
6#
7#     This program is free software; you can redistribute it and/or modify
8#     it under the terms of the GNU General Public License as published by
9#     the Free Software Foundation; version 2 of the License.
10#
11#     This program is distributed in the hope that it will be useful,
12#     but WITHOUT ANY WARRANTY; without even the implied warranty of
13#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14#     GNU General Public License for more details.
15#
16#     You should have received a copy of the GNU General Public License
17#     along with this program; if not, write to the Free Software
18#     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19#
20# mcformatgui.pl - perl-Tk gui for mcformat and mcconvert tools.
21#
22
23use Cwd;
24use IPC::Open2;
25use File::Basename;
26use File::Path;
27use File::Copy;
28use File::Spec;
29use Time::localtime;
30use Tk::Balloon;
31use Config;
32use FileHandle;
33
34
35# Determine the path to the McStas system directory. This must be done
36# in the BEGIN block so that it can be used in a "use lib" statement
37# afterwards.
38BEGIN {
39  # default configuration (for all high level perl scripts)
40  if($ENV{"MCSTAS"}) {
41    $MCSTAS::sys_dir = $ENV{"MCSTAS"};
42  } else {
43    if ($Config{'osname'} eq 'MSWin32') {
44      $MCSTAS::sys_dir = "c:\\mcstas\\lib";
45    } else {
46      $MCSTAS::sys_dir = "/usr/local/lib/mcstas";
47    }
48  }
49  $MCSTAS::perl_dir = "$MCSTAS::sys_dir/tools/perl";
50
51  # custom configuration (this script)
52  $MCSTAS::perl_modules = "$MCSTAS::perl_dir/modules";
53}
54
55use lib $MCSTAS::perl_dir;
56use lib $MCSTAS::perl_modules;
57require "mcstas_config.perl";
58
59# Overload with user's personal config
60if ($ENV{"HOME"} && -e $ENV{"HOME"}."/.mcstas/mcstas_config.perl") {
61  require $ENV{"HOME"}."/.mcstas/mcstas_config.perl";
62}
63
64my $dodisplay = 0;
65my $timeout = 5;
66my $show_help = 0;
67my $iformats = ['McStas','Scilab','Matlab'];
68my $oformats;
69my $runmodes;
70my $iformat="McStas";
71my $oformat="McStas";
72my $runmode="Merge";
73my $inputdir;
74my $outputdir;
75my $oformats_iMcStas;
76my $oformats_iMatlab = ['Scilab'];
77my $oformats_iScilab = ['Matlab'];
78my $runmodes_iMcStas = ['Convert','Merge','Scan assembly','Scan Merge'];
79my $runmodes_ilab = ['Convert'];
80my $recordlog=0;
81
82my $ext;
83my $filename = "";
84my $i;
85my $continue;
86
87my $iformat_crtl;
88my $oformat_line="";
89
90if ($MCSTAS::mcstas_config{'NEXUS'} ne "") {
91   $oformats_iMcStas = ['McStas','Scilab','Matlab','IDL','HTML','XML','Octave','NeXus'];
92} else {
93   $oformats_iMcStas = ['McStas','Scilab','Matlab','IDL','HTML','XML','Octave'];
94}
95
96my $cmd;
97my $logfile;
98my $date = time();
99$logfile = "mcformatgui_${date}.log";
100Tkgui();
101$iformat  = iformat_select($inputdir);
102my $fid;
103
104if ($recordlog) {
105  $logfile = "mcformatgui_${date}.log";
106  $fid = new FileHandle "> $logfile";
107  if (defined $fid) {
108    print $fid "# mcformatgui log file '$logfile'\n";
109    print $fid "# Directories: $inputdir \@ $iformat format -> $outputdir \@ $oformat format.\n";
110    print $fid "# Action: $runmode\n";
111
112    print "mcformatgui: Recording $inputdir -> $outputdir operations into log file '$logfile'\n";
113  }
114}
115
116if ($iformat =~ /Matlab|Scilab/i && $oformat =~ /Matlab|Scilab/i
117 && $iformat ne $oformat && $runmode eq "Convert") {
118    print "Using mcconvert.pl for $iformat -> $oformat conversion...\n";
119    $cmd="mcconvert$MCSTAS::mcstas_config{'SUFFIX'} --format=$oformat --indir=$inputdir --outdir=$outputdir";
120
121} elsif ($oformat_line !~ /binary/s) {
122    print "Input format is McStas, running mcformat to $runmode data. Output will go to $outputdir in $oformat...\n";
123    my $mode="";
124    if ($oformat =~ /IDL/i) { $oformat="IDL_binary"; }
125    if    ($runmode =~ /Scan assembly/i) { $mode="--scan-only"; }
126    elsif ($runmode =~ /Scan Merge/i)    { $mode="--scan"; }
127    elsif ($runmode =~ /merge/i)         { $mode="--merge"; }
128    if ($mode =~ /scan/i && $oformat !~ /McStas/i) {
129      my $ret = $w->messageBox(
130          -message => "For a Scan Operation ($mode)\n
131            The McStas/PGPLOT output format if prefered.\n
132            Other formats will not display correctly.\n
133            Press 'Yes' to export in McStas\n
134            or 'No' to keep $oformat.",
135          -title => "Scan operation: McStas prefered.",
136          -type => 'YesNo',
137          -icon => 'question',
138          -default => 'yes');
139        if (lc($ret) eq "yes") { $oformat="McStas"; }
140    }
141    $cmd="mcformat";
142    if ($Config{'osname'} eq 'MSWin32') { $cmd .= ".$MCSTAS::mcstas_config{'EXE'}"; }
143    $cmd.=" --format=$oformat --dir=$outputdir $inputdir $mode";
144} else {
145  print "mcformatgui: I do not have any appropriate method for conversion.\n";
146  print "ERROR        Try mcformat or mcconvert commands manually.\n";
147  exit();
148}
149if ($recordlog && defined $fid) {
150  print $fid "# Command: $cmd\n\n";
151  $cmd .= ">> $logfile 2>&1 ";
152  close($fid);
153}
154print "Executing: $cmd\n";
155system("$cmd");
156
157sub Tkgui {
158    use Tk;
159    use Tk::Toplevel;
160    use Tk::DirTree;
161    $continue = 0;
162    my $win = new MainWindow(-title => "McFormatGui: Handle McStas datasets");
163    build_gui($win);
164    MainLoop;
165    if (!($continue == 1)) {
166        exit;
167    }
168}
169
170sub build_gui {
171    # When mcdaemon is run without any input parms, we'll build a gui
172    # to set the parameters.
173    my ($win) = @_;
174    my $topframe = $win->Frame(-relief => 'raised', -borderwidth => 2);
175    my $b = $win->Balloon(-state => 'balloon');
176    $topframe->pack(-side => "top", -fill => "both", -ipady => 3, -ipadx => 3);
177    my $tmp1 = $topframe->Label(-text => "Input dir(s):", -anchor => 'w',
178                                     -justify => "center", -width => 15, -fg => 'blue')->pack(-side => "left");
179          $b->attach($tmp1, -balloonmsg => "Data directory to convert");
180    $topframe->Entry(-width => 40, -relief => "sunken",
181                                    -textvariable => \$inputdir)->pack(-side => "left");
182    my $dirselect = $topframe->Button(-text => "Select", -command => sub {
183        $inputdir = select_dir($inputdir);
184        $iformat  = iformat_select($inputdir);
185     })->pack(-side => "left");
186    $b->attach($dirselect, -balloonmsg => "Select an existing directory");
187
188    my $top2frame = $win->Frame(-relief => 'raised', -borderwidth => 2);
189    $top2frame->pack(-side => "top", -fill => "both", -ipady => 3, -ipadx => 3);
190    $tmp2 = $top2frame->Label(-text => "Output dir  :", -anchor => 'w',
191                                     -justify => "center", -width => 15, -fg => 'blue')->pack(-side => "left");
192                $b->attach($tmp2, -balloonmsg => "Target directory\nfor converted data");
193    $top2frame->Entry(-width => 40, -relief => "sunken",
194                      -textvariable => \$outputdir)->pack(-side => "left");
195    my $dirselect = $top2frame->Button(-text => "Select", -command => sub {
196        $outputdir = select_dir($outputdir);
197        $outputdir = check_dir($win,$outputdir);
198      })->pack(-side => "left");
199    $b->attach($dirselect, -balloonmsg => "Select an existing directory\nor enter a new one");
200
201    my $midframe = $win->Frame(-relief => 'raised', -borderwidth => 2);
202    $midframe->pack(-side => "top", -fill => "both", -ipady => 3, -ipadx => 3);
203    $tmp3=$midframe->Label(-text => "Output format: ", -anchor => 'w',
204                     -justify => "center", -fg => 'blue')->pack(-side => "left");
205                $b->attach($tmp3, -balloonmsg => "Format for converted data\nNOTE: If input data is Matlab/Scilab\n      and output format is Scilab/Matlab\n      'Convert' mode will work also with binary data.");
206    $oformats = $oformats_iMcStas;
207    $oformat_ctrl = $midframe->Optionmenu(-textvariable => \$oformat, -options =>
208                                         $oformats)->pack(-side => 'left');
209    $tmp4=$midframe->Label(-text => "Conversion mode: ", -anchor => 'w',
210                     -justify => "center", -fg => 'blue')->pack(-side => "left");
211                $b->attach($tmp4, -balloonmsg => "Convert: convert files one by one\nMerge: convert files and merge equivalent ones (e.g. clusters/grids)\nScan assembly: convert files and gather them in scan series\nScan merge: same as assembly, but also merge equivalent files");
212    $runmodes = $runmodes_iMcStas;
213    $runmode_ctrl = $midframe->Optionmenu(-textvariable => \$runmode, -options =>
214                                         $runmodes)->pack(-side => 'left');
215
216    my $bottomframe = $win->Frame(-relief => 'raised', -borderwidth => 2);
217    $bottomframe->pack(-side => "top", -fill => "both", -ipady => 3, -ipadx => 3);
218    my $recordlog = $bottomframe->Checkbutton(-text => "Record Log file",-variable => \$recordlog)->pack(-side => 'left');
219    $b->attach($recordlog, -balloonmsg => "Records data handling operations into $logfile file");
220
221    $bottomframe->Button(-text => "Cancel", -fg => 'red', -command => sub {exit;})->pack(-side => "right", -anchor => "e");
222    $bottomframe->Button(-text => "Ok", -fg => 'green', -command => sub {
223        if ($inputdir && $outputdir) {
224            $outputdir = check_dir($win,$outputdir);
225            $continue=1; $win->destroy;
226        } else {
227            $win->messageBox(
228                             -message => "You must select both an input and an output dir!",
229                             -title => "Problem:",
230                             -type => 'ok',
231                             -icon => 'error',
232                             -default => 'ok');
233        }
234    })->pack(-side => "right", -anchor => "w");
235}
236
237sub check_dir {
238    my ($win, $output) = @_;
239    if (-d $output && -e $output) {
240        $output = File::Spec->catfile( $output, "$date" );
241        $win->messageBox(
242                         -message => "For safety reasons I will create the subdir \n\n$output\n\n as final destination.\n\n ".
243                         "This directory does not exist now but will be created at runtime.\n",
244                         -title => "Notice: Directory exists",
245                         -type => 'ok',
246                         -icon => 'info',
247                         -default => 'ok');
248    }
249    return $output;
250}
251
252sub select_dir {
253    my ($start_dir) = @_;
254    my $top = new MainWindow;
255    $top->withdraw;
256
257    my $t = $top->Toplevel;
258    $t->title("Choose dir to monitor:");
259    my $ok = 0;
260    my $f = $t->Frame->pack(-fill => "x", -side => "bottom");
261
262    my $curr_dir;
263
264    if ($start_dir) {
265        $curr_dir = $start_dir;
266    } else {
267        $curr_dir = getcwd();
268    }
269
270    my $d;
271    $d = $t->Scrolled('DirTree',
272                      -scrollbars => 'osoe',
273                      -width => 35,
274                      -height => 20,
275                      -selectmode => 'browse',
276                      -exportselection => 1,
277                      -browsecmd => sub { $curr_dir = shift },
278                      -command   => sub { $ok = 1 },
279                      )->pack(-fill => "both", -expand => 1);
280    $f->Button(-text => 'Ok',
281               -command => sub { $ok =  1 })->pack(-side => 'left');
282    $f->Button(-text => 'Cancel',
283               -command => sub { $ok = -1 })->pack(-side => 'left');
284
285    $f->waitVariable(\$ok);
286
287    $top->destroy;
288
289    if ($ok == 1) {
290        return $curr_dir;
291    } else {
292        return $start_dir;
293    }
294
295}
296
297sub iformat_select {
298  my ($dir) = @_;
299  my $file = $dir;
300
301  # check input data directory
302  if (-d $file) { # check if dir containing result file
303    my $newfile = "$file/mcstas";
304    if (-e "$newfile.m" || -e "$newfile.sci" || -e "$newfile.sim" || -e "$newfile.html" || -e "$newfile.nxs" || -e "$newfile.pro" || -e "$newfile.xml") {
305      $file = $newfile; }
306  }
307
308  # look if there is only one file type and set iformat
309  if (-e "$file.m")    { $iformat = "Matlab";  $file = "$file.m"; }
310  if (-e "$file.sci")  { $iformat = "Scilab";  $file = "$file.sci"; }
311  if (-e "$file.sim")  { $iformat = "McStas";  $file = "$file.sim"; }
312  if (-e "$file.html") { $iformat = "HTML";    $file = "$file.html"; }
313  if (-e "$file.xml")  { $iformat = "XML";     $file = "$file.xml";  }
314  if (-e "$file.pro")  { $iformat = "IDL";     $file = "$file.pro"; }
315  if (-e "$file.nxs")  { $iformat = "NeXus";   $file = "$file.nxs"; }
316
317  if (open $handle, $file) {
318    while(<$handle>) {
319      if(/Format\s*(.*?)\s*$/i) {
320          $oformat_line = $1;
321      }
322    }
323    close($fid);
324    print "Input directory $dir presumably contains data in $iformat format.\n";
325    if ($oformat_line =~ /binary/i) { print "       It contains binary blocks.\n"; }
326  } else { print "mcformatgui: Warning: Could not open file '$file'. Conversion may fail.\n"; }
327
328  return($iformat);
329}
330
Note: See TracBrowser for help on using the browser.