You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
How to modify this code to make it import values from a file?
1 view (last 30 days)
Show older comments
Hi,
The following code opens a file (named "Pulse.acc") and writes c, s and t values as follows:
0 1 0
0 2 0
0 3 0
It also opens another file (named :Case.tcl") and writes each case number.
Each case over-writes the previous one.
I am now trying to import the values of s from the attached file (named "result_40.txt"). This file contains 40 columns and 10 rows. Each value in the columns will be printed in "Pulse.acc" file and excute OpenSees software model (along with c and t values. For example: 0 1 0, as shown above). This needs to continue until the 10th value in the column. Then, the second column starts.
The values of c and t will continue to be zero, so they could be left as below.
It would be great if a folder can be opened for the outputs from each column and numbered sequentially.
I hope I could explain what I want clearly, and please feel freel to let me know if I need to explain it further.
c=[0 0 0];
s=[1 2 3];
t=[0 0 0];
for j = 1:3
fidP = fopen('Pulse.acc','w+');
fidC= fopen('Case.tcl','w+');
fprintf(fidP, '%d\n%d\n%d',c(j), s(j), t(j));
fprintf(fidC, 'set case %d',j);
fclose(fidP);
fclose(fidC);
!OpenSees Model.tcl
end
Accepted Answer
Bob Thompson
on 19 Feb 2019
Importing and reading the data into matlab is fairly simple, and you can take your pick of text readers. It sounds like dlmread will work best for what you're trying to accomplish here so I will use that. Alternatively, you can investigate textscan(), csvread(), or just fopen() with fgetl().
fin = 'result_40.txt';
s = dlmread(fin,'');
c = 0;
t = 0;
for i = 1:size(s,2);
coldir = mkdir(['Column_',num2str(i)]);
cd(coldir);
for j = 1:size(s,1);
fidP = fopen('Pulse.acc','w+');
fidC= fopen('Case.tcl','w+');
fprintf(fidP, '%d\n%d\n%d',c, s(j,i), t);
fprintf(fidC, 'set case %d',j);
fclose(fidP);
fclose(fidC);
end
cd('../');
end
24 Comments
Ismail Qeshta
on 19 Feb 2019
Hi Bob,
Many thanks for your reply and the suggested code.
I tried it but I keep getting the following error message:
Error using cd
Path must be a string scalar or character vector.
Error in Frag2Ffyn (line 49)
cd(coldir);
Ismail Qeshta
on 19 Feb 2019
Edited: Ismail Qeshta
on 19 Feb 2019
Hi Stephen,
Thank you for your feedback. Would it be possible to explain where to get filepaths codes?
Bob Thompson
on 19 Feb 2019
Getting a file path is simply defining it in a variable. So, what Stephen is talking about is that instead of using cd() to change the directory you're working in, just define a specific path within the variable itself.
parentdir = 'C:\Users\bob\mytestfolder\';
... % Other bits of code I wrote already
for i = 1:size(s,2);
coldir = mkdir([parentdir,'Column_',num2str(i)]);
% We don't need cd() anymore
for j = 1:size(s,1);
fidP = fopen([coldir,'\Pulse.acc'],'w+');
fidC= fopen([coldir,'\Case.tcl'],'w+');
end
end
Ismail Qeshta
on 19 Feb 2019
Hi Bob,
Many thanks for correcting the code. I still get this error message:
Error using horzcat
The following error occurred converting from logical to char:
Conversion to char from logical is not possible.
Error in Frag2Ffyn (line 52)
fidP = fopen([coldir,'\Pulse.acc'],'w+');
Bob Thompson
on 19 Feb 2019
Change the following.
coldir = mkdir([parentdir,'Column_',num2str(i)]); % old
mkdir([parentdir,'Column_',num2str(i)]); %new
coldir = [parentdir,'Column_',num2str(i)];
Ismail Qeshta
on 19 Feb 2019
Edited: Ismail Qeshta
on 21 Feb 2019
Hi Bob,
Many thanks for your corrections.
I have tried to run the code.
Below you can see the directory where I am trying to excute the OpenSees model. I need to create folders for each column in the BridgePier foler (last folder in the directory).
However, the output files are printed in a file inside the that folder and no column files were created.
In other words, I actually need to create the Pulse.acc and Case.tcl in BridgePier folder, while creating the column1, column2, ... , column 40 in BridgePier folder.
The code:
parentdir = 'C:\Users\ismai\Desktop\B - SI\26\fgfg\BP';
fin = 'result_all.txt';
s = dlmread(fin,'');
c = 0;
t = 0;
for i = 1:size(s,2);
mkdir([parentdir,'Column_',num2str(i)]); %new
coldir = [parentdir,'Column_',num2str(i)]; % We don't need cd() anymore
for j = 1:size(s,1);
fidP = fopen([coldir,'\Pulse.acc'],'w+');
fidC= fopen([coldir,'\Case.tcl'],'w+');
!OpenSees Model.tcl
end
end
cd('../');
Bob Thompson
on 19 Feb 2019
This is a simple adjustment. All you need to do is change our directory variable for printing the files. Currently you are printing them to 'coldir' which is a combination of the parent directory and the column folder contained within the parent. If you want to put Pulse and Case within the parent directory then just change the fopen() command to call the parent directory instead of the 'coldir' directory.
Ismail Qeshta
on 19 Feb 2019
Edited: Ismail Qeshta
on 19 Feb 2019
Hi Bob,
Many thanks for your clarification. The 40 folders are still printed in the ModelValidation folder. I need them to be printed in BridgePier folder instead.
Ismail Qeshta
on 19 Feb 2019
Edited: Ismail Qeshta
on 19 Feb 2019
I think I am getting a little confused Bob.
I will double-check what procedures I exactly need with respect to folders and get back to you tomorrow.
Thank you.
Bob Thompson
on 19 Feb 2019
You need to add a slash in between your parent directory and your new folders. If you look at the directory being created it currently looks like this:
[parentdir,'Column_',num2str(i)]
% 'C:\Users\ismai\Desktop\Bridge under Tsunami - SI\eleLoad\ModelValidation\BridgePierColumn_#
It should look like this:
'C:\Users\ismai\Desktop\Bridge under Tsunami - SI\eleLoad\ModelValidation\BridgePier\Column_#
You can achieve this either by adding the slash to your parent directory definition, or to the mkdir command.
parentdir = 'C:\Users\ismai\Desktop\Bridge under Tsunami - SI\eleLoad\ModelValidation\BridgePier\';
or
mkdir([parentdir,'\Column_',num2str(i)]);
Ismail Qeshta
on 19 Feb 2019
Thank you Bob for the correction and clarification. I have just corrected that.
Actually, I just found that there not data printed in the Case.tcl and Pulse.acc files.
The other thing that I am double-checking now is that the output files for each column need to be printed inside each column folder.
Bob Thompson
on 19 Feb 2019
Checking output file locations should be very similar to what we just did.
For the lack of data printed to the two other files, I would double check that they are opening properly. You can do this by putting a debug flag on the line of your code which contains the write command, and checking to see if fidP or fidC are positive integers. If they are then the files are opening properly.
Ismail Qeshta
on 19 Feb 2019
Hi Bob,
Thank you very much for all your effort and time. I have just been thinking of the code and folders arrangements.
I think I can just ignore the idea of creating folders for each column, as I just discovered that it confuses a lot the OpenSees model.
Would it be possible if the code counts all column data sequentially?
It is basically the original code in my post, but instead it imports the data from file and counts each number for s. There is no need to create folders for each column.
Bob Thompson
on 19 Feb 2019
What exactly do you mean by 'count?' The for loops with indexes 'i' and 'j' will step through each of the values of s, and you can use that same indexing method to create individual files, or store the data in a single variable.
Ismail Qeshta
on 19 Feb 2019
Edited: Ismail Qeshta
on 19 Feb 2019
Thank you very much Bob.
Yes, I just did it. I cannot thank you enough for all your help and patience while developing the codes. I have just checked it and it worked.
For your kind reference:
fin = 'result_all.txt';
s = dlmread(fin,'');
c=[0 0 0 0 0 0 0 0 0 0 0 0];
t=[0 0 0 0 0 0 0 0 0 0 0 0];
for j = 1:12
fidP = fopen('Pulse.acc','w+');
fidC= fopen('Case.tcl','w+');
fprintf(fidP, '%d\n%d\n%d',c(j), s(j), t(j));
fprintf(fidC, 'set case %d',j);
fclose(fidP);
fclose(fidC);
!OpenSees Model.tcl
end
Ismail Qeshta
on 20 Feb 2019
Edited: Ismail Qeshta
on 20 Feb 2019
Hi Bob,
I have just noticed that the above code rounds the values that are read from "result_all".
For example, 189489.4 becomes 189000.
Would it be possible if the code can read the exact values? just for more accuracy of my results.
Bob Thompson
on 20 Feb 2019
Are you sure that Matlab is actually rounding the values? The default display format for matlab is 'short' so it doesn't display more than about 4 sig figs. Try setting your display settings to 'long'
format long
Ismail Qeshta
on 20 Feb 2019
Hi Bob,
Many thanks for the suggestion. I set it to "long", but nothing changed.
format long
fin = 'result_all.txt';
s = dlmread(fin,'');
c=[0 0 0 0 0 0 0 0 0 0 0 0];
t=[0 0 0 0 0 0 0 0 0 0 0 0];
for j = 1:12
fidP = fopen('Pulse.acc','w+');
fidC= fopen('Case.tcl','w+');
fprintf(fidP, '%d\n%d\n%d',c(j), s(j), t(j));
fprintf(fidC, 'set case %d',j);
fclose(fidP);
fclose(fidC);
!OpenSees Model.tcl
end
Bob Thompson
on 20 Feb 2019
To the best of my knowledge, dlmread does not round data when it loads it from a file. As I said, Matlab might display a rounded value, but the stored data should be the original. Is the data in the text file 189489.4 or 189000? The dlmread command is limited in its fidelity by the fidelity of the file. If the file is only displaying 189000 then it is not possible for the dlmread command to get 189489.4 from that.
Also, the format(long) command does only change the actual 'displayed' value. So if you are not displaying a value then it will not look any different. Try using the format(long) command directly in the command window, and then displaying some value of 's'. See if it has the fidelity you're looking for.
Ismail Qeshta
on 20 Feb 2019
Hi Bob,
In the original text file, it is 189489.4
In the "Pulse.acc" it is 189000
Ismail Qeshta
on 20 Feb 2019
Edited: Ismail Qeshta
on 20 Feb 2019
Thank you Bob. I think I just got it. The "rounding" or "display" of "digits" or "zeros" was due to the "copy" and "paste" from Excel sheet to text file.
Since Excel uses E format, the data copied to the text file are rounded.
Apologies for this confusion.
Bob Thompson
on 20 Feb 2019
Ah, I see. That is because you're printing with the fprintf command as a double. Try the following:
fprintf(fidP, '%f\n%f\n%f',c(j), s(j), t(j));
You want to print the values as a 'floating point number' rather than a double in order to get the level of fidelity you're looking for. Sorry I didn't catch that earlier.
Ismail Qeshta
on 20 Feb 2019
I see. Thank you very much Bob. That is so kind of you. Alright, I will incorporate this correction in the code.
More Answers (0)
See Also
Categories
Find more on Low-Level File I/O in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)