Ask for help about the structure

X

xiao

Can anyone help me to find out what are the structure of 'DataTable' ?
Does loop the 14 layers or the 800*800 array first?
(NumX=NumY=800)
gridde and WriteHeader are two structures
Thank you~~~ :)


void WriteCloudStats(GRIDDEF *griddef, char *StatsDir, int month, int
year, short ****DataTable)
{

FILE *fptr[2];
int i,j,k,l;
char filename[200],command[250],monstr[5];
GRIDDEF header;

if(month < 10)
sprintf(monstr,"0%d",month);
else
sprintf(monstr,"%d",month);

sprintf(filename,"%s/CldYearlyStats_%d_
%d.dat",StatsDir,month,year);
sprintf(command,"/bin/cp %s %s.arc",filename,filename);
system(command);
fptr[0] = fopen(filename,"w");
sprintf(filename,"%s/CldTotalStats_%d.dat",StatsDir,month);
sprintf(command,"/bin/cp %s %s.arc",filename,filename);
system(command);
fptr[1] = fopen(filename,"w");

for(i=0; i<2; i++){
if(fptr != NULL){
WriteHeader(griddef,fptr);
for(j=0; j<14; j++)fwrite(
&DataTable[j][0][0],
sizeof(short),
griddef->NumX*griddef->NumY,
fptr
);
printf("Data is %d \n",&DataTable[j][0][0]);
fclose(fptr);
}
}
}
 
J

Jens Thoms Toerring

xiao said:
Can anyone help me to find out what are the structure of 'DataTable' ?
Does loop the 14 layers or the 800*800 array first?
(NumX=NumY=800)
gridde and WriteHeader are two structures

Since the information you give is rather incomplete and not always
consistent all of the following is not more than guesswork...
void WriteCloudStats(GRIDDEF *griddef, char *StatsDir, int month, int
year, short ****DataTable)
{
FILE *fptr[2];
int i,j,k,l;

'k' and 'l' are never used.
char filename[200],command[250],monstr[5];
GRIDDEF header;

'header' is never used
if(month < 10)
sprintf(monstr,"0%d",month);
else
sprintf(monstr,"%d",month);

This could be simplfied to a single line of

sprintf( monstr, "%02d", month );

sprintf(filename,"%s/CldYearlyStats_%d_%d.dat",StatsDir,month,year);
sprintf(command,"/bin/cp %s %s.arc",filename,filename);
system(command);
fptr[0] = fopen(filename,"w");
sprintf(filename,"%s/CldTotalStats_%d.dat",StatsDir,month);
sprintf(command,"/bin/cp %s %s.arc",filename,filename);
system(command);
fptr[1] = fopen(filename,"w");
for(i=0; i<2; i++){
if(fptr != NULL){
WriteHeader(griddef,fptr);


This probably writes whatever 'griddef' points to to the file
for(j=0; j<14; j++)fwrite(
&DataTable[j][0][0],
sizeof(short),
griddef->NumX*griddef->NumY,
fptr
);


This obviously is supposed to write 14 times 'griddef->NumX *
griddef->NumY * sizeof(short)' bytes to the file, with the data
comming from memory starting at address '&DataTable[j][0][0]'
while 'j' is running from 0 through 13.

So you first get 'griddef' written into the file, then 14 repe-
titions of 800x800 data points.

But I am a bit worried if the compiler will like that since it
doesn't have any information that DataTable is a 4-domensional
array and about the index ranges. So it won't be able to calcu-
late where exactly DataTable[j][0][0] is. I guess you will
have to change the function to

void WriteCloudStats( GRIDDEF * griddef,
char *StatsDir,
int month,
int year,
short DataTable[ 2 ][ 14 ][ 800 ][ 800 ] )

to allow the compiler to figure out where the data are. Or you have
to calculate the address yourself with

for ( j =0; j < 14; j++ )
fwrite( DataTable + ( 14 * i + j ) * griddef->NumX * griddef->NumY
sizeof( short ),
griddef->NumX * griddef->NumY,
fptr[ i ] );

while using

void WriteCloudStats( GRIDDEF * griddef,
char *StatsDir,
int month,
int year,
short *DataTable )

That also has the advantage that it also works for other grid sizes
than 800x800.

The inner write loop could then further simplified by getting rid
of it altogether and writing all data in a single call

fwrite( DataTable + 14 * i * griddef->NumX * griddef->NumY
sizeof( short ),
14 * griddef->NumX * griddef->NumY,
fptr[ i ] );

Regards, Jens
 
X

xiao

How about:

sprintf( monstr, "%02d", month );

Thank you guys ~ Actually i compiled and run the program and it
generated a binary file that is 17920168 (800*800*14*2 bytes + 168
bytes header)
And I am trying to read the data stored in the binary file using IDL
and I am nit sure whether i should write like this intarr(14,800,800)
or intarr(800,800.14) But neither of them show a right image.......
Sign......
 
J

Jens Thoms Toerring

xiao said:
Thank you guys ~ Actually i compiled and run the program and it
generated a binary file that is 17920168 (800*800*14*2 bytes + 168
bytes header)

Thar indicates that 'sizeof(short)' is 2.
And I am trying to read the data stored in the binary file using IDL
and I am nit sure whether i should write like this intarr(14,800,800)
or intarr(800,800.14) But neither of them show a right image.......

I don't know anything about IDL and only just had a very short
look at the Application Programming manual. But from what I have
seen I guess that the main problem is that IDL reads more-dimen-
sional binary arrays from files in a FORTRAN fashion. FORTRAN
keeps them in memory in a column by column way while C in a row
by row fashion. And that's also th way you write them out in
your C program. So, if you read them in you have to transpose
the data to transform them back into an order that IDL can deal
with them. Here a short citation from that manual:

Sharing Data With Other Languages -- If binary data written by
a row major language is to be input and used by IDL, transposition
of the data is usually required first. Similarly, if IDL is writing
binary data for use by a program written in a row major language,
transposition of the data before writing (or on input by the other
program) is often required.

And C is a row major language...

Regards, Jens
 
X

xiao

Thar indicates that 'sizeof(short)' is 2.


I don't know anything about IDL and only just had a very short
look at the Application Programming manual. But from what I have
seen I guess that the main problem is that IDL reads more-dimen-
sional binary arrays from files in a FORTRAN fashion. FORTRAN
keeps them in memory in a column by column way while C in a row
by row fashion. And that's also th way you write them out in
your C program. So, if you read them in you have to transpose
the data to transform them back into an order that IDL can deal
with them. Here a short citation from that manual:

Sharing Data With Other Languages -- If binary data written by
a row major language is to be input and used by IDL, transposition
of the data is usually required first. Similarly, if IDL is writing
binary data for use by a program written in a row major language,
transposition of the data before writing (or on input by the other
program) is often required.

And C is a row major language...

Regards, Jens


Hoho~ Thank you very much~ Jens ~
I will try it~ :)
 
C

Chad

xiao said:
Can anyone help me to find out what are the structure of 'DataTable' ?
Does loop the 14 layers or the 800*800 array first?
(NumX=NumY=800)
gridde and WriteHeader are two structures
Thank you~~~ :)
void WriteCloudStats(GRIDDEF *griddef, char *StatsDir, int month, int
year, short ****DataTable)

     Bad ASCII art:

        short****  short***  short**    short*       short

        DataTable -> [0]
                     [1] -> [1][0]
                     ...    [1][1] -> [1][1][0]
                              ...     [1][1][1] -> [1][1][1][0]
                                         ...       [1][1][1][1]
                                                        ...
     FILE *fptr[2];
     int i,j,k,l;
     char filename[200],command[250],monstr[5];
     GRIDDEF header;
     if(month < 10)
        sprintf(monstr,"0%d",month);
     else
        sprintf(monstr,"%d",month);

     `sprintf(monstr, "%02d", month);' is easier.  (Easier still:
leave it out altogether, since `monstr' is never used.)
     sprintf(filename,"%s/CldYearlyStats_%d_
%d.dat",StatsDir,month,year);
     sprintf(command,"/bin/cp %s %s.arc",filename,filename);
     system(command);
     fptr[0] = fopen(filename,"w");
     sprintf(filename,"%s/CldTotalStats_%d.dat",StatsDir,month);
     sprintf(command,"/bin/cp %s %s.arc",filename,filename);
     system(command);
     fptr[1] = fopen(filename,"w");

     You'd better hope that nothing goes wrong with either of
the cp commands, or you could wipe out the old data ...  Since
you don't actually need the original copies (you overwrite them
immediately), why not just use the rename() function to change
the existing files' names?  The benefit is that you can check
whether rename() succeeded or failed; there's no portable way
to do so with system().

Maybe I'm not looking at it close enough, but how do you figure that a
failure with either cp could possibly wipe out the old data?
 
C

Chad

Chad said:
xiao wrote:
[...]
     sprintf(filename,"%s/CldYearlyStats_%d_
%d.dat",StatsDir,month,year);
     sprintf(command,"/bin/cp %s %s.arc",filename,filename);
     system(command);
     fptr[0] = fopen(filename,"w");
     sprintf(filename,"%s/CldTotalStats_%d.dat",StatsDir,month);
     sprintf(command,"/bin/cp %s %s.arc",filename,filename);
     system(command);
     fptr[1] = fopen(filename,"w");
     You'd better hope that nothing goes wrong with either of
the cp commands, or you could wipe out the old data ...  Since
you don't actually need the original copies (you overwrite them
immediately), why not just use the rename() function to change
the existing files' names?  The benefit is that you can check
whether rename() succeeded or failed; there's no portable way
to do so with system().
Maybe I'm not looking at it close enough, but how do you figure that a
failure with either cp could possibly wipe out the old data?

     If "cp foo foo.arc" fails, the original data in "foo" has
not been copied, and "foo" holds the only intact version of it.
If fopen("foo", "w") then succeeds, it truncates "foo" to zero
length and thus loses the only copy of the original data.

     Since the program is going to write a new "foo" this might not
be a tragedy -- but I assume the O.P. placed some value on the old
contents, or he wouldn't have bothered with the "cp" steps.

Maybe I need to read the man pages when I get home from work. Right
now I'm having a hard time picturing how fopen can possibly hose foo
in this case.
 
B

Barry Schwarz

xiao said:
Can anyone help me to find out what are the structure of 'DataTable' ?
Does loop the 14 layers or the 800*800 array first?
(NumX=NumY=800)
gridde and WriteHeader are two structures

Since the information you give is rather incomplete and not always
consistent all of the following is not more than guesswork...
void WriteCloudStats(GRIDDEF *griddef, char *StatsDir, int month, int
year, short ****DataTable)
{
FILE *fptr[2];
int i,j,k,l;

'k' and 'l' are never used.
char filename[200],command[250],monstr[5];
GRIDDEF header;

'header' is never used
if(month < 10)
sprintf(monstr,"0%d",month);
else
sprintf(monstr,"%d",month);

This could be simplfied to a single line of

sprintf( monstr, "%02d", month );

sprintf(filename,"%s/CldYearlyStats_%d_%d.dat",StatsDir,month,year);
sprintf(command,"/bin/cp %s %s.arc",filename,filename);
system(command);
fptr[0] = fopen(filename,"w");
sprintf(filename,"%s/CldTotalStats_%d.dat",StatsDir,month);
sprintf(command,"/bin/cp %s %s.arc",filename,filename);
system(command);
fptr[1] = fopen(filename,"w");
for(i=0; i<2; i++){
if(fptr != NULL){
WriteHeader(griddef,fptr);


This probably writes whatever 'griddef' points to to the file
for(j=0; j<14; j++)fwrite(
&DataTable[j][0][0],
sizeof(short),
griddef->NumX*griddef->NumY,
fptr
);


This obviously is supposed to write 14 times 'griddef->NumX *
griddef->NumY * sizeof(short)' bytes to the file, with the data
comming from memory starting at address '&DataTable[j][0][0]'
while 'j' is running from 0 through 13.

So you first get 'griddef' written into the file, then 14 repe-
titions of 800x800 data points.

But I am a bit worried if the compiler will like that since it
doesn't have any information that DataTable is a 4-domensional
array and about the index ranges. So it won't be able to calcu-


Actually, from the code presented we are guaranteed that DataTable is
in fact not an array. It must be a pointer to pointer to pointer to
pointer and is apparently simulating a 4D array.
late where exactly DataTable[j][0][0] is. I guess you will
have to change the function to

void WriteCloudStats( GRIDDEF * griddef,
char *StatsDir,
int month,
int year,
short DataTable[ 2 ][ 14 ][ 800 ][ 800 ] )

to allow the compiler to figure out where the data are. Or you have
to calculate the address yourself with

for ( j =0; j < 14; j++ )
fwrite( DataTable + ( 14 * i + j ) * griddef->NumX * griddef->NumY
sizeof( short ),
griddef->NumX * griddef->NumY,
fptr[ i ] );

while using

void WriteCloudStats( GRIDDEF * griddef,
char *StatsDir,
int month,
int year,
short *DataTable )

That also has the advantage that it also works for other grid sizes
than 800x800.

The inner write loop could then further simplified by getting rid
of it altogether and writing all data in a single call

fwrite( DataTable + 14 * i * griddef->NumX * griddef->NumY
sizeof( short ),
14 * griddef->NumX * griddef->NumY,
fptr[ i ] );

Regards, Jens



Remove del for email
 
X

xiao

Since the information you give is rather incomplete and not always
consistent all of the following is not more than guesswork...
void WriteCloudStats(GRIDDEF *griddef, char *StatsDir, int month, int
year, short ****DataTable)
{
FILE *fptr[2];
int i,j,k,l;
'k' and 'l' are never used.
char filename[200],command[250],monstr[5];
GRIDDEF header;
'header' is never used
This could be simplfied to a single line of
sprintf( monstr, "%02d", month );
sprintf(filename,"%s/CldYearlyStats_%d_%d.dat",StatsDir,month,year);
sprintf(command,"/bin/cp %s %s.arc",filename,filename);
system(command);
fptr[0] = fopen(filename,"w");
sprintf(filename,"%s/CldTotalStats_%d.dat",StatsDir,month);
sprintf(command,"/bin/cp %s %s.arc",filename,filename);
system(command);
fptr[1] = fopen(filename,"w");
for(i=0; i<2; i++){
if(fptr != NULL){
WriteHeader(griddef,fptr);

This probably writes whatever 'griddef' points to to the file
for(j=0; j<14; j++)fwrite(
&DataTable[j][0][0],
sizeof(short),
griddef->NumX*griddef->NumY,
fptr
);

This obviously is supposed to write 14 times 'griddef->NumX *
griddef->NumY * sizeof(short)' bytes to the file, with the data
comming from memory starting at address '&DataTable[j][0][0]'
while 'j' is running from 0 through 13.

So you first get 'griddef' written into the file, then 14 repe-
titions of 800x800 data points.
But I am a bit worried if the compiler will like that since it
doesn't have any information that DataTable is a 4-domensional
array and about the index ranges. So it won't be able to calcu-

Actually, from the code presented we are guaranteed that DataTable is
in fact not an array. It must be a pointer to pointer to pointer to
pointer and is apparently simulating a 4D array.


late where exactly DataTable[j][0][0] is. I guess you will
have to change the function to

void WriteCloudStats( GRIDDEF * griddef,
char *StatsDir,
int month,
int year,
short DataTable[ 2 ][ 14 ][ 800 ][ 800 ] )
to allow the compiler to figure out where the data are. Or you have
to calculate the address yourself with
for ( j =0; j < 14; j++ )
fwrite( DataTable + ( 14 * i + j ) * griddef->NumX * griddef->NumY
sizeof( short ),
griddef->NumX * griddef->NumY,
fptr[ i ] );
while using
void WriteCloudStats( GRIDDEF * griddef,
char *StatsDir,
int month,
int year,
short *DataTable )
That also has the advantage that it also works for other grid sizes
than 800x800.
The inner write loop could then further simplified by getting rid
of it altogether and writing all data in a single call
fwrite( DataTable + 14 * i * griddef->NumX * griddef->NumY
sizeof( short ),
14 * griddef->NumX * griddef->NumY,
fptr[ i ] );
Regards, Jens

Remove del for email


yup ,i think it is a pointer :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,061
Latest member
KetonaraKeto

Latest Threads

Top