Extracting X Y values from a .txt file

I am working on a small project using data for a 3D printer. My problem is I am having a hard time extracting the movements of the printer to a usable array. In my text file I have things like:
;TYPE:SKIRT
G1 F1500 X18.188 Y1.255 E0.36904
G1 X18.188 Y20.575 E1.33292
G1 X26.144 Y20.575 E1.72984
G1 X26.144 Y26.455 E2.02320
;TYPE:WALL-INNER
G1 F1500 X16.988 Y2.455 E9.77394
G1 X16.988 Y21.775 E10.73782
G1 X24.944 Y21.775 E11.13474
;TYPE:WALL-OUTTER
...
The code then continues with this same format for each layer. So if there are 50 layers there are 50 wall outer sections.
If all I want is each x and y numbers for all the wall outer values (while making note of which layer the xs and ys were for) how would I do that? I have been searching the net and have found nothing for something I would think would be very simple.

6 Comments

Can you provide part of the txt file?
Is the expected output for the example:
16.988 2.455
16.988 21.775
24.944 21.775
?
Is the expected output for the example:
16.988 2.455
16.988 21.775
24.944 21.775
?
If I were looking for the x and Ys of wall inner yes. Those would be the values. But like I said there are multiple blocks of wall inner and I would like to get the values of each block thought the whole file and making note which block they belong to.
https://imgur.com/41vaVKv So you can see at layer 0 these are the commands and I want all of the x and Ys that have a G1 in the front inside the block between Wall inner and wall outer (AKA getting all the moves that make the inner wall) That being said there are OTHER wall inners thought the text for each layer https://imgur.com/41vaVKv Here is further down in the code where a new block of commands are made for wall inner.
I really hope I am not asking for too much I just have no idea how to do this. I am currently trying to solve my problem myself by first converting the txt file into a table but it is having problems of its own.
Not a problem. Can you upload your text file please?
Still trying to get the table to work but having just as much trouble.

Sign in to comment.

Answers (2)

Paolo
Paolo on 8 Jul 2018
Edited: Paolo on 8 Jul 2018
I think the best solution in this situation is to use regular expressions. Matlab's regexp supports named capture groups, which automatically creates a structure for you, with the names of the capture groups as fields and the captured text as data. You can read more about it here.
There are three steps in the solution below.
1. Initially the text file is parsed and each layer is extracted.
2. A loop is used to iterate over every layer to extract the types.
3. A inner loop is used to iterate over every type in every layer, and X Y data is extracted.
Here's the code:
alldata = fileread('TGC.txt');
layers = regexp(alldata,'(?:LAYER:\d)(?<layer>[\w\s.;:-]*?)(?=;LAYER:|;End)','names');
n = size(layers);
for i=1:n(2)
[layers(i).types pos] = regexp(layers(i).layer,'(?:;TYPE:)(?<TYPE>[\w-]*)','names');
pos = [pos length(layers(i).layer)];
m = size(layers(i).types);
for j=1:m(2)
layers(i).types(j).data = regexp(layers(i).layer(pos(j):pos(j+1)),'(?:G1[\w\s]*X)(? <XDATA>\d*\.\d*)(?:\sY)(?<YDATA>\d*\.\d*)','names');
end
end
The output is a structure where you can easily access your data. I am attaching screenshots to clarify what the code does.
1. There are 58 layers in your code (your index starts from 0).
2. Each of your layers has several types:
3. Each type contains X and Y data:
To access your data you can use the dot notation. If you want the X and Y data for the first layer and the first type:
layer(1).types(1).data
Note that for numerical calculations you will need to convert your data from char to double.

3 Comments

dpb
dpb on 8 Jul 2018
Edited: dpb on 8 Jul 2018
Ah! Someone came along that does know regular expressions! :)
Altho the new(ish) string package has functions that allow for higher-level abstraction for many cases...here the big problem was that last record is missing the 'E' field and there are inconsistent numbers of fields to skip per record.
Always learning :) Questions like this one are great for practicing.
Yes, I found OP's instructions slightly confusing so I figured I might as well get all of the data for him to access.
I've decided I'm too old a dog for that new trick...no longer the patience needed! :)

Sign in to comment.

dpb
dpb on 6 Jul 2018
Edited: dpb on 8 Jul 2018
You'll have to parse that file to locate the desired sections...none of the builtin reading tools are able to do such a file structure on their own.
fid=fopen('TGC.txt');
while ~feof(fid) % begin a loop
l=fgetl(fid); % read a line
if contains(l,';Layer count:') % found the number layers
nLay=sscanf(l,';Layer count: %d'); % read the # layers
break % now can go counted loop
end
end
XY=cell(nLay,1); % preallocate a cell arrray that size
for i=1:nLay % go until get 'em all...
l=fgetl(fid); % read record
while ~contains(l,';TYPE:WALL-OUTER'),l=fgetl(fid);end % find the desired section
g={fgetl(fid)}; % get first record in section
while ~contains(g,';') % and build cellstr array
g=[g;{fgetl(fid)}];
end
g(end)=[]; % remove the trailing header line
g(end)=strcat(g(end),{' E'}); % normalize the row delimiters
XY{i}=str2double([extractBetween(g,"X","Y") extractBetween(g,"Y","E")]);
end
fid=fclose(fid);
ADDENDUM Above seems to work with a sorta' klunky fixup...
>> james % original name for script!!! :)
>> whos XY
Name Size Bytes Class Attributes
XY 58x1 14848 cell
>> XY{1}
ans =
17.388 2.055
17.388 21.375
25.344 21.375
25.344 25.655
3.616 25.655
3.616 21.375
11.591 21.375
11.591 2.055
12.129 2.795
>>
The layer isn't saved explicitly; it's inherent in the cell index(*); it appears for this file the size of each array is the same; not sure if that were to be a requirement, hence the cell array as opposed to, say, a 3D array by layer.
(*) Of course, it's 1-based instead of 0-based since ML arrays begin (only, unfortunately) at 1.

Categories

Asked:

on 6 Jul 2018

Commented:

dpb
on 9 Jul 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!