From 220e7d52cbe3c6b5bc43de7e025cca02b8790d3c Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@orfeo-toolbox.org>
Date: Wed, 2 Mar 2011 10:24:07 +0100
Subject: [PATCH] ENH: Applying the extract trick to perform faster memory
 print estimation

---
 Projections/otbBundleToPerfectSensor.cxx | 49 +++++++++++++++++++++---
 1 file changed, 44 insertions(+), 5 deletions(-)

diff --git a/Projections/otbBundleToPerfectSensor.cxx b/Projections/otbBundleToPerfectSensor.cxx
index dafc7720c3..a08cb5fa96 100644
--- a/Projections/otbBundleToPerfectSensor.cxx
+++ b/Projections/otbBundleToPerfectSensor.cxx
@@ -36,6 +36,7 @@
 #include "itkFixedArray.h"
 
 #include "otbPipelineMemoryPrintCalculator.h"
+#include "itkExtractImageFilter.h"
 
 namespace otb
 {
@@ -72,6 +73,8 @@ int BundleToPerfectSensor::Execute(otb::ApplicationOptionsResult* parseResult)
 
     typedef otb::SimpleRcsPanSharpeningFusionImageFilter<PanImageType,XsImageType,XsImageType> FusionFilterType;
 
+    typedef itk::ExtractImageFilter<XsImageType,XsImageType> ExtractFilterType;
+
     // Read input images information
     PanReaderType::Pointer preader= PanReaderType::New();
     preader->SetFileName(parseResult->GetParameterString("InputPanchro"));
@@ -142,20 +145,56 @@ int BundleToPerfectSensor::Execute(otb::ApplicationOptionsResult* parseResult)
 
     otb::StandardWriterWatcher w4(writer,resampler,"Perfect sensor fusion");
 
+    // Estimate memory print
     otb::PipelineMemoryPrintCalculator::Pointer memoryPrintCalculator = otb::PipelineMemoryPrintCalculator::New();
     const double byteToMegabyte = 1./vcl_pow(2.0, 20);
-    memoryPrintCalculator->SetDataToWrite(fusionFilter->GetOutput());
-    memoryPrintCalculator->SetAvailableMemory(256 / byteToMegabyte);
+    
+    // Trick to avoid having the resampler compute the whole
+    // deformation field
+    ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
+    extractFilter->SetInput(fusionFilter->GetOutput());
+    XsImageType::RegionType smallRegion;
+    XsImageType::SizeType smallSize;
+    smallSize.Fill(100);
+    XsImageType::IndexType index;
+    index[0] = fusionFilter->GetOutput()->GetLargestPossibleRegion().GetIndex()[0]
+      + fusionFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2 - 50;
+    index[1] = fusionFilter->GetOutput()->GetLargestPossibleRegion().GetIndex()[1]
+      + fusionFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[1]/2 - 50;
+    smallRegion.SetSize(smallSize);
+    smallRegion.SetIndex(index);
+
+    extractFilter->SetExtractionRegion(smallRegion);
+
+    bool smallRegionSuccess = smallRegion.Crop(fusionFilter->GetOutput()->GetLargestPossibleRegion());
+    
+    if( smallRegionSuccess)
+      {
+      memoryPrintCalculator->SetDataToWrite(extractFilter->GetOutput());
+      double regionTrickFactor = (double)fusionFilter->GetOutput()->GetLargestPossibleRegion().GetNumberOfPixels()
+        /(double)(smallRegion.GetNumberOfPixels());
+      memoryPrintCalculator->SetBiasCorrectionFactor(1.27 * regionTrickFactor);
+      }
+    else
+      {
+      memoryPrintCalculator->SetDataToWrite(fusionFilter->GetOutput());
+      memoryPrintCalculator->SetBiasCorrectionFactor(1.27);
+      }
+
+      memoryPrintCalculator->SetAvailableMemory(256 / byteToMegabyte);
     
     if (parseResult->IsOptionPresent("AvailableMemory"))
       {
       long long int memory = static_cast <long long int> (parseResult->GetParameterUInt("AvailableMemory"));
       memoryPrintCalculator->SetAvailableMemory(memory / byteToMegabyte);
       }
-    
-    memoryPrintCalculator->SetBiasCorrectionFactor(1.27);
+
     memoryPrintCalculator->Compute();
-  
+
+    std::cout<<"Total memory usage: "<<memoryPrintCalculator->GetMemoryPrint()*byteToMegabyte<<" Mb"<<std::endl;
+    std::cout<<"Optimal stream division: "<<memoryPrintCalculator->GetOptimalNumberOfStreamDivisions()<<std::endl;
+
+
     writer->SetTilingStreamDivisions(memoryPrintCalculator->GetOptimalNumberOfStreamDivisions());
    
     writer->Update();
-- 
GitLab