package Chemistry::ESPT::ESSfile; use strict; use warnings; =head1 NAME Chemistry::ESPT::ESSfile - Generic Electronic Structure Suite (ESS) file object. =head1 SYNOPSIS package Chemistry::ESPT::MyFile; use base qw(Chemistry::ESPT::ESSfile); package Main; my $object = Chemistry::ESPT::MyFile->new(); $object->prepare(filename); =head1 DESCRIPTION This module is the base class for all of the Electronic Structure Perl Toolkit (ESPT) ESS file objects. It provides the generic attributes, methods, and subroutines common to all ESPT file objects. =cut our $VERSION = '0.03'; =begin comment ### Version History ### 0.01 consolidate common properties & methods 0.02 moved to ESPT namespace, Time property 0.03 generalized get method for Rank N tensors, added CHARGE, ### To Do ### - Move ENERGY & EINFO attributes here - Move TIME into its own method that automatically handles time addition =end comment =head1 ATTRIBUTES All attributes are currently read-only and get populated by reading the assigned ESS file. Attribute values are accessible through the B method unless otherwise noted. =over 10 =item ALPHA Total number of alpha electrons. =item ATOMS Array of atoms stored as atomic symbols. Array length equals NATOMS. =item BASIS String containing the basis set employed in the calculation. =item BETA Total number of beta electrons. =item CHARGE Total molecular charge. =item COMPLETE Flag indicating ESS job completion (1). Defaults to 0. =item DEBUG Debug flag enabling or disabling (0) verbose output. Useful when writing new code. Defaults to 0. Accessible via the B method. =item EINFO Text description of the energy contained in ENERGY. =item ENERGY Total energy as described by EINFO. =item FILENAME Full name of the file, including path if passed, assigned to the object. =item JOBTYPE ESS job type stored as capitalized keyword(s). Current keywords are: =back =over 10 =over 5 =over 10 =item SP Single Point =item OPT Optimization =item OPT FREQ Optimization & Frequency =item OPT SP Optimization & Single Point =item FREQ Frequency =back =back =back =over 10 =item MULTIPLICITY Molecular spin multiplicity, 2S+1. =item NATOMS Total number of atoms. =item NBASIS Total number of basis functions in the basis set. =item PROGRAM Full name of the ESS program =item SPIN Type of electrons, Alpha or Beta, to analyse. =item THEORY Theory level used in the calculation. =item TITLE ESS job title. =item TIME Total time for all calculations perfomed in the ESS file. Stored as an array with four elements, [days, hours, minutes, seconds]. =item TYPE File type. This usually equal to the file's extension such as log, out, fchk, etc. =back =head1 METHODS Method parameters denoted in [ ] are optional. =over 15 =item B<$object-Enew()> Creates a new ESSfile object. =cut ## the object constructor ** sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $ESSfile = {}; # Generating ESS $ESSfile->{PROGRAM} = undef; # File type (log, out, fchk, etc.) $ESSfile->{TYPE} = undef; # Analysis info $ESSfile->{DEBUG} = 0; $ESSfile->{FILENAME} = undef; $ESSfile->{SPIN} = undef; # Calculation info $ESSfile->{BASIS} = undef; $ESSfile->{CHARGE} = undef; # total molecular charge $ESSfile->{COMPLETE} = 0; # flag indicating job completion $ESSfile->{EINFO} = undef; # string description of ENERGY $ESSfile->{ENERGY} = undef; # total energy $ESSfile->{JOBTYPE} = undef; # type of calculation performed $ESSfile->{MULTIPLICITY} = undef; # 2S+1 $ESSfile->{NBASIS} = undef; $ESSfile->{THEORY} = undef; $ESSfile->{TIME} = [ 0, 0, 0, 0 ]; # Total computation time in days [0], hours [1], minutes [2], seconds [3] $ESSfile->{TITLE} = undef; # Molecular info $ESSfile->{ALPHA} = undef; $ESSfile->{ATOMS} = undef; $ESSfile->{BETA} = undef; $ESSfile->{NATOMS} = undef; bless($ESSfile, $class); return $ESSfile; } ### Methods ### =item B<$object-Eprepare(filename [spin])> Set FILENAME, and SPIN. SPIN defaults to Alpha. =cut # set filename, spin, & debug options sub prepare : method { my $ESSfile = shift; $ESSfile->{FILENAME} = shift; $ESSfile->{SPIN} = shift; $ESSfile->{SPIN} ||= "Alpha"; return; } =item B<$object-Eatomconvert(atom)> Convert atomic symbols to atomic numbers and vice versa. Atom must be a valid atomic symbol or number. =cut # Convert atomic numbers to atomic symbols sub atomconvert : method { shift; # remove object reference my (@num2sym, %sym2num); #populate atomic symbols @num2sym = ("H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne"); push @num2sym, ("Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar"); push @num2sym, ("K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr"); push @num2sym, ("Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe"); push @num2sym, ("Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu"); push @num2sym, ("Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn"); push @num2sym, ("Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr"); push @num2sym, ("Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Uub", "Uut", "Uuq", "Uup"); for (my $i=0; $idebug([debuglevel])> Set or retrieve the DEBUG attribute. Passing a debuglevel equal to 1 enables standard debug printing. Verbose debug printing can be enabled by passing integers greater than one. =cut sub debug : method { my $ESSfile = shift; my $debug = shift; if (defined $debug && $debug =~ /\d+/ ) { $ESSfile->{DEBUG} = $debug; return; } else { return $ESSfile->{DEBUG}; } } =item B<$object-Eget(attribute [index1] [index2] ... [indexN])> Get attribute data stored in an N dimensional tensor. If the tensor indicies are not passed, then the last value for that attribute will be passesd. If a requested attribute is not present, then a null string is returned. If the requested datum is not present then undef will be returned as a string. =cut # retrieve values. for array data the last element is returned # unless otherwise requested sub get : method { my $ESSfile = shift; # required parameters : value my $value = shift; print "Get method called for ", $value, "\n" if $ESSfile->{DEBUG} >= 4; # optional parameters : index values my @index = @_; # warn if requested property is not coded & return empty string my $valid = 0; foreach my $p ( keys %$ESSfile ) { if ( $value eq $p ) { $valid = 1; last; } elsif ( $value eq "DEBUG" ) { $valid = 2; last; } } if ( $valid == 0 ) { warn "Requested property, $value, is not currently coded.\n$!\n" if $ESSfile->{DEBUG} == 1; return ""; } elsif ( $valid ==2 ) { warn "Please use the debug() method to access the DEBUG attribute.\n$!\n"; return ""; } # build hard reference my $reference = \$ESSfile->{$value}; # undef if no scalar value is present return "undef" unless ( defined $ESSfile->{$value} ); # check for multidimensional array in a nested # manner to avoid autovivification problems. my $i =0; while ( ref $$reference eq "ARRAY" ) { # get array length $index [$i] ||= scalar(@{$$reference}) - 1 unless ( defined $index[$i] ); return "undef" unless ( defined @{$$reference} [$index[$i]] ); # update reference $reference = \@{$$reference} [$index[$i]]; return $$reference unless ( ref $$reference eq "ARRAY" ); $i++; } # scalar values return $$reference; } =item B<$object-EMOdecoder(MO)> Return the molecular orbital number for the requested MO. MO may be HOMO, LUMO or SHOMO. =cut # decode homo, shomo & lumo # correct for arrays starting with 0 sub MOdecoder : method { my $ESSfile = shift; my $MO = lc(shift); if ($MO eq "homo") { return $ESSfile->{HOMO} - 1; } elsif ($MO eq "lumo") { return $ESSfile->{HOMO}; } elsif ($MO eq "shomo") { return $ESSfile->{HOMO} - 2; } else { return $MO - 1; } } ### Utilities ### sub printattributes : method { # print out object attributes my $ESSfile = shift; foreach my $p ( sort keys %$ESSfile ) { print "$p\n"; } } 1; __END__ =back =head1 VERSION 0.03 =head1 AUTHOR Dr. Jason L. Sonnenberg, Esonnenberg.11@osu.eduE =head1 COPYRIGHT Copyright 2008 by Dr. Jason L. Sonnenberg This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. I would like to hear of any suggestions for improvement. =cut