【问题标题】:Non-functioning elsif loop in perlperl中不起作用的elsif循环
【发布时间】:2015-11-05 02:17:00
【问题描述】:

此 Perl 程序将 *.mdp 文件作为输入,并生成该文件的副本,并对 init_lambdaforeign_Lambda 进行更改。

Lambda 从01 不等。参数foreign lambda 包含两个值,具体取决于间距,例如如果 lambda = 0.1 且间距为 0.05,则外部 lambda 值将是 0.05 和 0.1

但我想以不同的方式在Lower_LambdaHigher_Lambda 打印foreign lambda 的值。我使用了条件语句,但我不明白为什么第二个elsif 条件,即elsif ($i == $Higher_Lambda) 没有被执行。

如果我可以使用 sed 或 awk 实现这一点,请也提出建议

#!/usr/bin/perl -w

use strict;

# opens a generic .mdp file and replaces the values of
# 'init_lambda' and 'foreign_lambda' values at increments
# of by spacing

my $Lower_Lambda  = 0.1;
my $Higher_Lambda = 0.2;
my $Count         = 5;
my $init_spacing  = 0.05;

unless ( @ARGV ) {
    die "Usage: $0 input.mdp\n";
}

my $difference = $Higher_Lambda - $Lower_Lambda;
my $spacing    = $difference / $Count;
my $mdp        = $ARGV[0];
my @temp       = split( '\.', $mdp );
my $base       = $temp[0];

open( IN, "<$mdp" );
my @in = <IN>;
close( IN );

for ( my $i = $Lower_Lambda ; $i < $Higher_Lambda ; $i += $spacing ) {

    my $filename = "${base}_${i}.mdp";
    open( OUT, ">$filename" );

    foreach $_ ( @in ) {

        unless ( ( $_ =~ /^init_lambda/ ) || ( $_ =~ /^foreign_lambda/ ) ) {
            print OUT $_;
        }

        if ( $_ =~ /^init_lambda\s*=/ ) {

            if ( $i < 1 ) {
                printf OUT "%s %0.3f\n", $&, $i;
            }
            else {
                printf OUT "%s %.3f\n", $&, $i;
            }
        }

        if ( $_ =~ /^foreign_lambda\s*=/ ) {

            if ( $i < 1 ) {

                if ( $i == 0 ) {
                    printf OUT "%s %0.3f\n", $&, ( $i + $spacing );

                    print "I am in 0";
                }
                elsif ( $i == $lower_lambda ) {

                    printf OUT "%s %0.3f %0.3f\n", $&, $i - $init_spacing,
                      ( $i + $spacing );
                    print "I am not there";
                }
                elsif ( $i == $Higher_Lambda ) {

                    printf OUT "%s %0.3f %0.3f\n", $&, $i - $spacing,
                      $i + $init_spacing;
                    print "I am here bro";
                }
                else {

                    printf OUT "%s %0.3f %0.3f\n", $&, ( $i - $spacing ),
                      ( $i + $spacing );

                }
            }
            else {
                printf OUT "%s %0.3f\n", $&, ( $i - $spacing );
            }
        }
    }

    close( OUT );

}

exit;


输入文件

 energygrps               = W WF Protein DPPC 
 ; Neighborsearching and short-range nonbonded interactions
 nstlist                  = 10
 ns_type                  = grid
 pbc                      = xyz
 rlist                    = 1.3
 ; Electrostatics
 coulombtype              = shift
 rcoulomb                 = 1.2
 vdw-type                 = shift
 rvdw-switch              = 0.9

 tau_t                    = 1.0; 1.0 1.0
 ref_t                    = 300; 300 300
 ; Pressure coupling is on for NPT
 Pcoupl                   = Berendsen ; Parrinello-Rahman 
 Pcoupltype               = semiisotropic
 tau_p                    = 1.1 1.1
 compressibility          = 1e-05 1e-05
 ref_p                    = 1.0 1.0
 ; Free energy control stuff
 free_energy              = yes
 init_lambda              = 0.0
 delta_lambda             = 0
 foreign_lambda           = 0.05
 sc-alpha                 = 1.3
 sc-power                 = 1.0
 sc-sigma                 = 0.47 
 couple-moltype           = Protein  ; name of moleculetype to decouple
 couple-lambda0           = vdw-q      ; only van der Waals interactions
 couple-lambda1           = none     ; turn off everything, in this  
 vdW
 couple-intramol          = yes
 nstdhdl                  = 10
 ; Do not generate velocities
 gen_vel                  = no 
 ; options for bonds
 constraints              = h-bonds  ; we only have C-H bonds here
 ; Type of constraint algorithm
 constraint-algorithm     = lincs
 ; Constrain the starting configuration
 ; since we are continuing from NPT
 continuation             = yes  
 lincs-order              = 12
 ld_seed                   =-1

