Project

File Parsing NASA Thermodynamic data

Aim: Parsing NASA thermo dynamic data

Objective:

  1. Extracting coefficients to calculate Enthalpy, Entropy and Specific Heat at High and Low Temperature Ranges for each species in the data file
  2. Plotting the Data for local temperature ranges
  3. Saving plots in separate folders automatically
  4. Calculating Molecular Mass for all species and display in command window

Procedure:

Understanding the data:

1)The file starts with a header that is 5 lines long and ends with 'END' character string.

2) Species data has 14 coefficients each species saved in 4 lines, each ending with line number.

3) First 7 coefficients are for high temperature range and the remaining are for low temperature range.

4) Data starts with species name and details of its state. Then the temperature range limits are given as low temperature limit, high temperature limit, limit between low and high temperature ranges After which the coefficients are given.

Pointers for reading:

1) The data is not properly spaced: some of the coefficients have spaces while the others don't, few others have a - between them.

2) The line numbers must be removed so as not to be mistaken as coefficients.

Species data generation:

1) The '-' between coefficients was replaced by ' '. As some of the coefficients have 'E-##' first all the '-' characters were found, then the ones that follow 'E' were removed and then remaining were removed.

function line = brushing(line)
a = strfind(line,'-');
b = strfind(line,'E-');
for i = 1: length(a)
    for j = 1: length(b)
        if a(i) == b(j)+1
            a(i) = 0;%excluding all '-' that follow 'E'
        end
    end
end
for i = 1:length(a)
if a(i) ~= 0 
    line(a(i)) = ' ';%replacing all remaing '-' with space
end
end

2) As some coefficients did not have spacing between them, ' ' was added after all coefficients as an extra space wouldn't affect the ones that are already spaced. Data present after 'E###' was first saved to an array 'a', a space was added after 'E###' and then the array 'a' was stored in string.

function tline = spacing(tline)
for i = 1:length(tline)
    if tline(i) == 'E'
        k = 1;
        for j = i+4:length(tline)%saving data 
            a(k) = tline(j);
            k=k+1;
        end
        tline(i+4) = ' ';%adding space
        k = 1;
        for l = i+5:length(tline)+1%reinstalling saved array after incrementing the location by 1
            tline(l) = a(k);
            k=k+1;
        end
    end   
end
end

3) Line numbers in the file followed the following pattern ' # ', the same was used to locate the string and the number was replaced by ' ' . line number 4 does not affect the data as it in the end hence was left in place.

function line = datarefining(line)
    
    a = strfind(line,'1');%finding the line numbers
    for i = 1:length(a)
        if a(i) >= 50%excluding the species specification data
            if line(a(i)-1)== ' ' && line(a(i)+1)==' '   
                line(a(i)) = ' ';
                line(a(i)+1) = ' ';%replacing with space
                line(a(i)-1) = ' ';
            end
        end
    end
    
    a = strfind(line,'2');%finding the line numbers
    for i = 1:length(a)
        if a(i) >= 50%excluding the species specification data
            if line(a(i)-1)== ' ' && line(a(i)+1)==' '   
                line(a(i)) = ' ';
                line(a(i)+1) = ' ';%replacing with space
                line(a(i)-1) = ' ';
            end
        end
    end
    
    a = strfind(line,'3');%finding the line numbers
    for i = 1:length(a)
        if a(i) >= 50%excluding the species specification data
            if line(a(i)-1)== ' ' && line(a(i)+1)==' '   
                line(a(i)) = ' ';
                line(a(i)+1) = ' ';%replacing with space
                line(a(i)-1) = ' ';
            end
        end
    end
    
    a = strfind(line,'4');%finding the line numbers
    for i = 1:length(a)
        if a(i) >= 50%excluding the species specification data
            if line(a(i)-1)== ' ' && a(i)==length(line)   
                line(a(i)) = ' ';
                line(a(i)+1) = ' ';%replacing with space
                line(a(i)-1) = ' ';
            end
        end
    end
end

4) Data is then divided into two parts name and coefficients, string.name consists of all the data before lower temperature limit and string.coefficient consists of temperature ranges, coefficients.

function [o1,o2] = naming(tline)
a = strfind(tline,'00.00');
if size(a) >0
    for i = 1:a(1)-2
        o1(i) = tline(i);
    end
    j = 1;
    for i = a(1)-1:length(tline)
        o2(j) = tline(i);
        j = j+1;
    end
else
    o1 = [];%specification string
    o2 = [];%coefficient string
end
end

Note: As the project is data specific, above mentioned functions were defined according to this data file. They are not generic functions that can be called for other data parsing projects, but the final code can be used for data files of similar nature provided the file strictly follows the points under 'understanding the data' and have no additional constraints.

