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"
72 int main(
int argc,
char **argv) {
73 Optionpk<string> direction_opt(
"dir",
"direction",
"direction to run model (forward|backward|smooth)",
"forward");
74 Optionpk<string> model_opt(
"mod",
"model",
"model input datasets, e.g., MODIS (use: -mod model1 -mod model2 etc.)");
75 Optionpk<string> observation_opt(
"obs",
"observation",
"observation input datasets, e.g., landsat (use: -obs obs1 -obs obs2 etc.)");
76 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.");
77 Optionpk<int> tobservation_opt(
"tobs",
"tobservation",
"time sequence of observation input. Sequence must have exact same length as observation input)");
78 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");
79 Optionpk<string> outputfw_opt(
"ofw",
"outputfw",
"Output raster dataset for forward model");
80 Optionpk<string> outputbw_opt(
"obw",
"outputbw",
"Output raster dataset for backward model");
81 Optionpk<string> outputfb_opt(
"ofb",
"outputfb",
"Output raster dataset for smooth model");
84 Optionpk<double> modnodata_opt(
"modnodata",
"modnodata",
"invalid value for model input", 0);
85 Optionpk<double> obsnodata_opt(
"obsnodata",
"obsnodata",
"invalid value for observation input", 0);
86 Optionpk<double> obsmin_opt(
"obsmin",
"obsmin",
"Minimum value for observation data");
87 Optionpk<double> obsmax_opt(
"obsmax",
"obsmax",
"Maximum value for observation data");
88 Optionpk<double> eps_opt(
"eps",
"eps",
"epsilon for non zero division", 0.00001);
89 Optionpk<double> uncertModel_opt(
"um",
"uncertmodel",
"Uncertainty of model",1,1);
90 Optionpk<double> uncertObs_opt(
"uo",
"uncertobs",
"Uncertainty of valid observations",1,1);
91 Optionpk<double> processNoise_opt(
"q",
"q",
"Process noise: expresses instability (variance) of proportions of fine res pixels within a moderate resolution pixel",1);
92 Optionpk<double> uncertNodata_opt(
"unodata",
"uncertnodata",
"Uncertainty in case of no-data values in observation", 100);
93 Optionpk<int> down_opt(
"down",
"down",
"Downsampling factor for reading model data to calculate regression");
94 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate). Empty string: inherit from input image",
"GTiff",2);
95 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
96 Optionpk<short> verbose_opt(
"v",
"verbose",
"verbose mode when positive", 0);
100 doProcess=direction_opt.retrieveOption(argc,argv);
101 model_opt.retrieveOption(argc,argv);
102 observation_opt.retrieveOption(argc,argv);
103 tmodel_opt.retrieveOption(argc,argv);
104 tobservation_opt.retrieveOption(argc,argv);
105 projection_opt.retrieveOption(argc,argv);
106 outputfw_opt.retrieveOption(argc,argv);
107 outputbw_opt.retrieveOption(argc,argv);
108 outputfb_opt.retrieveOption(argc,argv);
109 gain_opt.retrieveOption(argc,argv);
110 modnodata_opt.retrieveOption(argc,argv);
111 obsnodata_opt.retrieveOption(argc,argv);
112 obsmin_opt.retrieveOption(argc,argv);
113 obsmax_opt.retrieveOption(argc,argv);
114 eps_opt.retrieveOption(argc,argv);
115 uncertModel_opt.retrieveOption(argc,argv);
116 uncertObs_opt.retrieveOption(argc,argv);
117 processNoise_opt.retrieveOption(argc,argv);
118 uncertNodata_opt.retrieveOption(argc,argv);
119 down_opt.retrieveOption(argc,argv);
120 oformat_opt.retrieveOption(argc,argv);
121 option_opt.retrieveOption(argc,argv);
122 verbose_opt.retrieveOption(argc,argv);
124 catch(
string predefinedString){
125 std::cout << predefinedString << std::endl;
129 std::cerr <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
133 if(down_opt.empty()){
134 std::cerr <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
138 ostringstream errorStream;
139 if(model_opt.size()<2){
140 errorStream <<
"Error: no model dataset selected, use option -mod" << endl;
141 throw(errorStream.str());
143 if(observation_opt.size()<1){
144 errorStream <<
"Error: no observation dataset selected, use option -obs" << endl;
145 throw(errorStream.str());
147 if(direction_opt[0]==
"smooth"){
148 if(outputfw_opt.empty()){
149 errorStream <<
"Error: output forward datasets is not provided, use option -ofw" << endl;
150 throw(errorStream.str());
152 if(outputbw_opt.empty()){
153 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
154 throw(errorStream.str());
156 if(outputfb_opt.empty()){
157 errorStream <<
"Error: output smooth datasets is not provided, use option -ofb" << endl;
158 throw(errorStream.str());
162 if(direction_opt[0]==
"forward"&&outputfw_opt.empty()){
163 errorStream <<
"Error: output forward datasets is not provided, use option -ofw" << endl;
164 throw(errorStream.str());
166 else if(direction_opt[0]==
"backward"&&outputbw_opt.empty()){
167 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
168 throw(errorStream.str());
171 if(model_opt.size()<observation_opt.size()){
172 errorStream <<
"Error: sequence of models should be larger than observations" << endl;
173 throw(errorStream.str());
175 if(tmodel_opt.size()!=model_opt.size()){
176 if(tmodel_opt.empty())
177 cout <<
"Warning: time sequence is not provided, self generating time sequence from 0 to " << model_opt.size() << endl;
179 cout <<
"Warning: time sequence provided (" << tmodel_opt.size() <<
") does not match number of model raster datasets (" << model_opt.size() <<
")" << endl;
181 for(
int tindex=0;tindex<model_opt.size();++tindex)
182 tmodel_opt.push_back(tindex);
184 if(tobservation_opt.size()!=observation_opt.size()){
185 errorStream <<
"Error: time sequence for observation must match size of observation dataset" << endl;
186 throw(errorStream.str());
190 catch(
string errorString){
191 std::cout << errorString << std::endl;
196 stat.setNoDataValues(modnodata_opt);
204 imgReaderObs.open(observation_opt[0]);
206 int ncol=imgReaderObs.nrOfCol();
207 int nrow=imgReaderObs.nrOfRow();
208 if(projection_opt.empty())
209 projection_opt.push_back(imgReaderObs.getProjection());
210 double geotransform[6];
211 imgReaderObs.getGeoTransform(geotransform);
213 string imageType=imgReaderObs.getImageType();
214 if(oformat_opt.size())
215 imageType=oformat_opt[0];
216 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
217 string theInterleave=
"INTERLEAVE=";
218 theInterleave+=imgReaderObs.getInterleave();
219 option_opt.push_back(theInterleave);
222 if(down_opt.empty()){
223 imgReaderModel1.open(model_opt[0]);
224 double resModel=imgReaderModel1.getDeltaX();
225 double resObs=imgReaderObs.getDeltaX();
226 int down=
static_cast<int>(ceil(resModel/resObs));
229 down_opt.push_back(down);
230 imgReaderModel1.close();
232 imgReaderObs.close();
236 const char* pszMessage;
237 void* pProgressArg=NULL;
238 GDALProgressFunc pfnProgress=GDALTermProgress;
241 double errObs=uncertNodata_opt[0];
243 vector<int> relobsindex;
245 for(
int tindex=0;tindex<tobservation_opt.size();++tindex){
246 vector<int>::iterator modit;
247 modit=upper_bound(tmodel_opt.begin(),tmodel_opt.end(),tobservation_opt[tindex]);
248 int relpos=modit-tmodel_opt.begin()-1;
250 relobsindex.push_back(relpos);
252 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;
255 int ndigit=log(1.0*tmodel_opt.back())/log(10.0)+1;
260 if(find(direction_opt.begin(),direction_opt.end(),
"forward")!=direction_opt.end()){
262 cout <<
"Running forward model" << endl;
266 if(outputfw_opt.size()==model_opt.size()){
267 output=outputfw_opt[0];
270 ostringstream outputstream;
271 outputstream << outputfw_opt[0] <<
"_";
272 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[0];
273 outputstream <<
".tif";
274 output=outputstream.str();
277 cout <<
"Opening image " << output <<
" for writing " << endl;
279 imgWriterEst.open(output,ncol,nrow,2,GDT_Float64,imageType,option_opt);
280 imgWriterEst.setProjectionProj4(projection_opt[0]);
281 imgWriterEst.setGeoTransform(geotransform);
282 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
286 imgWriterGain.open(gain_opt[0],ncol,nrow,model_opt.size(),GDT_Float64,imageType,option_opt);
287 imgWriterGain.setProjectionProj4(projection_opt[0]);
288 imgWriterGain.setGeoTransform(geotransform);
289 imgWriterGain.GDALSetNoDataValue(obsnodata_opt[0]);
293 cout <<
"processing time " << tmodel_opt[0] << endl;
294 if(obsindex<relobsindex.size())
295 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
297 cout <<
"There is no next observation" << endl;
301 imgReaderModel1.open(model_opt[0]);
302 imgReaderModel1.setNoData(modnodata_opt);
304 catch(
string errorString){
305 cerr << errorString << endl;
308 cerr <<
"Error opening file " << model_opt[0] << endl;
321 RESAMPLE theResample=BILINEAR;
323 if(relobsindex[0]>0){
326 cout <<
"write first model as output" << endl;
327 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
328 vector<double> estReadBuffer;
329 vector<double> estWriteBuffer(ncol);
330 vector<double> uncertWriteBuffer(ncol);
332 vector<double> gainWriteBuffer(ncol);
334 for(
int irow=jrow;irow<jrow+down_opt[0];++irow){
335 imgWriterEst.image2geo(0,irow,geox,geoy);
336 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
337 if(modRow<0||modRow>=imgReaderModel1.nrOfRow()){
338 cerr <<
"Error: geo coordinates (" << geox <<
"," << geoy <<
") not covered in model image " << imgReaderModel1.getFileName() << endl;
339 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
341 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow,0,theResample);
342 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
343 for(
int icol=icol;icol<icol+down_opt[0];++icol){
344 imgWriterEst.image2geo(icol,irow,geox,geoy);
345 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
347 lowerCol=
static_cast<int>(lowerCol);
349 upperCol=
static_cast<int>(upperCol);
352 if(upperCol>=imgReaderModel1.nrOfCol())
353 upperCol=imgReaderModel1.nrOfCol()-1;
354 double modValue=(modCol-0.5-lowerCol)*estReadBuffer[upperCol]+(1-modCol+0.5+lowerCol)*estReadBuffer[lowerCol];
356 if(imgReaderModel1.isNoData(modValue)){
357 estWriteBuffer[icol]=obsnodata_opt[0];
358 uncertWriteBuffer[icol]=uncertNodata_opt[0];
359 gainWriteBuffer[icol]=obsnodata_opt[0];
362 estWriteBuffer[icol]=modValue;
363 if(obsmin_opt.size()){
364 if(estWriteBuffer[icol]<obsmin_opt[0])
365 estWriteBuffer[icol]=obsmin_opt[0];
367 if(obsmax_opt.size()){
368 if(estWriteBuffer[icol]>obsmax_opt[0])
369 estWriteBuffer[icol]=obsmax_opt[0];
371 uncertWriteBuffer[icol]=uncertModel_opt[0];
372 gainWriteBuffer[icol]=0;
376 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
377 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
379 imgWriterGain.writeData(gainWriteBuffer,GDT_Float64,irow,0);
382 catch(
string errorString){
383 cerr << errorString << endl;
386 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
392 cout <<
"we have a measurement at initial time" << endl;
393 imgReaderObs.open(observation_opt[0]);
394 imgReaderObs.getGeoTransform(geotransform);
395 imgReaderObs.setNoData(obsnodata_opt);
397 vector< vector<double> > obsLineVector(down_opt[0]);
398 vector<double> obsLineBuffer;
399 vector<double> obsWindowBuffer;
400 vector<double> estReadBuffer;
401 vector<double> estWriteBuffer(ncol);
402 vector<double> uncertWriteBuffer(ncol);
403 vector<double> uncertObsLineBuffer;
405 vector<double> gainWriteBuffer(ncol);
408 cout <<
"initialize obsLineVector" << endl;
409 assert(down_opt[0]%2);
410 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
412 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
414 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
416 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
417 for(
int irow=jrow;irow<jrow+down_opt[0];++irow){
418 imgWriterEst.image2geo(0,irow,geox,geoy);
419 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
420 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
421 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow,0,theResample);
422 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
423 obsLineVector.erase(obsLineVector.begin());
424 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
425 obsLineVector.push_back(obsLineBuffer);
427 if(imgReaderObs.nrOfBand()>1)
428 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
430 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
431 for(
int icol=jcol;icol<jcol+down_opt[0];++icol){
432 imgWriterEst.image2geo(icol,irow,geox,geoy);
433 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
434 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
436 lowerCol=
static_cast<int>(lowerCol);
438 upperCol=
static_cast<int>(upperCol);
441 if(upperCol>=imgReaderModel1.nrOfCol())
442 upperCol=imgReaderModel1.nrOfCol()-1;
443 double modValue=(modCol-0.5-lowerCol)*estReadBuffer[upperCol]+(1-modCol+0.5+lowerCol)*estReadBuffer[lowerCol];
445 double errMod=uncertModel_opt[0];
446 if(imgReaderModel1.isNoData(modValue)){
447 if(imgReaderObs.isNoData(obsLineBuffer[icol])){
448 estWriteBuffer[icol]=obsnodata_opt[0];
449 uncertWriteBuffer[icol]=uncertNodata_opt[0];
450 gainWriteBuffer[icol]=obsnodata_opt[0];
453 estWriteBuffer[icol]=obsLineBuffer[icol];
454 if(obsmin_opt.size()){
455 if(estWriteBuffer[icol]<obsmin_opt[0])
456 estWriteBuffer[icol]=obsmin_opt[0];
458 if(obsmax_opt.size()){
459 if(estWriteBuffer[icol]>obsmax_opt[0])
460 estWriteBuffer[icol]=obsmax_opt[0];
462 if(uncertObsLineBuffer.size()>icol)
463 uncertWriteBuffer[icol]=uncertObsLineBuffer[icol];
465 uncertWriteBuffer[icol]=uncertObs_opt[0];
469 estWriteBuffer[icol]=modValue;
470 uncertWriteBuffer[icol]=errMod;
471 gainWriteBuffer[icol]=0;
474 if(!imgReaderObs.isNoData(obsLineBuffer[icol])){
477 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
478 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
479 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
480 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
481 obsWindowBuffer.clear();
482 for(
int iline=0;iline<obsLineVector.size();++iline){
483 for(
int isample=minCol;isample<=maxCol;++isample){
484 assert(isample<obsLineVector[iline].size());
485 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
488 if(!imgReaderModel1.isNoData(modValue)){
490 statobs.setNoDataValues(obsnodata_opt);
491 double obsMeanValue=statobs.mean(obsWindowBuffer);
493 difference=obsMeanValue-modValue;
494 errObs=uncertObs_opt[0]*sqrt(difference*difference);
497 double errorCovariance=errMod;
498 if(errorCovariance+errObs>eps_opt[0])
499 kalmanGain=errorCovariance/(errorCovariance+errObs);
502 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
503 if(obsmin_opt.size()){
504 if(estWriteBuffer[icol]<obsmin_opt[0])
505 estWriteBuffer[icol]=obsmin_opt[0];
507 if(obsmax_opt.size()){
508 if(estWriteBuffer[icol]>obsmax_opt[0])
509 estWriteBuffer[icol]=obsmax_opt[0];
512 assert(kalmanGain<=1);
513 gainWriteBuffer[icol]=kalmanGain;
518 imgWriterGain.writeData(gainWriteBuffer,GDT_Float64,irow,0);
519 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
520 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
523 imgReaderObs.close();
526 imgReaderModel1.close();
527 imgWriterEst.close();
529 for(
int modindex=1;modindex<model_opt.size();++modindex){
531 cout <<
"processing time " << tmodel_opt[modindex] << endl;
532 if(obsindex<relobsindex.size())
533 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
535 cout <<
"There is no next observation" << endl;
538 if(outputfw_opt.size()==model_opt.size())
539 output=outputfw_opt[modindex];
541 ostringstream outputstream;
542 outputstream << outputfw_opt[0] <<
"_";
543 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
544 outputstream <<
".tif";
546 output=outputstream.str();
550 imgWriterEst.open(output,ncol,nrow,2,GDT_Float64,imageType,option_opt);
551 imgWriterEst.setProjectionProj4(projection_opt[0]);
552 imgWriterEst.setGeoTransform(geotransform);
553 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
556 imgReaderModel1.open(model_opt[modindex-1]);
557 imgReaderModel1.setNoData(modnodata_opt);
558 imgReaderModel2.open(model_opt[modindex]);
559 imgReaderModel2.setNoData(modnodata_opt);
564 pfnProgress(progress,pszMessage,pProgressArg);
567 if(obsindex<relobsindex.size()){
568 update=(relobsindex[obsindex]==modindex);
572 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
574 imgReaderObs.open(observation_opt[obsindex]);
575 imgReaderObs.getGeoTransform(geotransform);
576 imgReaderObs.setNoData(obsnodata_opt);
580 if(outputfw_opt.size()==model_opt.size())
581 input=outputfw_opt[modindex-1];
583 ostringstream outputstream;
584 outputstream << outputfw_opt[0] <<
"_";
585 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex-1];
586 outputstream <<
".tif";
588 input=outputstream.str();
591 cout <<
"opening " << input << endl;
593 imgReaderEst.setNoData(obsnodata_opt);
595 vector< vector<double> > obsLineVector(down_opt[0]);
596 vector<double> obsLineBuffer;
597 vector<double> obsWindowBuffer;
598 vector<double> model1LineBuffer;
599 vector<double> model2LineBuffer;
600 vector<double> model1buffer;
601 vector<double> model2buffer;
602 vector<double> uncertObsLineBuffer;
603 vector< vector<double> > estLineVector(down_opt[0]);
604 vector<double> estLineBuffer;
605 vector<double> estWindowBuffer;
606 vector<double> uncertReadBuffer;
607 vector<double> estWriteBuffer(ncol);
608 vector<double> uncertWriteBuffer(ncol);
609 vector<double> gainWriteBuffer(ncol);
614 cout <<
"initialize obsLineVector" << endl;
615 assert(down_opt[0]%2);
616 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
618 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
620 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
625 cout <<
"initialize estLineVector" << endl;
626 assert(down_opt[0]%2);
627 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
629 imgReaderEst.readData(estLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
631 imgReaderEst.readData(estLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
634 statobs.setNoDataValues(obsnodata_opt);
636 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
638 for(
int irow=jrow;irow<jrow+down_opt[0];++irow){
639 imgReaderEst.readData(uncertReadBuffer,GDT_Float64,irow,1);
640 imgReaderEst.image2geo(0,irow,geox,geoy);
641 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
642 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
643 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,0,theResample);
645 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
646 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
647 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,0,theResample);
649 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
650 estLineVector.erase(estLineVector.begin());
651 imgReaderEst.readData(estLineBuffer,GDT_Float64,maxRow,0);
652 estLineVector.push_back(estLineBuffer);
653 estLineBuffer=estLineVector[down_opt[0]/2];
656 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
657 obsLineVector.erase(obsLineVector.begin());
658 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
659 obsLineVector.push_back(obsLineBuffer);
660 obsLineBuffer=obsLineVector[down_opt[0]/2];
662 if(imgReaderObs.nrOfBand()>1)
663 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
665 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
666 for(
int icol=jcol;icol<jcol+down_opt[0];++icol){
667 imgReaderEst.image2geo(icol,irow,geox,geoy);
668 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
669 int maxCol=(icol+down_opt[0]/2<imgReaderEst.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderEst.nrOfCol()-1;
670 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
671 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
672 estWindowBuffer.clear();
673 for(
int iline=0;iline<estLineVector.size();++iline){
674 for(
int isample=minCol;isample<=maxCol;++isample){
675 assert(isample<estLineVector[iline].size());
676 estWindowBuffer.push_back(estLineVector[iline][isample]);
680 obsWindowBuffer.clear();
681 for(
int iline=0;iline<obsLineVector.size();++iline){
682 for(
int isample=minCol;isample<=maxCol;++isample){
683 assert(isample<obsLineVector[iline].size());
684 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
688 double estValue=estLineBuffer[icol];
689 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
690 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
692 lowerCol=
static_cast<int>(lowerCol);
694 upperCol=
static_cast<int>(upperCol);
697 if(upperCol>=imgReaderModel1.nrOfCol())
698 upperCol=imgReaderModel1.nrOfCol()-1;
699 double modValue1=(modCol-0.5-lowerCol)*model1LineBuffer[upperCol]+(1-modCol+0.5+lowerCol)*model1LineBuffer[lowerCol];
701 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
702 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
704 lowerCol=
static_cast<int>(lowerCol);
706 upperCol=
static_cast<int>(upperCol);
709 if(upperCol>=imgReaderModel1.nrOfCol())
710 upperCol=imgReaderModel1.nrOfCol()-1;
711 double modValue2=(modCol-0.5-lowerCol)*model2LineBuffer[upperCol]+(1-modCol+0.5+lowerCol)*model2LineBuffer[lowerCol];
713 if(imgReaderEst.isNoData(estValue)){
715 if(imgReaderModel2.isNoData(modValue2)){
716 estWriteBuffer[icol]=obsnodata_opt[0];
717 uncertWriteBuffer[icol]=uncertNodata_opt[0];
718 gainWriteBuffer[icol]=0;
721 estWriteBuffer[icol]=modValue2;
722 if(obsmin_opt.size()){
723 if(estWriteBuffer[icol]<obsmin_opt[0])
724 estWriteBuffer[icol]=obsmin_opt[0];
726 if(obsmax_opt.size()){
727 if(estWriteBuffer[icol]>obsmax_opt[0])
728 estWriteBuffer[icol]=obsmax_opt[0];
730 uncertWriteBuffer[icol]=uncertModel_opt[0];
731 gainWriteBuffer[icol]=0;
735 double estMeanValue=statobs.mean(estWindowBuffer);
738 double processNoiseVariance=processNoise_opt[0];
742 if(imgReaderModel1.isNoData(modValue1)||imgReaderModel2.isNoData(modValue2)){
743 estWriteBuffer[icol]=estValue;
744 uncertWriteBuffer[icol]=uncertReadBuffer[icol]+processNoiseVariance;
747 double modRatio=modValue2/modValue1;
748 estWriteBuffer[icol]=estValue*modRatio;
749 uncertWriteBuffer[icol]=uncertReadBuffer[icol]*modRatio*modRatio+processNoiseVariance;
751 if(obsmin_opt.size()){
752 if(estWriteBuffer[icol]<obsmin_opt[0])
753 estWriteBuffer[icol]=obsmin_opt[0];
755 if(obsmax_opt.size()){
756 if(estWriteBuffer[icol]>obsmax_opt[0])
757 estWriteBuffer[icol]=obsmax_opt[0];
761 if(update&&!imgReaderObs.isNoData(obsLineBuffer[icol])){
763 if(!imgReaderModel2.isNoData(modValue2)){
765 statobs.setNoDataValues(obsnodata_opt);
766 double obsMeanValue=statobs.mean(obsWindowBuffer);
768 difference=obsMeanValue-modValue2;
769 errObs=uncertObs_opt[0]*sqrt(difference*difference);
773 if(errObs<eps_opt[0])
775 double errorCovariance=uncertWriteBuffer[icol];
777 if(errorCovariance+errObs>eps_opt[0])
778 kalmanGain=errorCovariance/(errorCovariance+errObs);
781 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
782 if(obsmin_opt.size()){
783 if(estWriteBuffer[icol]<obsmin_opt[0])
784 estWriteBuffer[icol]=obsmin_opt[0];
786 if(obsmax_opt.size()){
787 if(estWriteBuffer[icol]>obsmax_opt[0])
788 estWriteBuffer[icol]=obsmax_opt[0];
790 uncertWriteBuffer[icol]*=(1-kalmanGain);
792 assert(kalmanGain<=1);
793 gainWriteBuffer[icol]=kalmanGain;
799 imgWriterGain.writeData(gainWriteBuffer,GDT_Float64,irow,modindex);
801 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
802 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
803 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
804 pfnProgress(progress,pszMessage,pProgressArg);
807 imgWriterEst.close();
808 imgReaderEst.close();
811 imgReaderObs.close();
814 imgReaderModel1.close();
815 imgReaderModel2.close();
818 imgWriterGain.close();
820 if(find(direction_opt.begin(),direction_opt.end(),
"backward")!=direction_opt.end()){
822 cout <<
"Running backward model" << endl;
823 obsindex=relobsindex.size()-1;
826 if(outputbw_opt.size()==model_opt.size())
827 output=outputbw_opt.back();
829 ostringstream outputstream;
830 outputstream << outputbw_opt[0] <<
"_";
831 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt.back();
832 outputstream <<
".tif";
834 output=outputstream.str();
837 cout <<
"Opening image " << output <<
" for writing " << endl;
839 imgWriterEst.open(output,ncol,nrow,2,GDT_Float64,imageType,option_opt);
840 imgWriterEst.setProjectionProj4(projection_opt[0]);
841 imgWriterEst.setGeoTransform(geotransform);
842 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
845 cout <<
"processing time " << tmodel_opt.back() << endl;
846 if(obsindex<relobsindex.size())
847 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
849 cout <<
"There is no next observation" << endl;
853 imgReaderModel1.open(model_opt.back());
854 imgReaderModel1.setNoData(modnodata_opt);
856 catch(
string errorString){
857 cerr << errorString << endl;
860 cerr <<
"Error opening file " << model_opt[0] << endl;
873 RESAMPLE theResample=BILINEAR;
875 if(relobsindex.back()<model_opt.size()-1){
878 cout <<
"write last model as output" << endl;
879 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
880 vector<double> estReadBuffer;
881 vector<double> estWriteBuffer(ncol);
882 vector<double> uncertWriteBuffer(ncol);
884 for(
int irow=jrow;irow<jrow+down_opt[0];++irow){
885 imgWriterEst.image2geo(0,irow,geox,geoy);
886 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
887 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
888 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow,0,theResample);
889 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
890 for(
int icol=icol;icol<icol+down_opt[0];++icol){
891 imgWriterEst.image2geo(icol,irow,geox,geoy);
892 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
894 lowerCol=
static_cast<int>(lowerCol);
896 upperCol=
static_cast<int>(upperCol);
899 if(upperCol>=imgReaderModel1.nrOfCol())
900 upperCol=imgReaderModel1.nrOfCol()-1;
901 double modValue=(modCol-0.5-lowerCol)*estReadBuffer[upperCol]+(1-modCol+0.5+lowerCol)*estReadBuffer[lowerCol];
904 if(imgReaderModel1.isNoData(modValue)){
905 estWriteBuffer[icol]=obsnodata_opt[0];
906 uncertWriteBuffer[icol]=uncertNodata_opt[0];
909 estWriteBuffer[icol]=modValue;
910 if(obsmin_opt.size()){
911 if(estWriteBuffer[icol]<obsmin_opt[0])
912 estWriteBuffer[icol]=obsmin_opt[0];
914 if(obsmax_opt.size()){
915 if(estWriteBuffer[icol]>obsmax_opt[0])
916 estWriteBuffer[icol]=obsmax_opt[0];
918 uncertWriteBuffer[icol]=uncertModel_opt[0];
922 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
923 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
926 catch(
string errorString){
927 cerr << errorString << endl;
930 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
936 cout <<
"we have a measurement at end time" << endl;
937 imgReaderObs.open(observation_opt.back());
938 imgReaderObs.getGeoTransform(geotransform);
939 imgReaderObs.setNoData(obsnodata_opt);
941 vector< vector<double> > obsLineVector(down_opt[0]);
942 vector<double> obsLineBuffer;
943 vector<double> obsWindowBuffer;
944 vector<double> estReadBuffer;
945 vector<double> estWriteBuffer(ncol);
946 vector<double> uncertWriteBuffer(ncol);
947 vector<double> uncertObsLineBuffer;
950 cout <<
"initialize obsLineVector" << endl;
951 assert(down_opt[0]%2);
952 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
954 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
956 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
958 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
959 for(
int irow=jrow;irow<jrow+down_opt[0];++irow){
960 imgWriterEst.image2geo(0,irow,geox,geoy);
961 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
962 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
963 RESAMPLE theResample=BILINEAR;
964 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow,0,theResample);
965 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
966 obsLineVector.erase(obsLineVector.begin());
967 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
968 obsLineVector.push_back(obsLineBuffer);
970 if(imgReaderObs.nrOfBand()>1)
971 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
973 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
974 for(
int icol=jcol;icol<jcol+down_opt[0];++icol){
975 imgWriterEst.image2geo(icol,irow,geox,geoy);
976 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
977 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
979 lowerCol=
static_cast<int>(lowerCol);
981 upperCol=
static_cast<int>(upperCol);
984 if(upperCol>=imgReaderModel1.nrOfCol())
985 upperCol=imgReaderModel1.nrOfCol()-1;
986 double modValue=(modCol-0.5-lowerCol)*estReadBuffer[upperCol]+(1-modCol+0.5+lowerCol)*estReadBuffer[lowerCol];
988 double errMod=uncertModel_opt[0];
989 if(imgReaderModel1.isNoData(modValue)){
990 if(imgReaderObs.isNoData(obsLineBuffer[icol])){
991 estWriteBuffer[icol]=obsnodata_opt[0];
992 uncertWriteBuffer[icol]=uncertNodata_opt[0];
995 estWriteBuffer[icol]=obsLineBuffer[icol];
996 if(obsmin_opt.size()){
997 if(estWriteBuffer[icol]<obsmin_opt[0])
998 estWriteBuffer[icol]=obsmin_opt[0];
1000 if(obsmax_opt.size()){
1001 if(estWriteBuffer[icol]>obsmax_opt[0])
1002 estWriteBuffer[icol]=obsmax_opt[0];
1004 if(uncertObsLineBuffer.size()>icol)
1005 uncertWriteBuffer[icol]=uncertObsLineBuffer[icol];
1007 uncertWriteBuffer[icol]=uncertObs_opt[0];
1011 estWriteBuffer[icol]=modValue;
1012 uncertWriteBuffer[icol]=errMod;
1015 if(!imgReaderObs.isNoData(obsLineBuffer[icol])){
1017 double kalmanGain=1;
1018 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
1019 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
1020 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
1021 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
1022 obsWindowBuffer.clear();
1023 for(
int iline=0;iline<obsLineVector.size();++iline){
1024 for(
int isample=minCol;isample<=maxCol;++isample){
1025 assert(isample<obsLineVector[iline].size());
1026 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
1029 if(!imgReaderModel1.isNoData(modValue)){
1031 statobs.setNoDataValues(obsnodata_opt);
1032 double obsMeanValue=statobs.mean(obsWindowBuffer);
1033 double difference=0;
1034 difference=obsMeanValue-modValue;
1035 errObs=uncertObs_opt[0]*sqrt(difference*difference);
1038 double errorCovariance=errMod;
1039 if(errorCovariance+errObs>eps_opt[0])
1040 kalmanGain=errorCovariance/(errorCovariance+errObs);
1043 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1044 if(obsmin_opt.size()){
1045 if(estWriteBuffer[icol]<obsmin_opt[0])
1046 estWriteBuffer[icol]=obsmin_opt[0];
1048 if(obsmax_opt.size()){
1049 if(estWriteBuffer[icol]>obsmax_opt[0])
1050 estWriteBuffer[icol]=obsmax_opt[0];
1053 assert(kalmanGain<=1);
1057 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1058 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1061 imgReaderObs.close();
1065 imgReaderModel1.close();
1066 imgWriterEst.close();
1068 for(
int modindex=model_opt.size()-2;modindex>=0;--modindex){
1070 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1071 if(obsindex<relobsindex.size())
1072 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1074 cout <<
"There is no next observation" << endl;
1077 if(outputbw_opt.size()==model_opt.size())
1078 output=outputbw_opt[modindex];
1080 ostringstream outputstream;
1081 outputstream << outputbw_opt[0] <<
"_";
1082 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1083 outputstream <<
".tif";
1085 output=outputstream.str();
1089 imgWriterEst.open(output,ncol,nrow,2,GDT_Float64,imageType,option_opt);
1090 imgWriterEst.setProjectionProj4(projection_opt[0]);
1091 imgWriterEst.setGeoTransform(geotransform);
1092 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1095 imgReaderModel1.open(model_opt[modindex+1]);
1096 imgReaderModel1.setNoData(modnodata_opt);
1097 imgReaderModel2.open(model_opt[modindex]);
1098 imgReaderModel2.setNoData(modnodata_opt);
1103 pfnProgress(progress,pszMessage,pProgressArg);
1106 if(obsindex<relobsindex.size()){
1107 update=(relobsindex[obsindex]==modindex);
1111 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
1113 imgReaderObs.open(observation_opt[obsindex]);
1114 imgReaderObs.getGeoTransform(geotransform);
1115 imgReaderObs.setNoData(obsnodata_opt);
1119 if(outputbw_opt.size()==model_opt.size())
1120 input=outputbw_opt[modindex+1];
1122 ostringstream outputstream;
1123 outputstream << outputbw_opt[0] <<
"_";
1124 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex+1];
1125 outputstream <<
".tif";
1127 input=outputstream.str();
1130 cout <<
"opening " << input << endl;
1132 imgReaderEst.setNoData(obsnodata_opt);
1134 vector< vector<double> > obsLineVector(down_opt[0]);
1135 vector<double> obsLineBuffer;
1136 vector<double> obsWindowBuffer;
1137 vector<double> model1LineBuffer;
1138 vector<double> model2LineBuffer;
1139 vector<double> model1buffer;
1140 vector<double> model2buffer;
1141 vector<double> uncertObsLineBuffer;
1142 vector< vector<double> > estLineVector(down_opt[0]);
1143 vector<double> estLineBuffer;
1144 vector<double> estWindowBuffer;
1145 vector<double> uncertReadBuffer;
1146 vector<double> estWriteBuffer(ncol);
1147 vector<double> uncertWriteBuffer(ncol);
1152 cout <<
"initialize obsLineVector" << endl;
1153 assert(down_opt[0]%2);
1154 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
1156 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
1158 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
1163 cout <<
"initialize estLineVector" << endl;
1164 assert(down_opt[0]%2);
1165 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
1167 imgReaderEst.readData(estLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
1169 imgReaderEst.readData(estLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
1172 statobs.setNoDataValues(obsnodata_opt);
1174 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
1176 for(
int irow=jrow;irow<jrow+down_opt[0];++irow){
1177 imgReaderEst.readData(uncertReadBuffer,GDT_Float64,irow,1);
1178 imgReaderEst.image2geo(0,irow,geox,geoy);
1179 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1180 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1181 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,0,theResample);
1183 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1184 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1185 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,0,theResample);
1187 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
1188 estLineVector.erase(estLineVector.begin());
1189 imgReaderEst.readData(estLineBuffer,GDT_Float64,maxRow,0);
1190 estLineVector.push_back(estLineBuffer);
1191 estLineBuffer=estLineVector[down_opt[0]/2];
1194 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
1195 obsLineVector.erase(obsLineVector.begin());
1196 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
1197 obsLineVector.push_back(obsLineBuffer);
1198 obsLineBuffer=obsLineVector[down_opt[0]/2];
1200 if(imgReaderObs.nrOfBand()>1)
1201 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1203 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
1204 for(
int icol=jcol;icol<jcol+down_opt[0];++icol){
1205 imgReaderEst.image2geo(icol,irow,geox,geoy);
1206 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
1207 int maxCol=(icol+down_opt[0]/2<imgReaderEst.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderEst.nrOfCol()-1;
1208 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
1209 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
1210 estWindowBuffer.clear();
1211 for(
int iline=0;iline<estLineVector.size();++iline){
1212 for(
int isample=minCol;isample<=maxCol;++isample){
1213 assert(isample<estLineVector[iline].size());
1214 estWindowBuffer.push_back(estLineVector[iline][isample]);
1218 obsWindowBuffer.clear();
1219 for(
int iline=0;iline<obsLineVector.size();++iline){
1220 for(
int isample=minCol;isample<=maxCol;++isample){
1221 assert(isample<obsLineVector[iline].size());
1222 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
1226 double estValue=estLineBuffer[icol];
1227 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1228 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1229 lowerCol=modCol-0.5;
1230 lowerCol=
static_cast<int>(lowerCol);
1231 upperCol=modCol+0.5;
1232 upperCol=
static_cast<int>(upperCol);
1235 if(upperCol>=imgReaderModel1.nrOfCol())
1236 upperCol=imgReaderModel1.nrOfCol()-1;
1237 double modValue1=(modCol-0.5-lowerCol)*model1LineBuffer[upperCol]+(1-modCol+0.5+lowerCol)*model1LineBuffer[lowerCol];
1239 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1240 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1241 lowerCol=modCol-0.5;
1242 lowerCol=
static_cast<int>(lowerCol);
1243 upperCol=modCol+0.5;
1244 upperCol=
static_cast<int>(upperCol);
1247 if(upperCol>=imgReaderModel1.nrOfCol())
1248 upperCol=imgReaderModel1.nrOfCol()-1;
1249 double modValue2=(modCol-0.5-lowerCol)*model2LineBuffer[upperCol]+(1-modCol+0.5+lowerCol)*model2LineBuffer[lowerCol];
1251 if(imgReaderEst.isNoData(estValue)){
1253 if(imgReaderModel2.isNoData(modValue2)){
1254 estWriteBuffer[icol]=obsnodata_opt[0];
1255 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1258 estWriteBuffer[icol]=modValue2;
1259 if(obsmin_opt.size()){
1260 if(estWriteBuffer[icol]<obsmin_opt[0])
1261 estWriteBuffer[icol]=obsmin_opt[0];
1263 if(obsmax_opt.size()){
1264 if(estWriteBuffer[icol]>obsmax_opt[0])
1265 estWriteBuffer[icol]=obsmax_opt[0];
1267 uncertWriteBuffer[icol]=uncertModel_opt[0];
1271 double estMeanValue=statobs.mean(estWindowBuffer);
1274 double processNoiseVariance=processNoise_opt[0];
1278 if(imgReaderModel1.isNoData(modValue1)||imgReaderModel2.isNoData(modValue2)){
1279 estWriteBuffer[icol]=estValue;
1280 uncertWriteBuffer[icol]=uncertReadBuffer[icol]+processNoiseVariance;
1283 double modRatio=modValue2/modValue1;
1284 estWriteBuffer[icol]=estValue*modRatio;
1285 uncertWriteBuffer[icol]=uncertReadBuffer[icol]*modRatio*modRatio+processNoiseVariance;
1287 if(obsmin_opt.size()){
1288 if(estWriteBuffer[icol]<obsmin_opt[0])
1289 estWriteBuffer[icol]=obsmin_opt[0];
1291 if(obsmax_opt.size()){
1292 if(estWriteBuffer[icol]>obsmax_opt[0])
1293 estWriteBuffer[icol]=obsmax_opt[0];
1297 if(update&&!imgReaderObs.isNoData(obsLineBuffer[icol])){
1298 double kalmanGain=1;
1299 if(!imgReaderModel2.isNoData(modValue2)){
1301 statobs.setNoDataValues(obsnodata_opt);
1302 double obsMeanValue=statobs.mean(obsWindowBuffer);
1303 double difference=0;
1304 difference=obsMeanValue-modValue2;
1305 errObs=uncertObs_opt[0]*sqrt(difference*difference);
1309 double errorCovariance=uncertWriteBuffer[icol];
1311 if(errorCovariance+errObs>eps_opt[0])
1312 kalmanGain=errorCovariance/(errorCovariance+errObs);
1315 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1316 if(obsmin_opt.size()){
1317 if(estWriteBuffer[icol]<obsmin_opt[0])
1318 estWriteBuffer[icol]=obsmin_opt[0];
1320 if(obsmax_opt.size()){
1321 if(estWriteBuffer[icol]>obsmax_opt[0])
1322 estWriteBuffer[icol]=obsmax_opt[0];
1324 uncertWriteBuffer[icol]*=(1-kalmanGain);
1326 assert(kalmanGain<=1);
1330 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1331 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1332 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
1333 pfnProgress(progress,pszMessage,pProgressArg);
1336 imgWriterEst.close();
1337 imgReaderEst.close();
1340 imgReaderObs.close();
1343 imgReaderModel1.close();
1344 imgReaderModel2.close();
1347 if(find(direction_opt.begin(),direction_opt.end(),
"smooth")!=direction_opt.end()){
1349 cout <<
"Running smooth model" << endl;
1351 for(
int modindex=0;modindex<model_opt.size();++modindex){
1353 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1354 if(obsindex<relobsindex.size())
1355 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1357 cout <<
"There is no next observation" << endl;
1360 if(outputfb_opt.size()==model_opt.size())
1361 output=outputfb_opt[modindex];
1363 ostringstream outputstream;
1364 outputstream << outputfb_opt[0] <<
"_";
1365 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1366 outputstream <<
".tif";
1368 output=outputstream.str();
1372 imgWriterEst.open(output,ncol,nrow,2,GDT_Float64,imageType,option_opt);
1373 imgWriterEst.setProjectionProj4(projection_opt[0]);
1374 imgWriterEst.setGeoTransform(geotransform);
1375 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1382 if(outputfw_opt.size()==model_opt.size())
1383 inputfw=outputfw_opt[modindex];
1385 ostringstream outputstream;
1386 outputstream << outputfw_opt[0] <<
"_";
1387 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1388 outputstream <<
".tif";
1390 inputfw=outputstream.str();
1392 if(outputbw_opt.size()==model_opt.size())
1393 inputbw=outputbw_opt[modindex];
1395 ostringstream outputstream;
1396 outputstream << outputbw_opt[0] <<
"_";
1397 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1398 outputstream <<
".tif";
1400 inputbw=outputstream.str();
1404 imgReaderForward.setNoData(obsnodata_opt);
1405 imgReaderBackward.setNoData(obsnodata_opt);
1407 vector<double> estForwardBuffer;
1408 vector<double> estBackwardBuffer;
1409 vector<double> uncertObsLineBuffer;
1410 vector<double> uncertForwardBuffer;
1411 vector<double> uncertBackwardBuffer;
1412 vector<double> uncertReadBuffer;
1413 vector<double> estWriteBuffer(ncol);
1414 vector<double> uncertWriteBuffer(ncol);
1418 if(obsindex<relobsindex.size()){
1419 update=(relobsindex[obsindex]==modindex);
1424 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
1425 imgReaderObs.open(observation_opt[obsindex]);
1426 imgReaderObs.getGeoTransform(geotransform);
1427 imgReaderObs.setNoData(obsnodata_opt);
1431 pfnProgress(progress,pszMessage,pProgressArg);
1433 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
1434 assert(irow<imgReaderForward.nrOfRow());
1435 assert(irow<imgReaderBackward.nrOfRow());
1436 imgReaderForward.readData(estForwardBuffer,GDT_Float64,irow,0);
1437 imgReaderBackward.readData(estBackwardBuffer,GDT_Float64,irow,0);
1438 imgReaderForward.readData(uncertForwardBuffer,GDT_Float64,irow,1);
1439 imgReaderBackward.readData(uncertBackwardBuffer,GDT_Float64,irow,1);
1442 imgReaderObs.readData(estWriteBuffer,GDT_Float64,irow,0);
1443 if(imgReaderObs.nrOfBand()>1)
1444 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1448 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1449 imgWriterEst.image2geo(icol,irow,geox,geoy);
1450 double A=estForwardBuffer[icol];
1451 double B=estBackwardBuffer[icol];
1452 double C=uncertForwardBuffer[icol];
1453 double D=uncertBackwardBuffer[icol];
1454 double uncertObs=uncertObs_opt[0];
1463 double noemer=(C+D);
1465 if(imgReaderForward.isNoData(A)&&imgReaderBackward.isNoData(B)){
1466 estWriteBuffer[icol]=obsnodata_opt[0];
1467 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1469 else if(imgReaderForward.isNoData(A)){
1470 estWriteBuffer[icol]=B;
1471 uncertWriteBuffer[icol]=uncertBackwardBuffer[icol];
1473 else if(imgReaderForward.isNoData(B)){
1474 estWriteBuffer[icol]=A;
1475 uncertWriteBuffer[icol]=uncertForwardBuffer[icol];
1478 if(noemer<eps_opt[0]){
1479 estWriteBuffer[icol]=0.5*(A+B);
1480 uncertWriteBuffer[icol]=uncertObs;
1483 estWriteBuffer[icol]=(A*D+B*C)/noemer;
1484 if(obsmin_opt.size()){
1485 if(estWriteBuffer[icol]<obsmin_opt[0])
1486 estWriteBuffer[icol]=obsmin_opt[0];
1488 if(obsmax_opt.size()){
1489 if(estWriteBuffer[icol]>obsmax_opt[0])
1490 estWriteBuffer[icol]=obsmax_opt[0];
1504 uncertWriteBuffer[icol]=P;
1508 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1509 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1510 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
1511 pfnProgress(progress,pszMessage,pProgressArg);
1514 imgWriterEst.close();
1515 imgReaderForward.close();
1516 imgReaderBackward.close();
1518 imgReaderObs.close();