23 #include "base/Optionpk.h"
24 #include "base/Vector2d.h"
25 #include "imageclasses/ImgReaderGdal.h"
26 #include "imageclasses/ImgWriterGdal.h"
27 #include "algorithms/StatFactory.h"
28 #include "algorithms/ImgRegression.h"
80 int main(
int argc,
char **argv) {
81 Optionpk<string> direction_opt(
"dir",
"direction",
"direction to run model (forward|backward|smooth)",
"forward");
82 Optionpk<string> model_opt(
"mod",
"model",
"model input datasets, e.g., MODIS (use: -mod model1 -mod model2 etc.)");
83 Optionpk<string> observation_opt(
"obs",
"observation",
"observation input datasets, e.g., landsat (use: -obs obs1 -obs obs2 etc.)");
84 Optionpk<int> tmodel_opt(
"tmod",
"tmodel",
"time sequence of model input. Sequence must have exact same length as model input. Leave empty to have default sequence 0,1,2,etc.");
85 Optionpk<int> tobservation_opt(
"tobs",
"tobservation",
"time sequence of observation input. Sequence must have exact same length as observation input)");
86 Optionpk<string> projection_opt(
"a_srs",
"a_srs",
"Override the projection for the output file (leave blank to copy from input file, use epsg:3035 to use European projection and force to European grid");
87 Optionpk<string> outputfw_opt(
"ofw",
"outputfw",
"Output raster dataset for forward model");
88 Optionpk<string> outputbw_opt(
"obw",
"outputbw",
"Output raster dataset for backward model");
89 Optionpk<string> outputfb_opt(
"ofb",
"outputfb",
"Output raster dataset for smooth model");
90 Optionpk<double> modnodata_opt(
"modnodata",
"modnodata",
"invalid value for model input", 0);
91 Optionpk<double> obsnodata_opt(
"obsnodata",
"obsnodata",
"invalid value for observation input", 0);
92 Optionpk<double> modoffset_opt(
"modoffset",
"modoffset",
"offset used to read model input dataset (value=offset+scale*readValue)");
93 Optionpk<double> obsoffset_opt(
"obsoffset",
"obsoffset",
"offset used to read observation input dataset (value=offset+scale*readValue)");
94 Optionpk<double> modscale_opt(
"modscale",
"modscale",
"scale used to read model input dataset (value=offset+scale*readValue)");
95 Optionpk<double> obsscale_opt(
"obsscale",
"obsscale",
"scale used to read observation input dataset (value=offset+scale*readValue)");
96 Optionpk<double> eps_opt(
"eps",
"eps",
"epsilon for non zero division", 0.00001);
97 Optionpk<double> uncertModel_opt(
"um",
"uncertmodel",
"Multiply this value with std dev of first model image to obtain uncertainty of model",2);
98 Optionpk<double> uncertObs_opt(
"uo",
"uncertobs",
"Uncertainty of valid observations",0);
99 Optionpk<double> weight_opt(
"w",
"weight",
"Penalize outliers in measurement via weights. Use first weight to penalize small measurements wrt model and second weight to penalize large measurements wrt model");
100 Optionpk<double> deltaObs_opt(
"dobs",
"deltaobs",
"Lower and upper thresholds for relative pixel differences (in percentage): (observation-model)/model. For instance to force the observation within a +/- 10 % interval, use: -dobs -10 -dobs 10 (equivalent to -dobs 10). Leave empty to always update on observation");
101 Optionpk<double> uncertNodata_opt(
"unodata",
"uncertnodata",
"Uncertainty in case of no-data values in observation", 10000);
102 Optionpk<double> regTime_opt(
"rt",
"regtime",
"Weight for regression in time series", 1.0);
103 Optionpk<double> regSensor_opt(
"rs",
"regsensor",
"Weight for regression model - measurement (model - observation).");
104 Optionpk<int> down_opt(
"down",
"down",
"Downsampling factor for reading model data to calculate regression");
105 Optionpk<float> threshold_opt(
"th",
"threshold",
"threshold for selecting samples (randomly). Provide probability in percentage (>0) or absolute (<0).", 0);
106 Optionpk<int> minreg_opt(
"minreg",
"minreg",
"Minimum number of pixels to take into account for regression", 5, 2);
109 Optionpk<unsigned short> window_opt(
"win",
"window",
"window size for calculating regression (use 0 for global)", 0);
113 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate). Empty string: inherit from input image",
"GTiff",2);
114 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
115 Optionpk<short> verbose_opt(
"v",
"verbose",
"verbose mode when positive", 0);
119 doProcess=direction_opt.retrieveOption(argc,argv);
120 model_opt.retrieveOption(argc,argv);
121 observation_opt.retrieveOption(argc,argv);
122 tmodel_opt.retrieveOption(argc,argv);
123 tobservation_opt.retrieveOption(argc,argv);
124 projection_opt.retrieveOption(argc,argv);
125 outputfw_opt.retrieveOption(argc,argv);
126 outputbw_opt.retrieveOption(argc,argv);
127 outputfb_opt.retrieveOption(argc,argv);
128 modnodata_opt.retrieveOption(argc,argv);
129 obsnodata_opt.retrieveOption(argc,argv);
130 modoffset_opt.retrieveOption(argc,argv);
131 modscale_opt.retrieveOption(argc,argv);
132 obsoffset_opt.retrieveOption(argc,argv);
133 obsscale_opt.retrieveOption(argc,argv);
134 eps_opt.retrieveOption(argc,argv);
135 uncertModel_opt.retrieveOption(argc,argv);
136 uncertObs_opt.retrieveOption(argc,argv);
137 weight_opt.retrieveOption(argc,argv);
138 deltaObs_opt.retrieveOption(argc,argv);
139 uncertNodata_opt.retrieveOption(argc,argv);
140 regTime_opt.retrieveOption(argc,argv);
141 regSensor_opt.retrieveOption(argc,argv);
142 down_opt.retrieveOption(argc,argv);
143 threshold_opt.retrieveOption(argc,argv);
144 minreg_opt.retrieveOption(argc,argv);
147 window_opt.retrieveOption(argc,argv);
150 oformat_opt.retrieveOption(argc,argv);
151 option_opt.retrieveOption(argc,argv);
152 verbose_opt.retrieveOption(argc,argv);
154 catch(
string predefinedString){
155 std::cout << predefinedString << std::endl;
159 std::cerr <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
163 if(deltaObs_opt.size()==1){
164 if(deltaObs_opt[0]<=0)
165 deltaObs_opt.push_back(-deltaObs_opt[0]);
167 deltaObs_opt.insert(deltaObs_opt.begin(),-deltaObs_opt[0]);
169 if(weight_opt.size()==1){
170 weight_opt.push_back(weight_opt[0]);
173 if(down_opt.empty()){
174 std::cerr <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
178 ostringstream errorStream;
179 if(model_opt.size()<2){
180 errorStream <<
"Error: no model dataset selected, use option -mod" << endl;
181 throw(errorStream.str());
183 if(observation_opt.size()<1){
184 errorStream <<
"Error: no observation dataset selected, use option -obs" << endl;
185 throw(errorStream.str());
187 if(direction_opt[0]==
"smooth"){
188 if(outputfw_opt.empty()){
189 errorStream <<
"Error: output forward datasets is not provided, use option -ofw" << endl;
190 throw(errorStream.str());
192 if(outputbw_opt.empty()){
193 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
194 throw(errorStream.str());
196 if(outputfb_opt.empty()){
197 errorStream <<
"Error: output smooth datasets is not provided, use option -ofb" << endl;
198 throw(errorStream.str());
202 if(direction_opt[0]==
"forward"&&outputfw_opt.empty()){
203 errorStream <<
"Error: output forward datasets is not provided, use option -ofw" << endl;
204 throw(errorStream.str());
206 else if(direction_opt[0]==
"backward"&&outputbw_opt.empty()){
207 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
208 throw(errorStream.str());
211 if(model_opt.size()<observation_opt.size()){
212 errorStream <<
"Error: sequence of models should be larger than observations" << endl;
213 throw(errorStream.str());
215 if(tmodel_opt.size()!=model_opt.size()){
216 if(tmodel_opt.empty())
217 cout <<
"Warning: time sequence is not provided, self generating time sequence from 0 to " << model_opt.size() << endl;
219 cout <<
"Warning: time sequence provided (" << tmodel_opt.size() <<
") does not match number of model raster datasets (" << model_opt.size() <<
")" << endl;
221 for(
int tindex=0;tindex<model_opt.size();++tindex)
222 tmodel_opt.push_back(tindex);
224 if(tobservation_opt.size()!=observation_opt.size()){
225 errorStream <<
"Error: time sequence for observation must match size of observation dataset" << endl;
226 throw(errorStream.str());
230 catch(
string errorString){
231 std::cout << errorString << std::endl;
236 stat.setNoDataValues(modnodata_opt);
245 imgReaderObs.open(observation_opt[0]);
247 int ncol=imgReaderObs.nrOfCol();
248 int nrow=imgReaderObs.nrOfRow();
249 if(projection_opt.empty())
250 projection_opt.push_back(imgReaderObs.getProjection());
251 double geotransform[6];
252 imgReaderObs.getGeoTransform(geotransform);
254 string imageType=imgReaderObs.getImageType();
255 if(oformat_opt.size())
256 imageType=oformat_opt[0];
257 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
258 string theInterleave=
"INTERLEAVE=";
259 theInterleave+=imgReaderObs.getInterleave();
260 option_opt.push_back(theInterleave);
263 if(down_opt.empty()){
264 imgReaderModel1.open(model_opt[0]);
265 double resModel=imgReaderModel1.getDeltaX();
266 double resObs=imgReaderObs.getDeltaX();
267 int down=
static_cast<int>(ceil(resModel/resObs));
270 down_opt.push_back(down);
271 imgReaderModel1.close();
273 imgReaderObs.close();
275 if(regSensor_opt.empty())
276 regSensor_opt.push_back(1.0/down_opt[0]);
301 const char* pszMessage;
302 void* pProgressArg=NULL;
303 GDALProgressFunc pfnProgress=GDALTermProgress;
306 imgreg.setDown(down_opt[0]);
307 imgreg.setThreshold(threshold_opt[0]);
309 double c0modGlobal=0;
310 double c1modGlobal=1;
316 double errObs=uncertNodata_opt[0];
318 vector<int> relobsindex;
322 for(
int tindex=0;tindex<tobservation_opt.size();++tindex){
323 vector<int>::iterator modit;
324 modit=upper_bound(tmodel_opt.begin(),tmodel_opt.end(),tobservation_opt[tindex]);
325 int relpos=modit-tmodel_opt.begin()-1;
327 relobsindex.push_back(relpos);
329 cout <<
"observation " << tindex <<
": " <<
"relative position in model time series is " << relpos <<
", date of observation is (tobservation_opt[tindex]): " << tobservation_opt[tindex] <<
", relobsindex.back(): " << relobsindex.back() <<
", filename observation: " << observation_opt[tindex] <<
", filename of corresponding model: " << model_opt[relpos] << endl;
334 int ndigit=log(1.0*tmodel_opt.back())/log(10.0)+1;
339 if(find(direction_opt.begin(),direction_opt.end(),
"forward")!=direction_opt.end()){
341 cout <<
"Running forward model" << endl;
345 if(outputfw_opt.size()==model_opt.size()){
346 output=outputfw_opt[0];
349 ostringstream outputstream;
350 outputstream << outputfw_opt[0] <<
"_";
351 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[0];
352 outputstream <<
".tif";
355 output=outputstream.str();
358 cout <<
"Opening image " << output <<
" for writing " << endl;
360 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
361 imgWriterEst.setProjectionProj4(projection_opt[0]);
362 imgWriterEst.setGeoTransform(geotransform);
363 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
366 cout <<
"processing time " << tmodel_opt[0] << endl;
367 if(obsindex<relobsindex.size())
368 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
370 cout <<
"There is no next observation" << endl;
374 imgReaderModel1.open(model_opt[0]);
375 imgReaderModel1.setNoData(modnodata_opt);
376 if(modoffset_opt.size())
377 imgReaderModel1.setOffset(modoffset_opt[0]);
378 if(modscale_opt.size())
379 imgReaderModel1.setScale(modscale_opt[0]);
381 catch(
string errorString){
382 cerr << errorString << endl;
385 cerr <<
"Error opening file " << model_opt[0] << endl;
389 GDALRasterBand* rasterBand;
390 rasterBand=imgReaderModel1.getRasterBand(0);
391 double minValue, maxValue, meanValue, stdDev;
393 rasterBand->ComputeStatistics(0,&minValue,&maxValue,&meanValue,&stdDev,pfnProgress,pProgressData);
396 if(relobsindex[0]>0){
399 cout <<
"write first model as output" << endl;
400 for(
int irow=0;irow<nrow;++irow){
401 vector<double> estReadBuffer;
402 vector<double> estWriteBuffer(ncol);
403 vector<double> uncertWriteBuffer(ncol);
405 imgWriterEst.image2geo(0,irow,geox,geoy);
406 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
407 if(modRow<0||modRow>=imgReaderModel1.nrOfRow()){
408 cerr <<
"Error: geo coordinates (" << geox <<
"," << geoy <<
") not covered in model image " << imgReaderModel1.getFileName() << endl;
409 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
412 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
417 for(
int icol=0;icol<ncol;++icol){
418 imgWriterEst.image2geo(icol,irow,geox,geoy);
419 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
420 double modValue=estReadBuffer[modCol];
421 if(imgReaderModel1.isNoData(modValue)){
422 estWriteBuffer[icol]=obsnodata_opt[0];
423 uncertWriteBuffer[icol]=uncertNodata_opt[0];
427 estWriteBuffer[icol]=modValue;
428 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
431 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
432 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
434 catch(
string errorString){
435 cerr << errorString << endl;
438 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
444 cout <<
"we have a measurement at initial time" << endl;
445 imgReaderObs.open(observation_opt[0]);
446 imgReaderObs.getGeoTransform(geotransform);
447 imgReaderObs.setNoData(obsnodata_opt);
448 if(obsoffset_opt.size())
449 imgReaderObs.setOffset(obsoffset_opt[0]);
450 if(obsscale_opt.size())
451 imgReaderObs.setScale(obsscale_opt[0]);
453 if(regSensor_opt[0]>0)
454 errObs=regSensor_opt[0]*imgreg.getRMSE(imgReaderModel1,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
461 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
463 for(
int irow=0;irow<nrow;++irow){
464 vector<double> estReadBuffer;
465 imgWriterEst.image2geo(0,irow,geox,geoy);
466 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
467 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
468 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
469 vector<double> obsLineBuffer;
470 vector<double> estWriteBuffer(ncol);
471 vector<double> uncertWriteBuffer(ncol);
472 vector<double> uncertObsLineBuffer;
475 imgReaderObs.readData(obsLineBuffer,GDT_Float64,irow,0);
477 if(imgReaderObs.nrOfBand()>1)
478 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
480 for(
int icol=0;icol<ncol;++icol){
481 imgWriterEst.image2geo(icol,irow,geox,geoy);
482 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
483 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
484 double modValue=estReadBuffer[modCol];
485 if(imgReaderModel1.isNoData(modValue)){
486 estWriteBuffer[icol]=obsLineBuffer[icol];
487 if(imgReaderObs.isNoData(obsLineBuffer[icol])){
488 estWriteBuffer[icol]=obsnodata_opt[0];
489 uncertWriteBuffer[icol]=uncertNodata_opt[0];
491 else if(uncertObsLineBuffer.size()>icol)
492 uncertWriteBuffer[icol]=uncertObsLineBuffer[icol];
494 uncertWriteBuffer[icol]=uncertObs_opt[0];
497 double errMod=uncertModel_opt[0]*stdDev;
498 errMod*=regTime_opt[0];
505 estWriteBuffer[icol]=modValue;
506 double totalUncertainty=errMod;
515 uncertWriteBuffer[icol]=totalUncertainty;
519 if(!imgReaderObs.isNoData(obsLineBuffer[icol])){
521 double uncertObs=uncertObs_opt[0];
522 if(uncertObsLineBuffer.size()>icol)
523 uncertObs=uncertObsLineBuffer[icol];
524 else if(weight_opt.size()||deltaObs_opt.size()){
525 vector<double> obsWindowBuffer;
526 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
527 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
528 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
529 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
531 imgReaderObs.readDataBlock(obsWindowBuffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
533 statobs.setNoDataValues(obsnodata_opt);
534 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
535 double difference=obsMeanValue-modValue;
537 double relativeDifference=difference/modValue;
538 if(deltaObs_opt.size()){
539 assert(deltaObs_opt.size()>1);
540 if(100*relativeDifference<deltaObs_opt[0])
542 else if(100*relativeDifference>deltaObs_opt[1])
545 else if(weight_opt.size()){
546 assert(weight_opt.size()>1);
547 if(obsMeanValue<modValue)
548 uncertObs=weight_opt[0]*relativeDifference;
549 else if(obsMeanValue>modValue)
550 uncertObs=weight_opt[1]*relativeDifference;
556 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
559 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
560 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
562 assert(kalmanGain<=1);
563 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
564 uncertWriteBuffer[icol]*=(1-kalmanGain);
567 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
568 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
570 imgReaderObs.close();
573 imgReaderModel1.close();
574 imgWriterEst.close();
576 for(
int modindex=1;modindex<model_opt.size();++modindex){
578 cout <<
"processing time " << tmodel_opt[modindex] << endl;
579 if(obsindex<relobsindex.size())
580 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
582 cout <<
"There is no next observation" << endl;
585 if(outputfw_opt.size()==model_opt.size())
586 output=outputfw_opt[modindex];
588 ostringstream outputstream;
589 outputstream << outputfw_opt[0] <<
"_";
590 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
591 outputstream <<
".tif";
593 output=outputstream.str();
597 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
598 imgWriterEst.setProjectionProj4(projection_opt[0]);
599 imgWriterEst.setGeoTransform(geotransform);
600 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
603 imgReaderModel1.open(model_opt[modindex-1]);
604 imgReaderModel1.setNoData(modnodata_opt);
605 if(modoffset_opt.size())
606 imgReaderModel1.setOffset(modoffset_opt[0]);
607 if(modscale_opt.size())
608 imgReaderModel1.setScale(modscale_opt[0]);
609 imgReaderModel2.open(model_opt[modindex]);
610 imgReaderModel2.setNoData(modnodata_opt);
611 if(modoffset_opt.size())
612 imgReaderModel2.setOffset(modoffset_opt[0]);
613 if(modscale_opt.size())
614 imgReaderModel2.setScale(modscale_opt[0]);
619 pfnProgress(progress,pszMessage,pProgressArg);
622 cout <<
"Calculating regression for " << imgReaderModel1.getFileName() <<
" " << imgReaderModel2.getFileName() << endl;
624 double errMod=imgreg.getRMSE(imgReaderModel1,imgReaderModel2,c0modGlobal,c1modGlobal,0,0);
625 errMod*=regTime_opt[0];
629 cout <<
"c0modGlobal, c1modGlobal: " << c0modGlobal <<
", " << c1modGlobal << endl;
632 if(obsindex<relobsindex.size()){
633 update=(relobsindex[obsindex]==modindex);
637 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
639 imgReaderObs.open(observation_opt[obsindex]);
640 imgReaderObs.getGeoTransform(geotransform);
641 imgReaderObs.setNoData(obsnodata_opt);
642 if(obsoffset_opt.size())
643 imgReaderObs.setOffset(obsoffset_opt[0]);
644 if(obsscale_opt.size())
645 imgReaderObs.setScale(obsscale_opt[0]);
648 cout <<
"Calculating regression for " << imgReaderModel2.getFileName() <<
" " << imgReaderObs.getFileName() << endl;
649 if(regSensor_opt[0]>0)
650 errObs=regSensor_opt[0]*imgreg.getRMSE(imgReaderModel2,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
657 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
661 if(outputfw_opt.size()==model_opt.size())
662 input=outputfw_opt[modindex-1];
664 ostringstream outputstream;
665 outputstream << outputfw_opt[0] <<
"_";
666 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex-1];
667 outputstream <<
".tif";
669 input=outputstream.str();
672 cout <<
"opening " << input << endl;
674 imgReaderEst.setNoData(obsnodata_opt);
675 if(obsoffset_opt.size())
676 imgReaderEst.setOffset(obsoffset_opt[0]);
677 if(obsscale_opt.size())
678 imgReaderEst.setScale(obsscale_opt[0]);
680 vector< vector<double> > obsLineVector(down_opt[0]);
681 vector<double> obsLineBuffer;
682 vector<double> obsWindowBuffer;
683 vector<double> model1LineBuffer;
684 vector<double> model2LineBuffer;
685 vector<double> model1buffer;
686 vector<double> model2buffer;
687 vector<double> uncertObsLineBuffer;
688 vector<double> estReadBuffer;
690 vector<double> uncertReadBuffer;
691 vector<double> estWriteBuffer(ncol);
692 vector<double> uncertWriteBuffer(ncol);
698 cout <<
"initialize obsLineVector" << endl;
699 assert(down_opt[0]%2);
700 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
702 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
704 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
707 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
709 imgReaderEst.readData(estReadBuffer,GDT_Float64,irow,0);
710 imgReaderEst.readData(uncertReadBuffer,GDT_Float64,irow,1);
712 imgReaderEst.image2geo(0,irow,geox,geoy);
713 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
714 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
715 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,0);
717 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
718 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
719 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,0);
722 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
723 obsLineVector.erase(obsLineVector.begin());
724 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
725 obsLineVector.push_back(obsLineBuffer);
726 obsLineBuffer=obsLineVector[down_opt[0]/2];
728 if(imgReaderObs.nrOfBand()>1)
729 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
732 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
733 imgReaderEst.image2geo(icol,irow,geox,geoy);
734 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
735 int maxCol=(icol+down_opt[0]/2<imgReaderEst.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderEst.nrOfCol()-1;
736 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
737 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
739 obsWindowBuffer.clear();
740 for(
int iline=0;iline<obsLineVector.size();++iline){
741 for(
int isample=minCol;isample<=maxCol;++isample){
742 assert(isample<obsLineVector[iline].size());
743 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
748 double estValue=estReadBuffer[icol];
749 double estMeanValue=0;
752 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
753 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
754 double modValue=model2LineBuffer[modCol];
755 bool estNodata=imgReaderEst.isNoData(estValue);
758 if(imgReaderModel2.isNoData(modValue)){
759 estWriteBuffer[icol]=obsnodata_opt[0];
760 uncertWriteBuffer[icol]=uncertNodata_opt[0];
763 estWriteBuffer[icol]=modValue;
764 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
771 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
772 maxCol=(modCol+window_opt[0]/2<imgReaderModel2.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel2.nrOfCol()-1;
773 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
774 maxRow=(modRow+window_opt[0]/2<imgReaderModel2.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel2.nrOfRow()-1;
775 imgReaderModel2.readDataBlock(model2buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
777 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
778 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
779 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
780 maxCol=(modCol+window_opt[0]/2<imgReaderModel1.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel1.nrOfCol()-1;
781 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
782 maxRow=(modRow+window_opt[0]/2<imgReaderModel1.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel1.nrOfRow()-1;
783 imgReaderModel1.readDataBlock(model1buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
786 catch(
string errorString){
787 cerr <<
"Error reading data block for " << minCol <<
"-" << maxCol <<
", " << minRow <<
"-" << maxRow << endl;
790 vector<double>::iterator it1=model1buffer.begin();
791 vector<double>::iterator it2=model2buffer.begin();
792 while(it1!=model1buffer.end()&&it2!=model2buffer.end()){
794 bool modNodata=
false;
795 modNodata=modNodata||imgReaderModel1.isNoData(*it1);
796 modNodata=modNodata||imgReaderModel2.isNoData(*it2);
798 model1buffer.erase(it1);
799 model2buffer.erase(it2);
806 if(model1buffer.size()>minreg_opt[0]&&model2buffer.size()>minreg_opt[0]){
807 errMod=stat.linear_regression_err(model1buffer,model2buffer,c0mod,c1mod);
808 errMod*=regTime_opt[0];
819 double certNorm=(errMod*errMod+errObs*errObs);
820 double certMod=errObs*errObs/certNorm;
821 double certObs=errMod*errMod/certNorm;
822 double regTime=(c0mod+c1mod*estValue)*certObs;
823 double regSensor=(c0obs+c1obs*modValue)*certMod;
825 estWriteBuffer[icol]=regTime+regSensor;
834 double totalUncertainty=0;
835 if(errMod<eps_opt[0])
836 totalUncertainty=errObs;
837 else if(errObs<eps_opt[0])
838 totalUncertainty=errMod;
840 totalUncertainty=1.0/errMod/errMod+1/errObs/errObs;
841 totalUncertainty=sqrt(1.0/totalUncertainty);
843 uncertWriteBuffer[icol]=totalUncertainty+uncertReadBuffer[icol];
846 if(update&&!imgReaderObs.isNoData(obsLineBuffer[icol])){
848 double uncertObs=uncertObs_opt[0];
849 if(uncertObsLineBuffer.size()>icol)
850 uncertObs=uncertObsLineBuffer[icol];
851 else if(weight_opt.size()>1||deltaObs_opt.size()){
853 statobs.setNoDataValues(obsnodata_opt);
854 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
855 double difference=obsMeanValue-modValue;
857 double relativeDifference=difference/modValue;
858 if(deltaObs_opt.size()){
859 assert(deltaObs_opt.size()>1);
860 if(100*relativeDifference<deltaObs_opt[0])
862 else if(100*relativeDifference>deltaObs_opt[1])
865 else if(weight_opt.size()){
866 assert(weight_opt.size()>1);
867 if(obsMeanValue<modValue)
868 uncertObs=weight_opt[0]*relativeDifference;
869 else if(obsMeanValue>modValue)
870 uncertObs=weight_opt[1]*relativeDifference;
876 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
879 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
880 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
882 assert(kalmanGain<=1);
883 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
884 uncertWriteBuffer[icol]*=(1-kalmanGain);
887 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
888 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
889 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
890 pfnProgress(progress,pszMessage,pProgressArg);
893 imgWriterEst.close();
894 imgReaderEst.close();
897 imgReaderObs.close();
900 imgReaderModel1.close();
901 imgReaderModel2.close();
904 if(find(direction_opt.begin(),direction_opt.end(),
"backward")!=direction_opt.end()){
906 cout <<
"Running backward model" << endl;
907 obsindex=relobsindex.size()-1;
910 if(outputbw_opt.size()==model_opt.size())
911 output=outputbw_opt.back();
913 ostringstream outputstream;
914 outputstream << outputbw_opt[0] <<
"_";
915 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt.back();
916 outputstream <<
".tif";
918 output=outputstream.str();
921 cout <<
"Opening image " << output <<
" for writing " << endl;
922 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
923 imgWriterEst.setProjectionProj4(projection_opt[0]);
924 imgWriterEst.setGeoTransform(geotransform);
925 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
928 cout <<
"processing time " << tmodel_opt.back() << endl;
929 if(obsindex<relobsindex.size())
930 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
932 cout <<
"There is no next observation" << endl;
936 imgReaderModel1.open(model_opt.back());
937 imgReaderModel1.setNoData(modnodata_opt);
938 if(modoffset_opt.size())
939 imgReaderModel1.setOffset(modoffset_opt[0]);
940 if(modscale_opt.size())
941 imgReaderModel1.setScale(modscale_opt[0]);
943 catch(
string errorString){
944 cerr << errorString << endl;
947 cerr <<
"Error opening file " << model_opt[0] << endl;
951 GDALRasterBand* rasterBand;
952 rasterBand=imgReaderModel1.getRasterBand(0);
953 double minValue, maxValue, meanValue, stdDev;
955 rasterBand->ComputeStatistics(0,&minValue,&maxValue,&meanValue,&stdDev,pfnProgress,pProgressData);
958 if(relobsindex.back()<model_opt.size()-1){
961 cout <<
"write last model as output" << endl;
962 for(
int irow=0;irow<nrow;++irow){
963 vector<double> estReadBuffer;
964 vector<double> estWriteBuffer(ncol);
965 vector<double> uncertWriteBuffer(ncol);
967 imgWriterEst.image2geo(0,irow,geox,geoy);
968 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
969 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
971 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
976 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
977 imgWriterEst.image2geo(icol,irow,geox,geoy);
978 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
979 double modValue=estReadBuffer[modCol];
980 if(imgReaderModel1.isNoData(modValue)){
981 estWriteBuffer[icol]=obsnodata_opt[0];
982 uncertWriteBuffer[icol]=uncertNodata_opt[0];
985 estWriteBuffer[icol]=modValue;
986 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
989 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
990 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
992 catch(
string errorString){
993 cerr << errorString << endl;
996 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
1002 cout <<
"we have an measurement at end time" << endl;
1003 imgReaderObs.open(observation_opt.back());
1004 imgReaderObs.getGeoTransform(geotransform);
1005 imgReaderObs.setNoData(obsnodata_opt);
1006 if(obsoffset_opt.size())
1007 imgReaderObs.setOffset(obsoffset_opt[0]);
1008 if(obsscale_opt.size())
1009 imgReaderObs.setScale(obsscale_opt[0]);
1011 if(regSensor_opt[0]>0)
1012 errObs=regSensor_opt[0]*imgreg.getRMSE(imgReaderModel1,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
1019 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
1021 for(
int irow=0;irow<nrow;++irow){
1022 vector<double> estReadBuffer;
1023 imgWriterEst.image2geo(0,irow,geox,geoy);
1024 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1025 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1026 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
1027 vector<double> obsLineBuffer;
1028 vector<double> estWriteBuffer(ncol);
1029 vector<double> uncertWriteBuffer(ncol);
1030 vector<double> uncertObsLineBuffer;
1033 imgReaderObs.readData(obsLineBuffer,GDT_Float64,irow,0);
1035 if(imgReaderObs.nrOfBand()>1)
1036 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1038 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1039 imgWriterEst.image2geo(icol,irow,geox,geoy);
1040 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1041 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1042 double modValue=estReadBuffer[modCol];
1043 if(imgReaderModel1.isNoData(modValue)){
1044 estWriteBuffer[icol]=obsLineBuffer[icol];
1045 if(imgReaderObs.isNoData(obsLineBuffer[icol])){
1046 estWriteBuffer[icol]=obsnodata_opt[0];
1047 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1049 else if(uncertObsLineBuffer.size()>icol)
1050 uncertWriteBuffer[icol]=uncertObsLineBuffer[icol];
1052 uncertWriteBuffer[icol]=uncertObs_opt[0];
1055 double errMod=uncertModel_opt[0]*stdDev;
1056 errMod*=regTime_opt[0];
1063 estWriteBuffer[icol]=modValue;
1064 double totalUncertainty=errMod;
1073 uncertWriteBuffer[icol]=totalUncertainty;
1076 if(!imgReaderObs.isNoData(obsLineBuffer[icol])){
1077 double kalmanGain=1;
1078 double uncertObs=uncertObs_opt[0];
1079 if(uncertObsLineBuffer.size()>icol)
1080 uncertObs=uncertObsLineBuffer[icol];
1081 else if(weight_opt.size()>1||deltaObs_opt.size()){
1082 vector<double> obsWindowBuffer;
1083 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
1084 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
1085 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
1086 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
1088 imgReaderObs.readDataBlock(obsWindowBuffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
1090 statobs.setNoDataValues(obsnodata_opt);
1091 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
1092 double difference=obsMeanValue-modValue;
1094 double relativeDifference=difference/modValue;
1095 if(deltaObs_opt.size()){
1096 assert(deltaObs_opt.size()>1);
1097 if(100*relativeDifference<deltaObs_opt[0])
1099 else if(100*relativeDifference>deltaObs_opt[1])
1102 else if(weight_opt.size()){
1103 assert(weight_opt.size()>1);
1104 if(obsMeanValue<modValue)
1105 uncertObs=weight_opt[0]*relativeDifference;
1106 else if(obsMeanValue>modValue)
1107 uncertObs=weight_opt[1]*relativeDifference;
1112 if(verbose_opt[0]>1)
1113 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
1116 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
1117 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
1119 assert(kalmanGain<=1);
1120 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1121 uncertWriteBuffer[icol]*=(1-kalmanGain);
1124 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1125 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1127 imgReaderObs.close();
1130 imgReaderModel1.close();
1131 imgWriterEst.close();
1133 for(
int modindex=model_opt.size()-2;modindex>=0;--modindex){
1135 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1136 if(obsindex<relobsindex.size())
1137 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1139 cout <<
"There is no next observation" << endl;
1142 if(outputbw_opt.size()==model_opt.size())
1143 output=outputbw_opt[modindex];
1145 ostringstream outputstream;
1146 outputstream << outputbw_opt[0] <<
"_";
1147 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1148 outputstream <<
".tif";
1150 output=outputstream.str();
1154 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
1155 imgWriterEst.setProjectionProj4(projection_opt[0]);
1156 imgWriterEst.setGeoTransform(geotransform);
1157 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1160 imgReaderModel1.open(model_opt[modindex+1]);
1161 imgReaderModel1.setNoData(modnodata_opt);
1162 if(modoffset_opt.size())
1163 imgReaderModel1.setOffset(modoffset_opt[0]);
1164 if(modscale_opt.size())
1165 imgReaderModel1.setScale(modscale_opt[0]);
1166 imgReaderModel2.open(model_opt[modindex]);
1167 imgReaderModel2.setNoData(modnodata_opt);
1168 if(modoffset_opt.size())
1169 imgReaderModel2.setOffset(modoffset_opt[0]);
1170 if(modscale_opt.size())
1171 imgReaderModel2.setScale(modscale_opt[0]);
1176 pfnProgress(progress,pszMessage,pProgressArg);
1179 cout <<
"Calculating regression for " << imgReaderModel1.getFileName() <<
" " << imgReaderModel2.getFileName() << endl;
1181 double errMod=imgreg.getRMSE(imgReaderModel1,imgReaderModel2,c0modGlobal,c1modGlobal,0,0);
1182 errMod*=regTime_opt[0];
1186 cout <<
"c0modGlobal, c1modGlobal: " << c0modGlobal <<
", " << c1modGlobal << endl;
1189 if(obsindex<relobsindex.size()){
1190 update=(relobsindex[obsindex]==modindex);
1194 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
1196 imgReaderObs.open(observation_opt[obsindex]);
1197 imgReaderObs.getGeoTransform(geotransform);
1198 imgReaderObs.setNoData(obsnodata_opt);
1199 if(obsoffset_opt.size())
1200 imgReaderObs.setOffset(obsoffset_opt[0]);
1201 if(obsscale_opt.size())
1202 imgReaderObs.setScale(obsscale_opt[0]);
1205 cout <<
"Calculating regression for " << imgReaderModel2.getFileName() <<
" " << imgReaderObs.getFileName() << endl;
1206 if(regSensor_opt[0]>0)
1207 errObs=regSensor_opt[0]*imgreg.getRMSE(imgReaderModel2,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
1214 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
1218 if(outputbw_opt.size()==model_opt.size())
1219 input=outputbw_opt[modindex+1];
1221 ostringstream outputstream;
1222 outputstream << outputbw_opt[0] <<
"_";
1223 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex+1];
1224 outputstream <<
".tif";
1226 input=outputstream.str();
1229 imgReaderEst.setNoData(obsnodata_opt);
1230 if(obsoffset_opt.size())
1231 imgReaderEst.setOffset(obsoffset_opt[0]);
1232 if(obsscale_opt.size())
1233 imgReaderEst.setScale(obsscale_opt[0]);
1235 vector< vector<double> > obsLineVector(down_opt[0]);
1236 vector<double> obsLineBuffer;
1237 vector<double> obsWindowBuffer;
1238 vector<double> model1LineBuffer;
1239 vector<double> model2LineBuffer;
1240 vector<double> model1buffer;
1241 vector<double> model2buffer;
1242 vector<double> uncertObsLineBuffer;
1243 vector<double> estReadBuffer;
1245 vector<double> uncertReadBuffer;
1246 vector<double> estWriteBuffer(ncol);
1247 vector<double> uncertWriteBuffer(ncol);
1252 assert(down_opt[0]%2);
1253 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
1255 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
1257 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
1260 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
1261 assert(irow<imgReaderEst.nrOfRow());
1263 imgReaderEst.readData(estReadBuffer,GDT_Float64,irow,0);
1264 imgReaderEst.readData(uncertReadBuffer,GDT_Float64,irow,1);
1266 imgReaderEst.image2geo(0,irow,geox,geoy);
1267 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1268 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1269 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,0);
1271 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1272 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1273 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,0);
1276 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
1277 obsLineVector.erase(obsLineVector.begin());
1278 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
1279 obsLineVector.push_back(obsLineBuffer);
1280 obsLineBuffer=obsLineVector[down_opt[0]/2];
1282 if(imgReaderObs.nrOfBand()>1)
1283 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1286 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1287 imgReaderEst.image2geo(icol,irow,geox,geoy);
1288 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
1289 int maxCol=(icol+down_opt[0]/2<imgReaderEst.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderEst.nrOfCol()-1;
1290 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
1291 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
1293 obsWindowBuffer.clear();
1294 for(
int iline=0;iline<obsLineVector.size();++iline){
1295 for(
int isample=minCol;isample<=maxCol;++isample){
1296 assert(isample<obsLineVector[iline].size());
1297 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
1302 double estValue=estReadBuffer[icol];
1303 double estMeanValue=0;
1306 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1307 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1308 double modValue=model2LineBuffer[modCol];
1309 bool estNodata=imgReaderEst.isNoData(estValue);
1312 if(imgReaderModel2.isNoData(modValue)){
1313 estWriteBuffer[icol]=obsnodata_opt[0];
1314 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1317 estWriteBuffer[icol]=modValue;
1318 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
1322 if(window_opt[0]>0){
1325 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
1326 maxCol=(modCol+window_opt[0]/2<imgReaderModel2.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel2.nrOfCol()-1;
1327 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
1328 maxRow=(modRow+window_opt[0]/2<imgReaderModel2.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel2.nrOfRow()-1;
1329 imgReaderModel2.readDataBlock(model2buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
1331 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1332 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1333 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
1334 maxCol=(modCol+window_opt[0]/2<imgReaderModel1.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel1.nrOfCol()-1;
1335 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
1336 maxRow=(modRow+window_opt[0]/2<imgReaderModel1.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel1.nrOfRow()-1;
1337 imgReaderModel1.readDataBlock(model1buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
1340 catch(
string errorString){
1341 cerr <<
"Error reading data block for " << minCol <<
"-" << maxCol <<
", " << minRow <<
"-" << maxRow << endl;
1344 vector<double>::iterator it1=model1buffer.begin();
1345 vector<double>::iterator it2=model2buffer.begin();
1346 while(it1!=model1buffer.end()&&it2!=model2buffer.end()){
1348 bool modNodata=
false;
1349 modNodata=modNodata||imgReaderModel1.isNoData(*it1);
1350 modNodata=modNodata||imgReaderModel2.isNoData(*it2);
1352 model1buffer.erase(it1);
1353 model2buffer.erase(it2);
1360 if(model1buffer.size()>minreg_opt[0]&&model2buffer.size()>minreg_opt[0]){
1361 errMod=stat.linear_regression_err(model1buffer,model2buffer,c0mod,c1mod);
1362 errMod*=regTime_opt[0];
1373 double certNorm=(errMod*errMod+errObs*errObs);
1374 double certMod=errObs*errObs/certNorm;
1375 double certObs=errMod*errMod/certNorm;
1376 double regTime=(c0mod+c1mod*estValue)*certObs;
1379 double regSensor=(c0obs+c1obs*modValue)*certMod;
1380 estWriteBuffer[icol]=regTime+regSensor;
1381 double totalUncertainty=0;
1382 if(errMod<eps_opt[0])
1383 totalUncertainty=errObs;
1384 else if(errObs<eps_opt[0])
1385 totalUncertainty=errMod;
1387 totalUncertainty=1.0/errMod/errMod+1/errObs/errObs;
1388 totalUncertainty=sqrt(1.0/totalUncertainty);
1390 uncertWriteBuffer[icol]=totalUncertainty+uncertReadBuffer[icol];
1393 if(update&&!imgReaderObs.isNoData(obsLineBuffer[icol])){
1394 double kalmanGain=1;
1395 double uncertObs=uncertObs_opt[0];
1396 if(uncertObsLineBuffer.size()>icol)
1397 uncertObs=uncertObsLineBuffer[icol];
1398 else if(weight_opt.size()>1||deltaObs_opt.size()){
1400 statobs.setNoDataValues(obsnodata_opt);
1401 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
1402 double difference=obsMeanValue-modValue;
1404 double relativeDifference=difference/modValue;
1405 if(deltaObs_opt.size()){
1406 assert(deltaObs_opt.size()>1);
1407 if(100*relativeDifference<deltaObs_opt[0])
1409 else if(100*relativeDifference>deltaObs_opt[1])
1412 else if(weight_opt.size()){
1413 assert(weight_opt.size()>1);
1414 if(obsMeanValue<modValue)
1415 uncertObs=weight_opt[0]*relativeDifference;
1416 else if(obsMeanValue>modValue)
1417 uncertObs=weight_opt[1]*relativeDifference;
1422 if(verbose_opt[0]>1)
1423 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
1426 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
1427 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
1429 assert(kalmanGain<=1);
1430 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1431 uncertWriteBuffer[icol]*=(1-kalmanGain);
1434 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1435 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1436 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
1437 pfnProgress(progress,pszMessage,pProgressArg);
1440 imgWriterEst.close();
1441 imgReaderEst.close();
1444 imgReaderObs.close();
1447 imgReaderModel1.close();
1448 imgReaderModel2.close();
1451 if(find(direction_opt.begin(),direction_opt.end(),
"smooth")!=direction_opt.end()){
1453 cout <<
"Running smooth model" << endl;
1455 for(
int modindex=0;modindex<model_opt.size();++modindex){
1457 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1458 if(obsindex<relobsindex.size())
1459 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1461 cout <<
"There is no next observation" << endl;
1464 if(outputfb_opt.size()==model_opt.size())
1465 output=outputfb_opt[modindex];
1467 ostringstream outputstream;
1468 outputstream << outputfb_opt[0] <<
"_";
1469 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1470 outputstream <<
".tif";
1472 output=outputstream.str();
1476 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
1477 imgWriterEst.setProjectionProj4(projection_opt[0]);
1478 imgWriterEst.setGeoTransform(geotransform);
1479 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1486 if(outputfw_opt.size()==model_opt.size())
1487 inputfw=outputfw_opt[modindex];
1489 ostringstream outputstream;
1490 outputstream << outputfw_opt[0] <<
"_";
1491 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1492 outputstream <<
".tif";
1494 inputfw=outputstream.str();
1496 if(outputbw_opt.size()==model_opt.size())
1497 inputbw=outputbw_opt[modindex];
1499 ostringstream outputstream;
1500 outputstream << outputbw_opt[0] <<
"_";
1501 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1502 outputstream <<
".tif";
1504 inputbw=outputstream.str();
1508 imgReaderForward.setNoData(obsnodata_opt);
1509 if(obsoffset_opt.size())
1510 imgReaderForward.setOffset(obsoffset_opt[0]);
1511 if(obsscale_opt.size())
1512 imgReaderForward.setScale(obsscale_opt[0]);
1513 imgReaderBackward.setNoData(obsnodata_opt);
1514 if(obsoffset_opt.size())
1515 imgReaderBackward.setOffset(obsoffset_opt[0]);
1516 if(obsscale_opt.size())
1517 imgReaderBackward.setScale(obsscale_opt[0]);
1519 vector<double> estForwardBuffer;
1520 vector<double> estBackwardBuffer;
1521 vector<double> uncertObsLineBuffer;
1522 vector<double> uncertForwardBuffer;
1523 vector<double> uncertBackwardBuffer;
1524 vector<double> uncertReadBuffer;
1525 vector<double> estWriteBuffer(ncol);
1526 vector<double> uncertWriteBuffer(ncol);
1530 if(obsindex<relobsindex.size()){
1531 update=(relobsindex[obsindex]==modindex);
1536 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
1537 imgReaderObs.open(observation_opt[obsindex]);
1538 imgReaderObs.getGeoTransform(geotransform);
1539 imgReaderObs.setNoData(obsnodata_opt);
1540 if(obsoffset_opt.size())
1541 imgReaderObs.setOffset(obsoffset_opt[0]);
1542 if(obsscale_opt.size())
1543 imgReaderObs.setScale(obsscale_opt[0]);
1547 pfnProgress(progress,pszMessage,pProgressArg);
1549 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
1550 assert(irow<imgReaderForward.nrOfRow());
1551 assert(irow<imgReaderBackward.nrOfRow());
1552 imgReaderForward.readData(estForwardBuffer,GDT_Float64,irow,0);
1553 imgReaderBackward.readData(estBackwardBuffer,GDT_Float64,irow,0);
1554 imgReaderForward.readData(uncertForwardBuffer,GDT_Float64,irow,1);
1555 imgReaderBackward.readData(uncertBackwardBuffer,GDT_Float64,irow,1);
1558 imgReaderObs.readData(estWriteBuffer,GDT_Float64,irow,0);
1559 if(imgReaderObs.nrOfBand()>1)
1560 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1564 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1565 imgWriterEst.image2geo(icol,irow,geox,geoy);
1566 double A=estForwardBuffer[icol];
1567 double B=estBackwardBuffer[icol];
1568 double C=uncertForwardBuffer[icol]*uncertForwardBuffer[icol];
1569 double D=uncertBackwardBuffer[icol]*uncertBackwardBuffer[icol];
1570 double uncertObs=uncertObs_opt[0];
1579 double noemer=(C+D);
1581 if(imgReaderForward.isNoData(A)&&imgReaderBackward.isNoData(B)){
1582 estWriteBuffer[icol]=obsnodata_opt[0];
1583 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1585 else if(imgReaderForward.isNoData(A)){
1586 estWriteBuffer[icol]=B;
1587 uncertWriteBuffer[icol]=uncertBackwardBuffer[icol];
1589 else if(imgReaderForward.isNoData(B)){
1590 estWriteBuffer[icol]=A;
1591 uncertWriteBuffer[icol]=uncertForwardBuffer[icol];
1594 if(noemer<eps_opt[0]){
1595 estWriteBuffer[icol]=0.5*(A+B);
1596 uncertWriteBuffer[icol]=uncertObs;
1599 estWriteBuffer[icol]=(A*D+B*C)/noemer;
1605 if(uncertObs*uncertObs>eps_opt[0])
1606 P-=1.0/uncertObs/uncertObs;
1611 uncertWriteBuffer[icol]=P;
1615 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1616 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1617 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
1618 pfnProgress(progress,pszMessage,pProgressArg);
1621 imgWriterEst.close();
1622 imgReaderForward.close();
1623 imgReaderBackward.close();
1625 imgReaderObs.close();