Plots:

1) solutionNplot function:The function takes in the coefficients array along with species name. Generates the solution arrays for specific heat, enthalpy and entropy using the temperature ranges and coefficients for both high temperature range and low temperature range, created a new directory named using the species name and send the data to graphGenerate function for plotting and storing files in the generated directory.

function solutionNplot(A,B)
R = 8.314; %J/mol-k

%high temp range
T2 = A(1,3):10:A(1,2);
CP = R*(A(1,3+1) + A(1,3+2)*T2 + A(1,3+3)*(T2.^2) + A(1,3+4)*(T2.^3) + A(1,3+5)*(T2.^4));
H = R*((A(1,3+1)*T2)+(A(1,3+2)*(T2.^2)/2)+(A(1,3+3)*(T2.^3)/3)+(A(1,3+4)*(T2.^4)/4)+(A(1,3+5)*(T2.^5)/5)+A(1,3+6));
S = R*((A(1,3+1)*log(T2))+(A(1,3+2)*T2)+(A(1,3+3)*(T2.^2)/2)+(A(1,3+4)*(T2.^3)/3)+(A(1,3+5)*(T2.^4)/4)+A(1,3+7));

%low temp range
T1 = A(1,1):10:A(1,3);
cp = R*(A(1,3+1+7) + A(1,3+2+7)*T1 + A(1,3+3+7)*(T1.^2) + A(1,3+4+7)*(T1.^3) + A(1,3+5+7)*(T1.^4));
h = R*((A(1,3+1+7)*T1)+(A(1,3+2+7)*(T1.^2)/2)+(A(1,3+3+7)*(T1.^3)/3)+(A(1,3+4+7)*(T1.^4)/4)+(A(1,3+5+7)*(T1.^5)/5)+A(1,3+6+7));
s = R*((A(1,3+1+7)*log(T1))+(A(1,3+2+7)*T1)+(A(1,3+3+7)*(T1.^2)/2)+(A(1,3+4+7)*(T1.^3)/3)+(A(1,3+5+7)*(T1.^4)/4)+A(1,3+7+7));

%new directory
mkdir(B);

%plots
graphGenerate(T1,cp,'Specific Heat(J/mol-K)','Low',B);%Specific Heat plot - Low Temp
graphGenerate(T2,CP,'Specific Heat(J/mol-K)','High',B);%Specific Heat plot - High Temp
graphGenerate(T1,h,'Enthalpy (J)','Low',B);%enthalpy plot - Low Temp
graphGenerate(T2,H,'Enthalpy (J)','High',B);%enthalpy plot - High Temp
graphGenerate(T1,s,'Entropy (J)','Low',B);%entropy plot - Low Temp
graphGenerate(T2,S,'Entropy (J)','High',B);%entropy plot - High Temp

end

2) graphGenerate function:Given the inputs of data on x and y axes and their respective titles, the function plots the data and labels the plot using the titles and saves the plot. The name for the image being saved will be derived from the x and y labels and the species name given as input.

function graphGenerate(A,B,C,D,E)
p = plot(A,B,'color',rand(1,3),'linewidth',2);%plotting
xlabel('Temperature(K)');
ylabel(C);
title(strcat(C,' vs Temperature(K) at', D,'Temp Range for -',E));
saveas(p,strcat(E,'/',C(1:strfind(C,'(')-1),'_',D,'Temp_',E,'.jpg'));%file saving
end

Molecular mass:

1) composition function:The function takes the species name as input, reads the string looking for atoms and their multiplier. If an alphabet is followed by a number the function enters the alphabet into an array and the number to a corresponding row in another array. If the alphabet is followed by another alphabet the multiplier corresponding to this alphabet shall be 1. In case the alphabet is A, as the data has only Ar molecule with A; hence the value after r is considered for numbering. Also some species have (S), so '(' was ignored and remaining data was taken. The function results in a structure.molecule with the atom name and structure.multiplier with their corresponding multipliers

function [molecule ,multiplier] = composition(A)
i = 1;
j = 1;
while i <= length(A) %checking for total length
    if A(i) ~= '('%running the loop only if the character is not '('
        molecule(j) = A(i);%saving the atom
        if molecule(j) == 'A' | molecule(j) == 'a'
            i = i+1;%skipping one space if the atom A as the following character will be 'r' and belongs to the atom notation
        end
        if i < length(A)%For all elements in species except the one at the end of the string
            k = 0;
            while k <= 9
                if str2num(A(i+1)) == k
                    multiplier(j) = (A(i+1));%assinging the number of atoms of element in current assay to multipier string
                    i = i+1;%moving to next character in the string
                    k = 10;%terminating the loop
                else
                multiplier(j) = '1';%if the character is not a number then the multiplier is set to 1
                end
            k = k+1;%increment
            end
        else 
            multiplier(j) = '1';%If an element is at the end of the string then only one atom is present hence its multiplier 1
        end
        i = i+1;%moving to next character in the string
        j = j+1;%moving to next element
    else
        i = i+1;%moving to next character in the string if the character is '('
    end
