<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <atom:link href="http://kitchingroup.cheme.cmu.edu/blog/feed/index.xml" rel="self" type="application/rss+xml" />
    <title>The Kitchin Research Group</title>
    <link>https://kitchingroup.cheme.cmu.edu/blog</link>
    <description>Chemical Engineering at Carnegie Mellon University</description>
    <pubDate>Sat, 01 Nov 2025 13:47:46 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    
    <item>
      <title>Reading in delimited text files</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2013/02/27/Reading-in-delimited-text-files</link>
      <pubDate>Wed, 27 Feb 2013 14:42:19 EST</pubDate>
      <category><![CDATA[io]]></category>
      <guid isPermaLink="false">ysgf-sKnPd04dKWwZJiVFoDNAr0=</guid>
      <description>Reading in delimited text files</description>
      <content:encoded><![CDATA[


&lt;p&gt;
&lt;a href="http://matlab.cheme.cmu.edu/2011/08/07/reading-in-delimited-text-files/" &gt;Matlab post&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
sometimes you will get data in a delimited text file format, .e.g. separated by commas or tabs. Matlab can read these in easily. Suppose we have a file containing this data:
&lt;/p&gt;

&lt;pre class="example"&gt;
1   3
3   4
5   6
4   8
&lt;/pre&gt;

&lt;p&gt;
It is easy to read this directly into variables like this:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np

x,y = np.loadtxt(&lt;span style="color: #228b22;"&gt;'data/testdata.txt'&lt;/span&gt;, unpack=&lt;span style="color: #8b0000;"&gt;True&lt;/span&gt;)

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; x,y
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[ 1.  3.  5.  4.] [ 3.  4.  6.  8.]
&lt;/pre&gt;
&lt;p&gt;Copyright (C) 2013 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2013/02/27/Reading-in-delimited-text-files.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;]]></content:encoded>
    </item>
    <item>
      <title>Reading parameter database text files in python</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2013/02/27/Reading-parameter-database-text-files-in-python</link>
      <pubDate>Wed, 27 Feb 2013 10:52:22 EST</pubDate>
      <category><![CDATA[io]]></category>
      <guid isPermaLink="false">n66LCHdthWBW60A44kRyS5yJa3w=</guid>
      <description>Reading parameter database text files in python</description>
      <content:encoded><![CDATA[


&lt;p&gt;
&lt;a href="http://matlab.cheme.cmu.edu/2011/09/10/reading-parameter-database-text-files-in-matlab/" &gt;Matlab post&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
The datafile at &lt;a href="http://terpconnect.umd.edu/~nsw/ench250/antoine.dat" &gt;http://terpconnect.umd.edu/~nsw/ench250/antoine.dat&lt;/a&gt; (dead link) contains data that can be used to estimate the vapor pressure of about 700 pure compounds using the Antoine equation
&lt;/p&gt;

&lt;p&gt;
The data file has the following contents:
&lt;/p&gt;

&lt;pre class="example"&gt;
Antoine Coefficients
  log(P) = A-B/(T+C) where P is in mmHg and T is in Celsius
Source of data: Yaws and Yang (Yaws, C.  L.  and Yang, H.  C.,
"To estimate vapor pressure easily. antoine coefficients relate vapor pressure to temperature for almost 700 major organic compounds", Hydrocarbon Processing, 68(10), p65-68, 1989.

ID  formula  compound name                  A       B       C     Tmin Tmax ??    ?
-----------------------------------------------------------------------------------
  1 CCL4     carbon-tetrachloride        6.89410 1219.580 227.170  -20  101 Y2    0
  2 CCL3F    trichlorofluoromethane      6.88430 1043.010 236.860  -33   27 Y2    0
  3 CCL2F2   dichlorodifluoromethane     6.68619  782.072 235.377 -119  -30 Y6    0
&lt;/pre&gt;

&lt;p&gt;
To use this data, you find the line that has the compound you want, and read off the data. You could do that manually for each component you want but that is tedious, and error prone. Today we will see how to retrieve the file, then read the data into python to create a database we can use to store and retrieve the data.
&lt;/p&gt;

&lt;p&gt;
We will use the data to find the temperature at which the vapor pressure of acetone is 400 mmHg. 
&lt;/p&gt;

&lt;p&gt;
We use numpy.loadtxt to read the file, and tell the function the format of each column. This creates a special kind of record array which we can access data by field name.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np
&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; matplotlib.pyplot &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; plt

data = np.loadtxt(&lt;span style="color: #228b22;"&gt;'data/antoine_data.dat'&lt;/span&gt;,
                  dtype=[(&lt;span style="color: #228b22;"&gt;'id'&lt;/span&gt;, np.int),
                         (&lt;span style="color: #228b22;"&gt;'formula'&lt;/span&gt;, &lt;span style="color: #228b22;"&gt;'S8'&lt;/span&gt;),
                         (&lt;span style="color: #228b22;"&gt;'name'&lt;/span&gt;, &lt;span style="color: #228b22;"&gt;'S28'&lt;/span&gt;),
                         (&lt;span style="color: #228b22;"&gt;'A'&lt;/span&gt;, np.float),
                         (&lt;span style="color: #228b22;"&gt;'B'&lt;/span&gt;, np.float),
                         (&lt;span style="color: #228b22;"&gt;'C'&lt;/span&gt;, np.float),
                         (&lt;span style="color: #228b22;"&gt;'Tmin'&lt;/span&gt;, np.float),
                         (&lt;span style="color: #228b22;"&gt;'Tmax'&lt;/span&gt;, np.float),
                         (&lt;span style="color: #228b22;"&gt;'??'&lt;/span&gt;, &lt;span style="color: #228b22;"&gt;'S4'&lt;/span&gt;),
                         (&lt;span style="color: #228b22;"&gt;'?'&lt;/span&gt;, &lt;span style="color: #228b22;"&gt;'S4'&lt;/span&gt;)],
                  skiprows=7)

names = data[&lt;span style="color: #228b22;"&gt;'name'&lt;/span&gt;]

acetone, = data[names == &lt;span style="color: #228b22;"&gt;'acetone'&lt;/span&gt;]

&lt;span style="color: #ff0000; font-weight: bold;"&gt;# for readability we unpack the array into variables&lt;/span&gt;
id, formula, name, A, B, C, Tmin, Tmax, u1, u2 = acetone

T = np.linspace(Tmin, Tmax)
P = 10**(A - B / ( T + C))
plt.plot(T, P)
plt.xlabel(&lt;span style="color: #228b22;"&gt;'T ($^\circ$C)'&lt;/span&gt;)
plt.ylabel(&lt;span style="color: #228b22;"&gt;'P$_{vap}$ (mmHg)'&lt;/span&gt;)

&lt;span style="color: #ff0000; font-weight: bold;"&gt;# Find T at which Pvap = 400 mmHg&lt;/span&gt;
&lt;span style="color: #ff0000; font-weight: bold;"&gt;# from our graph we might guess T ~ 40 ^{\circ}C&lt;/span&gt;

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;objective&lt;/span&gt;(T):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; 400 - 10**(A - B / (T + C))

&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.optimize &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; fsolve
Tsol, = fsolve(objective, 40)
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; Tsol
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'The vapor pressure is 400 mmHg at T = {0:1.1f} degC'&lt;/span&gt;.format(Tsol)

&lt;span style="color: #ff0000; font-weight: bold;"&gt;#Plot CRC data http://en.wikipedia.org/wiki/Acetone_%28data_page%29#Vapor_pressure_of_liquid&lt;/span&gt;
&lt;span style="color: #ff0000; font-weight: bold;"&gt;# We only include the data for the range where the Antoine fit is valid.&lt;/span&gt;

Tcrc  = [-59.4,         -31.1,  -9.4,   7.7,    39.5,   56.5]
Pcrc = [        1,      10,     40,     100,    400,    760]

plt.plot(Tcrc, Pcrc, &lt;span style="color: #228b22;"&gt;'bo'&lt;/span&gt;)
plt.legend([&lt;span style="color: #228b22;"&gt;'Antoine'&lt;/span&gt;,&lt;span style="color: #228b22;"&gt;'CRC Handbook'&lt;/span&gt;], loc=&lt;span style="color: #228b22;"&gt;'best'&lt;/span&gt;)
plt.savefig(&lt;span style="color: #228b22;"&gt;'images/antoine-2.png'&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
38.6138198197
The vapor pressure is 400 mmHg at T = 38.6 degC
&lt;/pre&gt;

&lt;p&gt;&lt;img src="/img/images/antoine-1.png"&gt;&lt;p&gt;

&lt;p&gt;
This result is close to the value reported &lt;a href="http://en.wikipedia.org/wiki/Acetone_(data_page)#Vapor_pressure_of_liquid" &gt; here&lt;/a&gt; (39.5 degC), from the CRC Handbook. The difference is probably that the value reported in the CRC is an actual experimental number.
&lt;/p&gt;

&lt;p&gt;&lt;img src="/img/./images/antoine-2.png"&gt;&lt;p&gt;
&lt;p&gt;Copyright (C) 2013 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2013/02/27/Reading-parameter-database-text-files-in-python.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;]]></content:encoded>
    </item>
  </channel>
</rss>
