Chemistry-Harmonia

 view release on metacpan or  search on metacpan

lib/Chemistry/Harmonia.pm  view on Meta::CPAN

	    }
	}

	if( $balance_A ){
	    return if $no_ion;
	}else{
	    return $prop;
	}
	delete $prop->{$_}{'OS'} for keys %$prop;
    }
}

# Read Pauling electronegativity and OSE
# only for given elements of substance
# input:
#	%atoms -- elements
# return:
#	%atom_el_neg
#	%atom_OS
#	$intermet

sub _read_atoms{
    my $atoms = shift;

    my %atom_el_neg;	# atom electronegativity
    my %atom_OS;	# oxidation state
    my $intermet = 1;	# for intermetallic compound

    my $adb = &_atoms_db;

    for( my $i = 0; $i < @$adb; $i+=5 ){
	$_ = $adb->[$i];
	next if !exists $atoms->{ $_ };

	$atom_el_neg{ $_ } = $adb->[$i+2];
	$intermet = 0 unless $adb->[$i+3];	# Not intermetallic compound
	$atom_OS{ $_ } = $adb->[$i+4];
    }

    \%atom_el_neg, \%atom_OS, $intermet;
}

# Read necessary ion-group
# input:
#	$Chemistry_substance
# return:
#	$ions
sub _read_ions {
    my $chem_sub = shift;
    my %ions;

    my $idb = &_ions_db;

    # Construct pattern
    for( my $j = 0; $j < @$idb; $j+=2 ){
	my $frm = $idb->[$j];
	my $os = $idb->[$j+1];

	my %a = split /_|=/,$os; # Parse to element end OSE

	if($os =~ /~/){ # Macro-substitutions

	    my %ek;
	    my $max_n_ek = 0; # max number of element-pattern in macro-substitutions

	    while( my($e, $v) = each %a ){

		if($e =~ /(\w+~)(.*)/){
		    $ek{$1}[0] = [ split ',',$2 ]; # elements
		    $ek{$1}[1] = $v; # OSE for group

		    my $n_ek = $#{ $ek{$1}[0] }; # number of element-substitutions
		    $max_n_ek = $n_ek if $n_ek > $max_n_ek; # max list
		}
	    }

	    my $iter = variations_with_repetition( [ (0..$max_n_ek) ], scalar( keys %ek ) );
ELEMENT_MACRO_1:
	    while (my $p = $iter->next) {
		my $m = $frm; # macro-formula (mask)
		my $i = 0;
		for my $em (sort keys %ek){
		    my $e = $ek{ $em }[0][ $p->[$i++] ];	# element
		    next ELEMENT_MACRO_1 unless defined $e; # pattern have ended

		    $m =~ s/$em/$e/g; # Construct ion mask
		}

		next unless $chem_sub =~ /($m)/; # Ions in substance aren't present

		my $l = length($1); # Length of ion mask

		$i = 0;
		for my $em (sort keys %ek){
		    my $e = $ek{ $em }[0][ $p->[$i++] ]; # element

		    for my $z ( split /!/, $ek{ $em }[1] ){
			# list OSE
			push @{ $ions{ $e }{ $l }{ $m } }, [ split /;/,$z ];
		    }
		}

		while(my ($e, $v) = each %a ){
		    next if $e =~ /~/;

		    # list OSE
		    for my $z ( split /!/, $v ){
			push @{ $ions{ $e }{ $l }{ $m } }, [ split /;/,$z ];
		    }
		}
	    }

	}else{
	    next unless $chem_sub =~ /($frm)/; # no ions in substance

	    my $l = length($1); # Length of the found group

	    while(my ($e, $v) = each %a ){
		# list OSE
		for my $z ( split /!/, $v ){
		    push @{ $ions{ $e }{ $l }{ $frm } }, [ split /;/,$z ];



( run in 1.068 second using v1.01-cache-2.11-cpan-364913b4093 )