00001 #include "TePDIStatistic.hpp"
00002
00003 #include "../kernel/TeAgnostic.h"
00004 #include "TePDIUtils.hpp"
00005
00006 #include "../kernel/TeUtils.h"
00007 #include "../kernel/TeBox.h"
00008 #include "../kernel/TeGeometryAlgorithms.h"
00009
00010 #include <math.h>
00011 #include <float.h>
00012
00013
00014 TePDIStatistic::TePDIStatistic()
00015 {
00016 iterator_strat_ = TeBoxPixelIn;
00017
00018 polygonset_.reset( new TePolygonSet );
00019 }
00020
00021
00022 TePDIStatistic::~TePDIStatistic()
00023 {
00024 clear();
00025 }
00026
00027
00028 void TePDIStatistic::ResetState( const TePDIParameters& params )
00029 {
00030 if( params_ != params ) {
00031 clear();
00032
00033
00034
00035 if( params.CheckParameter< TeStrategicIterator > (
00036 "iterator_strat" ) ) {
00037
00038 params.GetParameter( "iterator_strat", iterator_strat_ );
00039 }
00040
00041
00042
00043
00044 TEAGN_TRUE_OR_THROW(
00045 params.GetParameter( "rasters", rasters_ ),
00046 "Missing parameter: rasters" );
00047
00048 TEAGN_TRUE_OR_THROW(
00049 params.GetParameter( "bands", bands_ ),
00050 "Missing parameter: bands" );
00051
00052
00053
00054 if( params.CheckParameter< TePDITypes::TePDIPolygonSetPtrType > (
00055 "polygonset" ) ) {
00056
00057 params.GetParameter( "polygonset", polygonset_ );
00058 } else {
00059 polygonset_.reset( new TePolygonSet );
00060
00061 TeBox rasterbox = rasters_[ 0 ]->params().boundingBox();
00062 TePolygon rasterpol = polygonFromBox( rasterbox );
00063
00064 polygonset_->add( rasterpol );
00065 }
00066
00067
00068
00069 if( params.CheckParameter< std::vector< TePDIHistogram::pointer > >(
00070 "histograms" ) ) {
00071
00072 std::vector< TePDIHistogram::pointer > histograms;
00073 TEAGN_TRUE_OR_THROW( params.GetParameter( "histograms",
00074 histograms ), "Missing parameter: histograms" );
00075 TePDIHistogram* histoPtr = 0;
00076
00077 for( unsigned int index = 0 ; index < rasters_.size() ; ++index )
00078 {
00079 SingleRasterCachesKeyT key;
00080 key.first = index;
00081 key.second = 0;
00082
00083 histoPtr = new TePDIHistogram;
00084 (*histoPtr) = (*histograms[ index ]);
00085
00086 histo_cache_[ key ] = histoPtr;
00087 }
00088 }
00089 }
00090 }
00091
00092
00093 bool TePDIStatistic::RunImplementation()
00094 {
00095 TEAGN_LOG_AND_THROW( "This function cannot be used for this class" );
00096 return false;
00097 }
00098
00099
00100 bool TePDIStatistic::CheckParameters(
00101 const TePDIParameters& parameters ) const
00102 {
00103
00104
00105 TePDITypes::TePDIRasterVectorType rasters;
00106 TEAGN_TRUE_OR_RETURN(
00107 parameters.GetParameter( "rasters", rasters ),
00108 "Missing parameter: rasters" );
00109
00110 std::vector< int > bands;
00111 TEAGN_TRUE_OR_RETURN(
00112 parameters.GetParameter( "bands", bands ),
00113 "Missing parameter: bands" );
00114
00115 TEAGN_TRUE_OR_RETURN( rasters.size() == bands.size(),
00116 "The number of rasters doesn't match the number of bands" );
00117
00118 TEAGN_TRUE_OR_RETURN( rasters.size() > 0, "Invalid number of rasters" );
00119
00120 for( unsigned int index = 0 ; index < rasters.size() ; ++index ) {
00121 TEAGN_TRUE_OR_RETURN( rasters[ index ].isActive(),
00122 "Invalid parameter: raster " +
00123 Te2String( index ) + " inactive" );
00124
00125 TEAGN_TRUE_OR_RETURN(
00126 rasters[ index ]->params().status_ != TeRasterParams::TeNotReady,
00127 "Invalid parameter: raster " +
00128 Te2String( index ) + " not ready" );
00129
00130 TEAGN_TRUE_OR_RETURN(
00131 bands[ index ] >= 0, "Invalid band number (" +
00132 Te2String( index ) + ")" );
00133 TEAGN_TRUE_OR_RETURN(
00134 bands[ index ] < rasters[ index ]->nBands(), "Invalid band number (" +
00135 Te2String( index ) + ")" );
00136
00137
00138
00139 TEAGN_TRUE_OR_RETURN( (
00140 ( rasters[ index ]->params().photometric_[
00141 bands[ index ] ] == TeRasterParams::TeRGB ) ||
00142 ( rasters[ index ]->params().photometric_[
00143 bands[ index ] ] == TeRasterParams::TeMultiBand ) ),
00144 "Invalid parameter - rasters (invalid photometric "
00145 "interpretation)" );
00146 }
00147
00148
00149
00150 TePDITypes::TePDIPolygonSetPtrType polygonset;
00151
00152 if( parameters.CheckParameter< TePDITypes::TePDIPolygonSetPtrType >(
00153 "polygonset" ) ) {
00154
00155 parameters.GetParameter( "polygonset", polygonset );
00156
00157 TEAGN_TRUE_OR_RETURN( polygonset.isActive(),
00158 "Invalid parameter : polygonset" );
00159
00160 TEAGN_TRUE_OR_RETURN( ( polygonset->size() > 0 ),
00161 "Invalid parameter : polygonset" );
00162
00163 TeBox rasterbbox = rasters[ 0 ]->params().boundingBox();
00164 TePolygon raster_bpol = polygonFromBox( rasterbbox );
00165
00166 TePolygonSet::iterator it = polygonset->begin();
00167 TePolygonSet::iterator it_end = polygonset->end();
00168
00169 while( it != it_end ) {
00170 TEAGN_TRUE_OR_RETURN(
00171 ( TeRelation( raster_bpol, *it ) != TeDISJOINT ),
00172 "Invalid parameter : polygonset" );
00173
00174 ++it;
00175 }
00176 }
00177
00178
00179
00180 if( parameters.CheckParameter< std::vector< TePDIHistogram::pointer > > (
00181 "histograms" ) ) {
00182
00183 TEAGN_TRUE_OR_RETURN( ( ! polygonset.isActive() ),
00184 "Invalid parameter: histograms cannot be used when polygonset is "
00185 "present" );
00186
00187 std::vector< TePDIHistogram::pointer > histograms;
00188
00189 TEAGN_TRUE_OR_THROW( parameters.GetParameter( "histograms",
00190 histograms ), "Invalid parameter: histograms" );
00191 TEAGN_TRUE_OR_RETURN( ( histograms.size() == rasters.size() ),
00192 "Invalid parameter: histograms" );
00193
00194 std::vector< TePDIHistogram::pointer >::iterator it =
00195 histograms.begin();
00196 std::vector< TePDIHistogram::pointer >::iterator it_end =
00197 histograms.end();
00198
00199 while( it != it_end ) {
00200 TEAGN_TRUE_OR_RETURN( ( (*it)->size() > 0 ),
00201 "Invalid parameter: histograms" );
00202
00203 ++it;
00204 }
00205 }
00206
00207 return true;
00208 }
00209
00210
00211 const TePDIHistogram& TePDIStatistic::getHistogram(
00212 unsigned int raster_index, unsigned int pol_index )
00213 {
00214 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00215 "Invalid raster index" );
00216 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00217 "Invalid polygon index" );
00218
00219 std::pair< unsigned int, unsigned int > temp_pair;
00220 temp_pair.first = raster_index;
00221 temp_pair.second = pol_index;
00222
00223 HistoCacheT::const_iterator it_cache =
00224 histo_cache_.find( temp_pair );
00225
00226 if( it_cache == histo_cache_.end() ) {
00227 unsigned int histo_levels = 0;
00228
00229 if( ( rasters_[ raster_index ]->params().dataType_[ bands_[ raster_index ] ]
00230 == TeFLOAT ) ||
00231 ( rasters_[ raster_index ]->params().dataType_[ bands_[ raster_index ] ]
00232 == TeDOUBLE ) )
00233 {
00234 histo_levels = 256;
00235 }
00236
00237 TePDITypes::TePDIPolygonSetPtrType local_polygonset( new TePolygonSet );
00238 local_polygonset->add( polygonset_->operator[]( pol_index ) );
00239
00240 TePDIHistogram* output_histogram = new TePDIHistogram;
00241 output_histogram->ToggleProgressInt(progress_enabled_);
00242
00243 TEAGN_TRUE_OR_LOG( output_histogram->reset(
00244 rasters_[ raster_index ],
00245 bands_[ raster_index ], histo_levels, iterator_strat_,
00246 local_polygonset ),
00247 "Histogram generation error" );
00248
00249 histo_cache_[ temp_pair ] = output_histogram;
00250
00251 return *(histo_cache_[ temp_pair ]);
00252 } else {
00253 return *(it_cache->second);
00254 }
00255 }
00256
00257 const TePDIJointHistogram& TePDIStatistic::getJointHistogram(
00258 unsigned int raster1_index, unsigned int raster2_index,
00259 unsigned int pol_index )
00260 {
00261 TEAGN_TRUE_OR_THROW( raster1_index < rasters_.size(),
00262 "Invalid raster 1 index" );
00263 TEAGN_TRUE_OR_THROW( raster2_index < rasters_.size(),
00264 "Invalid raster 2 index" );
00265 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00266 "Invalid polygon index" );
00267
00268 CoupleRasterCachesKeyT temp_pair;
00269 temp_pair.first = raster1_index;
00270 temp_pair.second.first = raster2_index;
00271 temp_pair.second.second = pol_index;
00272
00273 JHistoCacheT::iterator it_cache = jHistoCache_.find( temp_pair );
00274
00275 if( it_cache == jHistoCache_.end() )
00276 {
00277
00278
00279 CoupleRasterCachesKeyT inv_temp_pair;
00280 inv_temp_pair.first = raster2_index;
00281 inv_temp_pair.second.first = raster1_index;
00282 inv_temp_pair.second.second = pol_index;
00283
00284 if( jHistoCache_[ inv_temp_pair ] )
00285 delete jHistoCache_[ inv_temp_pair ];
00286
00287
00288
00289 unsigned int histo_levels = 0;
00290
00291 if( ( rasters_[ raster1_index ]->params().dataType_[ bands_[ raster1_index ] ]
00292 == TeFLOAT ) ||
00293 ( rasters_[ raster1_index ]->params().dataType_[ bands_[ raster1_index ] ]
00294 == TeDOUBLE ) ||
00295 ( rasters_[ raster2_index ]->params().dataType_[ bands_[ raster2_index ] ]
00296 == TeFLOAT ) ||
00297 ( rasters_[ raster2_index ]->params().dataType_[ bands_[ raster2_index ] ]
00298 == TeDOUBLE ) )
00299 {
00300 histo_levels = 256;
00301 }
00302
00303 TePolygonSet local_polygonset;
00304 local_polygonset.add( polygonset_->operator[]( pol_index ) );
00305
00306 TePDIJointHistogram* newR1R2HistoPtr = new TePDIJointHistogram;
00307 newR1R2HistoPtr->toggleProgress( progress_enabled_ );
00308
00309 TEAGN_TRUE_OR_LOG( newR1R2HistoPtr->update( *rasters_[ raster1_index ],
00310 bands_[ raster1_index ], *rasters_[ raster2_index ],
00311 bands_[ raster2_index ], iterator_strat_, histo_levels, local_polygonset ),
00312 "Joint Histogram generation error" );
00313
00314 jHistoCache_[ temp_pair ] = newR1R2HistoPtr;
00315
00316
00317
00318 TePDIHistogram* r1HistPtr = new TePDIHistogram;
00319 *r1HistPtr = newR1R2HistoPtr->getRaster1Hist();
00320 SingleRasterCachesKeyT r1key;
00321 r1key.first = raster1_index;
00322 r1key.second = pol_index;
00323 if( histo_cache_[ r1key ] != 0 ) delete histo_cache_[ r1key ];
00324 histo_cache_[ r1key ] = r1HistPtr;
00325
00326 TePDIHistogram* r2HistPtr( new TePDIHistogram );
00327 *r2HistPtr = newR1R2HistoPtr->getRaster2Hist();
00328 SingleRasterCachesKeyT r2key;
00329 r2key.first = raster2_index;
00330 r2key.second = pol_index;
00331 if( histo_cache_[ r2key ] != 0 ) delete histo_cache_[ r2key ];
00332 histo_cache_[ r2key ] = r2HistPtr;
00333
00334
00335
00336
00337 TePDIJointHistogram* newR2R1HistoPtr = new TePDIJointHistogram;
00338 newR1R2HistoPtr->getInverseJHist( *newR2R1HistoPtr );
00339
00340 jHistoCache_[ inv_temp_pair ] = newR2R1HistoPtr;
00341
00342 return *newR1R2HistoPtr;
00343 } else {
00344 return *(it_cache->second);
00345 }
00346 }
00347
00348 double TePDIStatistic::getSum( unsigned int raster_index,
00349 unsigned int pol_index )
00350 {
00351 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00352 "Invalid raster index" );
00353 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00354 "Invalid polygon index" );
00355
00356 const TePDIHistogram& hist = getHistogram( raster_index,
00357 pol_index );
00358
00359 if( hist.size() == 0 )
00360 {
00361 return DBL_MAX;
00362 }
00363 else
00364 {
00365 TePDIHistogram::const_iterator it_hist = hist.begin();
00366 TePDIHistogram::const_iterator it_hist_end = hist.end();
00367
00368 double result = 0;
00369
00370 while( it_hist != it_hist_end ) {
00371 result += it_hist->first * (double)it_hist->second;
00372
00373 ++it_hist;
00374 }
00375
00376 return result;
00377 }
00378 }
00379
00380
00381 double TePDIStatistic::getSum3( unsigned int raster_index,
00382 unsigned int pol_index )
00383 {
00384 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00385 "Invalid raster index" );
00386 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00387 "Invalid polygon index" );
00388
00389 const TePDIHistogram& hist = getHistogram( raster_index,
00390 pol_index );
00391
00392 if( hist.size() == 0 )
00393 {
00394 return DBL_MAX;
00395 }
00396 else
00397 {
00398 TePDIHistogram::const_iterator it = hist.begin();
00399 TePDIHistogram::const_iterator it_end = hist.end();
00400
00401 double sum = 0;
00402 double value = 0;
00403
00404 while( it != it_end ) {
00405 value = it->first;
00406
00407 sum += ( value * value * value * ( ( double ) it->second ) );
00408
00409 ++it;
00410 }
00411
00412 return sum;
00413 }
00414 }
00415
00416
00417 double TePDIStatistic::getSum4( unsigned int raster_index,
00418 unsigned int pol_index )
00419 {
00420 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00421 "Invalid raster index" );
00422 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00423 "Invalid polygon index" );
00424
00425 const TePDIHistogram& hist = getHistogram( raster_index,
00426 pol_index );
00427
00428 if( hist.size() == 0 )
00429 {
00430 return DBL_MAX;
00431 }
00432 else
00433 {
00434 TePDIHistogram::const_iterator it = hist.begin();
00435 TePDIHistogram::const_iterator it_end = hist.end();
00436
00437 double sum = 0;
00438 double value = 0;
00439
00440 while( it != it_end ) {
00441 value = it->first;
00442
00443 sum += ( value * value * value * value * ( ( double ) it->second ) );
00444
00445 ++it;
00446 }
00447
00448 return sum;
00449 }
00450 }
00451
00452 double TePDIStatistic::getSumPB1B2( unsigned int raster1_index,
00453 unsigned int raster2_index, unsigned int pol_index )
00454 {
00455 const TePDIJointHistogram& jHisto = getJointHistogram( raster1_index,
00456 raster2_index, pol_index );
00457
00458 TePDIJointHistogram::const_iterator it = jHisto.begin();
00459 TePDIJointHistogram::const_iterator it_end = jHisto.end();
00460
00461 double sum = 0;
00462
00463 while( it != it_end )
00464 {
00465 sum += ( it->first.first * it->first.second ) * (double)it->second;
00466 ++it;
00467 }
00468
00469 return sum;
00470 }
00471
00472
00473 double TePDIStatistic::getMean( unsigned int raster_index,
00474 unsigned int pol_index )
00475 {
00476 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(), "Invalid index" );
00477 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
00478
00479
00480
00481 const TePDIHistogram& hist = getHistogram( raster_index,
00482 pol_index );
00483
00484 if( hist.size() == 0 )
00485 {
00486 return DBL_MAX;
00487 }
00488 else
00489 {
00490 TePDIHistogram::const_iterator it_hist = hist.begin();
00491 TePDIHistogram::const_iterator it_hist_end = hist.end();
00492
00493 double sum = 0;
00494 double elem_nmb = 0.0;
00495
00496 while( it_hist != it_hist_end ) {
00497 sum += it_hist->first * ( (double)it_hist->second );
00498 elem_nmb += (double)it_hist->second;
00499
00500 ++it_hist;
00501 }
00502
00503 if( elem_nmb != 0.0 ) {
00504 return ( sum / ( (double)elem_nmb ) ) ;
00505 } else {
00506 return DBL_MAX;
00507 }
00508 }
00509 }
00510
00511
00512 TeMatrix TePDIStatistic::getMeanMatrix( unsigned int pol_index )
00513 {
00514 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
00515
00516 TeMatrix outmatrix;
00517 outmatrix.Init( 1, rasters_.size(), 0. );
00518
00519 for( unsigned int index = 0 ; index < rasters_.size() ; ++index ) {
00520 outmatrix( 0, index ) = getMean( index, pol_index );
00521 }
00522
00523 return outmatrix;
00524 }
00525
00526
00527 double TePDIStatistic::getCovariance( unsigned int raster1_index,
00528 unsigned int raster2_index, unsigned int pol_index )
00529 {
00530 TEAGN_TRUE_OR_THROW( raster1_index < rasters_.size(),
00531 "Invalid raster 1 index" );
00532 TEAGN_TRUE_OR_THROW( raster2_index < rasters_.size(),
00533 "Invalid raster 2 index" );
00534 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00535 "Invalid polygon index" );
00536
00537 const TePDIJointHistogram& jHist = getJointHistogram( raster1_index,
00538 raster2_index, pol_index );
00539
00540 double mean1 = getMean( raster1_index );
00541 double mean2 = getMean( raster2_index );
00542
00543 if( ( mean1 == DBL_MAX ) || ( mean2 == DBL_MAX) )
00544 {
00545 return DBL_MAX;
00546 }
00547
00548
00549
00550 double elem_nmb = (double)jHist.getFreqSum();
00551
00552 if( elem_nmb != 0.0 )
00553 {
00554 double covariance = 0;
00555 TePDIJointHistogram::const_iterator jHIt = jHist.begin();
00556 TePDIJointHistogram::const_iterator jHItEnd = jHist.end();
00557
00558 while( jHIt != jHItEnd )
00559 {
00560 if( jHIt->second )
00561 {
00562 covariance += ( ( jHIt->first.first - mean1 ) *
00563 ( jHIt->first.second - mean2 ) *
00564 ( (double)jHIt->second ) );
00565 }
00566
00567 ++jHIt;
00568 }
00569
00570 covariance /= elem_nmb;
00571
00572 return covariance;
00573 }
00574 else
00575 {
00576 return DBL_MAX;
00577 }
00578 }
00579
00580
00581 double TePDIStatistic::getVariance( unsigned int raster_index,
00582 unsigned int pol_index )
00583 {
00584 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00585 "Invalid raster index" );
00586 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00587 "Invalid polygon index" );
00588
00589 const TePDIHistogram& hist = getHistogram( raster_index,
00590 pol_index );
00591
00592 double elements_number = (double)hist.getTotalCount();
00593
00594 if( elements_number == 0.0 ) {
00595 return DBL_MAX;
00596 } else {
00597
00598
00599 TePDIHistogram::const_iterator it_hist = hist.begin();
00600 TePDIHistogram::const_iterator it_hist_end = hist.end();
00601
00602 double mean = getMean( raster_index, pol_index );
00603 double variance = 0;
00604
00605 while( it_hist != it_hist_end ) {
00606 variance += ( ( (double)it_hist->second ) / elements_number ) *
00607 ( it_hist->first - mean ) * ( it_hist->first - mean );
00608
00609 ++it_hist;
00610 }
00611
00612 return variance;
00613 }
00614 }
00615
00616
00617 double TePDIStatistic::getStdDev( unsigned int raster_index,
00618 unsigned int pol_index )
00619 {
00620 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00621 "Invalid raster index" );
00622 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00623 "Invalid polygon index" );
00624
00625 double variance = getVariance( raster_index, pol_index );
00626
00627 if( variance == DBL_MAX )
00628 {
00629 return DBL_MAX;
00630 }
00631 else
00632 {
00633 return sqrt( variance );
00634 }
00635 }
00636
00637
00638 double TePDIStatistic::getEntropy( unsigned int raster_index,
00639 unsigned int pol_index )
00640 {
00641 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00642 "Invalid raster index" );
00643 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00644 "Invalid polygon index" );
00645
00646 const TePDIHistogram& hist = getHistogram( raster_index,
00647 pol_index );
00648
00649 double elements_number = (double)hist.getTotalCount();
00650
00651 if( elements_number == 0.0 ) {
00652 return DBL_MAX;
00653 }
00654
00655
00656
00657 TePDIHistogram::const_iterator it = hist.begin();
00658 TePDIHistogram::const_iterator it_end = hist.end();
00659
00660 double entropy = 0;
00661 double probability = 0;
00662
00663 while( it != it_end ) {
00664 probability = ( (double)(it->second) ) / elements_number;
00665
00666 if( probability > 0.0 ) {
00667 entropy += ( probability * ( log( probability ) /
00668 log( (double)2 ) ) );
00669 }
00670
00671 ++it;
00672 }
00673
00674 entropy = (-1.0) * entropy;
00675
00676 return entropy;
00677 }
00678
00679
00680 double TePDIStatistic::getMin( unsigned int raster_index,
00681 unsigned int pol_index )
00682 {
00683 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00684 "Invalid raster index" );
00685 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00686 "Invalid polygon index" );
00687
00688 const TePDIHistogram& hist = getHistogram( raster_index,
00689 pol_index );
00690
00691 if( hist.size() == 0 )
00692 {
00693 return DBL_MAX;
00694 }
00695 else
00696 {
00697 return hist.GetMinLevel();
00698 }
00699 }
00700
00701
00702 double TePDIStatistic::getMax( unsigned int raster_index,
00703 unsigned int pol_index )
00704 {
00705 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00706 "Invalid raster index" );
00707 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00708 "Invalid polygon index" );
00709
00710 const TePDIHistogram& hist = getHistogram( raster_index,
00711 pol_index );
00712
00713 if( hist.size() == 0 )
00714 {
00715 return DBL_MAX;
00716 }
00717 else
00718 {
00719 return hist.GetMaxLevel();
00720 }
00721 }
00722
00723
00724 double TePDIStatistic::getMode( unsigned int raster_index,
00725 unsigned int pol_index )
00726 {
00727 TEAGN_TRUE_OR_THROW( raster_index < rasters_.size(),
00728 "Invalid raster index" );
00729 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00730 "Invalid polygon index" );
00731
00732 const TePDIHistogram& hist = getHistogram( raster_index, pol_index );
00733
00734 if( hist.size() == 0 )
00735 {
00736 return DBL_MAX;
00737 }
00738 else
00739 {
00740 TePDIHistogram::const_iterator it_hist = hist.begin();
00741 TePDIHistogram::const_iterator it_hist_end = hist.end();
00742
00743 unsigned int frequency = 0;
00744 double mode = 0;
00745
00746 while( it_hist != it_hist_end ) {
00747 if( it_hist->second > frequency ) {
00748 mode = it_hist->first;
00749 frequency = it_hist->second;
00750 }
00751
00752 ++it_hist;
00753 }
00754
00755 return mode;
00756 }
00757 }
00758
00759
00760 double TePDIStatistic::getCorrelation( unsigned int raster1_index,
00761 unsigned int raster2_index, unsigned int pol_index )
00762 {
00763 TEAGN_TRUE_OR_THROW( raster1_index < rasters_.size(),
00764 "Invalid raster 1 index" );
00765 TEAGN_TRUE_OR_THROW( raster2_index < rasters_.size(),
00766 "Invalid raster 2 index" );
00767 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(),
00768 "Invalid polygon index" );
00769
00770 double covariance = getCovariance( raster1_index, raster2_index,
00771 pol_index );
00772
00773 if( covariance == DBL_MAX )
00774 {
00775 return DBL_MAX;
00776 }
00777 else
00778 {
00779 double cov1 = getCovariance( raster1_index, raster1_index,
00780 pol_index );
00781 double cov2 = getCovariance( raster2_index, raster2_index,
00782 pol_index );
00783
00784 if( ( cov1 == DBL_MAX ) || ( cov2 == DBL_MAX ) )
00785 {
00786 return DBL_MAX;
00787 }
00788 else
00789 {
00790 double sqrt_c_1 = sqrt( cov1 );
00791 double sqrt_c_2 = sqrt( cov2 );
00792 double multi = ( sqrt_c_1 * sqrt_c_2 );
00793
00794 if( multi == 0.0 ) {
00795 return DBL_MAX;
00796 } else {
00797 return ( covariance / multi );
00798 }
00799 }
00800 }
00801 }
00802
00803
00804
00805 double TePDIStatistic::getPercentile( double sample_index,
00806 unsigned int raster_index, unsigned int pol_index )
00807 {
00808 TEAGN_TRUE_OR_THROW( ( raster_index < rasters_.size() ),
00809 "Invalid raster index" );
00810 TEAGN_TRUE_OR_THROW( ( pol_index < polygonset_->size() ),
00811 "Invalid polygon index" );
00812 TEAGN_TRUE_OR_THROW( ( ( sample_index >= 0.0 ) &&
00813 ( sample_index <= 100.0 ) ), "Invalid sample index" );
00814
00815 const TePDIHistogram& hist = getHistogram( raster_index, pol_index );
00816
00817 if( hist.size() == 0 )
00818 {
00819 return DBL_MAX;
00820 }
00821 else if( hist.size() == 1 )
00822 {
00823 return hist.begin()->first;
00824 }
00825 else
00826 {
00827 TePDIHistogram::const_iterator it;
00828 TePDIHistogram::const_iterator it_end = hist.end();
00829
00830 unsigned int lastindex = hist.getTotalCount() - 1;
00831
00832 double target_sample_index_double =
00833 ( (double)( lastindex ) ) * ( sample_index / 100.0 );
00834 unsigned int target_sample_index_floor =
00835 (unsigned int)ceil( target_sample_index_double );
00836
00837 if( target_sample_index_double ==
00838 ( (double) target_sample_index_floor ) ) {
00839
00840 it = hist.begin();
00841
00842 unsigned int counted_elements = 0;
00843 unsigned int target_index1 = target_sample_index_floor;
00844 unsigned int target_index2 = ( target_index1 == lastindex ) ?
00845 target_index1 : ( target_index1 + 1 );
00846 double target1_value = 0;
00847 double target2_value = 0;
00848 unsigned int curr_index_range_bound = 0;
00849
00850 while( it != it_end ) {
00851 curr_index_range_bound = counted_elements + it->second;
00852
00853 if( ( counted_elements <= target_index1 ) &&
00854 ( target_index1 < curr_index_range_bound ) ) {
00855
00856 target1_value = it->first;
00857 }
00858
00859 if( ( counted_elements <= target_index2 ) &&
00860 ( target_index2 < curr_index_range_bound ) ) {
00861
00862 target2_value = it->first;
00863
00864 break;
00865 }
00866
00867 counted_elements += it->second;
00868
00869 ++it;
00870 }
00871
00872 return ( ( target1_value + target2_value ) / 2.0 );
00873 } else {
00874 it = hist.begin();
00875
00876 unsigned int counted_elements = 0;
00877 unsigned int target_index1 = target_sample_index_floor + 1;
00878 unsigned int curr_index_range_bound = 0;
00879
00880 while( it != it_end ) {
00881 curr_index_range_bound = counted_elements + it->second;
00882
00883 if( ( counted_elements <= target_index1 ) &&
00884 ( target_index1 < curr_index_range_bound ) ) {
00885
00886 return it->first;
00887 }
00888
00889 counted_elements += it->second;
00890
00891 ++it;
00892 }
00893
00894 TEAGN_LOG_AND_THROW( "Target value not found" );
00895
00896 return 0;
00897 }
00898 }
00899 }
00900
00901 TeMatrix TePDIStatistic::getCMMatrix( unsigned int pol_index )
00902 {
00903 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
00904
00905 TeMatrix outmatrix;
00906 outmatrix.Init( 3, rasters_.size(), 0. );
00907
00908 double sum3 = 0;
00909 double sum4 = 0;
00910 double mean = 0;
00911 double sumpb1b2 = 0;
00912 double sumpb1b2_norm = 0;
00913 double pixels_nmb = 0;
00914
00915 for( unsigned int index = 0 ; index < rasters_.size() ; ++index ) {
00916 sumpb1b2 = getSumPB1B2( index, index, pol_index );
00917 const TePDIHistogram& histo = getHistogram( index, pol_index );
00918
00919 if( histo.size() == 0 )
00920 {
00921 outmatrix( 0, index ) = DBL_MAX;
00922 outmatrix( 1, index ) = DBL_MAX;
00923 outmatrix( 2, index ) = DBL_MAX;
00924 }
00925 else
00926 {
00927 sum3 = getSum3( index, pol_index );
00928 sum4 = getSum4( index, pol_index );
00929 mean = getMean( index, pol_index );
00930 pixels_nmb = (double)histo.getTotalCount();
00931 sumpb1b2_norm = sumpb1b2 / pixels_nmb;
00932
00933 outmatrix( 0, index ) = getCovariance( index, index, pol_index );
00934
00935 if( pixels_nmb == 0 ) {
00936 outmatrix( 1, index ) = DBL_MAX;
00937 } else {
00938 outmatrix( 1, index ) = sum3 / pixels_nmb - 3 * mean * sumpb1b2_norm +
00939 2 * pow( mean, 3 );
00940 }
00941
00942 if( pixels_nmb == 0 ) {
00943 outmatrix( 2, index ) = DBL_MAX;
00944 } else {
00945 outmatrix( 2, index ) = sum4 / pixels_nmb - 4 * mean * sum3 / pixels_nmb +
00946 6 * pow( mean, 2 ) * sumpb1b2_norm -
00947 3 * pow( mean, 4 );
00948 }
00949 }
00950 }
00951
00952 return outmatrix;
00953 }
00954
00955
00956 TeMatrix TePDIStatistic::getAssimetryMatrix( unsigned int pol_index )
00957 {
00958 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
00959
00960 TeMatrix outmatrix;
00961 outmatrix.Init( 1, rasters_.size(), 0. );
00962
00963 double sum3 = 0;
00964 double mean = 0;
00965 double cov = 0;
00966 double sigma = 0;
00967 double sigma3 = 0;
00968 double pixels_nmb = 0;
00969 double sumpb1b2 = 0;
00970 double sumpb1b2_norm = 0;
00971
00972 for( unsigned int index = 0 ; index < rasters_.size() ; ++index ) {
00973 cov = getCovariance( index, index, pol_index );
00974 const TePDIHistogram& histo = getHistogram( index, pol_index );
00975
00976 if( histo.size() == 0 )
00977 {
00978 outmatrix( 0, index ) = DBL_MAX;
00979 }
00980 else
00981 {
00982 sigma = sqrt( cov );
00983 sigma3 = sigma * sigma * sigma;
00984
00985 if( sigma3 != 0 ) {
00986 sumpb1b2 = getSumPB1B2( index, index, pol_index );
00987 sum3 = getSum3( index, pol_index );
00988 mean = getMean( index, pol_index );
00989 pixels_nmb = (double)histo.getTotalCount();
00990 sumpb1b2_norm = sumpb1b2 / pixels_nmb;
00991
00992 if( ( pixels_nmb == 0 ) || ( sigma3 == 0 ) ) {
00993 outmatrix( 0, index ) = 0;
00994 } else {
00995 outmatrix( 0, index ) = ( sum3 / pixels_nmb - 3 * mean * sumpb1b2_norm +
00996 2 * pow( mean, 3 ) ) / sigma3;
00997 }
00998 } else {
00999 outmatrix( 0, index ) = 0;
01000 }
01001 }
01002 }
01003
01004 return outmatrix;
01005 }
01006
01007
01008 TeMatrix TePDIStatistic::getKurtosisMatrix( unsigned int pol_index )
01009 {
01010 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
01011
01012 TeMatrix outmatrix;
01013 outmatrix.Init( 1, rasters_.size(), 0. );
01014
01015 double sum3;
01016 double sum4;
01017 double mean;
01018 double cov;
01019 double sigma;
01020 double sigma4;
01021 double sumpb1b2 = 0;
01022 double sumpb1b2_norm = 0;
01023 double pixels_nmb = 0;
01024
01025 for( unsigned int index = 0 ; index < rasters_.size() ; ++index ) {
01026 cov = getCovariance( index, index, pol_index );
01027 const TePDIHistogram& histo = getHistogram( index, pol_index );
01028
01029 if( histo.size() == 0 )
01030 {
01031 outmatrix( 0, index ) = DBL_MAX;
01032 }
01033 else
01034 {
01035 sigma = sqrt( cov );
01036 sigma4 = sigma * sigma * sigma * sigma;
01037
01038 if( sigma4 != 0 ) {
01039 sumpb1b2 = getSumPB1B2( index, index, pol_index );
01040 sum3 = getSum3( index, pol_index );
01041 sum4 = getSum4( index, pol_index );
01042 mean = getMean( index, pol_index );
01043 pixels_nmb = (double)histo.getTotalCount();
01044 sumpb1b2_norm = sumpb1b2 / pixels_nmb;
01045
01046 if( pixels_nmb == 0 ) {
01047 outmatrix( 0, index ) = DBL_MAX;
01048 } else {
01049 outmatrix( 0, index ) = ( sum4 / pixels_nmb - 4 * mean * sum3 /
01050 pixels_nmb + 6 * pow( mean, 2 ) * sumpb1b2_norm - 3 * pow( mean, 4 ) ) /
01051 sigma4 - 3.;
01052 }
01053 } else {
01054 outmatrix( 0, index ) = DBL_MAX;
01055 }
01056 }
01057 }
01058
01059 return outmatrix;
01060 }
01061
01062
01063 TeMatrix TePDIStatistic::getVarCoefMatrix( unsigned int pol_index )
01064 {
01065 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
01066
01067 TeMatrix outmatrix;
01068 outmatrix.Init( 1, rasters_.size(), 0. );
01069
01070 double mean = 0.0;
01071 double cov = 0.0;
01072
01073 for( unsigned int index = 0 ; index < rasters_.size() ; ++index ) {
01074 mean = getMean( index, pol_index );
01075
01076 if( mean == DBL_MAX )
01077 {
01078 outmatrix( 0, index ) = DBL_MAX;
01079 }
01080 else if( mean == 0 )
01081 {
01082 outmatrix( 0, index ) = DBL_MAX;
01083 }
01084 else
01085 {
01086 cov = getCovariance( index, index, pol_index );
01087
01088 if( cov == DBL_MAX )
01089 {
01090 outmatrix( 0, index ) = DBL_MAX;
01091 }
01092 else
01093 {
01094 outmatrix( 0, index ) = sqrt(
01095 getCovariance( index, index, pol_index ) ) / mean;
01096 }
01097 }
01098 }
01099
01100 return outmatrix;
01101 }
01102
01103
01104 TeMatrix TePDIStatistic::getCovMatrix( unsigned int pol_index )
01105 {
01106 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
01107
01108 TeMatrix outmatrix;
01109 outmatrix.Init( rasters_.size(), rasters_.size(), 0. );
01110
01111 for( unsigned int band1 = 0 ; band1 < rasters_.size() ; ++band1 ) {
01112 for( unsigned int band2 = 0 ; band2 < rasters_.size() ; ++band2 ) {
01113 outmatrix( band1, band2 ) =
01114 getCovariance( band1, band2, pol_index );
01115 }
01116 }
01117
01118 return outmatrix;
01119 }
01120
01121
01122 TeMatrix TePDIStatistic::getCorMatrix( unsigned int pol_index )
01123 {
01124 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
01125
01126 TeMatrix outmatrix;
01127 outmatrix.Init( rasters_.size(), rasters_.size(), 0. );
01128
01129 for( unsigned int band1 = 0 ; band1 < rasters_.size() ; ++band1 ) {
01130 for( unsigned int band2 = 0 ; band2 < rasters_.size() ; ++band2 ) {
01131 outmatrix( band1, band2 ) =
01132 getCorrelation( band1, band2, pol_index );
01133 }
01134 }
01135
01136 return outmatrix;
01137 }
01138
01139
01140 TeMatrix TePDIStatistic::getVarMatrix( unsigned int pol_index )
01141 {
01142 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
01143
01144 TeMatrix outmatrix;
01145 outmatrix.Init( rasters_.size(), 1, 0. );
01146
01147 for( unsigned int band = 0 ; band < rasters_.size() ; ++band ) {
01148 outmatrix( band, 0 ) = getVariance( band, pol_index );
01149 }
01150
01151 return outmatrix;
01152 }
01153
01154 TeMatrix TePDIStatistic::getStdDevMatrix( unsigned int pol_index )
01155 {
01156 TEAGN_TRUE_OR_THROW( pol_index < polygonset_->size(), "Invalid index" );
01157
01158 TeMatrix outmatrix;
01159 outmatrix.Init( rasters_.size(), 1, 0. );
01160
01161 for( unsigned int band = 0 ; band < rasters_.size() ; ++band ) {
01162 outmatrix( band, 0 ) = getStdDev( band, pol_index );
01163 }
01164
01165 return outmatrix;
01166 }
01167
01168 void TePDIStatistic::clear()
01169 {
01170 polygonset_.reset();
01171 rasters_.clear();
01172 bands_.clear();
01173
01174
01175
01176 JHistoCacheT::iterator jhcit =
01177 jHistoCache_.begin();
01178 while( jhcit != jHistoCache_.end() )
01179 {
01180 delete jhcit->second;
01181 ++jhcit;
01182 }
01183 jHistoCache_.clear();
01184
01185
01186
01187 HistoCacheT::iterator histCacheIt = histo_cache_.begin();
01188 while( histCacheIt != histo_cache_.end() )
01189 {
01190 delete histCacheIt->second;
01191 ++histCacheIt;
01192 }
01193
01194 histo_cache_.clear();
01195 }
01196
01197