Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
mpim-sw
cdo
Commits
7dad01da
Commit
7dad01da
authored
Apr 19, 2017
by
Uwe Schulzweida
Browse files
samplegridicon: compute mean and std1.
parent
874f1c6a
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/Samplegridicon.c
View file @
7dad01da
...
...
@@ -2,13 +2,16 @@
#include
"cdo_int.h"
#include
"grid.h"
typedef
struct
{
int
ncells
;
int
*
neighbor
;
// neighbor cell index
int
*
parent
;
// parent cell index
int
*
child
;
// child cell index
const
char
*
filename
;
}
cellindex_type
;
static
void
copy_data_to_index
(
int
ncells
,
const
double
*
restrict
data
,
int
*
restrict
cellindex
)
{
...
...
@@ -16,6 +19,15 @@ void copy_data_to_index(int ncells, const double *restrict data, int *restrict c
cellindex
[
i
]
=
(
int
)
lround
(
data
[
i
]);
}
static
void
free_cellindex
(
cellindex_type
*
cellindex
)
{
if
(
cellindex
->
neighbor
)
Free
(
cellindex
->
neighbor
);
if
(
cellindex
->
parent
)
Free
(
cellindex
->
parent
);
if
(
cellindex
->
child
)
Free
(
cellindex
->
child
);
Free
(
cellindex
);
}
static
cellindex_type
*
read_cellindex
(
const
char
*
filename
)
{
...
...
@@ -78,6 +90,10 @@ cellindex_type *read_cellindex(const char *filename)
}
}
// Fortran to C index
for
(
int
i
=
0
;
i
<
3
*
ncells
;
++
i
)
cellindex
->
neighbor
[
i
]
-=
1
;
for
(
int
i
=
0
;
i
<
ncells
;
++
i
)
cellindex
->
parent
[
i
]
-=
1
;
streamClose
(
streamID
);
Free
(
data
);
...
...
@@ -113,114 +129,106 @@ int read_grid(const char *filename)
}
/**
* Find the interval i-1 .. i in which an element x fits and return i, the
* bigger one of the interval borders or x itself if it is an interval border.
* Return the first index of element x fits.
*
* If no interval can be found return
the length of the array
.
* If no interval can be found return
-1
.
* @param *array ascending
or descending
sorted list
* @param n
elem
length of the sorted list
* @param
x
the element to find a position for
* @param *array ascending sorted list
* @param n
length of the sorted list
* @param
search
the element to find a position for
*/
static
int
find_
element
(
int
x
,
int
n
elem
,
const
int
*
restrict
array
)
int
find_
index
(
int
search
,
int
n
,
const
int
*
restrict
array
)
{
int
ii
;
int
mid
=
0
;
int
first
=
1
;
int
last
=
nelem
;
if
(
array
[
0
]
<
array
[
nelem
-
1
]
)
// ascending order
int
first
=
0
;
int
last
=
n
-
1
;
int
middle
=
(
first
+
last
)
/
2
;
while
(
first
<=
last
)
{
/* return the length of the array if x is out of bounds */
if
(
x
<
array
[
0
]
||
x
>
array
[
nelem
-
1
]
)
return
nelem
;
/* search for the interval in which x fits */
// implementation: binary search algorithm
for
(
ii
=
1
;
ii
<
nelem
;
++
ii
)
{
// binary search: divide search room in the middle
// mid = first + ((last - first) >> 1);
// faster!
mid
=
(
first
+
last
)
>>
1
;
/* return the bigger interval border of the interval in which x fits */
// if ( x >= array[mid-1] && x <= array[mid] ) break;
// faster!
if
(
!
(
x
<
array
[
mid
-
1
]
||
x
>
array
[
mid
])
)
break
;
// binary search: ignore half of the search room
if
(
x
>
array
[
mid
]
)
first
=
mid
;
else
last
=
mid
;
}
}
else
{
/* return the length of the array if x is out of bounds */
if
(
x
<
array
[
nelem
-
1
]
||
x
>
array
[
0
]
)
return
nelem
;
/* search for the interval in which x fits */
// implementation: binary search algorithm
for
(
ii
=
1
;
ii
<
nelem
;
++
ii
)
{
// binary search: divide search room in the middle
// mid = first + ((last - first) >> 1);
// faster!
mid
=
(
first
+
last
)
>>
1
;
/* return the bigger interval border of the interval in which x fits */
// if ( x >= array[mid] && x <= array[mid-1] ) break;
// faster!
if
(
!
(
x
<
array
[
mid
]
||
x
>
array
[
mid
-
1
])
)
break
;
// binary search: ignore half of the search room
if
(
x
<
array
[
mid
]
)
first
=
mid
;
else
last
=
mid
;
}
if
(
array
[
middle
]
<
search
)
first
=
middle
+
1
;
else
if
(
array
[
middle
]
==
search
)
{
for
(
int
i
=
middle
;
i
>=
0
;
i
--
)
{
if
(
array
[
i
]
==
search
)
middle
=
i
;
else
break
;
}
return
middle
;
}
else
last
=
middle
-
1
;
middle
=
(
first
+
last
)
/
2
;
}
if
(
mid
>
1
&&
IS_EQUAL
(
x
,
array
[
mid
-
1
])
)
mid
--
;
return
mid
;
return
-
1
;
}
static
void
samplegri
d
(
cellindex_type
*
cellindex1
,
double
*
array1
,
cellindex_type
*
cellindex2
,
double
*
array2
,
int
*
samp2
)
void
compute_chil
d
(
cellindex_type
*
cellindex1
,
cellindex_type
*
cellindex2
)
{
int
ncells1
=
cellindex1
->
ncells
;
int
*
parent1
=
cellindex1
->
parent
;
int
ncells2
=
cellindex2
->
ncells
;
int
*
child2
=
(
int
*
)
Malloc
(
4
*
ncells2
*
sizeof
(
int
));
cellindex2
->
child
=
child2
;
for
(
int
i
=
0
;
i
<
ncells2
;
++
i
)
{
int
j
=
find_element
(
i
+
1
,
ncells1
,
cellindex1
->
parent
);
if
(
i
%
10000
==
0
)
printf
(
"%d %d %d %d %d %d %d
\n
"
,
i
,
j
,
cellindex1
->
parent
[
j
-
2
],
cellindex1
->
parent
[
j
-
1
],
cellindex1
->
parent
[
j
],
cellindex1
->
parent
[
j
+
1
],
cellindex1
->
parent
[
j
+
2
]);
if
(
j
==
i
+
1
)
for
(
int
k
=
0
;
k
<
4
;
++
k
)
child2
[
i
*
4
+
k
]
=
-
1
;
int
j
=
find_index
(
i
,
ncells1
,
parent1
);
if
(
j
<
0
)
continue
;
for
(
int
k
=
0
;
k
<
4
;
++
k
)
{
if
(
i
!=
parent1
[
j
+
k
]
)
break
;
child2
[
i
*
4
+
k
]
=
j
+
k
;
}
// if ( i%10000 == 0 ) printf("%d %d %d %d %d %d\n", i, j, parent1[j], parent1[j+1], parent1[j+2], parent1[j+3]);
}
}
static
void
compute_
child
(
cellindex_type
*
cellindex1
,
cellindex_type
*
cellindex
2
)
void
compute_
sum
(
int
i
,
int
*
n
,
double
*
sum
,
double
*
sumq
,
int
kci
,
cellindex_type
*
*
cellindex
,
double
*
array
)
{
int
ncells2
=
cellindex2
->
ncells
;
cellindex2
->
child
=
(
int
*
)
Malloc
(
4
*
ncells2
*
sizeof
(
int
));
// printf("compute: i, kci %d %d\n", i, kci);
int
ncells2
=
cellindex
[
kci
]
->
ncells
;
if
(
i
<
0
||
i
>
ncells2
)
cdoAbort
(
"Child grid cell index %d out of bounds %d!"
,
i
,
ncells2
);
for
(
int
k
=
0
;
k
<
4
;
++
k
)
{
int
index
=
cellindex
[
kci
]
->
child
[
i
*
4
+
k
];
if
(
index
==
-
1
)
break
;
if
(
kci
==
1
)
{
*
sum
+=
array
[
index
];
*
sumq
+=
array
[
index
]
*
array
[
index
];
*
n
+=
1
;
}
else
compute_sum
(
index
,
n
,
sum
,
sumq
,
kci
-
1
,
cellindex
,
array
);
}
}
/*
static
void
map_index(int num_links, int dst_size, int *src_idx, int *dst_id
x, double *
src_
array, double *
dst_
array, double
missval
)
void
samplegrid
(
double
missval
,
int
nci
,
cellindex_type
**
cellinde
x
,
double
*
array
1
,
double
*
array
2
,
double
*
array3
)
{
for ( int n = 0; n < dst_size; ++n ) dst_array[n] = missval;
for ( int n = 0; n < num_links; ++n ) dst_array[dst_idx[n]] = 0.;
for ( int n = 0; n < num_links; ++n ) dst_array[dst_idx[n]] += src_array[src_idx[n]];
int
kci
=
nci
-
1
;
int
ncells2
=
cellindex
[
kci
]
->
ncells
;
#if defined(_OPENMP)
#pragma omp parallel for default(none) shared(missval, ncells2, kci, cellindex, array1, array2, array3)
#endif
for
(
int
i
=
0
;
i
<
ncells2
;
++
i
)
{
int
n
=
0
;
double
sum
=
0
,
sumq
=
0
;
compute_sum
(
i
,
&
n
,
&
sum
,
&
sumq
,
kci
,
cellindex
,
array1
);
array2
[
i
]
=
n
?
sum
/
n
:
missval
;
// mean
double
var1
=
(
n
*
n
>
n
)
?
(
sumq
*
n
-
sum
*
sum
)
/
(
n
*
n
-
n
)
:
missval
;
if
(
var1
<
0
&&
var1
>
-
1.e-5
)
var1
=
0
;
array3
[
i
]
=
var_to_std
(
var1
,
missval
);
// std1
}
}
*/
#include
"pstream.h"
...
...
@@ -229,7 +237,6 @@ void *Samplegridicon(void *argument)
{
int
nrecs
;
int
varID
,
levelID
;
int
nmiss
;
cdoInitialize
(
argument
);
...
...
@@ -238,23 +245,31 @@ void *Samplegridicon(void *argument)
int
nsamplegrids
=
operatorArgc
();
if
(
nsamplegrids
<
2
)
cdoAbort
(
"Parameter missing!"
);
cellindex_type
*
cellindex1
=
read_cellindex
(
operatorArgv
()[
0
]);
printf
(
"ncells %d
\n
"
,
cellindex1
->
ncells
);
cellindex_type
*
cellindex2
=
read_cellindex
(
operatorArgv
()[
1
]);
printf
(
"ncells %d
\n
"
,
cellindex2
->
ncells
);
cellindex_type
*
cellindex
[
nsamplegrids
];
for
(
int
i
=
0
;
i
<
nsamplegrids
;
++
i
)
{
cellindex
[
i
]
=
read_cellindex
(
operatorArgv
()[
i
]);
cellindex
[
i
]
->
filename
=
operatorArgv
()[
i
];
if
(
cdoVerbose
)
cdoPrint
(
"Found %d grid cells in %s"
,
cellindex
[
i
]
->
ncells
,
cellindex
[
i
]
->
filename
);
}
compute_child
(
cellindex1
,
cellindex2
);
for
(
int
i
=
0
;
i
<
nsamplegrids
-
1
;
++
i
)
compute_child
(
cellindex
[
i
],
cellindex
[
i
+
1
]);
int
gridID2
=
read_grid
(
operatorArgv
()[
1
]);
int
gridID2
=
read_grid
(
operatorArgv
()[
nsamplegrids
-
1
]);
int
streamID1
=
streamOpenRead
(
cdoStreamName
(
0
));
int
vlistID1
=
streamInqVlist
(
streamID1
);
int
vlistID2
=
vlistDuplicate
(
vlistID1
);
int
vlistID3
=
vlistDuplicate
(
vlistID1
);
int
taxisID1
=
vlistInqTaxis
(
vlistID1
);
int
taxisID2
=
taxisDuplicate
(
taxisID1
);
int
taxisID3
=
taxisDuplicate
(
taxisID1
);
vlistDefTaxis
(
vlistID2
,
taxisID2
);
vlistDefTaxis
(
vlistID3
,
taxisID3
);
int
ngrids
=
vlistNgrids
(
vlistID1
);
for
(
int
index
=
0
;
index
<
ngrids
;
++
index
)
...
...
@@ -265,73 +280,73 @@ void *Samplegridicon(void *argument)
cdoAbort
(
"Unsupported gridtype: %s with %d corners"
,
gridNamePtr
(
gridtype
),
gridInqNvertex
(
gridID
));
vlistChangeGridIndex
(
vlistID2
,
index
,
gridID2
);
vlistChangeGridIndex
(
vlistID3
,
index
,
gridID2
);
}
int
streamID2
=
streamOpenWrite
(
cdoStreamName
(
1
),
cdoFiletype
());
streamDefVlist
(
streamID2
,
vlistID2
);
int
streamID3
=
streamOpenWrite
(
cdoStreamName
(
2
),
cdoFiletype
());
streamDefVlist
(
streamID3
,
vlistID3
);
int
gridsize
=
vlistGridsizeMax
(
vlistID1
);
if
(
vlistNumber
(
vlistID1
)
!=
CDI_REAL
)
gridsize
*=
2
;
double
*
array1
=
(
double
*
)
Malloc
(
gridsize
*
sizeof
(
double
));
int
gridsize2
=
gridInqSize
(
gridID2
);
if
(
cdoVerbose
)
cdoPrint
(
"Target gridsize = %d"
,
gridsize2
);
if
(
vlistNumber
(
vlistID2
)
!=
CDI_REAL
)
gridsize2
*=
2
;
double
*
array2
=
(
double
*
)
Malloc
(
gridsize2
*
sizeof
(
double
));
int
*
samp2
=
(
int
*
)
Malloc
(
gridsize2
*
sizeof
(
int
));
for
(
int
i
=
0
;
i
<
gridsize2
;
++
i
)
samp2
[
i
]
=
0
;
for
(
int
i
=
0
;
i
<
gridsize2
;
++
i
)
array2
[
i
]
=
0
;
double
*
array3
=
(
double
*
)
Malloc
(
gridsize2
*
sizeof
(
double
));
int
tsID
=
0
;
while
(
(
nrecs
=
streamInqTimestep
(
streamID1
,
tsID
))
)
{
taxisCopyTimestep
(
taxisID2
,
taxisID1
);
taxisCopyTimestep
(
taxisID3
,
taxisID1
);
streamDefTimestep
(
streamID2
,
tsID
);
streamDefTimestep
(
streamID3
,
tsID
);
for
(
int
recID
=
0
;
recID
<
nrecs
;
recID
++
)
{
int
nmiss
;
streamInqRecord
(
streamID1
,
&
varID
,
&
levelID
);
streamReadRecord
(
streamID1
,
array1
,
&
nmiss
);
streamDefRecord
(
stream
ID
2
,
varID
,
levelID
);
double
missval
=
vlistInqVarMissval
(
vlist
ID
1
,
varID
);
int
gridID
=
vlistInqVarGrid
(
vlistID
1
,
v
ar
ID
);
samplegrid
(
missval
,
nsamplegrids
,
cellindex
,
array
1
,
ar
ray2
,
array3
);
//for ( int i = 0; i < gridsize2; ++i ) array2[i] = array1[i];
samplegrid
(
cellindex1
,
array1
,
cellindex2
,
array2
,
samp2
);
if
(
nmiss
)
{
nmiss
=
0
;
double
missval
=
vlistInqVarMissval
(
vlistID2
,
varID
);
for
(
int
i
=
0
;
i
<
gridsize2
;
i
++
)
if
(
DBL_IS_EQUAL
(
array2
[
i
],
missval
)
)
nmiss
++
;
}
nmiss
=
0
;
for
(
int
i
=
0
;
i
<
gridsize2
;
++
i
)
if
(
DBL_IS_EQUAL
(
array2
[
i
],
missval
)
)
nmiss
++
;
streamDefRecord
(
streamID2
,
varID
,
levelID
);
streamWriteRecord
(
streamID2
,
array2
,
nmiss
);
nmiss
=
0
;
for
(
int
i
=
0
;
i
<
gridsize2
;
++
i
)
if
(
DBL_IS_EQUAL
(
array3
[
i
],
missval
)
)
nmiss
++
;
streamDefRecord
(
streamID3
,
varID
,
levelID
);
streamWriteRecord
(
streamID3
,
array3
,
nmiss
);
}
tsID
++
;
}
streamClose
(
streamID3
);
streamClose
(
streamID2
);
streamClose
(
streamID1
);
vlistDestroy
(
vlistID2
);
gridDestroy
(
gridID2
);
if
(
samp2
)
Free
(
samp2
);
if
(
array3
)
Free
(
array3
);
if
(
array2
)
Free
(
array2
);
if
(
array1
)
Free
(
array1
);
if
(
cellindex1
->
neighbor
)
Free
(
cellindex1
->
neighbor
);
if
(
cellindex1
->
parent
)
Free
(
cellindex1
->
parent
);
if
(
cellindex1
->
child
)
Free
(
cellindex1
->
child
);
if
(
cellindex2
->
neighbor
)
Free
(
cellindex2
->
neighbor
);
if
(
cellindex2
->
parent
)
Free
(
cellindex2
->
parent
);
if
(
cellindex2
->
child
)
Free
(
cellindex2
->
child
);
for
(
int
i
=
0
;
i
<
nsamplegrids
;
++
i
)
free_cellindex
(
cellindex
[
i
]);
cdoFinish
();
...
...
src/modules.c
View file @
7dad01da
...
...
@@ -699,7 +699,7 @@ static modules_t Modules[] =
{
Rotuv
,
RotuvbHelp
,
RotuvOperators
,
1
,
CDI_REAL
,
1
,
1
},
{
Runpctl
,
RunpctlHelp
,
RunpctlOperators
,
1
,
CDI_REAL
,
1
,
1
},
{
Runstat
,
RunstatHelp
,
RunstatOperators
,
1
,
CDI_REAL
,
1
,
1
},
{
Samplegridicon
,
NULL
,
SamplegridiconOperators
,
1
,
CDI_REAL
,
1
,
1
},
{
Samplegridicon
,
NULL
,
SamplegridiconOperators
,
1
,
CDI_REAL
,
1
,
2
},
{
Seascount
,
NULL
,
SeascountOperators
,
1
,
CDI_BOTH
,
1
,
1
},
{
Seaspctl
,
SeaspctlHelp
,
SeaspctlOperators
,
1
,
CDI_REAL
,
3
,
1
},
{
Seasstat
,
SeasstatHelp
,
SeasstatOperators
,
1
,
CDI_REAL
,
1
,
1
},
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment