Molar weight calculator
ChrLie
//EDIT: 2/23/16; optimised function "ElementCount"
// The function molwt(str) returns the molar weight of a chemical formula specified by "str", e.g. molwt("H2O") returns 18.0148 (in grams per mole).
// The function is case-sensitive, e.g. molwt("h2o") will not return what you expect.
// The function ElementCount(input) returns a list of elements and their abundance, e.g. ElementCount("H2O") returns "H;2;O;1;"
// The element abundance in the input string MUST be a positive integer
function molwt(str)
string str
variable mw
variable AN
variable weight
variable n
variable i
string List = ElementCount(str)
string Element =""
//initialise elements and atomic weights: list index equals atomic number
string el=""
el += ";H;He;Li;Be;B;C;N;O;F;Ne;Na;Mg;Al;Si;P;S;Cl;Ar;"
el += "K;Ca;Sc;Ti;V;Cr;Mn;Fe;Co;Ni;Cu;Zn;Ga;Ge;As;Se;Br;Kr;"
el += "Rb;Sr;Y;Zr;Nb;Mo;Tc;Ru;Rh;Pd;Ag;Cd;In;Sn;Sb;Te;I;Xe;"
el += "Cs;Ba;La;Ce;Pr;Nd;Pm;Sm;Eu;Gd;Tb;Dy;Ho;Er;Tm;Yb;Lu;"
el += "Hf;Ta;W;Re;Os;Ir;Pt;Au;Hg;Tl;Pb;Bi;Po;At;Rn;"
el += "Fr;Ra;Ac;Th;Pa;U;Np;Pu;"
string aw=""
aw+=";1.0079;4.0026;6.941;9.0122;10.811;12.011;14.007;15.999;18.998;20.18;22.99;24.305;26.982;28.085;30.974;32.065;35.453;39.948;"
aw+="39.098;40.078;44.956;47.867;50.941;51.996;54.938;55.845;58.933;58.693;63.546;65.409;69.723;72.64;74.922;78.96;79.904;83.798;"
aw+="85.468;87.62;88.906;91.224;92.906;95.94;98.906;101.07;102.91;106.42;107.87;112.41;114.82;118.71;121.76;127.6;126.9;131.29;"
aw+="132.91;137.33;138.91;140.12;140.91;144.24;146.92;150.36;151.96;157.25;158.93;162.5;164.93;167.26;168.93;173.04;174.97;"
aw+="178.49;180.95;183.84;186.21;190.23;192.22;195.08;196.97;200.59;204.38;207.2;208.98;208.98;209.99;222.02;223.02;"
aw+="226.03;227.03;232.04;231.04;238.03;237.05;244.06;"
do
Element = StringFromList(i, List)
if ( strlen(Element) == 0)
break
endif
AN = WhichListItem(Element, el)
weight = str2num(StringFromList(AN, aw))
n = str2num(StringFromList(i+1, List))
mw += (n * weight)
i+=2
while(1)
return mw
end
function/S ElementCount(input) // analyses input string for elements and number of elements
String input
string list = ""
variable i
variable TheEnd = StrLen(input)
for(i=0;i<TheEnd; i+=1)
// consider cases where string item is a letter and upper case
if (GrepString( input[i], "[[:alpha:]]") && GrepString(input[i], "[[:upper:]]") )
list += input[i]
// is it a two character element, e.g. Fe instead of F?
if (GrepString(input[i+1], "[[:alpha:]]") && GrepString(input[i+1], "[[:lower:]]") )
list += input[i+1]
i+=1
endif
//this element is covered
list +=";"
// test if next list item is numeric or string; if it is string, then the present element has a count of 1, add this to list ....
// ...or check if i+1 is the last entry
if (GrepString(input[i+1], "[[:alpha:]]") || i+1 == TheEnd)
list += "1;"
endif
// we are done
continue
endif
// consider cases where string item is a number
if (GrepString(input[i], "[[:digit:]]") )
list +=input[i]
// is there more than one numeric character?
do
if (GrepString(input[i+1] "[[:digit:]]"))
list += input[i+1]
i+=1
else
break
endif
while(1)
List +=";"
endif
endfor
return list
end
// The function molwt(str) returns the molar weight of a chemical formula specified by "str", e.g. molwt("H2O") returns 18.0148 (in grams per mole).
// The function is case-sensitive, e.g. molwt("h2o") will not return what you expect.
// The function ElementCount(input) returns a list of elements and their abundance, e.g. ElementCount("H2O") returns "H;2;O;1;"
// The element abundance in the input string MUST be a positive integer
function molwt(str)
string str
variable mw
variable AN
variable weight
variable n
variable i
string List = ElementCount(str)
string Element =""
//initialise elements and atomic weights: list index equals atomic number
string el=""
el += ";H;He;Li;Be;B;C;N;O;F;Ne;Na;Mg;Al;Si;P;S;Cl;Ar;"
el += "K;Ca;Sc;Ti;V;Cr;Mn;Fe;Co;Ni;Cu;Zn;Ga;Ge;As;Se;Br;Kr;"
el += "Rb;Sr;Y;Zr;Nb;Mo;Tc;Ru;Rh;Pd;Ag;Cd;In;Sn;Sb;Te;I;Xe;"
el += "Cs;Ba;La;Ce;Pr;Nd;Pm;Sm;Eu;Gd;Tb;Dy;Ho;Er;Tm;Yb;Lu;"
el += "Hf;Ta;W;Re;Os;Ir;Pt;Au;Hg;Tl;Pb;Bi;Po;At;Rn;"
el += "Fr;Ra;Ac;Th;Pa;U;Np;Pu;"
string aw=""
aw+=";1.0079;4.0026;6.941;9.0122;10.811;12.011;14.007;15.999;18.998;20.18;22.99;24.305;26.982;28.085;30.974;32.065;35.453;39.948;"
aw+="39.098;40.078;44.956;47.867;50.941;51.996;54.938;55.845;58.933;58.693;63.546;65.409;69.723;72.64;74.922;78.96;79.904;83.798;"
aw+="85.468;87.62;88.906;91.224;92.906;95.94;98.906;101.07;102.91;106.42;107.87;112.41;114.82;118.71;121.76;127.6;126.9;131.29;"
aw+="132.91;137.33;138.91;140.12;140.91;144.24;146.92;150.36;151.96;157.25;158.93;162.5;164.93;167.26;168.93;173.04;174.97;"
aw+="178.49;180.95;183.84;186.21;190.23;192.22;195.08;196.97;200.59;204.38;207.2;208.98;208.98;209.99;222.02;223.02;"
aw+="226.03;227.03;232.04;231.04;238.03;237.05;244.06;"
do
Element = StringFromList(i, List)
if ( strlen(Element) == 0)
break
endif
AN = WhichListItem(Element, el)
weight = str2num(StringFromList(AN, aw))
n = str2num(StringFromList(i+1, List))
mw += (n * weight)
i+=2
while(1)
return mw
end
function/S ElementCount(input) // analyses input string for elements and number of elements
String input
string list = ""
variable i
variable TheEnd = StrLen(input)
for(i=0;i<TheEnd; i+=1)
// consider cases where string item is a letter and upper case
if (GrepString( input[i], "[[:alpha:]]") && GrepString(input[i], "[[:upper:]]") )
list += input[i]
// is it a two character element, e.g. Fe instead of F?
if (GrepString(input[i+1], "[[:alpha:]]") && GrepString(input[i+1], "[[:lower:]]") )
list += input[i+1]
i+=1
endif
//this element is covered
list +=";"
// test if next list item is numeric or string; if it is string, then the present element has a count of 1, add this to list ....
// ...or check if i+1 is the last entry
if (GrepString(input[i+1], "[[:alpha:]]") || i+1 == TheEnd)
list += "1;"
endif
// we are done
continue
endif
// consider cases where string item is a number
if (GrepString(input[i], "[[:digit:]]") )
list +=input[i]
// is there more than one numeric character?
do
if (GrepString(input[i+1] "[[:digit:]]"))
list += input[i+1]
i+=1
else
break
endif
while(1)
List +=";"
endif
endfor
return list
end
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
I have one of these too. Not tested for typos etc, so caveat emptor!
Edit: I removed the code and added a link to the molar mass calculator project below.
June 22, 2016 at 09:19 am - Permalink
Building on ChrLie's and Tony's code, I slightly enhanced the ElementCount function to deal with non-integer Stoichiometry and only parse actual element names
//works with non-integer stoichiometry
String input
string list = ""
variable i,ii
string dum
make /free /n=0 /T Elem
Elem = {"H","He","Li","Be","B","C","N","O","F","Ne"}
Elem[10] = {"Na","Mg","Al","Si","P","S","Cl","Ar","K","Ca"}
Elem[20] = {"Sc","Ti","V","Cr","Mn","Fe","Co","Ni","Cu","Zn"}
Elem[30] = {"Ga","Ge","As","Se","Br","Kr","Rb","Sr","Y","Zr"}
Elem[40] = {"Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn"}
Elem[50] = {"Sb","Te","I","Xe","Cs","Ba","La","Ce","Pr","Nd"}
Elem[60] = {"Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm","Yb"}
Elem[70] = {"Lu","Hf","Ta","W","Re","Os","Ir","Pt","Au","Hg"}
Elem[80] = {"Tl","Pb","Bi","Po","At","Rn","Fr","Ra","Ac","Th"}
Elem[90] = {"Pa","U","Np","Pu","Am","Cm","Bk","Cf","Es","Fm"}
Elem[100] = {"Md","No","Lr","Rf","Db","Sg","Bh","Hs","Mt","Ds"}
Elem[110] = {"Rg","Cn","Uut","Fl","Uup","Lv","Uus","Uuo"}
variable TheEnd = StrLen(input)
for(i=0;i<TheEnd; i+=1)
// consider cases where string item is a letter and upper case
if (GrepString( input[i], "[[:alpha:]]") && GrepString(input[i], "[[:upper:]]") )
list += input[i]
// is it a two character element, e.g. Fe instead of F?
if (GrepString(input[i+1], "[[:alpha:]]") && GrepString(input[i+1], "[[:lower:]]") )
list += input[i+1]
i+=1
endif
//this element is covered
list +=";"
// test if next list item is numeric or string; if it is string, then the present element has a count of 1, add this to list ....
// ...or check if i+1 is the last entry
if (GrepString(input[i+1], "[[:alpha:]]") || i+1 == TheEnd)
list += "1;"
FindValue /TEXT=StringFromList(itemsinList(list)-2,list)/TXOP=7 /Z Elem
if (v_value==-1)
list="" ; i=TheEnd ;Print "Could not resolve Chemical Formula";beep;beep;dowindow/h
endif
endif
continue
endif
if( grepstring(input[i],"[0-9]") )
dum=""
do
if( grepstring(input[i],"[0-9\.]"))
dum+=input[i]
i+=1
else
break
endif
while(i<strlen(input))
i-=1;
list += dum+";"
else
list+=";"
endif
endfor
return list
end
October 25, 2021 at 06:19 pm - Permalink
My version was later released as a project, here. I believe it deals with both non-integer values and parentheses properly, and only accepts valid elements.
147.001
October 26, 2021 at 12:24 am - Permalink
In reply to My version was later… by tony
Thanks Tony, indeed your molWt function works very nicely. However here i was interested in extracting the chemical composition...
October 26, 2021 at 06:51 am - Permalink
I see. You might consider using a key list, then you can use NumberByKey to get the element count.
Execute DisplayHelpTopic "NumberByKey" for more info.
October 26, 2021 at 10:01 am - Permalink