【问题讨论】:

  • 以可读的方式格式化您的代码。
  • 我想现在可以了吧?
  • @VikasDubey:您的更改阻止了它的编译。我已回滚到上一次编辑
  • 您能否将问题编辑为关注损坏的部分?我不想去挖掘找到这个“不起作用的 elsif”
  • 发布预期输出以配合您的示例输入。但是,您不能想出一个更简短的示例,这样我们就不必尝试阅读和理解这么多输入数据吗?如果您可以用 10 行或更少的输入而不是 50 行或其他任何内容来证明您的问题,可能会鼓励更多的人(例如我!)来帮助您。

标签: perl awk sed


【解决方案1】:

恐怕我根本无法遵循您的逻辑,但您的问题很可能与比较浮点值的相等性有关,您应该从不 em> 这样做是因为浮点表示的精度有限

相反,您应该使用 整数 计数器,并从中计算 lambda 值。在下面的代码中,我将 $i 从 0 迭代到 $count,然后使用

计算相应的 $lambda
my $lambda = $lower_lambda + $i * $difference / $count;

然后你可以比较 $i 与 0 和 $count 来检查你是在第一步还是最后一步

我无法知道范围是否正确($i 应该停在$count 还是$count-1?)但这个计算肯定是正确的

我很担心你的测试 $i== 0$i &lt; 1 因为它们几乎肯定也会失败,但我看不出你想要做什么。第一个只有在$lower_lambda 为负数或零,而$upper_lambda 为正数或零时才会发生,这似乎不太可能。我怀疑这些测试是多余的,可能是为了让您的代码正常工作?

不要为你的词法变量使用大写字母:它们是为包名之类的全局标识符保留的,将它们用于你的普通变量可能会让你感到非常困惑

此代码运行并正确创建文件序列,但您应仔细检查内容

#!/usr/bin/perl

use strict;
use warnings;
use v5.10.1;
use autodie;

our @ARGV = 'Lower_Lambda.mdp';

die "Usage: $0 input.mdp\n" unless @ARGV;

my $mdp = $ARGV[0];

my $lower_lambda  = 0.1;
my $higher_lambda = 0.2;
my $count         = 5;
my $init_spacing  = 0.05;

my $difference = $higher_lambda - $lower_lambda;
my $spacing    = $difference / $count;

for my $i ( 0 .. $count ) {

    my $lambda = $lower_lambda + $i * $difference / $count;

    my $filename = $mdp =~ s/.*\.\K/sprintf '_%0.3f', $lambda/er;    #/

    open my $in_fh,  '<', $mdp;
    open my $out_fh, '>', $filename;

    while ( <$in_fh> ) {

        if ( /^(init_lambda\s*=\s*)/ ) {

            my $label = $1;

            printf $out_fh $label . "%0.3f\n",
                $lambda;
        }
        elsif ( /^(foreign_lambda\s*=\s*)/ ) {

            my $label = $1;

            if ( $lambda >= 1 ) {
                printf $out_fh $label . "%0.3f\n",
                    $lambda - $spacing;
            }
            elsif ( $lambda == 0 ) {
                printf $out_fh $label . "%0.3f\n",
                    $lambda + $spacing;
            }
            elsif ( $i == 0 ) {
                printf $out_fh $label . "%0.3f %0.3f\n",
                  $lambda - $init_spacing,
                  $lambda + $spacing;
            }
            elsif ( $i == $count ) {
                printf $out_fh $label . "%0.3f %0.3f\n",
                  $lambda - $spacing,
                  $lambda + $init_spacing;
            }
            else {
                printf $out_fh $label . "%0.3f %0.3f\n",
                  $lambda - $spacing,
                  $lambda + $spacing;
            }

        }
        else {
            print $out_fh $_;
        }
    }

    close $out_fh;
}

【讨论】:

    【解决方案2】:

    关于你最后一个不重复的问题

    if(LAMBDA == 0.95  || ( LAMBDA > 0.96 && LAMBDA <1.01  ))
    
               LAMBDA += 0.05;
    
        else
    
               LAMBDA += 0.1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 2017-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多