moved nonpb.pm
[PsN.git] / lib / nonmem_subs.pm
blob46dddc56f010201965ed9b9ed2c299715e88e876
1 # {{{ include statements
3 start include statements
4 if( $0 =~ /nonmem.pm$/ ) {
5 use FindBin qw($Bin);
6 use lib "$Bin";
8 use File::Copy 'cp';
9 #use ext::Config::Tiny;
10 use ext::IPC::Run3;
11 use Config;
12 if( $0 =~ /nonmem.pm$/ ) {
13 require PsN;
14 my $nonmem = nonmem -> new( 'modelfile' => $ARGV[0],
15 'outputfile' => $ARGV[1],
16 'nice' => $ARGV[2],
17 'version' => $ARGV[3],
18 'fsubs' => [split( /,/ , $ARGV[6] )],
19 'nm_directory' => $ARGV[7],
20 'show_version' => 0);
22 my $compile = $ARGV[4];
23 my $execute = $ARGV[5];
25 if( $compile ){
26 unless( $nonmem -> compile() ){
27 debug -> die( message => $nonmem -> error_message );
31 if( $execute ){
32 $nonmem -> execute;
35 end include statements
37 # }}}
39 # {{{ new
41 start new
43 unless( defined $this -> {'outputfile'} ){
44 $this -> {'outputfile'} = $this -> {'modelfile'};
45 $this -> {'outputfile'} =~ s/\.mod$/\.lst/;
48 unless( defined $this -> {'nm_directory'} ){
49 my ($nmdir,$version) = split(/,/ , $PsN::config -> { 'nm_versions' } -> { $this -> {'version'} });
51 unless( defined $nmdir ){
52 print "Unknown NONMEM version ",$this -> {'version'}," specified.\n";
53 my @nmkeys = keys %{$PsN::config -> { 'nm_versions' }};
54 if ( $#nmkeys == 0 and
55 defined $nmkeys[0] and
56 defined $PsN::config -> { 'nm_versions' } -> {$nmkeys[0]} ) {
57 #print "Using ",$PsN::config -> { 'nm_versions' } -> {$nmkeys[0]}," instead\n";
58 my( $nmdir, $version ) = split(/,/,$PsN::config -> { 'nm_versions' } -> {$nmkeys[0]});;
62 $this -> {'nm_directory'} = $nmdir;
64 unless( defined $PsN::config -> {'compiler'} and defined $PsN::config -> {'compiler'} -> {'name'} ){
65 debug -> warn( level => 1,
66 message => "No compiler defined, assuming g77" );
67 $this -> {'compiler'} = 'g77';
68 } else {
69 $this -> {'compiler'} = $PsN::config -> {'compiler'} -> {'name'};
70 $this -> {'compiler_options'} = $PsN::config -> {'compiler'} -> {'options'};
74 end new
76 # }}}
78 # {{{ compile
80 start compile
82 my $version = $self -> {'version'};
83 my $nmdir = $self -> {'nm_directory'};
84 my $includes;
85 my $nmlink;
86 my $adaptive = $self -> {'adaptive'} ? '_adaptive' : '';
87 if( -e "$nmdir/util/nmlink5.exe" ){
88 $nmlink = "$nmdir/util/nmlink5.exe";
89 $self -> {'version'} = 5;
90 if( $self -> {'show_version'} ){
91 $version = $self -> {'version'};
92 } else {
93 $version = '';
95 } elsif ( -e "$nmdir/util/nmlink6.exe" ){
96 $self -> {'version'} = 6;
97 if( $self -> {'show_version'} ){
98 $version = $self -> {'version'};
99 } else {
100 $version = '';
102 $nmlink = "$nmdir/util/nmlink6.exe";
103 if( $Config{osname} eq 'MSWin32' ){
104 $includes = "-I$nmdir\\sizes";
105 } else {
106 $includes = "-I$nmdir/sizes";
108 } else {
109 my $err_version = ( defined $nmdir and $nmdir ne '' ) ? $nmdir : '[not configured]';
110 debug -> die( message => "Unable to find a supported version of NONMEM\n".
111 "The NONMEM installation directory is $err_version for version [".
112 $self -> {'version'}."] according to psn.conf." );
115 # first clean up from old compile
116 unlink( 'FLIB','FCON', 'FDATA', 'FREPORT','FSUBS', 'FSUBS.f','LINK.LNK','FSTREAM', 'PRDERR', 'nonmem.exe', 'nonmem', 'nonmem5', 'nonmem6', 'nonmem5_adaptive', 'nonmem6_adaptive' );
118 my $nm;
120 if( $Config{osname} eq 'MSWin32' ){
121 $nm="$nmdir\\nm";
122 } else {
123 $nm="$nmdir/nm";
126 my $modelfile = $self -> {'modelfile'};
128 if( $Config{osname} eq 'MSWin32' ){
129 run3( "$nmdir/tr/nmtran.exe", $modelfile, \$self -> {'nmtran_message'}, \$self -> {'nmtran_message'} );
130 } else {
131 run3( 'nice -' . $self -> {'nice'} . " $nmdir/tr/nmtran.exe", $modelfile, \$self -> {'nmtran_message'}, \$self -> {'nmtran_message'} );
134 open( NMMSG, '>compilation_output.txt' );
135 print( NMMSG $self -> {'nmtran_message'}, "\n" );
137 unless(-e 'FREPORT'){
138 close(NMMSG);
139 $self -> {'error_message'} = "NMtran failed: \n" . $self -> {'nmtran_message'} ;
140 return 0;
143 my $nmlink_message;
144 run3( "$nmlink", undef, \$nmlink_message, \$nmlink_message );
146 print( NMMSG $nmlink_message, "\n" );
148 my $fsub;
150 if(-e 'FSUBS'){
151 if( $self -> {'compiler'} eq 'g77' or $self -> {'compiler'} eq 'g95' ){
152 rename("FSUBS", "FSUBS.f");
153 $fsub='FSUBS.f';
154 } else {
155 rename("FSUBS", "FSUBS.for");
156 $fsub='FSUBS.for';
160 if( defined $self -> {'fsubs'} and $self -> {'version'} != 6 ){
161 foreach my $sub ( @{$self -> {'fsubs'}} ){
162 $fsub .= " $sub";
166 open( FH, "<", 'LINK.LNK' );
167 my @link;
168 while( <FH> ){
169 my $tmp = $_;
170 $tmp =~ s/^\s+//;
171 $tmp =~ s/\s+$//;
172 push(@link, $tmp);
174 close( FH );
176 my $compile_message;
177 my $compile_command;
179 my @nmlib;
181 if( $Config{osname} eq 'MSWin32' ){
182 @nmlib = ("$nm\\NONMEM.obj","$nm\\BLKDAT.obj","$nm\\nonmem.lib");
183 } else {
184 @nmlib = ("$nm/NONMEM.o", "$nm/BLKDAT.o", "$nm/nonmem.a");
186 $compile_command = "g77 " . $self -> {'compiler_options'} . " -ononmem$version$adaptive $includes $fsub @link @nmlib 2>&1";
188 if( $self -> {'compiler'} eq 'g77' ){
190 $compile_command = "g77 " . $self -> {'compiler_options'} . " -ononmem$version$adaptive $includes $fsub @link @nmlib 2>&1";
192 } elsif( $self -> {'compiler'} eq 'g95' ){
194 $compile_command = "g95 " . $self -> {'compiler_options'} . " -ononmem$version$adaptive $includes $fsub @link @nmlib 2>&1";
196 } elsif( $self -> {'compiler'} eq 'df' or $self -> {'compiler'} eq 'fl32' ){
197 $compile_command = $self -> {'compiler'}." " . $self -> {'compiler_options'} . " /Fenonmem $fsub @nmlib @link";
199 } elsif( $self -> {'compiler'} eq 'ifort' ){
201 $compile_command = "ifort " . $self -> {'compiler_options'} . " -ononmem$version$adaptive $includes $fsub @link @nmlib 2>&1";
205 run3( "$compile_command", undef, \$compile_message, \$compile_message );
207 print( NMMSG $compile_message, "\n" );
209 close( NMMSG );
211 unless(-e "nonmem.exe" or -e "nonmem$version$adaptive" ) {
212 $self -> {'error_message'} = "Fortran Compilation failed: \n" . $compile_message ;
213 return 0;
216 end compile
218 # }}}
220 # {{{ execute
222 start execute
224 my $version = $self -> {'version'};
225 my $nmdir = $self -> {'nm_directory'};
226 my $outputfile = $self -> {'outputfile'};
227 my $adaptive = $self -> {'adaptive'} ? '_adaptive' : '';
229 my ( $start_time, $fin_time );
230 if( $Config{osname} eq 'MSWin32' ){
231 $start_time = `date /T`;
232 chomp($start_time);
233 $start_time = $start_time.' '.`time /T`;
234 run3( "nonmem.exe", undef, \undef );
235 $fin_time = `date /T`;
236 chomp($fin_time);
237 $fin_time = $fin_time.' '.`time /T`;
238 if ( -e "output" ) {
239 cp( "output", $outputfile );
240 unlink( "output" );
241 } elsif ( -e "OUTPUT" ) {
242 cp( "OUTPUT", $outputfile );
243 unlink( "OUTPUT" );
245 } else {
246 unless( $self -> {'show_version'} ){
247 $version = '';
249 $start_time = `date`;
250 if ( -e "/proc/self/lock" ) {
251 open (OUTFILE,">/proc/self/lock") || die "Could not unlock myself!\n";
252 print OUTFILE "0";
253 close (OUTFILE);
255 run3( "nice -n " . $self -> {'nice'} . " ./nonmem$version$adaptive", "FCON", $outputfile );
256 if ( -e "/proc/self/lock" ) {
257 open (OUTFILE,">/proc/self/lock") || die "Could not lock myself!\n";
258 print OUTFILE "1";
259 close (OUTFILE);
261 $fin_time = `date`;
263 open( OUT, '>>', $outputfile );
264 print( OUT "This file was created using the NONMEM version in directory $nmdir\n" );
265 print( OUT "Started $start_time" );
266 print( OUT "Finished $fin_time" );
267 close( OUT );
269 end execute
271 # }}}