Index: ThirdParty/mpqc_open/lib/perl/QCParse.pm
===================================================================
--- ThirdParty/mpqc_open/lib/perl/QCParse.pm	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/lib/perl/QCParse.pm	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,1232 @@
+#
+eval 'exec perl $0 $*'
+    if 0;
+
+require Molecule;
+
+##########################################################################
+
+package QCParse;
+$debug = 0;
+
+sub testparse {
+    my $parse = new QCParse;
+
+    my $string = "x:
+ xval
+test_basis: STO-3G 6-311G**
+charge: 1
+method: scf
+basis: sto-3g
+state: 3b1
+molecule:
+  H 0 0.0000001 1.00000001
+  H 0 0 -1
+gradient: yes
+optimize: no
+frequencies: yes
+properties: NPA
+y:
+yval
+z: zval1 zval2
+zval3
+h:
+0 a
+1
+ 2  c";
+
+    print "string:\n--------------\n$string\n--------------\n";
+
+    $parse->parse_string($string);
+    $parse->doprint();
+
+    my @t = $parse->value_as_array('h');
+    print "-----------------\n";
+    for ($i = 0; $i <= $#t; $i++) {
+        print "$i: $t[$i]\n";
+    }
+    print "-----------------\n";
+
+    @t = $parse->value_as_lines('h');
+    print "-----------------\n";
+    for ($i = 0; $i <= $#t; $i++) {
+        print "$i: $t[$i]\n";
+    }
+    print "-----------------\n";
+
+    my $qcinp = new QCInput($parse);
+    my $test_basis = $parse->value("test_basis");
+    my @test_basis_a = $parse->value_as_array("test_basis");
+    my $state = $qcinp->state();
+    my $mult = $qcinp->mult();
+    my $method = $qcinp->method();
+    my $charge = $qcinp->charge();
+    my $basis = $qcinp->basis();
+    my $gradient = $qcinp->gradient();
+    my $frequencies = $qcinp->frequencies();
+    my $optimize = $qcinp->optimize();
+    my $natom = $qcinp->n_atom();
+    foreach $i (@test_basis_a) {
+        print "test_basis_a: $i\n";
+    }
+    print "test_basis = $test_basis\n";
+    print "state = $state\n";
+    print "mult = $mult\n";
+    print "method = $method\n";
+    print "basis = $basis\n";
+    print "optimize = $optimize\n";
+    print "gradient = $gradient\n";
+    print "frequencies = $frequencies\n";
+    print "natom = $natom\n";
+    for ($i = 0; $i < $natom; $i++) {
+        printf "%s %14.8f %14.8f %14.8f\n", $qcinp->element($i),
+                                $qcinp->position($i,0),
+                                $qcinp->position($i,1),
+                                $qcinp->position($i,2);
+    }
+    printf "qcinp errors: %s\n", $qcinp->error();
+
+    my $inpwr = new MPQCInputWriter($qcinp);
+    printf "MPQC input:\n%s", $inpwr->input_string();
+}
+
+sub new {
+    my $this = shift;
+    my $class = ref($this) || $this;
+    my $self = {};
+    bless $self, $class;
+    $self->initialize();
+    return $self;
+}
+
+sub initialize {
+    my $self = shift;
+    $self->{'keyval'} = {};
+    $self->{'error'} = "";
+}
+
+sub parse_file {
+    my $self = shift;
+    my $file = shift;
+    if (! -f "$file") {
+        $self->{"ok"} = 0;
+        $self->error("File $file not found.");
+        return;
+    }
+    open(INPUT, "<$file");
+    my $string = "";
+    while (<INPUT>) {
+        $string = "$string$_";
+    }
+    close(INPUT);
+    #print "Got file:\n$string\n";
+    $self->parse_string($string);
+    $self->{"ok"} = 1;
+}
+
+sub write_file {
+    my $self = shift;
+    my $file = shift;
+    my $keyval = $self->{'keyval'};
+    my @keys = keys(%$keyval);
+    open(OUTPUT, ">$file");
+    foreach $key (@keys) {
+        my $value = $keyval->{$key};
+        print OUTPUT "${key}:\n";
+        print OUTPUT "$value\n";
+    }
+    close(OUTPUT);
+}
+
+sub parse_string {
+    my $self = shift;
+    my $string = shift;
+    my $value = "";
+    my $keyword = "";
+    $string = "$string\n";
+    while ($string) {
+        $string =~ s/^[^\n]*\n//;
+        $_ = $&;
+        s/#.*//;
+        if (/^\s*(\w+)\s*:\s*(.*)\s*$/) {
+            $self->add($keyword, $value);
+            $keyword = $1;
+            $value = $2;
+        }
+        elsif (/^\s*$/) {
+            $self->add($keyword, $value);
+            $keyword = "";
+            $value = "";
+        }
+        else {
+            $value = "$value$_";
+        }
+    }
+    $self->add($keyword, $value);
+}
+
+sub add {
+    my $self = shift;
+    my $keyword = shift;
+    my $value = shift;
+    if ($keyword ne "") {
+        $self->{'keyval'}{$keyword} = $value;
+        printf("%s = %s\n", $keyword, $value) if ($debug);
+    }
+}
+
+# returns the value of the keyword
+sub value {
+    my $self = shift;
+    my $keyword = shift;
+    my $keyval = $self->{'keyval'};
+    my $value = $keyval->{$keyword};
+    return $value;
+}
+
+# sets the value of the keyword
+sub set_value {
+    my $self = shift;
+    my $keyword = shift;
+    my $value = shift;
+    my $keyval = $self->{'keyval'};
+    $keyval->{$keyword} = $value;
+    return $value;
+}
+
+# returns the value of the keyword
+sub boolean_value {
+    my $self = shift;
+    my $keyword = shift;
+    my $keyval = $self->{'keyval'};
+    $_ = $keyval->{$keyword};
+    return "1" if (/^\s*(y|yes|1|true|t)\s*$/i);
+    return "0" if (/^\s*(n|no|0|false|f|)\s*$/i);
+    "";
+}
+
+# returns an array of whitespace delimited tokens
+sub value_as_array {
+    my $self = shift;
+    my $keyword = shift;
+    my $keyval = $self->{'keyval'};
+    my $value = $keyval->{$keyword};
+    my @array = ();
+    $i = 0;
+    $value =~ s/^\s+$//;
+    while ($value ne '') {
+        $value =~ s/^\s*(\S+)\s*//s;
+        $array[$i] = $1;
+        $i++;
+    }
+    return @array;
+}
+
+# returns an array reference of whitespace delimited tokens
+sub value_as_arrayref {
+    my $self = shift;
+    my $keyword = shift;
+    my $keyval = $self->{'keyval'};
+    my $value = $keyval->{$keyword};
+    my $array = [];
+    $i = 0;
+    $value =~ s/^\s+$//;
+    while ($value ne '') {
+        $value =~ s/^\s*(\S+)\s*//s;
+        $array->[$i] = $1;
+        $i++;
+    }
+    return $array;
+}
+
+# returns an array of lines
+sub value_as_lines {
+    my $self = shift;
+    my $keyword = shift;
+    my $keyval = $self->{'keyval'};
+    my $value = $keyval->{$keyword};
+    my @array = ();
+    $i = 0;
+    while ($value) {
+        $value =~ s/^\s*(.*)\s*\n//;
+        $array[$i] = $1;
+        $i++;
+    }
+    return @array;
+}
+
+# returns 1 if the input file existed
+sub ok {
+    my $self = shift;
+    $self->{"ok"};
+}
+
+sub display {
+    my $self = shift;
+    my @keys = @_ ? @_ : sort keys %$self;
+    foreach $key (@keys) {
+        print "\t$key => $self->{$key}\n";
+    }
+}
+
+sub doprint {
+    my $self = shift;
+    print "QCParse:\n";
+    my $keyval = $self->{'keyval'};
+    foreach $i (keys %$keyval) {
+        my $val = $keyval->{$i};
+        $val =~ s/\n/\\n/g;
+        print "keyword = $i, value = $val\n";
+    }
+}
+
+sub error {
+    my $self = shift;
+    my $msg = shift;
+    $self->{"error"} = "$self->{'error'}$msg";
+}
+
+##########################################################################
+
+package QCInput;
+$debug = 0;
+
+sub new {
+    my $this = shift;
+    my $class = ref($this) || $this;
+    my $self = {};
+    bless $self, $class;
+    $self->initialize(@_);
+    return $self;
+}
+
+sub initialize {
+    my $self = shift;
+    my $parser = shift;
+    if ($parser eq "") {
+        $parser = new QCParse;
+    }
+    $self->{"parser"} = $parser;
+    $self->{"error"} = $parser->error();
+
+    $self->{"molecule"} = new Molecule($parser->value("molecule"));
+}
+
+sub error {
+    my $self = shift;
+    my $msg = shift;
+    $self->{"error"} = "$self->{'error'}$msg";
+}
+
+sub checkpoint {
+    my $self = shift;
+    my $bval = $self->{"parser"}->boolean_value("checkpoint");
+    my $val = $self->{"parser"}->value("checkpoint");
+    if ($val ne "" && $bval eq "") {
+        $self->error("Bad value for checkpoint: $val");
+        $bval = "0";
+    }
+    elsif ($val eq "") {
+        $bval = "1";
+    }
+    $bval;
+}
+
+sub restart {
+    my $self = shift;
+    my $bval = $self->{"parser"}->boolean_value("restart");
+    my $val = $self->{"parser"}->value("restart");
+    if ($val ne "" && $bval eq "") {
+        $self->error("Bad value for restart: $val");
+        $bval = "0";
+    }
+    elsif ($val eq "") {
+        $bval = "1";
+    }
+    $bval;
+}
+
+sub label {
+    my $self = shift;
+    $self->{"parser"}->value("label");
+}
+
+sub charge {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("charge");
+    s/^\s+//;
+    s/\s+$//;
+    s/^\+//;
+    if (/^$/) { $_ = "0"; }
+    if (! /^-?\d+$/) {
+        $self->error("Bad charge: $_ (using 0)\n");
+        $_ = "0";
+    }
+    $_;
+}
+
+sub method {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("method");
+    s/^\s+//;
+    s/\s+$//;
+    if ($_ eq "") {
+        $self->error("No method given (using default).\n");
+        $_ = "SCF";
+    }
+    tr/a-z/A-Z/;
+    $_;
+}
+
+sub symmetry {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("symmetry");
+    s/^\s*//;
+    s/\s*$//;
+    uc $_;
+}
+
+sub memory {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("memory");
+    s/^\s*//;
+    s/\s*$//;
+    if ($_ eq "") {
+        $_ = 32000000;
+    }
+    $_;
+}
+
+sub state {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("state");
+    s/^\s*//;
+    s/\s*$//;
+    uc $_;
+}
+
+sub mult {
+    my $self = shift;
+    $_ = $self->state();
+    s/^\s*(\d+)/\1/;
+    if (/^\s*$/) {
+        $_ = 1;
+    }
+    $_;
+}
+
+sub basis {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("basis");
+    s/^\s+//;
+    s/\s+$//;
+    if ($_ eq "") {
+        $self->error("No basis given (using default).\n");
+        $_ = "STO-3G";
+    }
+    $_;
+}
+
+sub auxbasis {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("auxbasis");
+    s/^\s+//;
+    s/\s+$//;
+    if ($_ eq "") {
+        $self->error("No auxiliary basis given (using default).\n");
+        $_ = "STO-3G";
+    }
+    $_;
+}
+
+sub grid {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("grid");
+    s/^\s+//;
+    s/\s+$//;
+    if ($_ eq "") {
+        $_ = "default";
+    }
+    $_;
+}
+
+sub gradient {
+    my $self = shift;
+    my $bval = $self->{"parser"}->boolean_value("gradient");
+    if ($bval eq "") {
+        my $val = $self->{"parser"}->value("gradient");
+        $self->error("Bad value for gradient: $val");
+    }
+    $bval;
+}
+
+sub fzc {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("fzc");
+    s/^\s+//;
+    s/\s+$//;
+    if ($_ eq "") {
+        $_ = 0;
+    }
+    $_;
+}
+
+sub fzv {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("fzv");
+    s/^\s+//;
+    s/\s+$//;
+    if ($_ eq "") {
+        $_ = 0;
+    }
+    $_;
+}
+
+sub docc {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("docc");
+    s/^\s+//;
+    s/\s+$//;
+    if ($_ eq "" || $_ eq "-") {
+        $_ = "auto";
+    }
+    $_;
+}
+
+sub socc {
+    my $self = shift;
+    $_ = $self->{"parser"}->value("socc");
+    s/^\s+//;
+    s/\s+$//;
+    if ($_ eq "" || $_ eq "-") {
+        $_ = "auto";
+    }
+    $_;
+}
+
+sub optimize {
+    my $self = shift;
+    my $bval = $self->{"parser"}->boolean_value("optimize");
+    if ($bval eq "") {
+        my $val = $self->{"parser"}->value("optimize");
+        $self->error("Bad value for optimize: $val");
+    }
+    $bval;
+}
+
+# returns "" if orthog_method not set
+sub orthog_method {
+    my $self = shift;
+    my $bval = $self->{"parser"}->value("orthog_method");
+    $bval;
+}
+
+# returns "" if lindep_tol not set
+sub lindep_tol {
+    my $self = shift;
+    my $bval = $self->{"parser"}->value("lindep_tol");
+    $bval;
+}
+
+sub transition_state {
+    my $self = shift;
+    my $bval = $self->{"parser"}->boolean_value("transition_state");
+    if ($bval eq "") {
+        my $val = $self->{"parser"}->value("transition_state");
+        $self->error("Bad value for transtion_state: $val");
+    }
+    $bval;
+}
+
+sub frequencies {
+    my $self = shift;
+    my $bval = $self->{"parser"}->boolean_value("frequencies");
+    if ($bval eq "") {
+        my $val = $self->{"parser"}->value("frequencies");
+        $self->error("Bad value for frequencies: $val");
+    }
+    $bval;
+}
+
+sub axyz_lines {
+    my $self = shift;
+    $self->molecule()->string();
+}
+
+sub molecule() {
+    my $self = shift;
+    return $self->{"molecule"};
+}
+
+sub n_atom {
+    my $self = shift;
+    printf "QCInput: returning natom = %d\n", $self->{"natom"} if ($debug);
+    $self->molecule()->n_atom();
+}
+
+sub element {
+    my $self = shift;
+    $self->molecule()->element(@_);
+}
+
+sub position {
+    my $self = shift;
+    $self->molecule()->position(@_);
+}
+
+sub write_file {
+    my $self = shift;
+    my $file = shift;
+    my $parser = $self->{'parser'};
+    $parser->write_file($file);
+}
+
+sub mode_following() {
+    my $self = shift;
+    return scalar($self->{"parser"}->value_as_array("followed")) != 0;
+}
+
+# returns 1 if the input file existed
+sub ok {
+    my $self = shift;
+    $self->{"parser"}->{"ok"};
+}
+
+##########################################################################
+
+package InputWriter;
+
+# Input Writer is abstract
+sub new {
+    my $this = shift;
+    my $class = ref($this) || $this;
+    my $self = {};
+    bless $self, $class;
+    $self->initialize(@_);
+    return $self;
+}
+
+sub initialize() {
+    my $self = shift;
+    my $qcinput = shift;
+    $self->{"qcinput"} = $qcinput;
+}
+
+# this should be overridden
+sub input_string() {
+    "";
+}
+
+sub write_input() {
+    my $self = shift;
+    my $file = shift;
+    my $input = $self->input_string();
+    open(OUTPUT,">$file");
+    printf OUTPUT "%s", $input;
+    close(OUTPUT);
+}
+
+sub write_qcinput {
+    my $self = shift;
+    my $file = shift;
+    my $qcinput = $self->{'qcinput'};
+    $qcinput->write_file($file);
+}
+
+##########################################################################
+
+package MPQCInputWriter;
+@ISA = qw( InputWriter );
+%methodmap = ("MP2-R12/A" => "MBPT2_R12",
+              "MP2-R12/A'" => "MBPT2_R12",
+              "MP2" => "MBPT2",
+              "OPT1[2]" => "MBPT2",
+              "OPT2[2]" => "MBPT2",
+              "ZAPT2" => "MBPT2",
+              "MP2V1" => "MBPT2",
+              "OPT1[2]V1" => "MBPT2",
+              "OPT2[2]V1" => "MBPT2",
+              "ZAPT2V1" => "MBPT2",
+              "MP2V2" => "MBPT2",
+              "OPT1[2]V2" => "MBPT2",
+              "OPT2[2]V2" => "MBPT2",
+              "ZAPT2V2" => "MBPT2",
+              "MP2V2LB" => "MBPT2",
+              "OPT1[2]V2LB" => "MBPT2",
+              "OPT2[2]V2LB" => "MBPT2",
+              "ZAPT2V2LB" => "MBPT2",
+              "ROSCF" => "SCF",
+              "SCF" => "SCF",
+              "UHF" => "UHF",
+              "CLHF" => "CLHF",
+              "HSOSHF" => "HSOSHF",
+              "HF" => "SCF",
+              "HFK" => "DFT",
+              "XALPHA" => "DFT",
+              "HFS"    => "DFT",
+              "HFB"    => "DFT",
+              "HFG96"  => "DFT",
+              "BLYP"   => "DFT",
+              "B3LYP"  => "DFT",
+              "KMLYP"  => "DFT",
+              "B3PW91"  => "DFT",
+              "PBE"    => "DFT",
+              "PW91"    => "DFT",
+              "SPZ81"   => "DFT",
+              "B3P86"   => "DFT",
+              "BP86"    => "DFT",
+              "BPW91"   => "DFT",
+              "CLHFK" => "DFT",
+              "CLXALPHA" => "DFT",
+              "CLHFS"    => "DFT",
+              "CLHFB"    => "DFT",
+              "CLHFG96"  => "DFT",
+              "CLBLYP"   => "DFT",
+              "CLB3LYP"  => "DFT",
+              "CLKMLYP"  => "DFT",
+              "CLB3PW91"  => "DFT",
+              "CLPBE"    => "DFT",
+              "CLPW91"    => "DFT",
+              "SPZ81"   => "DFT",
+              "B3P86"   => "DFT",
+              "BP86"    => "DFT",
+              "BPW91"   => "DFT",
+              "HSOSHFK" => "DFT",
+              "HSOSXALPHA" => "DFT",
+              "HSOSHFS"    => "DFT",
+              "HSOSHFB"    => "DFT",
+              "HSOSHFG96"  => "DFT",
+              "HSOSBLYP"   => "DFT",
+              "HSOSB3LYP"  => "DFT",
+              "HSOSKMLYP"  => "DFT",
+              "HSOSB3PW91"  => "DFT",
+              "HSOSPBE"    => "DFT",
+              "HSOSPW91"    => "DFT",
+              "HSOSSPZ81"   => "DFT",
+              "HSOSB3P86"   => "DFT",
+              "HSOSBP86"    => "DFT",
+              "HSOSBPW91"   => "DFT",
+              "UHFK" => "DFT",
+              "UXALPHA" => "DFT",
+              "UHFS"    => "DFT",
+              "UHFB"    => "DFT",
+              "UHFG96"  => "DFT",
+              "UBLYP"   => "DFT",
+              "UB3LYP"  => "DFT",
+              "UKMLYP"  => "DFT",
+              "UB3PW91"  => "DFT",
+              "UPBE"    => "DFT",
+              "UPW91"    => "DFT",
+              "USPZ81"   => "DFT",
+              "UB3P86"   => "DFT",
+              "UBP86"    => "DFT",
+              "UBPW91"   => "DFT",
+             );
+%mbpt2r12stdapproxmap = ("MP2-R12/A" => "A",
+                         "MP2-R12/A'" => "A'",
+                         );
+%mbpt2map = ("MP2" => "mp",
+             "OPT1[2]" => "opt1",
+             "OPT2[2]" => "opt2",
+             "ZAPT2" => "zapt",
+             "MP2V1" => "mp",
+             "OPT1[2]V1" => "opt1",
+             "OPT2[2]V1" => "opt2",
+             "ZAPT2V1" => "zapt",
+             "MP2V2" => "mp",
+             "OPT1[2]V2" => "opt1",
+             "OPT2[2]V2" => "opt2",
+             "ZAPT2V2" => "zapt",
+             "MP2V2LB" => "mp",
+             "OPT1[2]V2LB" => "opt1",
+             "OPT2[2]V2LB" => "opt2",
+             "ZAPT2V2LB" => "zapt");
+%mbpt2algmap = ("MP2" => "",
+                "OPT1[2]" => "",
+                "OPT2[2]" => "",
+                "ZAPT2" => "",
+                "MP2V1" => "v1",
+                "OPT1[2]V1" => "v1",
+                "OPT2[2]V1" => "v1",
+                "ZAPT2V1" => "v1",
+                "MP2V2" => "v2",
+                "OPT1[2]V2" => "v2",
+                "OPT2[2]V2" => "v2",
+                "ZAPT2V2" => "v2",
+                "MP2V2LB" => "v2lb",
+                "OPT1[2]V2LB" => "v2lb",
+                "OPT2[2]V2LB" => "v2lb",
+                "ZAPT2V2LB" => "v2lb");
+$debug = 0;
+
+sub new {
+    my $this = shift;
+    my $class = ref($this) || $this;
+    my $self = {};
+    bless $self, $class;
+
+    $self->initialize(@_);
+    return $self;
+}
+
+sub initialize() {
+    my $self = shift;
+    my $qcinput = shift;
+    $self->{"qcinput"} = $qcinput;
+}
+
+sub docc_string() {
+    my $self = shift;
+    my $qcinput = $self->{"qcinput"};
+    my $occs = $qcinput->docc();
+    if ($occs eq "auto") { return ""; }
+    $occs =~ s/,/ /g;
+    "docc = [ $occs ]";
+}
+
+sub socc_string() {
+    my $self = shift;
+    my $qcinput = $self->{"qcinput"};
+    my $occs = $qcinput->socc();
+    if ($occs eq "auto") { return ""; }
+    $occs =~ s/,/ /g;
+    "socc = [ $occs ]";
+}
+
+sub input_string() {
+    my $self = shift;
+    my $qcinput = $self->{"qcinput"};
+    my $qcparse = $qcinput->{"parser"};
+
+    my $use_cints = 0;
+    my $do_cca = $qcparse->value("do_cca");
+
+    printf "molecule = %s\n", $qcparse->value("molecule") if ($debug);
+
+    my $symmetry = $qcinput->symmetry();
+    my $mol = "% molecule specification";
+    $mol = "$mol\nmolecule<Molecule>: (";
+    $symmetry = lc $symmetry if ($symmetry eq "AUTO");
+    if ($qcinput->frequencies()) {
+        $mol = "$mol\n  symmetry = C1";
+    }
+    else {
+        $mol = "$mol\n  symmetry = $symmetry";
+    }
+    $mol = "$mol\n  unit = angstrom";
+    $mol = "$mol\n  { atoms geometry } = {";
+    printf "MPQCInputWriter: natom = %d\n", $qcinput->n_atom() if ($debug);
+    my $i;
+    for ($i = 0; $i < $qcinput->n_atom(); $i++) {
+        $mol = sprintf "%s\n    %2s     [ %18.12f %18.12f %18.12f ]",
+                       $mol, $qcinput->element($i),
+                       $qcinput->position($i,0),
+                       $qcinput->position($i,1),
+                       $qcinput->position($i,2);
+    }
+    $mol = "$mol\n  }";
+    $mol = "$mol\n)\n";
+
+    my $basis = "% basis set specification";
+    $basis = "$basis\nbasis<GaussianBasisSet>: (";
+    $basis = sprintf "%s\n  name = \"%s\"", $basis, $qcinput->basis();
+    $basis = "$basis\n  molecule = \$:molecule";
+    $basis = "$basis\n)\n";
+
+    my $integrals = "";
+    if($do_cca) {
+      $integrals = "% using cca integrals";
+      $integrals = "$integrals\nintegrals<IntegralCCA>: (";
+      my $buffer_type = $qcparse->value("integral_buffer");
+      if( $buffer_type ne "opaque" && $buffer_type ne "array" ) {
+        $buffer_type = "opaque";
+      }     
+      my $int_package = $qcparse->value("integral_package");
+      if( $int_package ne "intv3" && $int_package ne "cints" ) {
+        $int_package = "intv3";
+      }
+      $integrals = "$integrals\n  integral_buffer = $buffer_type";
+      $integrals = "$integrals\n  integral_package = $int_package";
+      $integrals = "$integrals\n  evaluator_factory = MPQC.IntegralEvaluatorFactory";
+      $integrals = "$integrals\n  molecule = \$:molecule";
+      $integrals = "$integrals\n)\n";
+    }
+
+    my $fixed = $qcparse->value_as_arrayref("fixed");
+    my $followed = $qcparse->value_as_arrayref("followed");
+    if (scalar(@{$fixed}) != 0) {
+        $fixed = $self->mpqc_fixed_coor($fixed);
+    }
+    else {
+        $fixed = "";
+    }
+    if (scalar(@{$followed}) != 0) {
+        $followed = $self->mpqc_followed_coor($followed);
+    }
+    else {
+        $followed = "";
+    }
+
+    my $coor = "  % molecular coordinates for optimization";
+    $coor = "$coor\n  coor<SymmMolecularCoor>: (";
+    $coor = "$coor\n    molecule = \$:molecule";
+    $coor = "$coor\n    generator<IntCoorGen>: (";
+    $coor = "$coor\n      molecule = \$:molecule";
+    $coor = "$coor\n    )";
+    $coor = "$coor$followed";
+    $coor = "$coor$fixed";
+    $coor = "$coor\n  )\n";
+
+    my $charge = $qcinput->charge();
+    my $mult = $qcinput->mult();
+    my $docc = $self->docc_string();
+    my $socc = $self->socc_string();
+
+    my $grid = $qcinput->grid();
+
+    my $memory = $qcinput->memory();
+    my $inputmethod = $methodmap{uc($qcinput->method())};
+    my $method = "$inputmethod";
+    $method = "SCF" if ($method eq "");
+    my $openmethod = substr(uc($qcinput->method()),0,4);
+    if (substr($openmethod,0,2) eq "CL") { $openmethod = "CL"; }
+    if (substr($openmethod,0,1) eq "U") { $openmethod = "U"; }
+    if ($method eq "SCF") {
+        if ($openmethod eq "U") {
+            $method = "UHF";
+        }
+        elsif ($openmethod eq "CL") {
+            $method = "CLHF";
+        }
+        elsif ($openmethod eq "HSOS") {
+            $method = "HSOSHF";
+        }
+        elsif ($qcinput->mult() == 1) {
+            $method = "CLHF";
+            $openmethod = "CL";
+        }
+        else {
+            $method = "HSOSHF";
+            $openmethod = "HSOS";
+        }
+    }
+    my $functional;
+    if ($method eq "DFT") {
+        $functional = uc($qcinput->method());
+        if ($openmethod eq "U") {
+            $method = "UKS";
+            $functional = substr($functional,1);
+        }
+        elsif ($openmethod eq "CL") {
+            $method = "CLKS";
+            $functional = substr($functional,2);
+        }
+        elsif ($openmethod eq "HSOS") {
+            $method = "HSOSKS";
+            $functional = substr($functional,4);
+        }
+        elsif ($qcinput->mult() == 1) {
+            $method = "CLKS";
+            $openmethod = "CL";
+        }
+        else {
+            $method = "UKS";
+            $openmethod = "U";
+        }
+    }
+    my $orthog_method = $qcinput->orthog_method();
+    my $lindep_tol = $qcinput->lindep_tol();
+    my $mole = "  do_energy = yes";
+    if ($qcinput->gradient()) {
+        $mole = "$mole\n  do_gradient = yes";
+    }
+    else {
+        $mole = "$mole\n  do_gradient = no";
+    }
+    if($do_cca) {
+      $mole = "$mole\n  do_cca = yes";
+    }
+    $mole = "$mole\n  % method for computing the molecule's energy";
+    $mole = "$mole\n  mole<$method>: (";
+    $mole = "$mole\n    molecule = \$:molecule";
+    $mole = "$mole\n    basis = \$:basis";
+    $mole = "$mole\n    coor = \$..:coor";
+    $mole = "$mole\n    memory = $memory";
+    if($do_cca) {
+      $mole = "$mole\n    integrals = \$:integrals";
+    }
+    if ($inputmethod eq "SCF" || $inputmethod eq "UHF"
+        || $method eq "CLKS" || $method eq "UKS" || $method eq "HSOSKS") {
+        $mole = "$mole\n    total_charge = $charge";
+        $mole = "$mole\n    multiplicity = $mult";
+        $mole = "$mole\n    print_npa = yes";
+        if ($docc ne "") {$mole = "$mole\n    $docc";}
+        if ($socc ne "") {$mole = "$mole\n    $socc";}
+        if ($orthog_method ne "" ) {
+            $mole = "$mole\n    orthog_method = $orthog_method";
+        }
+        if ($lindep_tol ne "" ) {
+            $mole = "$mole\n    lindep_tol = $lindep_tol";
+        }
+    }
+    if ($method eq "CLKS" || $method eq "UKS" || $method eq "HSOSKS") {
+        $mole = "$mole\n    functional<StdDenFunctional>: name = \"$functional\"";
+    }
+    if (($method eq "CLKS" || $method eq "UKS" || $method eq "HSOSKS")
+        && $grid ne "default") {
+        $mole = "$mole\n    integrator<RadialAngularIntegrator>: (grid = $grid)";
+    }
+    if ($method eq "MBPT2_R12") {
+        my $stdapprox = $mbpt2r12stdapproxmap{uc($qcinput->method())};
+        my $auxbasis = $qcinput->auxbasis();
+        my $fzc = $qcinput->fzc();
+
+        $mole = sprintf "%s\n    stdapprox = \"%s\"", $mole, $stdapprox;
+        $mole = "$mole\n    integrals<IntegralCints>: ()";
+        $mole = "$mole\n    nfzc = $fzc";
+        # don't write an auxbasis if the auxbasis is the same as the basis set.
+        # this will speed up the calculation
+        if ("$auxbasis" ne "" && "$auxbasis" ne $qcinput->basis()) {
+            $mole = "$mole\n    aux_basis<GaussianBasisSet>: (";
+            $mole = sprintf "%s\n      name = \"%s\"", $mole, $auxbasis;
+            $mole = "$mole\n      molecule = \$:molecule";
+            $mole = "$mole\n    )\n";
+        }
+        $mole = append_reference($mole,"CLHF",$charge,$mult,$memory,$orthog_method,
+                                 $lindep_tol,$docc,$socc,"DZ (Dunning)");
+        $use_cints = 1;
+    }
+    elsif ($method eq "MBPT2") {
+        my $fzc = $qcinput->fzc();
+        my $fzv = $qcinput->fzv();
+        my $mbpt2method = $mbpt2map{uc($qcinput->method())};
+        my $mbpt2algorithm = $mbpt2algmap{uc($qcinput->method())};
+        $mole = "$mole\n    method = $mbpt2method";
+        if ($mbpt2algorithm ne "") {
+            $mole = "$mole\n    algorithm = $mbpt2algorithm";
+        }
+        $mole = "$mole\n    nfzc = $fzc";
+        $mole = "$mole\n    nfzv = $fzv";
+        my $refmethod = "";
+        if ($qcinput->mult() == 1) {
+            $refmethod = "CLHF";
+        }
+        else {
+            $refmethod = "HSOSHF";
+        }
+        $mole = append_reference($mole,$refmethod,$charge,$mult,$memory,$orthog_method,
+                                 $lindep_tol,$docc,$socc,"STO-3G");
+    }
+    elsif (! ($basis =~ /^STO/
+              || $basis =~ /^MI/
+              || $basis =~ /^\d-\d1G$/) && ! $do_cca ) {
+        my $guessmethod = "${openmethod}HF";
+        $mole = "$mole\n    guess_wavefunction<$guessmethod>: (";
+        $mole = "$mole\n      molecule = \$:molecule";
+        $mole = "$mole\n      total_charge = $charge";
+        $mole = "$mole\n      multiplicity = $mult";
+        if ($docc ne "") {$mole = "$mole\n      $docc";}
+        if ($socc ne "") {$mole = "$mole\n      $socc";}
+        $mole = "$mole\n      basis<GaussianBasisSet>: (";
+        $mole = "$mole\n        molecule = \$:molecule";
+        $mole = "$mole\n        name = \"STO-3G\"";
+        $mole = "$mole\n      )";
+        $mole = "$mole\n      memory = $memory";
+        if($do_cca) {
+          $mole = "$mole\n      integrals = \$:integrals";
+        }
+        $mole = "$mole\n    )";
+    }
+    if ($qcinput->frequencies()) {
+        $mole = "$mole\n    hessian<FinDispMolecularHessian>: (";
+        if ($symmetry ne "C1") {
+            $mole="$mole\n      point_group<PointGroup>: symmetry = $symmetry";
+        }
+        $mole = "$mole\n      checkpoint = no";
+        $mole = "$mole\n      restart = no";
+        $mole = "$mole\n    )";
+    }
+    $mole = "$mole\n  )\n";
+
+    my $opt;
+    if ($qcinput->optimize()) {
+        $opt = "  optimize = yes";
+    }
+    else {
+        $opt = "  optimize = no";
+    }
+    my $optclass, $updateclass;
+    if ($qcinput->transition_state()) {
+        $optclass = "EFCOpt";
+        $updateclass = "PowellUpdate";
+    }
+    else {
+        $optclass = "QNewtonOpt";
+        $updateclass = "BFGSUpdate";
+    }
+    $opt = "$opt\n  % optimizer object for the molecular geometry";
+    $opt = "$opt\n  opt<$optclass>: (";
+    $opt = "$opt\n    max_iterations = 20";
+    $opt = "$opt\n    function = \$..:mole";
+    if ($qcinput->transition_state()) {
+        $opt = "$opt\n    transition_state = yes";
+        if ($qcinput->mode_following()) {
+            $opt = "$opt\n    hessian = [ [ -0.1 ] ]";
+            $opt = "$opt\n    mode_following = yes";
+        }
+    }
+    $opt = "$opt\n    update<$updateclass>: ()";
+    $opt = "$opt\n    convergence<MolEnergyConvergence>: (";
+    $opt = "$opt\n      cartesian = yes";
+    $opt = "$opt\n      energy = \$..:..:mole";
+    $opt = "$opt\n    )";
+    $opt = "$opt\n  )\n";
+
+    my $freq = "";
+    if ($qcinput->frequencies()) {
+        $freq = "% vibrational frequency input";
+        $freq = "$freq\n  freq<MolecularFrequencies>: (";
+        if ($symmetry ne "C1") {
+            $freq = "$freq\n    point_group<PointGroup>: symmetry = $symmetry";
+        }
+        $freq = "$freq\n    molecule = \$:molecule";
+        $freq = "$freq\n  )\n";
+    }
+
+    my $mpqcstart = sprintf ("mpqc: (\n  checkpoint = %s\n",
+                             bool_to_yesno($qcinput->checkpoint()));
+    $mpqcstart = sprintf ("%s  savestate = %s\n",
+                          $mpqcstart,bool_to_yesno($qcinput->checkpoint()));
+    $mpqcstart = sprintf ("%s  restart = %s\n",
+                          $mpqcstart,bool_to_yesno($qcinput->restart()));
+    if ($use_cints) {
+        $mpqcstart = "$mpqcstart  integrals<IntegralCints>: ()\n";
+    }
+    my $mpqcstop = ")\n";
+    my $emacs = "% Emacs should use -*- KeyVal -*- mode\n";
+    my $warn = "% this file was automatically generated\n";
+    my $lab = $qcinput->label();
+    my $label = "";
+    if (! $lab =~ /^\s*$/) {
+        $label = "% label: $lab";
+        $label =~ s/\n/\n% label: /g;
+        $label = "$label\n";
+    }
+    "$emacs$warn$label$mol$basis$integrals$mpqcstart$coor$mole$opt$freq$mpqcstop";
+}
+
+sub mpqc_fixed_coor {
+    my $self = shift;
+    my $coorref = shift;
+    my $result = "";
+    $result = "\n    fixed<SetIntCoor>: [";
+    while (scalar(@{$coorref}) != 0) {
+        my $nextcoor = $self->mpqc_sum_coor("      ","",$coorref);
+        $result = "$result\n$nextcoor";
+    }
+    $result = "$result\n    ]";
+}
+
+sub mpqc_followed_coor {
+    my $self = shift;
+    my $coorref = shift;
+    sprintf "\n%s", $self->mpqc_sum_coor("    ","followed",$coorref);
+}
+
+sub mpqc_sum_coor {
+    my $self = shift;
+    my $space = shift;
+    my $name = shift;
+    my $coor = shift;
+    my $result = "$space$name<SumIntCoor>:(";
+    $result = "$result\n$space  coor: [";
+    my @coef = ();
+    do {
+        $coef[$ncoor] = shift @{$coor};
+        my $simple = $self->mpqc_coor($coor);
+        $result = "$result\n$space    $simple";
+        $ncoor = $ncoor + 1;
+    } while($coor->[0] eq "+" && shift @{$coor} eq "+");
+    $result = "$result\n$space  ]";
+    $result = "$result\n$space  coef = [";
+    my $i;
+    foreach $i (0..$#coef) {
+        $result = "$result $coef[$i]";
+    }
+    $result = "$result]";
+    $result = "$result\n$space)";
+    $result;
+}
+
+sub mpqc_coor {
+    my $self = shift;
+    my $coor = shift;
+    my $type = shift @{$coor};
+    if ($type eq "TORS") {
+        return sprintf "<TorsSimpleCo>:(atoms = [%d %d %d %d])",
+                       shift @{$coor},shift @{$coor},
+                       shift @{$coor},shift @{$coor};
+    }
+    if ($type eq "BEND") {
+        return sprintf "<BendSimpleCo>:(atoms = [%d %d %d])",
+                       shift @{$coor},shift @{$coor},
+                       shift @{$coor};
+    }
+    if ($type eq "STRE") {
+        return sprintf "<StreSimpleCo>:(atoms = [%d %d])",
+                        shift @{$coor},shift @{$coor};
+    }
+}
+
+sub bool_to_yesno {
+    if (shift) { return "yes"; }
+    else { return "no"; }
+}
+
+sub append_reference {
+    my $mole = shift;
+    my $refmethod = shift;
+    my $charge = shift;
+    my $mult = shift;
+    my $memory = shift;
+    my $orthog_method = shift;
+    my $lindep_tol = shift;
+    my $docc = shift;
+    my $socc = shift;
+    my $guessbasis = shift;
+    $mole = "$mole\n    reference<$refmethod>: (";
+    $mole = "$mole\n      molecule = \$:molecule";
+    $mole = "$mole\n      basis = \$:basis";
+    $mole = "$mole\n      total_charge = $charge";
+    $mole = "$mole\n      multiplicity = $mult";
+    $mole = "$mole\n      memory = $memory";
+    if ($orthog_method ne "" ) {
+        $mole = "$mole\n      orthog_method = $orthog_method";
+    }
+    if ($lindep_tol ne "" ) {
+        $mole = "$mole\n      lindep_tol = $lindep_tol";
+    }
+    if ($docc ne "") {$mole = "$mole\n      $docc";}
+    if ($socc ne "") {$mole = "$mole\n      $socc";}
+    if (! ($basis =~ /^STO/
+           || $basis =~ /^MI/
+           || $basis =~ /^\d-\d1G$/)) {
+        $mole = "$mole\n      guess_wavefunction<$refmethod>: (";
+        $mole = "$mole\n        molecule = \$:molecule";
+        $mole = "$mole\n        total_charge = $charge";
+        $mole = "$mole\n        multiplicity = $mult";
+        if ($docc ne "") {$mole = "$mole\n        $docc";}
+        if ($socc ne "") {$mole = "$mole\n        $socc";}
+        $mole = "$mole\n        basis<GaussianBasisSet>: (";
+        $mole = "$mole\n          molecule = \$:molecule";
+        $mole = "$mole\n          name = \"$guessbasis\"";
+        $mole = "$mole\n        )";
+        $mole = "$mole\n        memory = $memory";
+        $mole = "$mole\n      )";
+    }
+    $mole = "$mole\n    )";
+    return $mole;
+}
+
+1;
+
