3 start include statements
6 my $nrec_exp = '^\s*NO. OF DATA RECS IN DATA SET:\s*(\d*)|^\s*TOT. NO. OF DATA RECS:\s*(\d*)';
7 my $nobs_exp = ' TOT. NO. OF OBS RECS:\s*(\d*)';
8 my $nind_exp = ' TOT. NO. OF INDIVIDUALS:\s*(\d*)';
9 my $subprob_exp = '^ PROBLEM NO\.:\s*\d+\s*SUBPROBLEM NO\.:\s*(\d+)';
13 # }}} include statements
20 $this -> _read_nrecs
();
21 $this -> _read_nobs
() if ( $this -> parsed_successfully
() and not
22 $this -> finished_parsing
() );
23 $this -> _read_nind
() if ( $this -> parsed_successfully
() and not
24 $this -> finished_parsing
() );
25 $this -> _read_msfo_status
() if ( $this -> parsed_successfully
() and not
26 $this -> finished_parsing
() );
27 $this -> _read_block_structures
() if ( $this -> parsed_successfully
() and not
28 $this -> finished_parsing
() );
29 $this -> _read_inits
() if ( $this -> parsed_successfully
() and not
30 $this -> finished_parsing
() );
31 $this -> _read_eststep
() if ( $this -> parsed_successfully
() and not
32 $this -> finished_parsing
() );
33 $this -> _read_nonpstep
() if ( $this -> parsed_successfully
() and not
34 $this -> finished_parsing
() );
35 $this -> _read_covstep
() if ( $this -> parsed_successfully
() and not
36 $this -> finished_parsing
() );
37 $this -> _read_tablesstep
() if ( $this -> parsed_successfully
() and not
38 $this -> finished_parsing
() );
39 $this -> _read_prior
() if ( $this -> parsed_successfully
() and not
40 $this -> finished_parsing
() );
41 $this -> _read_steps_allowed
() if ( $this -> parsed_successfully
() and not
42 $this -> finished_parsing
() );
43 $this -> _read_subproblems
() if ( $this -> parsed_successfully
() and not
44 $this -> finished_parsing
() );
45 my $mes = $this -> parsing_error_message
();
46 if( defined $this -> subproblems
() ) {
47 foreach my $subp ( @
{$this -> subproblems
()} ) {
48 $mes .= $subp -> parsing_error_message
();
49 $this -> parsed_successfully
($this -> parsed_successfully
() *
50 $subp -> parsed_successfully
());
54 $this -> parsing_error_message
( $mes );
56 if ( defined $this -> {'subproblems'} and $this -> parsed_successfully
() ) {
60 delete $this -> {'lstfile'};
68 $self -> parsed_successfully
( 0 );
69 $self -> parsing_error_message
( $message );
73 # {{{ register_in_database
75 start register_in_database
76 if ( $PsN::config
-> {'_'} -> {'use_database'} ) {
77 my ( $date_str, $time_str );
78 if ( $Config{osname
} eq 'MSWin32' ) {
79 $date_str = `date /T`;
80 $time_str = ' '.`time /T`;
87 my $date_time = $date_str.$time_str;
88 my $dbh = DBI
-> connect("DBI:mysql:host=".$PsN::config
-> {'_'} -> {'database_server'}.
89 ";databse=".$PsN::config
-> {'_'} -> {'project'},
90 $PsN::config
-> {'_'} -> {'user'},
91 $PsN::config
-> {'_'} -> {'password'},
94 my @mod_str = ('','');
95 if ( defined $self -> {'model_id'} ) {
96 @mod_str = ('model_id, ',"$self->{'model_id'}, ");
98 $sth = $dbh -> prepare
("INSERT INTO ".$PsN::config
-> {'_'} -> {'project'}.
103 "VALUES ( '$output_id' ,".
105 "'$self->{'nrecs'}' ".
106 ",'$self->{'nobs'}' ,'$self->{'nind'}' )");
108 $self -> {'problem_id'} = $sth->{'mysql_insertid'};
111 if ( defined $self -> {'problem_id'} ) {
112 foreach my $problem ( @
{$self -> {'subproblems'}} ) {
113 $problem -> register_in_database
( output_id
=> $output_id,
114 problem_id
=> $self -> {'problem_id'},
115 model_id
=> $model_id );
119 end register_in_database
121 # }}} register_in_database
123 # {{{ _read_subproblems
124 start _read_subproblems
125 my $subproblem_start;
126 while ( $_ = @
{$self -> {'lstfile'}}[ $self -> {'lstfile_pos'}++ ] ) {
127 if( /$subprob_exp/ or $self -> {'lstfile_pos'} > $#{$self -> {'lstfile'}} ){
128 if( defined $subproblem_start ){
129 my @subproblem_lstfile =
130 @
{$self -> {'lstfile'}}[$subproblem_start .. $self -> {'lstfile_pos'} - 2];
132 if( $self -> {'lstfile_pos'} > $#{$self -> {'lstfile'}} ) {
135 $subproblems = $2 - 1; # Assuming problems come in order
137 $self -> add_subproblem
138 ( 'init_data' => {lstfile
=> \
@subproblem_lstfile,
139 estimation_step_initiated
=> $self -> estimation_step_initiated
(),
140 estimation_step_run
=> $self -> estimation_step_run
(),
141 nonparametric_step_run
=> $self -> {'nonparametric_step_run'},
142 covariance_step_run
=> $self -> {'covariance_step_run'},
143 msfi_used
=> $self -> msfi_used
(),
144 omega_block_structure_type
=> $self -> {'omega_block_structure_type'},
145 sigma_block_structure_type
=> $self -> {'sigma_block_structure_type'},
146 omega_block_structure
=> $self -> {'omega_block_structure'},
147 sigma_block_structure
=> $self -> {'sigma_block_structure'},
148 omega_block_sets
=> $self -> {'omega_block_sets'},
149 sigma_block_sets
=> $self -> {'sigma_block_sets'},
150 estimated_thetas
=> $self -> {'estimated_thetas'},
151 estimated_omegas
=> $self -> {'estimated_omegas'},
152 estimated_sigmas
=> $self -> {'estimated_sigmas'},
153 # lower_theta_bounds => $self -> {'lower_theta_bounds'},
154 # upper_theta_bounds => $self -> {'upper_theta_bounds'},
155 tablename
=> @
{$self -> {'tablenames'}}[$subproblems],
156 tableidcolumn
=> @
{$self -> {'tableidcolumns'}}[$subproblems],
157 model_id
=> $self -> {'model_id'},
158 problem_id
=> $self -> {'problem_id'},
159 output_id
=> $self -> {'output_id'} });
161 unless ( $self -> {'lstfile_pos'} > $#{$self -> {'lstfile'}} ){
162 $subproblem_start = $self -> {'lstfile_pos'};
167 unless( defined $subproblem_start ) { # No subproblems. Try to make one from the whole file.
168 $self -> add_subproblem
169 ( 'init_data' => {lstfile
=> $self -> {'lstfile'},
170 estimation_step_initiated
=> $self -> estimation_step_initiated
(),
171 estimation_step_run
=> $self -> estimation_step_run
(),
172 nonparametric_step_run
=> $self -> {'nonparametric_step_run'},
173 covariance_step_run
=> $self -> {'covariance_step_run'},
174 msfi_used
=> $self -> msfi_used
(),
175 omega_block_structure_type
=> $self -> {'omega_block_structure_type'},
176 sigma_block_structure_type
=> $self -> {'sigma_block_structure_type'},
177 omega_block_structure
=> $self -> {'omega_block_structure'},
178 sigma_block_structure
=> $self -> {'sigma_block_structure'},
179 omega_block_sets
=> $self -> {'omega_block_sets'},
180 sigma_block_sets
=> $self -> {'sigma_block_sets'},
181 estimated_thetas
=> $self -> {'estimated_thetas'},
182 estimated_omegas
=> $self -> {'estimated_omegas'},
183 estimated_sigmas
=> $self -> {'estimated_sigmas'},
184 # lower_theta_bounds => $self -> {'lower_theta_bounds'},
185 # upper_theta_bounds => $self -> {'upper_theta_bounds'},
186 tablename
=> @
{$self -> {'tablenames'}}[0],
187 tableidcolumn
=> @
{$self -> {'tableidcolumns'}}[0],
188 model_id
=> $self -> {'model_id'},
189 problem_id
=> $self -> {'problem_id'},
190 output_id
=> $self -> {'output_id'} } );
193 end _read_subproblems
194 # }}} _read_subproblems
198 # The data recs statement should always be present
199 # Raise parsing error if not found
200 my $errmess = "Error in reading the number of data records!\n";
201 my $start_pos = $self -> {'lstfile_pos'};
204 while ( $_ = @
{$self -> {'lstfile'}}[$start_pos++] ) {
205 if ( /$nobs_exp/ or ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
206 debug
-> warn( level
=> 1,
207 message
=> $errmess."$!" );
208 $self -> parsing_error
( message
=> $errmess."$!" );
218 $self -> {'lstfile_pos'} = $start_pos;
220 debug
-> warn( level
=> 1,
221 message
=> $errmess."$!" );
222 $self -> parsing_error
( message
=> $errmess."$!" );
229 # The no of obs recs statement should always be present
230 # Raise parsing error if not found
231 my $errmess = "Error in reading the number of observation records!\n";
232 my $start_pos = $self -> {'lstfile_pos'};
235 while ( $_ = @
{$self -> {'lstfile'}}[$start_pos++] ) {
236 if ( /$nind_exp/ or ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
237 debug
-> warn( level
=> 1,
238 message
=> $errmess."$!" );
239 $self -> parsing_error
( message
=> $errmess."$!" );
249 $self -> {'lstfile_pos'} = $start_pos;
251 debug
-> warn( level
=> 1,
252 message
=> $errmess."$!" );
253 $self -> parsing_error
( message
=> $errmess."$!" );
260 # The no of individuals statement should always be present
261 # Raise parsing error if not found
262 my $errmess = "Error in reading the number of individuals!\n";
263 my $start_pos = $self -> {'lstfile_pos'};
266 while ( $_ = @
{$self -> {'lstfile'}}[$start_pos++] ) {
267 if ( /^0LENGTH OF THETA/ or
268 /^0MODEL SPECIFICATION FILE INPUT/ or
269 ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
270 debug
-> warn( level
=> 1,
271 message
=> $errmess."$!" );
272 $self -> parsing_error
( message
=> $errmess."$!" );
282 $self -> {'lstfile_pos'} = $start_pos;
284 debug
-> warn( level
=> 1,
285 message
=> $errmess."$!" );
286 $self -> parsing_error
( message
=> $errmess."$!" );
291 # {{{ _read_arbitrary
293 start _read_arbitrary
295 my $start_pos = $self -> {'lstfile_pos'};
298 while ( $_ = @
{$self -> {'lstfile'}}[$start_pos++] ) {
299 last if ( /^ PROBLEM.*SUBPROBLEM/ or /^ PROBLEM NO\.:\s+\d/ );
301 $self -> { $member } = $1;
307 $self -> {'lstfile_pos'} = $start_pos;
309 debug
-> warn( level
=> 1,
310 message
=> "rewinding to first position..." );
315 # }}} _read_arbitrary
317 # {{{ _read_msfo_status
318 start _read_msfo_status
320 my $start_pos = $self -> {'lstfile_pos'};
321 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
323 if( /^0SEARCH WITH ESTIMATION STEP WILL NOT PROCEED BEYOND PREVIOUS TERMINATION POINT/ ){
324 $self -> msfo_has_terminated
(1); # Means that $ESTIMATION
325 # must be removed to enable continuation.
326 $self -> finished_parsing
(1);
329 if( /^0MODEL SPECIFICATION FILE IS EMPTY/ ){
330 $self -> {'msfo_file_empty'} = 1;
331 $self -> finished_parsing
(1);
335 end _read_msfo_status
338 # {{{ _read_block_structures
340 start _read_block_structures
341 # These structures should always be present if no model specification file input is used
342 # Raise parsing error if not found
343 # $success is not used, really, with the latest fix
345 my $errmess = "Error in reading the block structures!";
346 my $start_pos = $self -> {'lstfile_pos'};
354 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
355 if ( /^0MODEL SPECIFICATION FILE INPUT/ ) {
356 # We can't find anything but that's ok
362 if ( /^0INITIAL ESTIMATE/ or /^0DEFAULT OMEGA BOUNDARY TEST OMITTED:/ ) {
363 # We want to find this if we are currently reading omega
364 # or sigma block structures
365 $success = 1 if ( $sbarea or $obarea );
370 if ( ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
371 #EOF This should not happen, raise error
372 my $errmess = "Reached end of file while parsing block structures\n";
373 debug
-> warn( level
=> 1,
374 message
=> $errmess."$!" );
375 $self -> parsing_error
( message
=> $errmess."$!" );
379 if(/0OMEGA HAS BLOCK FORM:/) {
380 $self -> {'omega_block_structure_type'} = 'BLOCK';
385 if(/0SIGMA HAS BLOCK FORM:/) {
386 $self -> {'sigma_block_structure_type'} = 'BLOCK';
392 if ( /^0OMEGA HAS SIMPLE DIAGONAL FORM/ ) {
393 $self -> {'omega_block_structure_type'} = 'DIAGONAL';
397 if ( /^0SIGMA HAS SIMPLE DIAGONAL FORM/ ) {
398 $self -> {'sigma_block_structure_type'} = 'DIAGONAL';
404 # All rows with the last but one element set to 0 indicate the start of a new block
405 # $#row == 0 indicates the first row of the matrix.
406 if ( $#row == 0 or $row[$#row-1] == 0 ) {
407 # If the same number as previous set
408 if ( $oblock_set == $row[$#row] ) {
409 $self -> {'omega_block_sets'}{$oblock_set}{'size'}++;
411 $oblock_set = $row[$#row];
412 $self -> {'omega_block_sets'}{$oblock_set}{'size'} = 1;
414 # Always set dimension to 1 when starting a new block
415 $self -> {'omega_block_sets'}{$oblock_set}{'dimension'} = 1;
417 $self -> {'omega_block_sets'}{$oblock_set}{'dimension'}++;
419 push( @
{$self -> {'omega_block_structure'}}, \
@row );
423 # All rows with the last but one element set to 0 indicate the start of a new block
424 if ( $#row == 0 or $row[$#row-1] == 0 ) {
425 # If the same number as previous set
426 if ( $sblock_set == $row[$#row] ) {
427 $self -> {'sigma_block_sets'}{$sblock_set}{'size'}++;
429 $sblock_set = $row[$#row];
430 $self -> {'sigma_block_sets'}{$sblock_set}{'size'} = 1;
432 # Always set dimension to 1 when starting a new block
433 $self -> {'sigma_block_sets'}{$sblock_set}{'dimension'} = 1;
435 $self -> {'sigma_block_sets'}{$sblock_set}{'dimension'}++;
437 push( @
{$self -> {'sigma_block_structure'}}, \
@row );
441 unless( defined $self -> {'omega_block_structure_type'} ){
442 $self -> {'omega_block_structure_type'} = 'DIAGONAL';
444 unless( defined $self -> {'sigma_block_structure_type'} ){
445 $self -> {'sigma_block_structure_type'} = 'DIAGONAL';
448 unless ( $success ) {
449 debug
-> warn( level
=> 1,
450 message
=> $errmess." 2 $!" );
451 $self -> parsing_error
( message
=> $errmess." 2 $!" );
453 $self -> {'lstfile_pos'} = $start_pos;
456 end _read_block_structures
458 # }}} _read_block_structures
460 # {{{ _read_steps_allowed
461 start _read_steps_allowed
462 # These statements are optional. Return to start_pos if not found
463 my $start_pos = $self -> {'lstfile_pos'};
466 my $nonp_allowed = 1;
467 my $tables_allowed = 1; # I am not sure that this is actually something which can be marked as not valid
469 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
470 if ( /^ PROBLEM.*SUBPROBLEM/ or /^ PROBLEM NO\.:\s+\d/ or
471 /^0ITERATION NO./ or /^0MINIMIZATION/) {
472 # This is ok, we should end up here
476 if( /0ESTIMATION STEP NOT ALLOWED/ ) {
480 if( /0COVARIANCE STEP NOT ALLOWED/ ) {
484 if( /0NONPARAMETRIC STEP NOT ALLOWED/ ) {
488 if( /0TABLES STEP NOT ALLOWED/ ) { # As indicated above, this is unsure but this coding should not harm
492 if( /0INPUT MODEL SPECIFICATION FILE GENERATED FROM A NON-TERMINATING ESTIMATION STEP/ ) {
493 if( @
{$self -> {'lstfile'}}[ $start_pos ] =~ / BUT CONTINUING ESTIMATION STEP NOT IMPLEMENTED/ ) {
494 # If this happens, NONMEM aborts so we are finished reading
495 $self -> finished_parsing
(1);
499 if( /0MODEL SPECIFICATION FILE IS EMPTY/ ) {
500 # If this happens, NONMEM aborts so we are finished reading
501 $self -> finished_parsing
(1);
505 unless( ( $self -> estimation_step_initiated
() * $est_allowed ) or
506 ( $self -> covariance_step_run
() * $cov_allowed ) or
507 ( $self -> nonparametric_step_run
() * $nonp_allowed ) or
508 ( $self -> tables_step_run
() * $tables_allowed ) ) {
509 # If this happens, NONMEM aborts so we are finished reading
510 $self -> finished_parsing
(1);
512 end _read_steps_allowed
513 # }}} _read_steps_allowed
515 # {{{ _read_tablesstep
516 start _read_tablesstep
517 # The tables step is optional
518 my $start_pos = $self -> {'lstfile_pos'};
521 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
523 # This is ok, the tables step was not used.
528 if( /^ PROBLEM NO\.:\s+\d/ or
530 # This should not happen, raise error
531 my $errmess = "Found $_ while searching for the (optional) ".
532 "tables step indicator\n";
533 debug
-> warn( level
=> 1,
534 message
=> $errmess."$!" );
535 $self -> parsing_error
( message
=> $errmess."$!" );
539 if ( ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
540 #EOF This should not happen, raise error
541 my $errmess = "Reached end of file while searching for the ".
542 "(optional) tables step indicator\n";
543 debug
-> warn( level
=> 1,
544 message
=> $errmess."$!" );
545 $self -> parsing_error
( message
=> $errmess."$!" );
549 if(/^0TABLES STEP OMITTED:\s*\b(.*)\b/) {
550 $self -> {'tables_step_run'} = 0 if $1 eq 'YES';
551 $self -> {'tables_step_run'} = 1 if $1 eq 'NO';
557 unless ( $success ) {
558 debug
-> warn( level
=> 2,
559 message
=> "rewinding to first position..." );
561 $self -> {'lstfile_pos'} = $start_pos;
564 # }}} _read_tablesstep
570 my $start_pos = $self -> {'lstfile_pos'};
572 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
573 # if ( /1DOUBLE PRECISION PREDPP/ ) { This is not always printed
575 /0SEARCH WITH ESTIMATION STEP WILL NOT PROCEED/ ) {
576 # This is ok, no user defined prior was used.
581 if( /^ PROBLEM NO\.:\s+\d/ or
583 # This should not happen, raise error
584 my $errmess = "Found $_ while searching for the (optional) ".
585 "user defined prior indicator\n";
586 debug
-> warn( level
=> 1,
587 message
=> $errmess."$!" );
588 $self -> parsing_error
( message
=> $errmess."$!" );
592 if ( ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
593 #EOF This should not happen, raise error
594 my $errmess = "Reached end of file while searching for the ".
595 "(optional) user defined prior indicator\n";
596 debug
-> warn( level
=> 1,
597 message
=> $errmess."$!" );
598 $self -> parsing_error
( message
=> $errmess."$!" );
602 if(/^ PRIOR SUBROUTINE USER-SUPPLIED/){
603 $self -> {'user_defined_prior'} = 1;
609 unless ( $success ) {
610 debug
-> warn( level
=> 2,
611 message
=> "rewinding to first position..." );
613 $self -> {'lstfile_pos'} = $start_pos;
623 # The nonparametric step is optional
624 my $start_pos = $self -> {'lstfile_pos'};
627 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
628 if ( /^0COVARIANCE STEP OMITTED/ or
629 /0TABLES STEP OMITTED/ or
630 /1DOUBLE PRECISION PREDPP/ or
631 /0SEARCH WITH ESTIMATION STEP WILL NOT PROCEED/ or
634 /^ PROBLEM NO\.:\s+\d/ ) {
635 # This is ok, the nonp step was not used.
639 # if( /^ PROBLEM NO\.:\s+\d/ or
640 # /^0MINIMIZATION/ ) {
641 # This should not happen, raise error
642 # my $errmess = "Found $_ while searching for the (optional) ".
643 # "nonparametric step indicator\n";
644 # debug -> warn( level => 1,
645 # message => $errmess."$!" );
646 # $self -> parsing_error( message => $errmess."$!" );
650 if ( ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
651 #EOF This should not happen, raise error
652 my $errmess = "Reached end of file while searching for the ".
653 "(optional) nonparametric step indicator\n";
654 debug
-> warn( level
=> 1,
655 message
=> $errmess."$!" );
656 $self -> parsing_error
( message
=> $errmess."$!" );
660 if(/^0NONPARAMETRIC STEP OMITTED:\s*\b(.*)\b/) {
661 $self -> {'nonparametric_step_run'} = 0 if $1 eq 'YES';
662 $self -> {'nonparametric_step_run'} = 1 if $1 eq 'NO';
668 unless ( $success ) {
669 debug
-> warn( level
=> 2,
670 message
=> "rewinding to first position..." );
672 $self -> {'lstfile_pos'} = $start_pos;
679 # A combination of simulation and estimation step indications should always be found, raise error otherwise
680 my $start_pos = $self -> {'lstfile_pos'};
683 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
684 if ( /^0COVARIANCE STEP OMITTED/ or
685 /^0NONPARAMETRIC STEP OMITTED/ or
686 /^0TABLES STEP OMITTED/ or
689 /^ PROBLEM NO\.:\s+\d/ ) {
691 # This should not happen, raise error
692 my $errmess = "Found $_ while searching for the simulation/estimation step indicators\n";
693 debug
-> warn( level
=> 1,
694 message
=> $errmess."$!" );
695 $self -> parsing_error
( message
=> $errmess."$!" );
700 if ( ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
701 #EOF This should not happen, raise error
702 my $errmess = "Reached end of file while searching for the simulation/estimation step indicators\n";
703 debug
-> warn( level
=> 1,
704 message
=> $errmess."$!" );
705 $self -> parsing_error
( message
=> $errmess."$!" );
709 if(/^ PRIOR SUBROUTINE USER-SUPPLIED/){
713 if(/^0ESTIMATION STEP OMITTED:\s*\b(.*)\b/) {
714 $self -> estimation_step_initiated
(1);
715 $self -> estimation_step_run
(0) if $1 eq 'YES';
716 $self -> estimation_step_run
(1) if $1 eq 'NO';
719 if(/^0SIMULATION STEP OMITTED:\s*\b(.*)\b/) {
720 $self -> simulation_step_run
(0) if $1 eq 'YES';
721 $self -> simulation_step_run
(1) if $1 eq 'NO';
726 unless ( $success ) {
727 debug
-> warn( level
=> 2,
728 message
=> "rewinding to first position..." );
730 $self -> {'lstfile_pos'} = $start_pos;
738 my $start_pos = $self -> {'lstfile_pos'};
741 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
743 if(/0COVARIANCE STEP OMITTED:\s*\b(.*)\b/) {
744 $self -> {'covariance_step_run'} = 0 if $1 eq 'YES';
745 $self -> {'covariance_step_run'} = 1 if $1 eq 'NO';
749 if ( /^ PROBLEM.*SUBPROBLEM/ or /^ PROBLEM NO\.:\s+\d/ or
750 /^0ITERATION NO./ or /^0MINIMIZATION/) {
751 # This is ok, we should end up here
756 unless ( $success ) {
757 debug
-> warn( level
=> 2,
758 message
=> "rewinding to first position..." );
760 $self -> {'lstfile_pos'} = $start_pos;
769 # The inits should always be present if no model specification file input is used
770 # Raise parsing error if not found
772 my $errmess = "Error in reading the initial estimates!\n";
773 my $start_pos = $self -> {'lstfile_pos'};
774 my ( @thetas, @omegas, @sigmas );
779 my $tmp = $start_pos;
781 # Look for a general statement of fixed sigmas and omegas
782 my $all_sigmas_fixed = 0;
783 my $all_omegas_fixed = 0;
784 while( $_ = @
{$self -> {'lstfile'}}[ $tmp++ ] ) {
785 if ( /^0SIGMA CONSTRAINED TO BE THIS INITIAL ESTIMATE/ ) {
786 $all_sigmas_fixed = 1;
788 if ( /^0OMEGA CONSTRAINED TO BE THIS INITIAL ESTIMATE/ ) {
789 $all_omegas_fixed = 1;
791 if ( /^0ESTIMATION STEP OMITTED/ or
792 /^0SIMULATION STEP OMITTED/ ) {
795 if ( /^ INITIAL ESTIMATE OF OMEGA HAS A NONZERO BLOCK WHICH IS NUMERICALLY NOT POSITIVE DEFINITE/ ) {
796 $self -> finished_parsing
(1);
797 $self -> pre_run_errors
($_);
800 if ( ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
801 #EOF This should not happen, raise error
802 my $errmess = "Reached end of file while parsing initial estimates\n";
803 debug
-> warn( level
=> 1,
804 message
=> $errmess."$!" );
805 $self -> parsing_error
( message
=> $errmess."$!" );
811 while( $_ = @
{$self -> {'lstfile'}}[ $start_pos++ ] ) {
813 if ( /^0MODEL SPECIFICATION FILE INPUT/ ) {
814 # We can't find any initial estimates but that's ok
815 $self -> msfi_used
(1);
821 if ( /^0INITIAL ESTIMATE OF THETA/ ) {
822 # If we find this we must find other stuff too. Set
823 # success = 0 and change this if we find the rest. Nope,
824 # not true. $THETA can be found alone using the LIKE
825 # option in the $EST record.
829 if ( /^0ESTIMATION STEP OMITTED/ or
830 /^0SIMULATION STEP OMITTED/ ) {
831 # We want to find this if we are currently reading the omega or sigma inits
832 $success = 1 if ( $thetarea or $sigmarea or $omegarea);
837 if ( ($start_pos + 1) == scalar @
{$self -> {'lstfile'}} ) {
838 #EOF This should not happen, raise error
839 my $errmess = "Reached end of file while parsing the initial estimates\n";
840 debug
-> warn( level
=> 1,
841 message
=> $errmess."$!" );
842 $self -> parsing_error
( message
=> $errmess."$!" );
845 if ( $thetarea and /^\s*-?\d*\.\d*/ ) {
846 my @T = split(' ',$_);
847 push(@
{$self -> {'initthetas'}},eval($T[1]));
848 push(@
{$self -> {'lower_theta_bounds'}},eval($T[0]));
849 push(@
{$self -> {'upper_theta_bounds'}},eval($T[2]));
850 if ( $T[0] == $T[1] and $T[0] == $T[2] ) {
851 push(@
{$self -> {'fixedthetas'}},1);
852 push(@
{$self -> {'estimated_thetas'}},0);
854 push(@
{$self -> {'fixedthetas'}},0);
855 push(@
{$self -> {'estimated_thetas'}},1);
858 if ( /^0INITIAL ESTIMATE OF OMEGA:/ ) {
862 if ( defined $self -> {'omega_block_sets'} and
863 scalar keys %{$self -> {'omega_block_sets'}} > 0 ) {
864 # We currently assume that this part is atomic. No parser checks are made
866 my %om_bl = %{$self -> {'omega_block_sets'}};
867 my @blocks = sort {$a <=> $b} keys %om_bl;
868 foreach my $block ( @blocks ) {
869 my @fix_row = split(' ', $self -> {'lstfile'}[ $start_pos++ ]);
870 my $fix = $fix_row[1] eq 'YES' ?
1 : 0;
871 if( $all_omegas_fixed ) {
874 for ( my $size = 1; $size <= $om_bl{$block}{'size'}; $size++ ) {
875 for ( my $row = $start_pos ; $row < $start_pos + $om_bl{$block}{'dimension'}; $row++ ) {
876 my @init_row = split(' ', $self -> {'lstfile'}[ $row ]);
877 foreach my $init ( @init_row ) {
878 push( @
{$self -> {'fixedomegas'}}, $fix );
879 push( @
{$self -> {'estimated_omegas'}}, (not $fix and $size == 1) ?
1 : 0 );
880 push(@
{$self -> {'initomegas'}}, eval($init) );
881 push(@
{$self -> {'lower_omega_bounds'}},0);
882 push(@
{$self -> {'upper_omega_bounds'}},1000000);
886 $start_pos += $om_bl{$block}{'dimension'};
890 while( ($start_pos + 1) < scalar @
{$self -> {'lstfile'}} ) {
891 if( $self -> {'lstfile'}[ $start_pos ] =~ /^0INITIAL ESTIMATE OF SIGMA/ or
892 $self -> {'lstfile'}[ $start_pos ] =~ /^0SIMULATION STEP OMITTED/ or
893 $self -> {'lstfile'}[ $start_pos ] =~ /^0ESTIMATION STEP OMITTED/ or
894 $self -> {'lstfile'}[ $start_pos ] =~ /^0OMEGA CONSTRAINED TO BE THIS INITIAL ESTIMATE/ ) {
899 # After ten rows of omegas NONMEM starts wrapping
900 # lines. We then need to skip the first part of the
901 # wrapped lines. This nice littel formula calculates
902 # how many lines to skip.
904 my $skip_lines = ($om_row - $om_row % 10)/10;
906 $start_pos += $skip_lines if( $om_row > 10 );
908 my @init_row = split(' ', $self -> {'lstfile'}[ $start_pos++ ]);
909 if( not $init_row[$#init_row] =~ /[0-9]?\.[0-9]{4}E[+-][0-9]{2}/ ) {
910 my $errmess = "Error parsing omega initial estimates, found non-number:\n".
911 $self -> {'lstfile'}[ $start_pos-1 ]."\n";
912 debug
-> warn( level
=> 1,
913 message
=> $errmess."$!" );
914 $self -> parsing_error
( message
=> $errmess."$!" );
918 my $init = eval($init_row[$#init_row]);
919 unless( $init == 0 ) {
920 push( @
{$self -> {'fixedomegas'}}, $all_omegas_fixed ?
1 : 0 );
921 push( @
{$self -> {'initomegas'}}, eval($init) );
923 push( @
{$self -> {'estimated_omegas'}}, $all_omegas_fixed ?
0 : 1 );
924 push(@
{$self -> {'lower_omega_bounds'}},0);
925 push(@
{$self -> {'upper_omega_bounds'}},1000000);
930 if ( /^0INITIAL ESTIMATE OF SIGMA:/ ) {
934 if ( defined $self -> {'sigma_block_sets'} and
935 scalar keys %{$self -> {'sigma_block_sets'}} > 0 ) {
936 # We currently assume that this part is atomic. No parser checks are made
938 my %si_bl = %{$self -> {'sigma_block_sets'}};
939 my @blocks = sort {$a <=> $b} keys %si_bl;
940 foreach my $block ( @blocks ) {
941 my @fix_row = split(' ', $self -> {'lstfile'}[ $start_pos++ ]);
942 my $fix = $fix_row[1] eq 'YES' ?
1 : 0;
943 if( $all_sigmas_fixed ) {
946 for ( my $size = 1; $size <= $si_bl{$block}{'size'}; $size++ ) {
947 for ( my $row = $start_pos ; $row < $start_pos + $si_bl{$block}{'dimension'}; $row++ ) {
948 my @init_row = split(' ', $self -> {'lstfile'}[ $row ]);
949 foreach my $init ( @init_row ) {
950 push( @
{$self -> {'fixedsigmas'}}, $fix );
951 push( @
{$self -> {'estimated_sigmas'}}, (not $fix and $size == 1) ?
1 : 0 );
952 push(@
{$self -> {'initsigmas'}}, eval($init) );
953 push(@
{$self -> {'lower_sigma_bounds'}},0);
954 push(@
{$self -> {'upper_sigma_bounds'}},1000000);
958 $start_pos += $si_bl{$block}{'dimension'};
962 while( ($start_pos + 1) < scalar @
{$self -> {'lstfile'}} ) {
963 if( $self -> {'lstfile'}[ $start_pos ] =~ /^0SIMULATION STEP OMITTED/ or
964 $self -> {'lstfile'}[ $start_pos ] =~ /^0ESTIMATION STEP OMITTED/ or
965 $self -> {'lstfile'}[ $start_pos ] =~ /^0SIGMA CONSTRAINED TO BE THIS INITIAL ESTIMATE/ ) {
970 # After ten rows of sigmas NONMEM starts wrapping
971 # lines. We then need to skip the first part of the
972 # wrapped lines. This nice littel formula calculates
973 # how many lines to skip.
975 my $skip_lines = ($sm_row - $sm_row % 10)/10;
977 $start_pos += $skip_lines if( $sm_row > 10 );
979 my @init_row = split(' ', $self -> {'lstfile'}[ $start_pos++ ]);
980 if( not $init_row[$#init_row] =~ /[0-9]?\.[0-9]{4}E[+-][0-9]{2}/ ) {
981 my $errmess = "Error parsing sigma initial estimates, found non-number\n".
982 $self -> {'lstfile'}[ $start_pos-1 ];
983 debug
-> warn( level
=> 1,
984 message
=> $errmess."$!" );
985 $self -> parsing_error
( message
=> $errmess."$!" );
989 my $init = eval($init_row[$#init_row]);
990 unless( $init == 0 ) {
991 push( @
{$self -> {'fixedsigmas'}}, $all_sigmas_fixed ?
1 : 0 );
992 push( @
{$self -> {'initsigmas'}}, eval($init) );
994 push( @
{$self -> {'estimated_sigmas'}}, $all_sigmas_fixed ?
0 : 1 );
995 push(@
{$self -> {'lower_sigma_bounds'}},0);
996 push(@
{$self -> {'upper_sigma_bounds'}},1000000);
1001 # if ( /^0MINIMIZATION/ ) {
1006 unless ( $success ) {
1007 debug
-> warn( level
=> 2,
1008 message
=> "rewinding to first position..." );
1011 # if ( $PsN::config -> {'_'} -> {'use_database'} and
1012 # $self -> {'register_in_database'} ) {
1013 # my $dbh = DBI -> connect("DBI:mysql:host=".$PsN::config -> {'_'} -> {'database_server'}.
1014 # ";databse=".$PsN::config -> {'_'} -> {'project'},
1015 # $PsN::config -> {'_'} -> {'user'},
1016 # $PsN::config -> {'_'} -> {'password'},
1017 # {'RaiseError' => 1});
1019 # my @mod_str = ('','');
1020 # if ( defined $self -> {'model_id'} ) {
1021 # @mod_str = ('model_id,',"$self->{'model_id'},");
1023 # foreach my $param ( 'theta', 'omega', 'sigma' ) {
1024 # foreach my $par_str ( @{$self -> {'init'.$param.'s'}} ) {
1025 # $sth = $dbh -> prepare("INSERT INTO ".$PsN::config -> {'_'} -> {'project'}.
1027 # "(subproblem_id,problem_id,output_id,".
1029 # "type,value,init) ".
1031 # "'$self->{'problem_id'}' ,".
1032 # "'$self->{'output_id'}' ,".
1034 # "'$param','$par_str','1')");
1036 # push( @{$self -> {'estimate_ids'}}, $sth->{'mysql_insertid'} );
1041 # $dbh -> disconnect;
1044 $self -> {'lstfile_pos'} = $start_pos;
1055 unless( $#subproblems > 0 ){
1056 debug
-> warn( level
=> 2,
1057 message
=> "subproblems undefined, using all." );
1058 if( defined $self -> {'subproblems'} ) {
1059 @subproblems = (1 .. scalar @
{$self -> {'subproblems'}});
1061 debug
-> warn( level
=> 1,
1062 message
=> "No subproblems defined in this problem." );
1068 my @own_subproblems = defined $self -> {'subproblems'} ? @
{$self -> {'subproblems'}} : ();
1069 foreach my $i ( @subproblems ) {
1070 if ( defined $own_subproblems[$i-1] ) {
1071 debug
-> warn( level
=> 2,
1072 message
=> "subproblems: $i" );
1073 debug
-> warn( level
=> 2,
1074 message
=> "Attribute: ".$own_subproblems[$i-1] -> $attribute );
1075 my $meth_ret = $own_subproblems[$i-1] -> $attribute;
1077 # Test if the returned value is an array (with hashes we
1078 # can't allow selection based on parameter numbers, since
1079 # a hash is not ordered)
1080 if ( ref ( $meth_ret ) eq 'ARRAY' ) {
1081 #my @subprob_attr = @{$own_subproblems[$i-1] -> $attribute};
1082 my @subprob_attr = @
{$meth_ret};
1083 if ( scalar @parameter_numbers > 0 ) {
1085 foreach my $num ( @parameter_numbers ) {
1086 if ( $num > 0 and $num <= scalar @subprob_attr ) {
1087 push( @tmp_arr, $subprob_attr[$num-1] );
1089 debug
-> die( message
=> "( $attribute ): no such parameter number $num!".
1090 "(".scalar @subprob_attr." exists)" );
1093 @subprob_attr = @tmp_arr;
1095 push( @return_value, \
@subprob_attr );
1097 # push( @return_value, $meth_ret ) if defined $meth_ret;
1098 push( @return_value, $meth_ret );
1101 debug
-> die( message
=> "No such subproblem ".($i-1) );
1104 # Check the return_value to see if we have empty arrays
1105 if ( $#return_value == 0 and ref ($return_value[0]) eq 'ARRAY' and scalar @
{$return_value[0]} < 1 ) {
1117 if ( defined $self -> {'subproblems' } ) {
1118 foreach my $type ( ('theta','omega','sigma') ) {
1119 my $first_sub = @
{$self -> {'subproblems'}}[0];
1120 my $accessor = $type eq 'theta' ?
$type.'s' : 'raw_'.$type.'s';
1121 if( defined $first_sub -> $accessor ) {
1122 my @param = @
{$first_sub -> $accessor};
1123 if ( scalar @param > 0 ) {
1124 my ( @names, @indexes );
1126 foreach $j (1..scalar @param) {
1127 if ( $type eq 'theta' ) {
1128 push( @names, "TH$j" );
1130 if ( $first_sub -> _isdiagonal
('index' => $j) ) {
1131 push @names, uc(substr($type,0,2)).++$ndiags;
1132 if ( $type eq 'omega' ) {
1133 push ( @
{$self -> {'omega_indexes'}}, [$ndiags, $ndiags] );
1135 push ( @
{$self -> {'sigma_indexes'}}, [$ndiags, $ndiags] );
1138 } elsif ($param[$j-1] !=0) {
1139 @indexes = $first_sub -> _rowcolind
( index => $j);
1140 push @names,uc(substr($type,0,2)).$indexes[0].'_'.$indexes[1];
1141 if ( $type eq 'omega' ) {
1142 push ( @
{$self -> {'omega_indexes'}}, [$indexes[0], $indexes[1]] );
1144 push ( @
{$self -> {'sigma_indexes'}}, [$indexes[0], $indexes[1]] );
1149 $self ->{$type.'names'} = \
@names;