5 use lib "$Bin/../PsN_2_2_0_patches_serial/lib";
7 # Don't edit the line below, it must look exactly like this.
8 # Everything above this line will be replaced #
25 my $cmd_line = $0 . " " . join( " ", @ARGV );
29 my %optional_options = ( 'dv_column:s'
32 my $res = GetOptions( \%options,
33 @common_options::get_opt_strings,
34 keys(%optional_options) );
38 common_options::set_globals( \%options, 'se_of_eta' );
39 common_options::get_defaults( \%options, 'se_of_eta' );
40 common_options::sanity_checks( \%options, 'se_of_eta' );
43 $help_text{Pre_help_message} = <<'EOF';
44 <h3 class="heading1">se_of_eta</h3>
46 Perl script for getting standard errors of etas.
48 <h3 class="heading1">Usage:</h3>
51 $help_text{Description
} = <<'EOF';
52 <h3 class="heading1">Description:</h3>
54 se_of_eta requires "MAXEVALS" to be abreviated to "MAX" if it
55 exists in the model file.
58 $help_text{Examples
} = <<'EOF';
59 <h3 class="heading1">Example:</h3>
61 <p class="style2">se_of_eta pheno.mod</p>
63 This will create a new directory se_of_eta_dirX where X is a
64 number increased every time you run the program. Inside that
65 directory it will create a new model file for each OMEGA in the
66 file. You will be able to retrieve the results from the
67 corresponding table file.
70 common_options
::online_help
('se_of_eta',\
%options, \
%help_text, {}, {});
72 if ( scalar( @ARGV ) < 1 ) {
73 print "A model file must be specified. Use '$0 -h' for help.\n";
77 unless( defined $options{'dv_column'} ) {
78 $options{'dv_column'} = 'DV';
81 my( $base_dir, $dummy) = OSspecific
::absolute_path
( '', '' );
85 if ( defined $options{'directory'} ) {
87 ( $directory, $dummy ) = OSspecific
::absolute_path
( $options{'directory'} );
89 $directory = OSspecific
::unique_path
( 'se_of_eta_dir' ,
93 unless( -d
$directory ){
96 open(CMD
, ">", $directory . "/command.txt");
97 print CMD
$cmd_line, "\n";
101 my $eval_string = common_options
::model_parameters
(\
%options);
105 $model = model
-> new
( eval( $eval_string ),
106 filename
=> $ARGV[0],
107 ignore_missing_output_files
=> 1 );
109 my $datafile_name = $model -> datas
-> [0] -> full_name
;
115 $modelfit = tool
::modelfit
->
116 new
( eval( $common_options::parameters
),
117 directory
=> 'orig_modelfit_dir',
118 models
=> [$model] );
122 my $nr_of_old_etas = $model -> nomegas
-> [0];
123 my $nr_of_old_sigmas = $model -> nsigmas
-> [0];
124 my $nr_of_old_thetas = $model -> nthetas
;
132 my $data = $model -> datas
-> [0];
134 $data -> synchronize
;
136 my $ids = $data -> individuals
;
138 my $nrec = scalar @
{$ids -> [0] -> subject_data
};
140 foreach my $id (0..$#{$ids}) {
142 my $model_copy = $model -> copy
( filename
=> 'se_model_'.($id+1).'.mod',
143 copy_data
=> ($id+1), # Trick to copy data once
144 data_file_names
=> ['se_model.dta']);
146 push(@models,$model_copy);
148 $model_copy -> datas
-> [0] -> synchronize
;
149 $model_copy -> datas
-> [0] -> filename
('se_model.dta');
150 $model_copy -> datas
-> [0] -> directory
( $directory );
151 $model_copy -> datafiles
(new_names
=> ['se_model.dta']);
153 $model_copy -> update_inits
( from_output
=> $model -> outputs
-> [0] );
155 # 1 Change all ETA(n) to THETA(n + $nr_of_old_thetas)
159 # Find PK or PRED block
160 if( defined $model_copy -> pk
){
161 $code_block = $model_copy -> pk
;
163 } elsif( defined $model_copy -> pred
){
164 $code_block = $model_copy -> pred
;
166 die "Error: No \$PK or \$PRED found... \n";
169 for( my $row = 0; $row <= $#{$code_block}; $row++ ){
171 # High-tech RegExp to find ETA(n) and put n in $dummy. Then update
172 # $dummy and replace ETA(n) with THETA($dummy). Also register all
173 # n in ETA(n) by storing them in %seen_eta.
175 $code_block -> [$row] =~ s
/
177 (?
{$seen_eta{$2}=1;$dummy=$2+$nr_of_old_thetas;})\
)
181 my $nr_of_new_thetas = $nr_of_old_thetas + scalar keys %seen_eta;
184 $model_copy -> pk
( new_pk
=> $code_block );
186 $model_copy -> pred
( new_pred
=> $code_block );
189 # Fixate all old thetas and omegas.
191 $model_copy -> fixed
( parameter_type
=> 'theta',
192 new_values
=> [[(1)x
$nr_of_old_thetas]] );
194 # Set low(0.01) initial values for the new thetas.
196 $model_copy -> initial_values
( parameter_type
=> 'theta',
198 parameter_numbers
=> [[($nr_of_old_thetas+1)..($nr_of_new_thetas)]],
199 new_values
=> [[(0.01) x
(($nr_of_new_thetas) - $nr_of_old_thetas)]]);
201 # Change all sigmas to omegas
203 my $sigmas = $model_copy -> initial_values
( parameter_type
=> 'sigma' );
205 $model_copy -> remove_records
( type
=> 'sigma' );
207 my $nr_of_old_etas_with_corr = $model_copy -> nomegas
( with_correlations
=> 1 ) -> [0];
209 $model_copy -> initial_values
( parameter_type
=> 'omega',
211 parameter_numbers
=> [[($nr_of_old_etas_with_corr+1)..($nr_of_old_etas_with_corr+$nr_of_old_sigmas)]],
212 new_values
=> $sigmas );
214 $model_copy -> fixed
( parameter_type
=> 'omega',
215 new_values
=> [[(1) x
($nr_of_old_etas_with_corr+$nr_of_old_sigmas)]] );
217 # Add EBAY column to dataset and change ID to IID
219 my $input = $model_copy -> record
( record_name
=> 'input' );
221 # $input->[0]->[0] =~ s/ID/IID/;
222 $input->[0]->[0] =~ s/\$INPUT//;
223 chomp( $input->[0]->[ $#{$input->[0]} ] );
224 $input->[0]->[ $#{$input->[0]} ] .= ' EBAY L2';
226 $model_copy -> set_records
( type
=> 'input',
227 record_strings
=> $input->[0]);
229 # Get error block to replace EPS(n) with ETA(n + $nr_of_old_eta) and
230 # replace ERR(n) with ERR(n+$nr_of_old_eta)
232 my $error = $model_copy -> record
( record_name
=> 'error' );
234 for( my $row = 0 ; $row <= $#{$error->[0]}; $row ++ ){
236 $error -> [0] -> [$row] =~ s
/
238 (?
{$seen_eps{$2}=1;$dummy=$2+$nr_of_old_etas;})\
)
241 $error -> [0] -> [$row] =~ s
/
243 (?
{$seen_err{$2}=1;$dummy=$2+$nr_of_old_etas;})\
)
247 if( $error -> [0] -> [$row] =~ /(.*)Y(\s*)=(.*)/ ){
249 @
{$error -> [0]} = ( @
{$error -> [0]}[0..($row-1)],
250 'IF( EBAY.LE.0 ) ' . $error -> [0] -> [$row],
251 @
{$error -> [0]}[$row+1..$#{$error->[0]}] );
256 # my $nr_of_new_etas = $nr_of_old_etas + scalar keys %seen_eps;
258 foreach( 1..$nr_of_old_etas ){
259 push(@
{$error -> [0]}, ' IF( EBAY.EQ.'.($_).' ) Y = THETA(' .
260 ($nr_of_old_thetas+$_) .
264 $model_copy -> set_records
( type
=> 'error',
265 record_strings
=> $error -> [0] );
267 # Set options in $EST and $COV
269 $model_copy -> maxeval
( new_values
=> [[9999]] );
271 if( scalar @
{$model_copy -> record
( record_name
=> 'covariance' )} > 0 ){
272 $model_copy -> remove_records
( type
=> 'covariance' );
275 $model_copy -> add_records
( type
=> 'covariance',
276 record_strings
=> ['MAT=R'] );
278 $model_copy -> set_records
( type
=> 'estimation' );
280 $model_copy -> remove_records
( type
=> 'table' );
282 # $model_copy -> set_option( record_name => 'data',
283 # option_name => 'NREC',
284 # option_value => $nrec );
286 $model_copy -> set_option
( record_name
=> 'data',
287 option_name
=> 'ACCEPT',
288 option_value
=> '(ID.EQ.'.$ids -> [$id] -> idnumber
().')' );
290 $model_copy -> _write
;
294 my $data_copy = $models[0] -> datas
-> [0];
296 my $ids = $data_copy -> individuals
;
298 my $omegas = $models[0] -> problems
-> [0] -> omegas
();
302 foreach my $omega( @
{$omegas} ){
304 for( 1..$omega -> size
() ){
305 push( @L2_column, $L2_value );
309 foreach my $id( @
{$ids} ){
310 my @last_row_of_id = split(/,/,$id -> subject_data
-> [$#{$id -> subject_data}]);
311 my $DV_column = $data_copy -> column_head_indices
-> {$options{'dv_column'}};
313 my $L2_first_value=0;
314 foreach my $row( @
{$id -> subject_data
} ){
316 $row .= ",0,$L2_first_value";
319 for( 1..$nr_of_old_etas ) {
320 $last_row_of_id[$DV_column-1] = '0';
321 push( @
{$id -> subject_data
}, join(',', @last_row_of_id, $_, $L2_first_value + @L2_column[$_ - 1] ) );
325 push( @
{$data_copy -> {'header'}}, 'EBAY', 'L2' );
326 $data_copy -> synchronize
;
328 $data_copy -> _write
;
330 $modelfit = tool
::modelfit
->
331 new
( eval( $common_options::parameters
),
332 directory
=> 'se_of_eta',
333 models
=> \
@models );
337 # New Results section 9:th of June.
339 my $num = scalar @
{$ids};
341 my (@theta,@setheta);
344 open( FILE1
,'>termination.csv' );
345 open( FILE2
,'>parameters.csv' );
347 print FILE1
"ID, OFV\n";
351 foreach my $i( 1..$nr_of_old_thetas ){
355 foreach my $i( 1..$nr_of_old_etas ){
356 print FILE2
"ETA$i,";
359 foreach my $i( 1..$nr_of_old_thetas ){
360 print FILE2
"SEth$i,";
363 foreach my $i( 1..$nr_of_old_etas ){
364 if( $i == $nr_of_old_etas ){
365 print FILE2
"SEeta$i\n";
367 print FILE2
"SEeta$i,";
371 foreach my $i(1..$num) {
373 @theta = get_theta
($i);
374 @setheta = get_setheta
($i);
376 print FILE1
"ID$i,$ofv\n";
377 print FILE2
"ID$i,", join( ',', @theta,@setheta ), "\n";
381 #####################################################################################################################################
383 #####################################################################################################################################
385 ### Retrieves the ofv from a NONMEM-output file using function "ofv" in PsN ###
388 my $lst = new output
('filename' => "se_model_$n.lst");
389 my $obf = $lst -> ofv
;
390 return $obf -> [0][0];
393 ### Retreives the estimated thetas from a NONMEM-output file using function "theta" in PsN ###
396 my $lst = new output
('filename' => "se_model_$n.lst");
397 my $theta = $lst -> thetas
;
398 if(defined $theta and defined $theta->[0] and defined $theta -> [0][0]){ return @
{$theta -> [0][0]}; }
399 else { return ('.','.','.'); }
402 ### Retreives the SEs estimated thetas from a NONMEM-output file using function "sethetas" in PsN ###
405 my $lst = new output
('filename' => "se_model_$n.lst");
406 my $setheta = $lst -> sethetas
;
407 if(defined $setheta and defined $setheta->[0] and defined $setheta -> [0][0]){ return @
{$setheta -> [0][0]}; }
408 else { return ('.','.','.'); }