0

I have a "parent" text file called reference, which is:

VERSION 3.82
CALCULATION 3
OPTIONS 0
PROJNAME 
DATE 
ENGINEER 
NOTES ""
PASSWORD 
MSTART CONSTANTS
RHO 1.225
RHOW 1027
VISCOS .0000182
GRAVITY 9.81
MEND

MSTART WINDND
SPMODEL 7
NLAT 31
NVER 45
LATDIM 150
VERDIM 220
LONGLS 340.2
LATLS 0
VERTLS 0
XLV 113.4
YLV 0
ZLV 0
XLW 27.72
YLW 0
ZLW 0
LAMBDA1 0
CohScale 12
COHDEC 3
SCALE 33.6
GAMMA 3.9
YDIML 0
N2 32
YDIMS 0
K1MIN 3
LENGTH 1830
STEP .2233888
UBAR 3
SEED 12
OUTFILE None
DIAM 0
HUBHT 0
TURBHTTYPE 0
TURBBOTTOM 0
GUSTAVT 0
GUSTSPEED 0
TOLERANCE 0
DLONGMIN 0
DLONGMAX 0
Z0MIN 0
Z0MAX 0
MAXITER 14
MAXSEED 100
NFILES 1
UseWindShear 0
WVMODEL 0
MATCHFILE ''
SPACING 0
SAMPLEFREQ 0
MEANSPEED 0
ILAT 0
IVERT 0
GUSTMETHOD 0
DLONG 0
ILAT 0
IVERT 0
LONGGUST 0
LATGUST 0
VERTGUST 0
iLONGGUST 0
iLATGUST 0
iVERTGUST 0
PEAKINESS 0
MAXFRAN 0
MEND

0CONSTANTS
0WINDND

The idea is to generate a set similar files, only changing 4 determined lines of the above file (LENGTH,STEP,UBAR,SEED).

Currently I am using this code:

clc
clear all
close all


V = [4 6 8 10 12 14 16 18 20 22 24 26 28 29];


for j = 1:6
f1 = ['D:\01_department\DLC1-2']
if exist(f1,'dir') ~= 7
    mkdir(f1);
