This is an automated email from the git hooks/post-receive script. sebastic-guest pushed a commit to branch upstream-master in repository pktools.
commit 8fd9b88f970417bf49e8d2b64234b1393fa2e705 Author: Pieter Kempeneers <kempe...@gmail.com> Date: Wed Jun 25 23:37:18 2014 +0200 worked on pkkalman, supporting different spatial resolutions for model and observation --- src/algorithms/ImgRegression.cc | 10 ++- src/algorithms/StatFactory.h | 17 +++++ src/apps/pkkalman.cc | 163 +++++++++++++++++++++++++++++++--------- 3 files changed, 150 insertions(+), 40 deletions(-) diff --git a/src/algorithms/ImgRegression.cc b/src/algorithms/ImgRegression.cc index b945206..df88973 100644 --- a/src/algorithms/ImgRegression.cc +++ b/src/algorithms/ImgRegression.cc @@ -30,6 +30,8 @@ ImgRegression::~ImgRegression(void) {} double ImgRegression::getRMSE(const ImgReaderGdal& imgReader1, const ImgReaderGdal& imgReader2, double& c0, double& c1, short verbose) const{ + c0=0; + c1=1; int icol1=0,irow1=0; std::vector<double> rowBuffer1(imgReader1.nrOfCol()); std::vector<double> rowBuffer2(imgReader2.nrOfCol()); @@ -74,9 +76,11 @@ double ImgRegression::getRMSE(const ImgReaderGdal& imgReader1, const ImgReaderGd std::cout << geox << " " << geoy << " " << icol1 << " " << irow1 << " " << icol2 << " " << irow2 << " " << buffer1.back() << " " << buffer2.back() << std::endl; } } - statfactory::StatFactory stat; - double err=stat.linear_regression_err(buffer1,buffer2,c0,c1); - + double err=0; + if(buffer1.size()||buffer2.size()){ + statfactory::StatFactory stat; + err=stat.linear_regression_err(buffer1,buffer2,c0,c1); + } if(verbose) std::cout << "linear regression based on " << buffer1.size() << " points: " << c0 << "+" << c1 << " * x " << " with rmse: " << err << std::endl; return err; diff --git a/src/algorithms/StatFactory.h b/src/algorithms/StatFactory.h index d8f76a7..abf7640 100644 --- a/src/algorithms/StatFactory.h +++ b/src/algorithms/StatFactory.h @@ -184,6 +184,7 @@ public: // template<class T> void interpolateUp(const std::vector< std::vector<T> >& input, std::vector< std::vector<T> >& output, double start, double end, double step, const gsl_interp_type* type); // template<class T> void interpolateUp(const std::vector< std::vector<T> >& input, const std::vector<double>& wavelengthIn, std::vector< std::vector<T> >& output, std::vector<double>& wavelengthOut, double start, double end, double step, const gsl_interp_type* type); template<class T> void interpolateUp(const std::vector<T>& input, std::vector<T>& output, int nbin) const; + template<class T> void nearUp(const std::vector<T>& input, std::vector<T>& output) const; template<class T> void interpolateUp(double* input, int dim, std::vector<T>& output, int nbin); template<class T> void interpolateDown(const std::vector<T>& input, std::vector<T>& output, int nbin) const; template<class T> void interpolateDown(double* input, int dim, std::vector<T>& output, int nbin); @@ -989,6 +990,22 @@ template<class T> void StatFactory::interpolateUp(const std::vector<T>& input, s } } +template<class T> void StatFactory::nearUp(const std::vector<T>& input, std::vector<T>& output) const +{ + assert(input.size()); + assert(output.size()>=input.size()); + int dimInput=input.size(); + int dimOutput=output.size(); + + for(int iin=0;iin<dimInput;++iin){ + for(int iout=0;iout<dimOutput/dimInput;++iout){ + int indexOutput=iin*dimOutput/dimInput+iout; + assert(indexOutput<output.size()); + output[indexOutput]=input[iin]; + } + } +} + template<class T> void StatFactory::interpolateUp(double* input, int dim, std::vector<T>& output, int nbin) { assert(nbin); diff --git a/src/apps/pkkalman.cc b/src/apps/pkkalman.cc index 9d31cd9..61d93ef 100644 --- a/src/apps/pkkalman.cc +++ b/src/apps/pkkalman.cc @@ -44,7 +44,7 @@ int main(int argc,char **argv) { Optionpk<string> outputbw_opt("obw", "outputbw", "Output raster dataset for backward model"); Optionpk<string> outputfb_opt("ofb", "outputfb", "Output raster dataset for smooth model"); Optionpk<float> threshold_opt("th", "threshold", "threshold for selecting samples (randomly). Provide probability in percentage (>0) or absolute (<0).", 0); - // Optionpk<double> modnodata_opt("modnodata", "modnodata", "invalid value for model input", 0); + Optionpk<double> modnodata_opt("modnodata", "modnodata", "invalid value for model input", 0); Optionpk<double> obsnodata_opt("obsnodata", "obsnodata", "invalid value for observation input", 0); Optionpk<double> eps_opt("eps", "eps", "epsilon for non zero division", 0.00001); Optionpk<double> uncertModel_opt("um", "uncertmodel", "Multiply this value with std dev of first model image to obtain uncertainty of model",2); @@ -69,7 +69,7 @@ int main(int argc,char **argv) { outputbw_opt.retrieveOption(argc,argv); outputfb_opt.retrieveOption(argc,argv); threshold_opt.retrieveOption(argc,argv); - // modnodata_opt.retrieveOption(argc,argv); + modnodata_opt.retrieveOption(argc,argv); obsnodata_opt.retrieveOption(argc,argv); eps_opt.retrieveOption(argc,argv); uncertModel_opt.retrieveOption(argc,argv); @@ -147,6 +147,7 @@ int main(int argc,char **argv) { exit(1); } + statfactory::StatFactory stat; imgregression::ImgRegression imgreg; // vector<ImgReaderGdal> imgReaderModel(model_opt.size()); // vector<ImgReaderGdal> imgReaderObs(observation_opt.size()); @@ -173,6 +174,8 @@ int main(int argc,char **argv) { option_opt.push_back(theInterleave); } + imgReaderObs.close(); + int obsindex=0; const char* pszMessage; @@ -194,12 +197,14 @@ int main(int argc,char **argv) { for(int tindex=0;tindex<tobservation_opt.size();++tindex){ vector<int>::iterator modit; modit=lower_bound(tmodel_opt.begin(),tmodel_opt.end(),tobservation_opt[tindex]); - int relpos=modit-tmodel_opt.begin()-1; - if(relpos<0) - relpos=0; + int relpos=modit-tmodel_opt.begin(); + // if(relpos<0) + // relpos=0; relobsindex.push_back(relpos); if(verbose_opt[0]) - cout << "tobservation_opt[tindex] " << tobservation_opt[tindex] << " " << relobsindex.back() << endl; + cout << "tobservation_opt[tindex] " << tobservation_opt[tindex] << " " << relobsindex.back() << " " << observation_opt[tindex] << " " << model_opt[relpos] << endl; + // if(verbose_opt[0]) + // cout << "tobservation_opt[tindex] " << tobservation_opt[tindex] << " " << relobsindex.back() << endl; } if(find(direction_opt.begin(),direction_opt.end(),"forward")!=direction_opt.end()){ @@ -231,32 +236,67 @@ int main(int argc,char **argv) { cout << "There is no next observation" << endl; } - imgReaderModel1.open(model_opt[0]); + try{ + imgReaderModel1.open(model_opt[0]); + imgReaderModel1.setNoData(modnodata_opt); + } + catch(string errorString){ + cerr << errorString << endl; + } + catch(...){ + cerr << "Error opening file " << model_opt[0] << endl; + } + //calculate standard deviation of image to serve as model uncertainty GDALRasterBand* rasterBand; rasterBand=imgReaderModel1.getRasterBand(0); double minValue, maxValue, meanValue, stdDev; void* pProgressData; rasterBand->ComputeStatistics(0,&minValue,&maxValue,&meanValue,&stdDev,pfnProgress,pProgressData); + double x=0; + double y=0; + double modRow=0; + double modCol=0; if(relobsindex[0]>0){//initialize output_opt[0] as model[0] //write first model as output + if(verbose_opt[0]) + cout << "write first model as output" << endl; for(int irow=0;irow<nrow;++irow){ vector<double> estReadBuffer; + vector<double> estWriteBuffer(ncol); vector<double> uncertWriteBuffer(ncol); - imgReaderModel1.readData(estReadBuffer,GDT_Float64,irow); - imgWriterEst.writeData(estReadBuffer,GDT_Float64,irow,0); - for(int icol=0;icol<ncol;++icol) - uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev; - imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1); + imgWriterEst.image2geo(0,irow,x,y); + imgReaderModel1.geo2image(x,y,modCol,modRow); + assert(modRow>=0||modRow<imgReaderModel1.nrOfRow()); + try{ + imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow); + //simple nearest neighbor + stat.nearUp(estReadBuffer,estWriteBuffer); + imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0); + for(int icol=0;icol<ncol;++icol) + uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev; + imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1); + } + catch(string errorString){ + cerr << errorString << endl; + } + catch(...){ + cerr << "Error writing file " << imgWriterEst.getFileName() << endl; + } } } else{//we have an observation at time 0 + if(verbose_opt[0]) + cout << "we have an observation at time 0" << endl; imgReaderObs.open(observation_opt[0]); imgReaderObs.getGeoTransform(geotransform); imgReaderObs.setNoData(obsnodata_opt); for(int irow=0;irow<nrow;++irow){ vector<double> estReadBuffer; - imgReaderModel1.readData(estReadBuffer,GDT_Float64,irow); + imgWriterEst.image2geo(0,irow,x,y); + imgReaderModel1.geo2image(x,y,modCol,modRow); + assert(modRow>=0||modRow<imgReaderModel1.nrOfRow()); + imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow); vector<double> estWriteBuffer(ncol); vector<double> uncertWriteBuffer(ncol); vector<double> uncertObsBuffer; @@ -265,7 +305,10 @@ int main(int argc,char **argv) { imgReaderObs.readData(uncertObsBuffer,GDT_Float64,irow,1); for(int icol=0;icol<ncol;++icol){ if(imgReaderObs.isNoData(estWriteBuffer[icol])){ - estWriteBuffer[icol]=estReadBuffer[icol]; + imgWriterEst.image2geo(icol,irow,x,y); + imgReaderModel1.geo2image(x,y,modCol,modRow); + assert(modRow>=0||modRow<imgReaderModel1.nrOfRow()); + estWriteBuffer[icol]=estReadBuffer[modCol]; uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev; } else{ @@ -273,12 +316,15 @@ int main(int argc,char **argv) { if(uncertObsBuffer.size()>icol) uncertObs=uncertObsBuffer[icol]; if(uncertModel_opt[0]*stdDev+uncertObs>eps_opt[0]){ + imgWriterEst.image2geo(icol,irow,x,y); + imgReaderModel1.geo2image(x,y,modCol,modRow); + assert(modRow>=0||modRow<imgReaderModel1.nrOfRow()); // double noemer=uncertObs*uncertObs+stdDev*stdDev;//todo: multiply stdDev with uncertModel_opt[0] // estWriteBuffer[icol]*=uncertModel_opt[0]*stdDev*stdDev/noemer; // estWriteBuffer[icol]+=uncertModel_opt[0]*uncertObs*uncertObs/noemer;//todo:check! error? double kalmanGain=uncertModel_opt[0]*stdDev/(uncertModel_opt[0]*stdDev+uncertObs); assert(kalmanGain<=1); - estWriteBuffer[icol]=estReadBuffer[icol]+kalmanGain*(estWriteBuffer[icol]-estReadBuffer[icol]); + estWriteBuffer[icol]=estReadBuffer[modCol]+kalmanGain*(estWriteBuffer[icol]-estReadBuffer[modCol]); uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev*(1-kalmanGain); } else{ @@ -318,12 +364,13 @@ int main(int argc,char **argv) { imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt); imgWriterEst.setProjectionProj4(projection_opt[0]); imgWriterEst.setGeoTransform(geotransform); - imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]); //calculate regression between two subsequence model inputs imgReaderModel1.open(model_opt[modindex-1]); + imgReaderModel1.setNoData(modnodata_opt); imgReaderModel2.open(model_opt[modindex]); + imgReaderModel2.setNoData(modnodata_opt); //calculate regression //we could re-use the points from second image from last run, but //to keep it general, we must redo it (overlap might have changed) @@ -350,9 +397,10 @@ int main(int argc,char **argv) { imgReaderObs.setNoData(obsnodata_opt); //calculate regression between model and observation if(verbose_opt[0]) - cout << "Calculating regression for " << imgReaderModel1.getFileName() << " " << imgReaderObs.getFileName() << endl; - errObs=imgreg.getRMSE(imgReaderModel1,imgReaderObs,c0obs,c1obs,verbose_opt[0]); + cout << "Calculating regression for " << imgReaderModel2.getFileName() << " " << imgReaderObs.getFileName() << endl; + errObs=imgreg.getRMSE(imgReaderModel2,imgReaderObs,c0obs,c1obs,verbose_opt[0]); } + //prediction (also to fill cloudy pixels in update mode) string input; if(outputfw_opt.size()==model_opt.size()) input=outputfw_opt[modindex-1]; @@ -369,6 +417,7 @@ int main(int argc,char **argv) { vector<double> uncertReadBuffer; vector<double> estWriteBuffer(ncol); vector<double> uncertWriteBuffer(ncol); + for(int irow=0;irow<imgWriterEst.nrOfRow();++irow){ assert(irow<imgReaderEst.nrOfRow()); imgReaderEst.readData(estReadBuffer,GDT_Float64,irow,0); @@ -429,8 +478,8 @@ int main(int argc,char **argv) { } } if(find(direction_opt.begin(),direction_opt.end(),"backward")!=direction_opt.end()){ - obsindex=relobsindex.size()-1; ///////////////////////////// backward model ///////////////////////// + obsindex=relobsindex.size()-1; if(verbose_opt[0]) cout << "Running backward model" << endl; //initialization @@ -456,32 +505,68 @@ int main(int argc,char **argv) { else cout << "There is no next observation" << endl; } - imgReaderModel1.open(model_opt.back()); + + try{ + imgReaderModel1.open(model_opt.back()); + imgReaderModel1.setNoData(modnodata_opt); + } + catch(string errorString){ + cerr << errorString << endl; + } + catch(...){ + cerr << "Error opening file " << model_opt[0] << endl; + } + //calculate standard deviation of image to serve as model uncertainty GDALRasterBand* rasterBand; rasterBand=imgReaderModel1.getRasterBand(0); double minValue, maxValue, meanValue, stdDev; void* pProgressData; rasterBand->ComputeStatistics(0,&minValue,&maxValue,&meanValue,&stdDev,pfnProgress,pProgressData); + double x=0; + double y=0; + double modRow=0; + double modCol=0; if(relobsindex.back()<model_opt.size()-1){//initialize output_opt.back() as model[0] //write last model as output + if(verbose_opt[0]) + cout << "write last model as output" << endl; for(int irow=0;irow<imgWriterEst.nrOfRow();++irow){ vector<double> estReadBuffer; + vector<double> estWriteBuffer(ncol); vector<double> uncertWriteBuffer(ncol); - imgReaderModel1.readData(estReadBuffer,GDT_Float64,irow); - imgWriterEst.writeData(estReadBuffer,GDT_Float64,irow,0); - for(int icol=0;icol<imgWriterEst.nrOfCol();++icol) - uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev; - imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1); + imgWriterEst.image2geo(0,irow,x,y); + imgReaderModel1.geo2image(x,y,modCol,modRow); + assert(modRow>=0||modRow<imgReaderModel1.nrOfRow()); + try{ + imgReaderModel1.readData(estReadBuffer,GDT_Float64,irow); + //simple nearest neighbor + stat.nearUp(estReadBuffer,estWriteBuffer); + imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0); + for(int icol=0;icol<imgWriterEst.nrOfCol();++icol) + uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev; + imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1); + } + catch(string errorString){ + cerr << errorString << endl; + } + catch(...){ + cerr << "Error writing file " << imgWriterEst.getFileName() << endl; + } } } else{//we have an observation at end time + if(verbose_opt[0]) + cout << "we have an observation at end time" << endl; imgReaderObs.open(observation_opt.back()); imgReaderObs.getGeoTransform(geotransform); imgReaderObs.setNoData(obsnodata_opt); for(int irow=0;irow<nrow;++irow){ vector<double> estReadBuffer; - imgReaderModel1.readData(estReadBuffer,GDT_Float64,irow); + imgWriterEst.image2geo(0,irow,x,y); + imgReaderModel1.geo2image(x,y,modCol,modRow); + assert(modRow>=0||modRow<imgReaderModel1.nrOfRow()); + imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow); vector<double> estWriteBuffer(ncol); vector<double> uncertWriteBuffer(ncol); vector<double> uncertObsBuffer; @@ -490,7 +575,10 @@ int main(int argc,char **argv) { imgReaderObs.readData(uncertObsBuffer,GDT_Float64,irow,1); for(int icol=0;icol<imgWriterEst.nrOfCol();++icol){ if(imgReaderObs.isNoData(estWriteBuffer[icol])){ - estWriteBuffer[icol]=estReadBuffer[icol]; + imgWriterEst.image2geo(icol,irow,x,y); + imgReaderModel1.geo2image(x,y,modCol,modRow); + assert(modRow>=0||modRow<imgReaderModel1.nrOfRow()); + estWriteBuffer[icol]=estReadBuffer[modCol]; uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev; } else{ @@ -498,19 +586,17 @@ int main(int argc,char **argv) { if(uncertObsBuffer.size()>icol) uncertObs=uncertObsBuffer[icol]; if(uncertModel_opt[0]*stdDev+uncertObs>eps_opt[0]){ + imgWriterEst.image2geo(icol,irow,x,y); + imgReaderModel1.geo2image(x,y,modCol,modRow); + assert(modRow>=0||modRow<imgReaderModel1.nrOfRow()); // double noemer=uncertObs*uncertObs+stdDev*stdDev;//todo: multiply stdDev with uncertModel_opt[0] // estWriteBuffer[icol]*=uncertModel_opt[0]*stdDev*stdDev/noemer; // estWriteBuffer[icol]+=uncertModel_opt[0]*uncertObs*uncertObs/noemer;//todo:check! error? double kalmanGain=uncertModel_opt[0]*stdDev/(uncertModel_opt[0]*stdDev+uncertObs); assert(kalmanGain<=1); - estWriteBuffer[icol]=estReadBuffer[icol]+kalmanGain*(estWriteBuffer[icol]-estReadBuffer[icol]); + estWriteBuffer[icol]=estReadBuffer[modCol]+kalmanGain*(estWriteBuffer[icol]-estReadBuffer[modCol]); uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev*(1-kalmanGain); } - // if(uncertObs>eps_opt[0]){ - // double noemer=uncertObs*uncertObs+stdDev*stdDev; - // estWriteBuffer[icol]*=uncertModel_opt[0]*stdDev*stdDev/noemer; - // estWriteBuffer[icol]+=uncertModel_opt[0]*uncertObs*uncertObs/noemer;//todo: check error? - // } else{ //no need to fill write buffer (already done in imgReaderObs.readData uncertWriteBuffer[icol]=uncertObs; @@ -543,6 +629,7 @@ int main(int argc,char **argv) { // outputstream << output_opt[0] << "_" << modindex+1 << ".tif"; output=outputstream.str(); } + //two band output band0=estimation, band1=uncertainty imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt); imgWriterEst.setProjectionProj4(projection_opt[0]); @@ -551,7 +638,9 @@ int main(int argc,char **argv) { //calculate regression between two subsequence model inputs imgReaderModel1.open(model_opt[modindex+1]); + imgReaderModel1.setNoData(modnodata_opt); imgReaderModel2.open(model_opt[modindex]); + imgReaderModel2.setNoData(modnodata_opt); //calculate regression //we could re-use the points from second image from last run, but //to keep it general, we must redo it (overlap might have changed) @@ -572,19 +661,19 @@ int main(int argc,char **argv) { if(update){ if(verbose_opt[0]) cout << "***update " << relobsindex[obsindex] << " = " << modindex << " " << observation_opt[obsindex] << " ***" << endl; + imgReaderObs.open(observation_opt[obsindex]); imgReaderObs.getGeoTransform(geotransform); imgReaderObs.setNoData(obsnodata_opt); //calculate regression between model and observation if(verbose_opt[0]) - cout << "Calculating regression for " << imgReaderModel1.getFileName() << " " << imgReaderObs.getFileName() << endl; - errObs=imgreg.getRMSE(imgReaderModel1,imgReaderObs,c0obs,c1obs,verbose_opt[0]); + cout << "Calculating regression for " << imgReaderModel2.getFileName() << " " << imgReaderObs.getFileName() << endl; + errObs=imgreg.getRMSE(imgReaderModel2,imgReaderObs,c0obs,c1obs,verbose_opt[0]); } //prediction (also to fill cloudy pixels in update mode) string input; - if(outputbw_opt.size()==model_opt.size()){ + if(outputbw_opt.size()==model_opt.size()) input=outputbw_opt[modindex+1]; - } else{ ostringstream outputstream; outputstream << outputbw_opt[0] << "_" << tmodel_opt[modindex+1] << ".tif"; -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/pktools.git _______________________________________________ Pkg-grass-devel mailing list Pkg-grass-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel