1 
2 ///////////////////////////////////////////////////////////
3 //                                                       //
4 //                         SAGA                          //
5 //                                                       //
6 //      System for Automated Geoscientific Analyses      //
7 //                                                       //
8 //                     Tool Library                      //
9 //                    statistics_grid                    //
10 //                                                       //
11 //-------------------------------------------------------//
12 //                                                       //
13 //                 GSGrid_Statistics.cpp                 //
14 //                                                       //
15 //                 Copyright (C) 2003 by                 //
16 //                      Olaf Conrad                      //
17 //                                                       //
18 //-------------------------------------------------------//
19 //                                                       //
20 // This file is part of 'SAGA - System for Automated     //
21 // Geoscientific Analyses'. SAGA is free software; you   //
22 // can redistribute it and/or modify it under the terms  //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the     //
25 // License, or (at your option) any later version.       //
26 //                                                       //
27 // SAGA is distributed in the hope that it will be       //
28 // useful, but WITHOUT ANY WARRANTY; without even the    //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
30 // PARTICULAR PURPOSE. See the GNU General Public        //
31 // License for more details.                             //
32 //                                                       //
33 // You should have received a copy of the GNU General    //
34 // Public License along with this program; if not, see   //
35 // <http://www.gnu.org/licenses/>.                       //
36 //                                                       //
37 //-------------------------------------------------------//
38 //                                                       //
39 //    e-mail:     oconrad@saga-gis.org                   //
40 //                                                       //
41 //    contact:    Olaf Conrad                            //
42 //                Institute of Geography                 //
43 //                University of Goettingen               //
44 //                Goldschmidtstr. 5                      //
45 //                37077 Goettingen                       //
46 //                Germany                                //
47 //                                                       //
48 ///////////////////////////////////////////////////////////
49 
50 //---------------------------------------------------------
51 #include "GSGrid_Statistics.h"
52 
53 
54 ///////////////////////////////////////////////////////////
55 //														 //
56 //														 //
57 //														 //
58 ///////////////////////////////////////////////////////////
59 
60 //---------------------------------------------------------
CGSGrid_Statistics(void)61 CGSGrid_Statistics::CGSGrid_Statistics(void)
62 {
63 	Set_Name		(_TL("Statistics for Grids"));
64 
65 	Set_Author		("O.Conrad (c) 2005");
66 
67 	Set_Description	(_TW(
68 		"Calculates statistical properties (arithmetic mean, minimum, maximum, "
69 		"variance, standard deviation) for each cell position for the values of "
70 		"the selected grids.\n"
71 		"Optionally you can supply a list of grids with weights. If you want to "
72 		"use weights, the number of value and weight grids have to be the same "
73 		"Value and weight grids are associated by their order in the lists. "
74 		"Weight grids have not to share the grid system of the value grids. "
75 		"In case that no weight can be obtained from a weight grid for value, "
76 		"that value will be ignored. "
77 	));
78 
79 	Parameters.Add_Grid_List("",
80 		"GRIDS"		, _TL("Values"),
81 		_TL(""),
82 		PARAMETER_INPUT
83 	);
84 
85 	Parameters.Add_Grid_List("",
86 		"WEIGHTS"	, _TL("Weights"),
87 		_TL(""),
88 		PARAMETER_INPUT_OPTIONAL, false
89 	);
90 
91 	Parameters.Add_Choice("WEIGHTS",
92 		"RESAMPLING", _TL("Resampling"),
93 		_TL(""),
94 		CSG_String::Format("%s|%s|%s|%s",
95 			_TL("Nearest Neighbour"),
96 			_TL("Bilinear Interpolation"),
97 			_TL("Bicubic Spline Interpolation"),
98 			_TL("B-Spline Interpolation")
99 		), 0
100 	);
101 
102 	Parameters.Add_Grid("", "MEAN"    , _TL("Arithmetic Mean"             ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
103 	Parameters.Add_Grid("", "MIN"     , _TL("Minimum"                     ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
104 	Parameters.Add_Grid("", "MAX"     , _TL("Maximum"                     ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
105 	Parameters.Add_Grid("", "RANGE"   , _TL("Range"                       ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
106 	Parameters.Add_Grid("", "SUM"     , _TL("Sum"                         ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
107 	Parameters.Add_Grid("", "SUM2"    , _TL("Sum2"                        ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
108 	Parameters.Add_Grid("", "VAR"     , _TL("Variance"                    ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
109 	Parameters.Add_Grid("", "STDDEV"  , _TL("Standard Deviation"          ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
110 	Parameters.Add_Grid("", "STDDEVLO", _TL("Mean less Standard Deviation"), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
111 	Parameters.Add_Grid("", "STDDEVHI", _TL("Mean plus Standard Deviation"), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
112 	Parameters.Add_Grid("", "PCTL"    , _TL("Percentile"                  ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
113 
114 	Parameters.Add_Double("PCTL",
115 		"PCTL_VAL"	, _TL("Percentile"),
116 		_TL(""),
117 		50., 0., true, 100., true
118 	);
119 }
120 
121 
122 ///////////////////////////////////////////////////////////
123 //														 //
124 ///////////////////////////////////////////////////////////
125 
126 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)127 int CGSGrid_Statistics::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
128 {
129 	if(	pParameter->Cmp_Identifier("PCTL") )
130 	{
131 		pParameters->Set_Enabled("PCTL_VAL", pParameter->asPointer() != NULL);
132 	}
133 
134 	if(	pParameter->Cmp_Identifier("WEIGHTS") )
135 	{
136 		pParameters->Set_Enabled("RESAMPLING", pParameter->asGridList()->Get_Grid_Count() > 0);
137 	}
138 
139 	return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
140 }
141 
142 
143 ///////////////////////////////////////////////////////////
144 //														 //
145 ///////////////////////////////////////////////////////////
146 
147 //---------------------------------------------------------
On_Execute(void)148 bool CGSGrid_Statistics::On_Execute(void)
149 {
150 	CSG_Parameter_Grid_List	*pGrids	= Parameters("GRIDS")->asGridList();
151 
152 	if( pGrids->Get_Grid_Count() <= 1 )
153 	{
154 		Error_Set(_TL("no grids in selection"));
155 
156 		return( false );
157 	}
158 
159 	//-----------------------------------------------------
160 	CSG_Parameter_Grid_List	*pWeights	= Parameters("WEIGHTS")->asGridList();
161 
162 	if( pWeights->Get_Grid_Count() == 0 )
163 	{
164 		pWeights	= NULL;
165 	}
166 	else if( pWeights->Get_Grid_Count() != pGrids->Get_Grid_Count() )
167 	{
168 		Error_Set(_TL("number of weight grids have to be equal to the number of value grids"));
169 
170 		return( false );
171 	}
172 
173 	//-----------------------------------------------------
174 	TSG_Grid_Resampling	Resampling;
175 
176 	switch( Parameters("RESAMPLING")->asInt() )
177 	{
178 	default: Resampling = GRID_RESAMPLING_NearestNeighbour; break;
179 	case  1: Resampling = GRID_RESAMPLING_Bilinear        ; break;
180 	case  2: Resampling = GRID_RESAMPLING_BicubicSpline   ; break;
181 	case  3: Resampling = GRID_RESAMPLING_BSpline         ; break;
182 	}
183 
184 	//-----------------------------------------------------
185 	#define Get_Output(id) Parameters(id)->asGrid(); if( Parameters(id)->asGrid() ) bHasOutput = true;
186 
187 	bool	bHasOutput	= false;
188 
189 	CSG_Grid *pMean       = Get_Output("MEAN"    );
190 	CSG_Grid *pMin        = Get_Output("MIN"     );
191 	CSG_Grid *pMax        = Get_Output("MAX"     );
192 	CSG_Grid *pRange      = Get_Output("RANGE"   );
193 	CSG_Grid *pSum        = Get_Output("SUM"     );
194 	CSG_Grid *pSum2       = Get_Output("SUM2"    );
195 	CSG_Grid *pVar        = Get_Output("VAR"     );
196 	CSG_Grid *pStdDev     = Get_Output("STDDEV"  );
197 	CSG_Grid *pStdDevLo   = Get_Output("STDDEVLO");
198 	CSG_Grid *pStdDevHi   = Get_Output("STDDEVHI");
199 	CSG_Grid *pPercentile = Get_Output("PCTL"    );
200 
201 	if( !bHasOutput )
202 	{
203 		Error_Set(_TL("no output parameter has been selected"));
204 
205 		return( false );
206 	}
207 
208 	double	Rank	= Parameters("PCTL_VAL")->asDouble();
209 
210 	if( pPercentile )
211 	{
212 		pPercentile->Fmt_Name("%s [%.1f]", _TL("Percentile"), Rank);
213 	}
214 
215 	//-----------------------------------------------------
216 	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
217 	{
218 		#pragma omp parallel for
219 		for(int x=0; x<Get_NX(); x++)
220 		{
221 			CSG_Simple_Statistics s(pPercentile != NULL);
222 
223 			for(int i=0; i<pGrids->Get_Grid_Count(); i++)
224 			{
225 				if( !pGrids->Get_Grid(i)->is_NoData(x, y) )
226 				{
227 					if( pWeights )
228 					{
229 						double	w = 0.;
230 
231 						if( pWeights->Get_Grid(i)->Get_Value(Get_System().Get_Grid_to_World(x, y), w, Resampling) && w > 0. )
232 						{
233 							s.Add_Value(pGrids->Get_Grid(i)->asDouble(x, y), w);
234 						}
235 					}
236 					else
237 					{
238 						s.Add_Value(pGrids->Get_Grid(i)->asDouble(x, y));
239 					}
240 				}
241 			}
242 
243 			//---------------------------------------------
244 			if( s.Get_Count() < 1 )
245 			{
246 				if( pMean       ) pMean      ->Set_NoData(x, y);
247 				if( pMin        ) pMin       ->Set_NoData(x, y);
248 				if( pMax        ) pMax       ->Set_NoData(x, y);
249 				if( pRange      ) pRange     ->Set_NoData(x, y);
250 				if( pSum        ) pSum       ->Set_NoData(x, y);
251 				if( pSum2       ) pSum2      ->Set_NoData(x, y);
252 				if( pVar        ) pVar       ->Set_NoData(x, y);
253 				if( pStdDev     ) pStdDev    ->Set_NoData(x, y);
254 				if( pStdDevLo   ) pStdDevLo  ->Set_NoData(x, y);
255 				if( pStdDevHi   ) pStdDevHi  ->Set_NoData(x, y);
256 				if( pPercentile ) pPercentile->Set_NoData(x, y);
257 			}
258 			else
259 			{
260 				if( pMean       ) pMean      ->Set_Value(x, y, s.Get_Mean          ());
261 				if( pMin        ) pMin       ->Set_Value(x, y, s.Get_Minimum       ());
262 				if( pMax        ) pMax       ->Set_Value(x, y, s.Get_Maximum       ());
263 				if( pRange      ) pRange     ->Set_Value(x, y, s.Get_Range         ());
264 				if( pSum        ) pSum       ->Set_Value(x, y, s.Get_Sum           ());
265 				if( pSum2       ) pSum2      ->Set_Value(x, y, s.Get_Sum_Of_Squares());
266 				if( pVar        ) pVar       ->Set_Value(x, y, s.Get_Variance      ());
267 				if( pStdDev     ) pStdDev    ->Set_Value(x, y, s.Get_StdDev        ());
268 				if( pStdDevLo   ) pStdDevLo  ->Set_Value(x, y, s.Get_Mean() - s.Get_StdDev());
269 				if( pStdDevHi   ) pStdDevHi  ->Set_Value(x, y, s.Get_Mean() + s.Get_StdDev());
270 				if( pPercentile ) pPercentile->Set_Value(x, y, s.Get_Percentile(Rank));
271 			}
272 		}
273 	}
274 
275 	//-----------------------------------------------------
276 	return( true );
277 }
278 
279 
280 ///////////////////////////////////////////////////////////
281 //														 //
282 //														 //
283 //														 //
284 ///////////////////////////////////////////////////////////
285 
286 //---------------------------------------------------------
CGSGrid_Unique_Value_Statistics(void)287 CGSGrid_Unique_Value_Statistics::CGSGrid_Unique_Value_Statistics(void)
288 {
289 	Set_Name		(_TL("Unique Value Statistics for Grids"));
290 
291 	Set_Author		("O.Conrad (c) 2020");
292 
293 	Set_Description	(_TW(
294 		"This tool analyzes for each cell position the uniquely appearing values "
295 		"of the input grids. Output is the number of unique values, the most "
296 		"frequent value (the majority), and the least frequent value (minority). "
297 	));
298 
299 	Parameters.Add_Grid_List("",
300 		"GRIDS"		, _TL("Values"),
301 		_TL(""),
302 		PARAMETER_INPUT
303 	);
304 
305 	Parameters.Add_Grid("", "MAJORITY", _TL("Majority"               ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
306 	Parameters.Add_Grid("", "MINORITY", _TL("Minority"               ), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
307 	Parameters.Add_Grid("", "NUNIQUES", _TL("Number of Unique Values"), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
308 }
309 
310 
311 ///////////////////////////////////////////////////////////
312 //														 //
313 ///////////////////////////////////////////////////////////
314 
315 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)316 int CGSGrid_Unique_Value_Statistics::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
317 {
318 	return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
319 }
320 
321 
322 ///////////////////////////////////////////////////////////
323 //														 //
324 ///////////////////////////////////////////////////////////
325 
326 //---------------------------------------------------------
On_Execute(void)327 bool CGSGrid_Unique_Value_Statistics::On_Execute(void)
328 {
329 	CSG_Parameter_Grid_List	*pGrids	= Parameters("GRIDS")->asGridList();
330 
331 	if( pGrids->Get_Grid_Count() <= 1 )
332 	{
333 		Error_Set(_TL("no grids in selection"));
334 
335 		return( false );
336 	}
337 
338 	//-----------------------------------------------------
339 	#define Get_Output(id) Parameters(id)->asGrid(); if( Parameters(id)->asGrid() ) bHasOutput = true;
340 
341 	bool	bHasOutput	= false;
342 
343 	CSG_Grid *pMajority   = Get_Output("MAJORITY");
344 	CSG_Grid *pMinority   = Get_Output("MINORITY");
345 	CSG_Grid *pNUniques   = Get_Output("NUNIQUES");
346 
347 	//-----------------------------------------------------
348 	if( !bHasOutput )
349 	{
350 		Error_Set(_TL("no output parameter has been selected"));
351 
352 		return( false );
353 	}
354 
355 	//-----------------------------------------------------
356 	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
357 	{
358 		#pragma omp parallel for
359 		for(int x=0; x<Get_NX(); x++)
360 		{
361 			CSG_Unique_Number_Statistics s;
362 
363 			for(int i=0; i<pGrids->Get_Grid_Count(); i++)
364 			{
365 				if( !pGrids->Get_Grid(i)->is_NoData(x, y) )
366 				{
367 					s	+= pGrids->Get_Grid(i)->asDouble(x, y);
368 				}
369 			}
370 
371 			//---------------------------------------------
372 			if( s.Get_Count() < 1 )
373 			{
374 				if( pMajority ) pMajority->Set_NoData(x, y);
375 				if( pMinority ) pMinority->Set_NoData(x, y);
376 				if( pNUniques ) pNUniques->Set_NoData(x, y);
377 			}
378 			else
379 			{
380 				if( pMajority ) { double d; s.Get_Majority(d); pMajority->Set_Value(x, y, d); }
381 				if( pMinority ) { double d; s.Get_Minority(d); pMinority->Set_Value(x, y, d); }
382 				if( pNUniques ) pNUniques->Set_Value(x, y, s.Get_Count());
383 			}
384 		}
385 	}
386 
387 	//-----------------------------------------------------
388 	return( true );
389 }
390 
391 
392 ///////////////////////////////////////////////////////////
393 //														 //
394 //														 //
395 //														 //
396 ///////////////////////////////////////////////////////////
397 
398 //---------------------------------------------------------
CGSGrid_Statistics_To_Table(void)399 CGSGrid_Statistics_To_Table::CGSGrid_Statistics_To_Table(void)
400 {
401 	Set_Name		(_TL("Save Grid Statistics to Table"));
402 
403 	Set_Author		("O.Conrad (c) 2013");
404 
405 	Set_Description	(_TW(
406 		"Calculates statistical properties (arithmetic mean, minimum, maximum, "
407 		"variance, standard deviation) for each of the given grids and saves "
408 		"it to a table."
409 	));
410 
411 	Parameters.Add_Grid_List("",
412 		"GRIDS"	, _TL("Grids"),
413 		_TL(""),
414 		PARAMETER_INPUT
415 	);
416 
417 	Parameters.Add_Table("",
418 		"STATS"	, _TL("Statistics for Grids"),
419 		_TL(""),
420 		PARAMETER_OUTPUT
421 	);
422 
423 	Parameters.Add_Bool("", "DATA_CELLS"  , _TL("Number of Data Cells"        ), _TL(""), false);
424 	Parameters.Add_Bool("", "NODATA_CELLS", _TL("Number of No-Data Cells"     ), _TL(""), false);
425 	Parameters.Add_Bool("", "CELLSIZE"    , _TL("Cellsize"                    ), _TL(""), false);
426 	Parameters.Add_Bool("", "MEAN"        , _TL("Arithmetic Mean"             ), _TL(""),  true);
427 	Parameters.Add_Bool("", "MIN"         , _TL("Minimum"                     ), _TL(""),  true);
428 	Parameters.Add_Bool("", "MAX"         , _TL("Maximum"                     ), _TL(""),  true);
429 	Parameters.Add_Bool("", "RANGE"       , _TL("Range"                       ), _TL(""), false);
430 	Parameters.Add_Bool("", "SUM"         , _TL("Sum"                         ), _TL(""), false);
431 	Parameters.Add_Bool("", "SUM2"        , _TL("Sum of Squares"              ), _TL(""), false);
432 	Parameters.Add_Bool("", "VAR"         , _TL("Variance"                    ), _TL(""),  true);
433 	Parameters.Add_Bool("", "STDDEV"      , _TL("Standard Deviation"          ), _TL(""),  true);
434 	Parameters.Add_Bool("", "STDDEVLO"    , _TL("Mean less Standard Deviation"), _TL(""), false);
435 	Parameters.Add_Bool("", "STDDEVHI"    , _TL("Mean plus Standard Deviation"), _TL(""), false);
436 
437 	Parameters.Add_String("",
438 		"PCTL_VAL"	, _TL("Percentiles"),
439 		_TL("Separate the desired percentiles by semicolon"),
440 		"5; 25; 50; 75; 95"
441 	);
442 
443 	Parameters.Add_Bool("PCTL_VAL",
444 		"PCTL_HST"	, _TL("From Histogram"),
445 		_TL(""),
446 		true
447 	);
448 
449 	Parameters.Add_Double("",
450 		"SAMPLES"	, _TL("Sample Size"),
451 		_TL("Minimum sample size [percent] used to calculate statistics. Ignored, if set to zero."),
452 		0., 0., true, 100., true
453 	);
454 }
455 
456 
457 ///////////////////////////////////////////////////////////
458 //														 //
459 ///////////////////////////////////////////////////////////
460 
461 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter)462 int CGSGrid_Statistics_To_Table::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
463 {
464 	return( CSG_Tool_Grid::On_Parameter_Changed(pParameters, pParameter) );
465 }
466 
467 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)468 int CGSGrid_Statistics_To_Table::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
469 {
470 	if(	pParameter->Cmp_Identifier("PCTL_VAL") )
471 	{
472 		pParameters->Set_Enabled("PCTL_HST", *pParameter->asString() != '\0');
473 	}
474 
475 	return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
476 }
477 
478 
479 ///////////////////////////////////////////////////////////
480 //														 //
481 ///////////////////////////////////////////////////////////
482 
483 //---------------------------------------------------------
On_Execute(void)484 bool CGSGrid_Statistics_To_Table::On_Execute(void)
485 {
486 	CSG_Parameter_Grid_List	*pGrids	= Parameters("GRIDS")->asGridList();
487 
488 	if( pGrids->Get_Grid_Count() < 1 )
489 	{
490 		Error_Set(_TL("no grids in selection"));
491 
492 		return( false );
493 	}
494 
495 	//-----------------------------------------------------
496 	CSG_Table	*pTable	= Parameters("STATS")->asTable();
497 
498 	pTable->Destroy();
499 	pTable->Set_Name(_TL("Statistics for Grids"));
500 	pTable->Add_Field(_TL("NAME"), SG_DATATYPE_String);
501 
502 	if( Parameters("DATA_CELLS"  )->asBool() )	pTable->Add_Field(_TL("DATA_CELLS"  ), SG_DATATYPE_Int   );
503 	if( Parameters("NODATA_CELLS")->asBool() )	pTable->Add_Field(_TL("NODATA_CELLS"), SG_DATATYPE_Int   );
504 	if( Parameters("CELLSIZE"    )->asBool() )	pTable->Add_Field(_TL("CELLSIZE"    ), SG_DATATYPE_Double);
505 	if( Parameters("MEAN"        )->asBool() )	pTable->Add_Field(_TL("MEAN"        ), SG_DATATYPE_Double);
506 	if( Parameters("MIN"         )->asBool() )	pTable->Add_Field(_TL("MIN"         ), SG_DATATYPE_Double);
507 	if( Parameters("MAX"         )->asBool() )	pTable->Add_Field(_TL("MAX"         ), SG_DATATYPE_Double);
508 	if( Parameters("RANGE"       )->asBool() )	pTable->Add_Field(_TL("RANGE"       ), SG_DATATYPE_Double);
509 	if( Parameters("SUM"         )->asBool() )	pTable->Add_Field(_TL("SUM"         ), SG_DATATYPE_Double);
510 	if( Parameters("SUM2"        )->asBool() )	pTable->Add_Field(_TL("SUM2"        ), SG_DATATYPE_Double);
511 	if( Parameters("VAR"         )->asBool() )	pTable->Add_Field(_TL("VAR"         ), SG_DATATYPE_Double);
512 	if( Parameters("STDDEV"      )->asBool() )	pTable->Add_Field(_TL("STDDEV"      ), SG_DATATYPE_Double);
513 	if( Parameters("STDDEVLO"    )->asBool() )	pTable->Add_Field(_TL("STDDEVLO"    ), SG_DATATYPE_Double);
514 	if( Parameters("STDDEVHI"    )->asBool() )	pTable->Add_Field(_TL("STDDEVHI"    ), SG_DATATYPE_Double);
515 
516 	//-----------------------------------------------------
517 	CSG_Table	Percentiles;
518 
519 	Percentiles.Add_Field("FIELD", SG_DATATYPE_Int   );
520 	Percentiles.Add_Field("VALUE", SG_DATATYPE_Double);
521 
522 	for(CSG_String_Tokenizer Values(Parameters("PCTL_VAL")->asString(), ";"); Values.Has_More_Tokens(); )
523 	{
524 		CSG_String	s(Values.Get_Next_Token()); s.Trim_Both();	double	v;
525 
526 		if( s.asDouble(v) && v >= 0. && v <= 100. )
527 		{
528 			int	n	= Percentiles.Get_Count();
529 
530 			Percentiles.Add_Record();
531 
532 			Percentiles[n].Set_Value(0, pTable->Get_Field_Count());
533 			Percentiles[n].Set_Value(1, v);
534 
535 			pTable->Add_Field(CSG_String::Format("%s%02d", _TL("PCTL"), (int)v), SG_DATATYPE_Double);
536 		}
537 	}
538 
539 	//-----------------------------------------------------
540 	if( pTable->Get_Field_Count() <= 1 )
541 	{
542 		Error_Set(_TL("no parameter output has been selected"));
543 
544 		return( false );
545 	}
546 
547 	sLong nSamples[2]; nSamples[0] = (sLong)(pGrids->Get_System()->Get_NCells() * Parameters("SAMPLES")->asDouble() / 100.);
548 
549 	//-----------------------------------------------------
550 	for(int i=0; i<pGrids->Get_Grid_Count() && Process_Get_Okay(); i++)
551 	{
552 		CSG_Grid	*pGrid	= pGrids->Get_Grid(i);
553 
554 		CSG_Table_Record	*pRecord	= pTable->Add_Record();
555 
556 		CSG_Simple_Statistics	s;
557 
558 		if( nSamples[0] > (nSamples[1] = pGrid->Get_Max_Samples()) )
559 		{
560 			pGrid->Set_Max_Samples(nSamples[0]);
561 			s	= pGrid->Get_Statistics();
562 			pGrid->Set_Max_Samples(nSamples[1]);	// restore old sample size
563 		}
564 		else
565 		{
566 			s	= pGrid->Get_Statistics();
567 		}
568 
569 		pRecord->Set_Value("NAME"        , pGrid->Get_Name             ());
570 		pRecord->Set_Value("DATA_CELLS"  , (int)(pGrid->Get_NCells() - pGrid->Get_NoData_Count()));
571 		pRecord->Set_Value("NODATA_CELLS", (int)(                      pGrid->Get_NoData_Count()));
572 		pRecord->Set_Value("CELLSIZE"    , pGrid->Get_Cellsize         ());
573 		pRecord->Set_Value("MEAN"        , s.Get_Mean                  ());
574 		pRecord->Set_Value("MIN"         , s.Get_Minimum               ());
575 		pRecord->Set_Value("MAX"         , s.Get_Maximum               ());
576 		pRecord->Set_Value("RANGE"       , s.Get_Range                 ());
577 		pRecord->Set_Value("SUM"         , s.Get_Sum                   ());
578 		pRecord->Set_Value("SUM2"        , s.Get_Sum_Of_Squares        ());
579 		pRecord->Set_Value("VAR"         , s.Get_Variance              ());
580 		pRecord->Set_Value("STDDEV"      , s.Get_StdDev                ());
581 		pRecord->Set_Value("STDDEVLO"    , s.Get_Mean() - s.Get_StdDev ());
582 		pRecord->Set_Value("STDDEVHI"    , s.Get_Mean() + s.Get_StdDev ());
583 
584 		for(int j=0; j<Percentiles.Get_Count(); j++)
585 		{
586 			pRecord->Set_Value(Percentiles[j].asInt(0),
587 				pGrid->Get_Percentile(Percentiles[j].asDouble(1), Parameters("PCTL_HST")->asBool())
588 			);
589 		}
590 	}
591 
592 	//-----------------------------------------------------
593 	return( true );
594 }
595 
596 
597 ///////////////////////////////////////////////////////////
598 //														 //
599 //														 //
600 //														 //
601 ///////////////////////////////////////////////////////////
602 
603 //---------------------------------------------------------
604