end 
fname = [f1 '\' 's0' num2str(j)];
if exist(fname,'dir') ~= 7
    mkdir(fname);
end
 for i = 1:length(V),
filename = [fname '\' num2str(V(i)) '.$PJ'];
 fid = fopen(filename,'w');
 fprintf(fid, 'VERSION 3.82\r\n')
 fprintf(fid, 'CALCULATION 3\r\n')
 fprintf(fid, 'OPTIONS 0\r\n')
 fprintf(fid, 'PROJECTNAME\t\r\n')
 fprintf(fid, 'DATE\t\r\n')
 fprintf(fid, 'ENGINEER\t\r\n')
 fprintf(fid, 'NOTES\t""\r\n')
 fprintf(fid, 'PASSWORD\t\r\n')
 fprintf(fid, 'MSTART CONSTANTS\r\n')
 fprintf(fid, 'RHO 1.225\r\n')
 fprintf(fid, 'RHOW 1027\r\n')
 fprintf(fid, 'VISCOS 0.0000182\r\n')
 fprintf(fid, 'GRAVITY 9.81\r\n')
 fprintf(fid, 'MEND\r\n')
 fprintf(fid, '\r\n')
 fprintf(fid, 'MSTART WINDND\r\n')
 fprintf(fid, 'SPMODEL 7\r\n')
 fprintf(fid, 'NLAT 31\r\n')
 fprintf(fid, 'NVER 45\r\n')
 fprintf(fid, 'LATDIM 150\r\n')
 fprintf(fid, 'VERDIM 220\r\n')
 fprintf(fid, 'LONGLS 340.2\r\n')
 fprintf(fid, 'LATLS 0\r\n')
 fprintf(fid, 'VERTLS 0\r\n')
 fprintf(fid, 'XLV 113.4\r\n')
 fprintf(fid, 'YLV 0\r\n')
 fprintf(fid, 'ZLV 0\r\n')
 fprintf(fid, 'XLW 27.72\r\n')
 fprintf(fid, 'YLW 0\r\n')
 fprintf(fid, 'ZLW 0\r\n')
 fprintf(fid, 'LAMBDA1 0\r\n')
 fprintf(fid, 'CohScale 12\r\n')
 fprintf(fid, 'COHDEC 3\r\n')
 fprintf(fid, 'SCALE 33.6\r\n')
 fprintf(fid, 'GAMMA 3.9\r\n')
 fprintf(fid, 'YDIML 0\r\n')
 fprintf(fid, 'N2 32\r\n')
 fprintf(fid, 'YDIMS 0\r\n')
 fprintf(fid, 'K1MIN 3\r\n')
 fprintf(fid, 'LENGTH %g\r\n', V(i)*610)
 fprintf(fid, 'STEP %g\r\n', V(i)/13.4295)
 fprintf(fid, 'UBAR %g\r\n', V(i))
 fprintf(fid, 'SEED %i\r\n', randi(999,1))
 fprintf(fid, 'OUTFILE None\r\n')
 fprintf(fid, 'DIAM 0\r\n')
 fprintf(fid, 'HUBHT 0\r\n')
 fprintf(fid, 'TURBHTTYPE 0\r\n')
 fprintf(fid, 'TURBBOTTOM 0\r\n')
 fprintf(fid, 'GUSTAVT 0\r\n')
 fprintf(fid, 'GUSTSPEED 0\r\n')
 fprintf(fid, 'TOLERANCE 0\r\n')
 fprintf(fid, 'DLONGMIN 0\r\n')
 fprintf(fid, 'DLONGMAX 0\r\n')
 fprintf(fid, 'Z0MIN 0\r\n')
 fprintf(fid, 'Z0MAX 0\r\n')
 fprintf(fid, 'MAXITER 14\r\n')
 fprintf(fid, 'MAXSEED 100\r\n')
 fprintf(fid, 'NFILES 1\r\n')
 fprintf(fid, 'UseWindShear 0\r\n')
 fprintf(fid, 'WVMODEL 0\r\n')
 fprintf(fid, 'MATCHFILE %c\r\n', '')
 fprintf(fid, 'SPACING 0\r\n')
 fprintf(fid, 'SAMPLEFREQ 0\r\n')
 fprintf(fid, 'MEANSPEED 0\r\n')
 fprintf(fid, 'ILAT 0\r\n')
 fprintf(fid, 'IVERT 0\r\n')
 fprintf(fid, 'GUSTMETHOD 0\r\n')
 fprintf(fid, 'DLONG 0\r\n')
 fprintf(fid, 'ILAT 0\r\n')
 fprintf(fid, 'IVERT 0\r\n')
 fprintf(fid, 'LONGGUST 0\r\n')
 fprintf(fid, 'LATGUST 0\r\n')
 fprintf(fid, 'VERTGUST 0\r\n')
 fprintf(fid, 'iLONGGUST 0\r\n')
 fprintf(fid, 'iLATGUST 0\r\n')
 fprintf(fid, 'iVERTGUST 0\r\n')
 fprintf(fid, 'PEAKINESS 0\r\n')
 fprintf(fid, 'MAXFRAN 0\r\n')
 fprintf(fid, ' MEND\r\n')
 fprintf(fid, '\r\n')
 fprintf(fid, '0CONSTANTS\r\n')
 fprintf(fid, '0WINDND\r\n')
 fclose(fid)
 end
end

But this way, the code spends most of the time in writing the output. I would like more doing the same only reading the reference file (with fopen() or other commands) and the changing(printing) only

fprintf(fid, 'LENGTH %g\r\n', V(i)*610)
fprintf(fid, 'STEP %g\r\n', V(i)/13.4295)
fprintf(fid, 'UBAR %g\r\n', V(i))
fprintf(fid, 'SEED %i\r\n', randi(999,1))

within the new files.

Does anybody have an idea how to achieve this result? If possible I also would like to vectorize instead of using for loops.

otherwise, I was thinking this kind of process: I thank you for the answer and to share the code with me.

As you probably noticed the code is made up of blocks: they start with "MSTART" and end with "MEND"; each MSTART is followed by the label/name of the single block.

In this case the blocks are CONSTANTS and WINDND. I wonder if it is possible to:

1.read the parent file;
2.find the different block the parent file presents;
3.store the information/strings of each block in a Matlab structure;
4.write new files just recalling the blocks of the parent file;
5.look for strings LENGTH, STEP, UBAR, SEED;
6.update the above string with the corresponding formula;
7.store in a specified folder.

The beginning of the code would be:

%# read lines
fid = fopen('file.txt','rt');
C = textscan(fid, '%s', 'Delimiter','\r\n'); 
C = C{1};  fclose(fid);

%# start/end of each structure
startIdx = find(ismember(C, 'MSTART'));
endIdx = find(ismember(C, 'MEND'));

But then I have no clue how to go on, since I'm only a freshman with Matlab, and especially with text/structure manipulating.

I hope you will be patient with me.

Regards.

I thank you all in advance.

Kindest regards, Francesco

fpe
  • 2,700
  • 2
  • 23
  • 47
  • So I take it these are config files for some other program. Does the order of settings matter, or can they be in any order? – Rody Oldenhuis Aug 23 '12 at 08:50
  • See the edit to my answer. This works over here (R2010a). If you have any problems with it, please let me know. – Rody Oldenhuis Aug 23 '12 at 09:40
  • 2
    why do you want do this from within Matlab? e.g. on linux you can use tools like sed to easily replace parts of text files – steabert Aug 23 '12 at 10:02
  • I'm confused that your original code performs so poorly. Can you give some numbers how much the solution improved the performance for you? – bdecaf Aug 24 '12 at 08:27
  • Not a huge increase in performance, but the code results cleaner and more elegant than just brutal fprintf of every single line. But for the generation of 1440 files distributed somehow in the folders of interest the elapsed time is around 1.45 seconds. – fpe Aug 24 '12 at 08:32

1 Answers1

1

This should work:

clc, clear all, close all

V = [4 6 8 10 12 14 16 18 20 22 24 26 28 29];


fid = fopen('parent.txt', 'r');
C = textscan(fid,'%s', 'delimiter', '\r\n');
C = C{1};
fclose(fid);

D = C;
for j = 1:6
    f1 = 'd:\01_department\dlc1-2';
    if exist(f1,'dir') ~= 7, mkdir(f1); end

    fname = [f1 '\' 's0' num2str(j)];
    if exist(fname,'dir') ~= 7, mkdir(fname); end

    for i = 1:numel(v)
        filename = [fname '\' num2str(V(i)) '.$pj'];

        D{strncmp('LENGTH', c, length('LENGTH'))} = ...
            sprintf('length %g', V(i)*610);

        D{strncmp('STEP', c, length('STEP'))} = ...
            sprintf('STEP %g', V(i)/13.4295);

        D{strncmp('UBAR', c, length('UBAR'))} = ...
            sprintf('UBAR %g', V(i));

        D{strncmp('SEED', c, length('SEED'))} = ...
            sprintf('SEED %i', randi(999,1));


        fid = fopen(filename,'w');        
        txt = sprintf([repmat('%s\r\n',1,size(d,1)),'\r\n'],d{:});        
        fprintf(fid, '%s', txt);        
        fclose(fid);

    end
end

This can still be improved -- the strings to be replaced are ideally vectorized, and/or only entered ONCE in the command. But oh well, this should already give you a significant speedup.

Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96
  • I would like the structure of the file to stay the same; Unfortunately at the moment I have no free license (because those are floating), so if you could provide me with a piece of code, I would appreciate :) Thanks – fpe Aug 23 '12 at 08:57
  • It worked; the only flaw was that \r was missing in repmat('%s\n',1,size(d,1)); I changed it to repmat('%s\r\n',1,size(d,1)). Many thanks!!! – fpe Aug 24 '12 at 06:59
  • @FrancescoPerrone Yes, I come from the land where `\n` means newline (Linux), and `\r\n` is an easy-to-forget nuisance to take care of when communicating with the rest of the world (MS Windows) :) Anyway, glad it works OK now. – Rody Oldenhuis Aug 24 '12 at 07:12
  • The main point is that this files are to be generated with the exact format in order to feed the tool elaborating them. So that \r\n is of capital importance :) I thank you again for your support – fpe Aug 24 '12 at 07:30