views:

348

answers:

2

EDITED QUESTION:

I have 2500 rows x 100 columns seismic data in variable named avg_seismic_data_models. I also have 2500 rows x 100 columns variable 'X' and similar size matrix variable 'Y', both containing the co-ordinates. I want to save the values of this variable in a text (.dat) file which must have 302 header lines in the following manner:

avg_seismic_data_models
300
X_1
X_2
.
.
.
X_100
Y_1
Y_2
.
.
.
Y_100
avg_seismic_data_models_1
avg_seismic_data_models_2
avg_seismic_data_models_3
.
.
.
.
.
avg_seismic_data_models_100

In the above header style, the first line is the name of the file, the 2nd line tells the number of columns (each column has 2500 rows), and the rest of the 300 lines represent the model of each variable respectively - Like 100 models of X, 100 models of Y and 100 models of avg_seismic_data_models.

+1  A: 

You can use fprintf to write the header, like so:

%# define the number of data
nModels = 100;
dataName = 'avg_seismic_data_models';

%# open the file
fid = fopen('output.dat','w');

%# start writing. First line: title
fprintf(fid,'%s\n',dataName); %# don't forget \n for newline. Use \n\r if yow want to open this in notepad

%# write number of models
fprintf(fid,'%i\n',nModels)

%# loop to write the rest of the header
for iModel = 1:nModels
fprintf(fid,'%s_%i\n',dataName,iModel);
end

%# use your favorite method to write the rest of the data. 
%# for example, you could use fprintf again, using /t to add tabs 
%# create format-string
%# check the help to fprintf to learn about formatting details
formatString = repmat('%f\t',1,100);
formatString = [formatString(1:end-1),'n']; %# replace last tab with newline

%# transpose the array, because fprintf reshapes the array to a vector and 
%# 'fills' the format-strings sequentially until it runs out of data
fprintf(fid,formatString,avg_seismic_data'); %'# SO formatting

%# close the file
fclose(fid);
Jonas
Thanks Jonas. If I am not wrong I think 'wt' should be added in fopen to suggest writing in text.When it comes to writing the data following the header lines, I get the require 2500 x 100 data in form of single row only. I looked up the function repmat, however I find your use of repmat in different format as suggeste by Matlab help. Can you help with that step?
Harpreet
@Harpreet: Sorry for the mistakes in `fopen` and `repmat`. I put `/t` instead of `\t`, which means that if you replace the last letter `t` with `n`, there would be no newline (`\n`). I fixed the issues.Also, I thought your data was 100x2500, so I thought you'd want to have 100 rows with 2500 columns. I have changed that as well.
Jonas
Thanks a lot Jonas. Perfect help.
Harpreet
I could not mark this answer as useful after fidgeting with it which got it locked. If you edit (anything) this answer then it may again let me mark it useful. Just reminding you about this incase its of use to you :)
Harpreet
@Harpreet: I made a formatting change. Thanks for the heads-up!
Jonas
@Jonas: I have made some addition to the requirement of the file by including two more matrix of similar sizes to be included in the file. Can you have a look at the edited question above?
Harpreet
+2  A: 

Consider this code:

%# here you have your data X/Y/..
%#X = rand(2500,100);

[r c] = size(X);
prefixX = 'X';
prefixY = 'Y';
prefixData = 'avg_seismic_data_models';

%# build a cell array that contains all the header lines
num = strtrim( cellstr(num2str((1:c)','_%d')) );   %#' SO fix
headers = [ prefixData ;
            num2str(3*c) ;
            strcat(prefixX,num) ;
            strcat(prefixY,num) ;
            strcat(prefixData,num) ];

%# write to file
fid = fopen('outputFile.dat', 'wt');
fprintf(fid, '%s\n',headers{:});
fclose(fid);

EDIT

It seems I misunderstood the question.. Here's the code to write the actual data (not the header titles!):

%# here you have your data X/Y/..
avg_seismic_data_models = rand(2500,100);
X = rand(2500,100);
Y = rand(2500,100);

%# create file, and write the title and number of columns
fid = fopen('outputFile.dat', 'wt');
fprintf(fid, '%s\n%d\n', 'avg_seismic_data_models', 3*size(X,2));
fclose(fid);

%# append rest of data
dlmwrite('outputFile.dat', [X Y avg_seismic_data_models], '-append', 'delimiter',',')

Note: I used a comma , as delimiter, you can change it to be a space or a tab \t if you like..

Amro
@Amro: I am sorry to have confused you, but I was having difficulty in writing the data of the variables I have defined in the headers. Since I have to write multiple variables, they were not getting written as I want. I want each variable to be written side by side in accordance with the name of the columns in headers.
Harpreet
@Harpreet: updated the code, now write the data values instead of the name of headers..
Amro
@Amro: Can you include the previous answer of headers as well in the edited answer? Thanks.
Harpreet
@Harpreet: sure. You can always see all previous revisions of answers on SO by clicking on the "edited <datetime>" link
Amro
@Amro: Thanks. I don't want the data to be appended vertically. I want the variables (matrices) to be appended horizontally i.e. my first 100 columns would be data of X, next 100 columns of Y etc.
Harpreet
@Harpreet: that exactly what its doing, note that `[x';y';z']` is equivalent to `[x y z]'`
Amro
If you want you can write it as: `dlmwrite('outputFile.dat', X', '-append')` then followed by the same thing for `Y` and `avg_seismic_data_models`...
Amro
Amro: Actually its appending the variables after every new line. I want the variables to be appended horizontally, and not on new lines i.e. stack the variables horizontally without changing the dimensions of the variable or without taking their transpose.
Harpreet
@Harpreet: Ok I'm confused now, please explain exactly what you want the output to be (2500*3-by-100, 100-by-2500*3, 3*100-by-2500, ...)
Amro
I want: 2500 X 100 (all X's), then 2500 X 100 (all Y's) stacked horizontally to the last realization of X, then 2500 X 100 (all avg_seismic_data_models) stacked horizontally to the last realization of Y. Note: each X, Y and avg_seismic_data_models are a column vector of 2500 elements, and each of them have 100 realizations, so each of them are matrices of 2500 X 100 size.
Harpreet
so it will create a matrix of total size 2500-by-3*100, that is: `dlmwrite('outputFile.dat', [X Y avg_seismic_data_models], '-append')` (without transpose). Am I correct?
Amro
@Amro: Yep. Now its fine. You may want to include the final version in the answer above by editing it. Thanks!
Harpreet