end 

2)molecularmass function: This function called composition function to get the element and multiplier arrays of species in assay. Checking for the element and its corresponding atomic mass; it calculates the molecular mass using the atomic masses of each element and the corresponding multipliers.

function molmas = molecularmass(a)
[element, multiplier] = composition(a);%calling function
for i = 1:length(element)%initializing
    species(i).element = element(i);
    species(i).multiplier = multiplier(i);
for i = 1:length(species)%atomic weigth assignment
    if species(i).element == 'C'| species(i).element == 'c'
        m(i) = 12;
    elseif species(i).element == 'O'|species(i).element == 'o'
         m(i) = 16;
    elseif species(i).element == 'H'|species(i).element == 'h'
         m(i) = 1;
    elseif species(i).element == 'N'|species(i).element == 'n'
         m(i) = 14;
    elseif species(i).element == 'S'|species(i).element == 's'
         m(i) = 32;
    elseif species(i).element == 'A'|species(i).element == 'a'
         m(i) = 18;
    else
        m(i) = 0;
    end
end
for i = 1:length(species)%multiplier assignment
    B(i) = str2num(species(i).multiplier);
end
b = m.*B;%molecular weigth of each element
molmas = 0;
for i = 1:length(b)
    molmas = molmas+b(i);%molecular weigth increment
end
end

Main:

1) The data file is stored in a variable (line 6)

2) Each line of the data is stored into the structure as s.line (lines 7-13)

3) Excluding the header and footer, remaining lines are saved as species with four lines each (lines 16-31)

4) Data is then formatted using functions defined above for each species (lines 35-38)

5) The species specifications S.spec are then defined by splitting the string s.name and coefficients by first splitting the string s.efficients and then converting string to number (lines 39-44)

6) solutionNplot function is then called to generate plot and save them using the coefficient array and the species name stored in S.specs{1,1} (line 45)

7) Molecular mass of species is calculated using the molecularmass function and displayed using 'disp' command (lines 48-52)

clear all
close all
clc

%reading file; generating strings for each species and storing in structure 's'
D = fopen('THERM.dat','r');
a = [];
i = 1;
while size(a) ~= 1 
    s(i).line = fgetl(D);
    a = strfind(s(i).line,'END');  
    i = i+1;
end

%species grouping
numberoflines = i-1;
numberofspecies = 1;
var = 6;
for i = 1:1:(numberoflines-6)/4
    line1 = s(var).line;
    var = var+1;
    line2 = s(var).line;
    var = var+1;
    line3 = s(var).line;
    var = var+1;
    line4 = s(var).line;
    s(numberofspecies).species = strcat(line1,line2,line3,line4);
    var = var + 1;
    numberofspecies = numberofspecies + 1;
end
clear('var','line1','line2','line3','line4')

%Data formating and plotting
for i = 1:numberofspecies-1 
    s(i).brushing = brushing(s(i).species);%species generation
    s(i).refined = datarefining(s(i).brushing);%data refining
    s(i).spacing = spacing(s(i).refined);%spacing
    [s(i).name,s(i).coefficients]= naming(s(i).spacing);%seperation
    S(i).specs = strsplit(s(i).name,'    ');%splitting
    S(i).coefficients = strsplit(s(i).coefficients,' ');%splitting
    %Coefficient cell to number array
    iteration = 1;
    while iteration <= 17 
        Coeff(i,iteration) = str2num(S(i).coefficients{1,iteration});
        iteration = iteration + 1;
    end
    solutionNplot(Coeff(i,:),S(i).specs{1,1})%Plots - Specific Heat, Enthalpy, Entropy
end

for i = 1:numberofspecies-1
    Molecularmass(i) = molecularmass(S(i).specs{1,1});%Molecular Mass 
    disp(strcat('Molecular Mass of -',S(i).specs{1,1},'='))
    disp(Molecularmass(i))
end

clear('i','iteration','a','D')
close all

Results & Discussion:

1) Folders were created for each species

2) CO2 folder:

CO2 - Google Drive

3) O2 folder:

O2 - Google Drive

4) N2 folder:

N2 - Google Drive

5) Screenshots of the command window:

Command Window ScreenShots - Google Drive

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.