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"
34 int main(
int argc,
char **argv) {
35 Optionpk<string> direction_opt(
"dir",
"direction",
"direction to run model (forward|backward|smooth)",
"forward");
36 Optionpk<string> model_opt(
"mod",
"model",
"model input datasets, e.g., MODIS (use: -mod model1 -mod model2 etc.)");
37 Optionpk<string> observation_opt(
"obs",
"observation",
"observation input datasets, e.g., landsat (use: -obs obs1 -obs obs2 etc.)");
38 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.");
39 Optionpk<int> tobservation_opt(
"tobs",
"tobservation",
"time sequence of observation input. Sequence must have exact same length as observation input)");
40 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");
41 Optionpk<string> outputfw_opt(
"ofw",
"outputfw",
"Output raster dataset for forward model");
42 Optionpk<string> outputbw_opt(
"obw",
"outputbw",
"Output raster dataset for backward model");
43 Optionpk<string> outputfb_opt(
"ofb",
"outputfb",
"Output raster dataset for smooth model");
44 Optionpk<double> modnodata_opt(
"modnodata",
"modnodata",
"invalid value for model input", 0);
45 Optionpk<double> obsnodata_opt(
"obsnodata",
"obsnodata",
"invalid value for observation input", 0);
46 Optionpk<double> modoffset_opt(
"modoffset",
"modoffset",
"offset used to read model input dataset (value=offset+scale*readValue)");
47 Optionpk<double> obsoffset_opt(
"obsoffset",
"obsoffset",
"offset used to read observation input dataset (value=offset+scale*readValue)");
48 Optionpk<double> modscale_opt(
"modscale",
"modscale",
"scale used to read model input dataset (value=offset+scale*readValue)");
49 Optionpk<double> obsscale_opt(
"obsscale",
"obsscale",
"scale used to read observation input dataset (value=offset+scale*readValue)");
50 Optionpk<double> eps_opt(
"eps",
"eps",
"epsilon for non zero division", 0.00001);
51 Optionpk<double> uncertModel_opt(
"um",
"uncertmodel",
"Multiply this value with std dev of first model image to obtain uncertainty of model",2);
52 Optionpk<double> uncertObs_opt(
"uo",
"uncertobs",
"Uncertainty of valid observations",0);
53 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");
54 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");
55 Optionpk<double> uncertNodata_opt(
"unodata",
"uncertnodata",
"Uncertainty in case of no-data values in observation", 10000);
57 Optionpk<bool> regSensor_opt(
"rs",
"regsensor",
"Set optional regression for sensor difference (model - observation).",
false);
58 Optionpk<int> down_opt(
"down",
"down",
"Downsampling factor for reading model data to calculate regression");
59 Optionpk<float> threshold_opt(
"th",
"threshold",
"threshold for selecting samples (randomly). Provide probability in percentage (>0) or absolute (<0).", 0);
60 Optionpk<int> minreg_opt(
"minreg",
"minreg",
"Minimum number of pixels to take into account for regression", 5, 2);
63 Optionpk<unsigned short> window_opt(
"win",
"window",
"window size for calculating regression (use 0 for global)", 0);
67 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate). Empty string: inherit from input image",
"GTiff",2);
68 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
69 Optionpk<short> verbose_opt(
"v",
"verbose",
"verbose mode when positive", 0);
73 doProcess=direction_opt.retrieveOption(argc,argv);
74 model_opt.retrieveOption(argc,argv);
75 observation_opt.retrieveOption(argc,argv);
76 tmodel_opt.retrieveOption(argc,argv);
77 tobservation_opt.retrieveOption(argc,argv);
78 projection_opt.retrieveOption(argc,argv);
79 outputfw_opt.retrieveOption(argc,argv);
80 outputbw_opt.retrieveOption(argc,argv);
81 outputfb_opt.retrieveOption(argc,argv);
82 modnodata_opt.retrieveOption(argc,argv);
83 obsnodata_opt.retrieveOption(argc,argv);
84 modoffset_opt.retrieveOption(argc,argv);
85 modscale_opt.retrieveOption(argc,argv);
86 obsoffset_opt.retrieveOption(argc,argv);
87 obsscale_opt.retrieveOption(argc,argv);
88 eps_opt.retrieveOption(argc,argv);
89 uncertModel_opt.retrieveOption(argc,argv);
90 uncertObs_opt.retrieveOption(argc,argv);
91 weight_opt.retrieveOption(argc,argv);
92 deltaObs_opt.retrieveOption(argc,argv);
93 uncertNodata_opt.retrieveOption(argc,argv);
95 regSensor_opt.retrieveOption(argc,argv);
96 down_opt.retrieveOption(argc,argv);
97 threshold_opt.retrieveOption(argc,argv);
98 minreg_opt.retrieveOption(argc,argv);
101 window_opt.retrieveOption(argc,argv);
104 oformat_opt.retrieveOption(argc,argv);
105 option_opt.retrieveOption(argc,argv);
106 verbose_opt.retrieveOption(argc,argv);
108 catch(
string predefinedString){
109 std::cout << predefinedString << std::endl;
113 std::cout <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
117 if(deltaObs_opt.size()==1){
118 if(deltaObs_opt[0]<=0)
119 deltaObs_opt.push_back(-deltaObs_opt[0]);
121 deltaObs_opt.insert(deltaObs_opt.begin(),-deltaObs_opt[0]);
123 if(weight_opt.size()==1){
124 weight_opt.push_back(weight_opt[0]);
128 ostringstream errorStream;
129 if(model_opt.size()<2){
130 errorStream <<
"Error: no model dataset selected, use option -mod" << endl;
131 throw(errorStream.str());
133 if(observation_opt.size()<1){
134 errorStream <<
"Error: no observation dataset selected, use option -obs" << endl;
135 throw(errorStream.str());
137 if(direction_opt[0]==
"smooth"){
138 if(outputfw_opt.empty()){
139 errorStream <<
"Error: output forward datasets is not provided, use option -ofw" << endl;
140 throw(errorStream.str());
142 if(outputbw_opt.empty()){
143 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
144 throw(errorStream.str());
146 if(outputfb_opt.empty()){
147 errorStream <<
"Error: output smooth datasets is not provided, use option -ofb" << endl;
148 throw(errorStream.str());
152 if(direction_opt[0]==
"forward"&&outputfw_opt.empty()){
153 errorStream <<
"Error: output forward datasets is not provided, use option -ofw" << endl;
154 throw(errorStream.str());
156 else if(direction_opt[0]==
"backward"&&outputbw_opt.empty()){
157 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
158 throw(errorStream.str());
161 if(model_opt.size()<observation_opt.size()){
162 errorStream <<
"Error: sequence of models should be larger than observations" << endl;
163 throw(errorStream.str());
165 if(tmodel_opt.size()!=model_opt.size()){
166 if(tmodel_opt.empty())
167 cout <<
"Warning: time sequence is not provided, self generating time sequence from 0 to " << model_opt.size() << endl;
169 cout <<
"Warning: time sequence provided (" << tmodel_opt.size() <<
") does not match number of model raster datasets (" << model_opt.size() <<
")" << endl;
171 for(
int tindex=0;tindex<model_opt.size();++tindex)
172 tmodel_opt.push_back(tindex);
174 if(tobservation_opt.size()!=observation_opt.size()){
175 errorStream <<
"Error: time sequence for observation must match size of observation dataset" << endl;
176 throw(errorStream.str());
180 catch(
string errorString){
181 std::cout << errorString << std::endl;
186 stat.setNoDataValues(modnodata_opt);
195 imgReaderObs.open(observation_opt[0]);
197 int ncol=imgReaderObs.nrOfCol();
198 int nrow=imgReaderObs.nrOfRow();
199 if(projection_opt.empty())
200 projection_opt.push_back(imgReaderObs.getProjection());
201 double geotransform[6];
202 imgReaderObs.getGeoTransform(geotransform);
204 string imageType=imgReaderObs.getImageType();
205 if(oformat_opt.size())
206 imageType=oformat_opt[0];
207 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
208 string theInterleave=
"INTERLEAVE=";
209 theInterleave+=imgReaderObs.getInterleave();
210 option_opt.push_back(theInterleave);
213 if(down_opt.empty()){
214 imgReaderModel1.open(model_opt[0]);
215 double resModel=imgReaderModel1.getDeltaX();
216 double resObs=imgReaderObs.getDeltaX();
217 int down=
static_cast<int>(ceil(resModel/resObs));
220 down_opt.push_back(down);
221 imgReaderModel1.close();
223 imgReaderObs.close();
248 const char* pszMessage;
249 void* pProgressArg=NULL;
250 GDALProgressFunc pfnProgress=GDALTermProgress;
253 imgreg.setDown(down_opt[0]);
254 imgreg.setThreshold(threshold_opt[0]);
256 double c0modGlobal=0;
257 double c1modGlobal=1;
263 double errObs=uncertNodata_opt[0];
265 vector<int> relobsindex;
269 for(
int tindex=0;tindex<tobservation_opt.size();++tindex){
270 vector<int>::iterator modit;
271 modit=lower_bound(tmodel_opt.begin(),tmodel_opt.end(),tobservation_opt[tindex]);
272 int relpos=modit-tmodel_opt.begin();
275 relobsindex.push_back(relpos);
277 cout <<
"tobservation_opt[tindex] " << tobservation_opt[tindex] <<
" " << relobsindex.back() <<
" " << observation_opt[tindex] <<
" " << model_opt[relpos] << endl;
285 if(find(direction_opt.begin(),direction_opt.end(),
"forward")!=direction_opt.end()){
287 cout <<
"Running forward model" << endl;
291 if(outputfw_opt.size()==model_opt.size())
292 output=outputfw_opt[0];
294 ostringstream outputstream;
295 outputstream << outputfw_opt[0] <<
"_" << tmodel_opt[0] <<
".tif";
296 output=outputstream.str();
299 cout <<
"Opening image " << output <<
" for writing " << endl;
300 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
301 imgWriterEst.setProjectionProj4(projection_opt[0]);
302 imgWriterEst.setGeoTransform(geotransform);
303 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
306 cout <<
"processing time " << tmodel_opt[0] << endl;
307 if(obsindex<relobsindex.size())
308 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
310 cout <<
"There is no next observation" << endl;
314 imgReaderModel1.open(model_opt[0]);
315 imgReaderModel1.setNoData(modnodata_opt);
316 if(modoffset_opt.size())
317 imgReaderModel1.setOffset(modoffset_opt[0]);
318 if(modscale_opt.size())
319 imgReaderModel1.setScale(modscale_opt[0]);
321 catch(
string errorString){
322 cerr << errorString << endl;
325 cerr <<
"Error opening file " << model_opt[0] << endl;
329 GDALRasterBand* rasterBand;
330 rasterBand=imgReaderModel1.getRasterBand(0);
331 double minValue, maxValue, meanValue, stdDev;
333 rasterBand->ComputeStatistics(0,&minValue,&maxValue,&meanValue,&stdDev,pfnProgress,pProgressData);
336 if(relobsindex[0]>0){
339 cout <<
"write first model as output" << endl;
340 for(
int irow=0;irow<nrow;++irow){
341 vector<double> estReadBuffer;
342 vector<double> estWriteBuffer(ncol);
343 vector<double> uncertWriteBuffer(ncol);
345 imgWriterEst.image2geo(0,irow,geox,geoy);
346 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
347 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
349 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
354 for(
int icol=0;icol<ncol;++icol){
355 imgWriterEst.image2geo(icol,irow,geox,geoy);
356 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
357 double modValue=estReadBuffer[modCol];
358 if(imgReaderModel1.isNoData(modValue)){
359 estWriteBuffer[icol]=obsnodata_opt[0];
360 uncertWriteBuffer[icol]=uncertNodata_opt[0];
363 estWriteBuffer[icol]=modValue;
364 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
367 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
368 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
370 catch(
string errorString){
371 cerr << errorString << endl;
374 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
380 cout <<
"we have an observation at time 0" << endl;
381 imgReaderObs.open(observation_opt[0]);
382 imgReaderObs.getGeoTransform(geotransform);
383 imgReaderObs.setNoData(obsnodata_opt);
384 if(obsoffset_opt.size())
385 imgReaderObs.setOffset(obsoffset_opt[0]);
386 if(obsscale_opt.size())
387 imgReaderObs.setScale(obsscale_opt[0]);
390 errObs=imgreg.getRMSE(imgReaderModel1,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
397 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
399 for(
int irow=0;irow<nrow;++irow){
400 vector<double> estReadBuffer;
401 imgWriterEst.image2geo(0,irow,geox,geoy);
402 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
403 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
404 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
405 vector<double> obsLineBuffer;
406 vector<double> estWriteBuffer(ncol);
407 vector<double> uncertWriteBuffer(ncol);
408 vector<double> uncertObsLineBuffer;
411 imgReaderObs.readData(obsLineBuffer,GDT_Float64,irow,0);
413 if(imgReaderObs.nrOfBand()>1)
414 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
416 for(
int icol=0;icol<ncol;++icol){
417 imgWriterEst.image2geo(icol,irow,geox,geoy);
418 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
419 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
420 double modValue=estReadBuffer[modCol];
421 if(imgReaderModel1.isNoData(modValue)){
422 estWriteBuffer[icol]=obsLineBuffer[icol];
423 if(imgReaderObs.isNoData(obsLineBuffer[icol])){
424 estWriteBuffer[icol]=obsnodata_opt[0];
425 uncertWriteBuffer[icol]=uncertNodata_opt[0];
427 else if(uncertObsLineBuffer.size()>icol)
428 uncertWriteBuffer[icol]=uncertObsLineBuffer[icol];
430 uncertWriteBuffer[icol]=uncertObs_opt[0];
433 double errMod=uncertModel_opt[0]*stdDev;
434 double certNorm=(errMod*errMod+errObs*errObs);
435 double certMod=errObs*errObs/certNorm;
436 double certObs=errMod*errMod/certNorm;
438 double regSensor=(c0obs+c1obs*modValue)*certObs;
439 estWriteBuffer[icol]=regTime+regSensor;
440 double totalUncertainty=0;
441 if(errMod<eps_opt[0])
442 totalUncertainty=errObs;
443 else if(errObs<eps_opt[0])
444 totalUncertainty=errMod;
446 totalUncertainty=1.0/errMod/errMod+1/errObs/errObs;
447 totalUncertainty=sqrt(1.0/totalUncertainty);
449 uncertWriteBuffer[icol]=totalUncertainty;
453 if(!imgReaderObs.isNoData(obsLineBuffer[icol])){
455 double uncertObs=uncertObs_opt[0];
456 if(uncertObsLineBuffer.size()>icol)
457 uncertObs=uncertObsLineBuffer[icol];
458 else if(weight_opt.size()||deltaObs_opt.size()){
459 vector<double> obsWindowBuffer;
460 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
461 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
462 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
463 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
465 imgReaderObs.readDataBlock(obsWindowBuffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
467 statobs.setNoDataValues(obsnodata_opt);
468 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
469 double difference=obsMeanValue-modValue;
471 double relativeDifference=difference/modValue;
472 if(deltaObs_opt.size()){
473 assert(deltaObs_opt.size()>1);
474 if(100*relativeDifference<deltaObs_opt[0])
476 else if(100*relativeDifference>deltaObs_opt[1])
479 else if(weight_opt.size()){
480 assert(weight_opt.size()>1);
481 if(obsMeanValue<modValue)
482 uncertObs=weight_opt[0]*relativeDifference;
483 else if(obsMeanValue>modValue)
484 uncertObs=weight_opt[1]*relativeDifference;
490 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
493 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
494 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
496 assert(kalmanGain<=1);
497 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
498 uncertWriteBuffer[icol]*=(1-kalmanGain);
501 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
502 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
504 imgReaderObs.close();
507 imgReaderModel1.close();
508 imgWriterEst.close();
510 for(
int modindex=1;modindex<model_opt.size();++modindex){
512 cout <<
"processing time " << tmodel_opt[modindex] << endl;
513 if(obsindex<relobsindex.size())
514 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
516 cout <<
"There is no next observation" << endl;
519 if(outputfw_opt.size()==model_opt.size())
520 output=outputfw_opt[modindex];
522 ostringstream outputstream;
523 outputstream << outputfw_opt[0] <<
"_" << tmodel_opt[modindex] <<
".tif";
525 output=outputstream.str();
529 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
530 imgWriterEst.setProjectionProj4(projection_opt[0]);
531 imgWriterEst.setGeoTransform(geotransform);
532 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
535 imgReaderModel1.open(model_opt[modindex-1]);
536 imgReaderModel1.setNoData(modnodata_opt);
537 if(modoffset_opt.size())
538 imgReaderModel1.setOffset(modoffset_opt[0]);
539 if(modscale_opt.size())
540 imgReaderModel1.setScale(modscale_opt[0]);
541 imgReaderModel2.open(model_opt[modindex]);
542 imgReaderModel2.setNoData(modnodata_opt);
543 if(modoffset_opt.size())
544 imgReaderModel2.setOffset(modoffset_opt[0]);
545 if(modscale_opt.size())
546 imgReaderModel2.setScale(modscale_opt[0]);
551 pfnProgress(progress,pszMessage,pProgressArg);
554 cout <<
"Calculating regression for " << imgReaderModel1.getFileName() <<
" " << imgReaderModel2.getFileName() << endl;
556 double errMod=imgreg.getRMSE(imgReaderModel1,imgReaderModel2,c0modGlobal,c1modGlobal,0,0);
559 cout <<
"c0modGlobal, c1modGlobal: " << c0modGlobal <<
", " << c1modGlobal << endl;
562 if(obsindex<relobsindex.size()){
563 update=(relobsindex[obsindex]==modindex);
567 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
569 imgReaderObs.open(observation_opt[obsindex]);
570 imgReaderObs.getGeoTransform(geotransform);
571 imgReaderObs.setNoData(obsnodata_opt);
572 if(obsoffset_opt.size())
573 imgReaderObs.setOffset(obsoffset_opt[0]);
574 if(obsscale_opt.size())
575 imgReaderObs.setScale(obsscale_opt[0]);
578 cout <<
"Calculating regression for " << imgReaderModel2.getFileName() <<
" " << imgReaderObs.getFileName() << endl;
580 errObs=imgreg.getRMSE(imgReaderModel2,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
587 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
591 if(outputfw_opt.size()==model_opt.size())
592 input=outputfw_opt[modindex-1];
594 ostringstream outputstream;
595 outputstream << outputfw_opt[0] <<
"_" << tmodel_opt[modindex-1] <<
".tif";
596 input=outputstream.str();
599 imgReaderEst.setNoData(obsnodata_opt);
600 if(obsoffset_opt.size())
601 imgReaderEst.setOffset(obsoffset_opt[0]);
602 if(obsscale_opt.size())
603 imgReaderEst.setScale(obsscale_opt[0]);
605 vector< vector<double> > obsLineVector(down_opt[0]);
606 vector<double> obsLineBuffer;
607 vector<double> obsWindowBuffer;
608 vector<double> model1LineBuffer;
609 vector<double> model2LineBuffer;
610 vector<double> model1buffer;
611 vector<double> model2buffer;
612 vector<double> uncertObsLineBuffer;
613 vector<double> estReadBuffer;
615 vector<double> uncertReadBuffer;
616 vector<double> estWriteBuffer(ncol);
617 vector<double> uncertWriteBuffer(ncol);
621 assert(down_opt[0]%2);
622 for(
int iline=-down_opt[0]/2+1;iline<down_opt[0]/2+1;++iline){
624 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
626 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
628 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
629 assert(irow<imgReaderEst.nrOfRow());
631 imgReaderEst.readData(estReadBuffer,GDT_Float64,irow,0);
632 imgReaderEst.readData(uncertReadBuffer,GDT_Float64,irow,1);
634 imgReaderEst.image2geo(0,irow,geox,geoy);
635 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
636 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
637 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,0);
639 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
640 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
641 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,0);
644 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
645 obsLineVector.erase(obsLineVector.begin());
646 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
647 obsLineVector.push_back(obsLineBuffer);
648 obsLineBuffer=obsLineVector[down_opt[0]/2];
650 if(imgReaderObs.nrOfBand()>1)
651 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
654 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
655 imgReaderEst.image2geo(icol,irow,geox,geoy);
656 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
657 int maxCol=(icol+down_opt[0]/2<imgReaderEst.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderEst.nrOfCol()-1;
658 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
659 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
661 obsWindowBuffer.clear();
662 for(
int iline=0;iline<obsLineVector.size();++iline){
663 for(
int isample=minCol;isample<=maxCol;++isample){
664 assert(isample<obsLineVector[iline].size());
665 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
670 double estValue=estReadBuffer[icol];
671 double estMeanValue=0;
674 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
675 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
676 double modValue=model2LineBuffer[modCol];
677 bool estNodata=imgReaderEst.isNoData(estValue);
680 if(imgReaderModel2.isNoData(modValue)){
681 estWriteBuffer[icol]=obsnodata_opt[0];
682 uncertWriteBuffer[icol]=uncertNodata_opt[0];
685 estWriteBuffer[icol]=modValue;
686 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
693 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
694 maxCol=(modCol+window_opt[0]/2<imgReaderModel2.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel2.nrOfCol()-1;
695 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
696 maxRow=(modRow+window_opt[0]/2<imgReaderModel2.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel2.nrOfRow()-1;
697 imgReaderModel2.readDataBlock(model2buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
699 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
700 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
701 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
702 maxCol=(modCol+window_opt[0]/2<imgReaderModel1.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel1.nrOfCol()-1;
703 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
704 maxRow=(modRow+window_opt[0]/2<imgReaderModel1.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel1.nrOfRow()-1;
705 imgReaderModel1.readDataBlock(model1buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
708 catch(
string errorString){
709 cerr <<
"Error reading data block for " << minCol <<
"-" << maxCol <<
", " << minRow <<
"-" << maxRow << endl;
712 vector<double>::iterator it1=model1buffer.begin();
713 vector<double>::iterator it2=model2buffer.begin();
714 while(it1!=model1buffer.end()&&it2!=model2buffer.end()){
716 bool modNodata=
false;
717 modNodata=modNodata||imgReaderModel1.isNoData(*it1);
718 modNodata=modNodata||imgReaderModel2.isNoData(*it2);
720 model1buffer.erase(it1);
721 model2buffer.erase(it2);
728 if(model1buffer.size()>minreg_opt[0]&&model2buffer.size()>minreg_opt[0])
729 errMod=stat.linear_regression_err(model1buffer,model2buffer,c0mod,c1mod);
739 double certNorm=(errMod*errMod+errObs*errObs);
740 double certMod=errObs*errObs/certNorm;
741 double certObs=errMod*errMod/certNorm;
742 double regTime=(c0mod+c1mod*estValue)*certMod;
745 double regSensor=(c0obs+c1obs*modValue)*certObs;
746 estWriteBuffer[icol]=regTime+regSensor;
747 double totalUncertainty=0;
748 if(errMod<eps_opt[0])
749 totalUncertainty=errObs;
750 else if(errObs<eps_opt[0])
751 totalUncertainty=errMod;
753 totalUncertainty=1.0/errMod/errMod+1/errObs/errObs;
754 totalUncertainty=sqrt(1.0/totalUncertainty);
756 uncertWriteBuffer[icol]=totalUncertainty+uncertReadBuffer[icol];
759 if(update&&!imgReaderObs.isNoData(obsLineBuffer[icol])){
761 double uncertObs=uncertObs_opt[0];
762 if(uncertObsLineBuffer.size()>icol)
763 uncertObs=uncertObsLineBuffer[icol];
764 else if(weight_opt.size()>1||deltaObs_opt.size()){
766 statobs.setNoDataValues(obsnodata_opt);
767 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
768 double difference=obsMeanValue-modValue;
770 double relativeDifference=difference/modValue;
771 if(deltaObs_opt.size()){
772 assert(deltaObs_opt.size()>1);
773 if(100*relativeDifference<deltaObs_opt[0])
775 else if(100*relativeDifference>deltaObs_opt[1])
778 else if(weight_opt.size()){
779 assert(weight_opt.size()>1);
780 if(obsMeanValue<modValue)
781 uncertObs=weight_opt[0]*relativeDifference;
782 else if(obsMeanValue>modValue)
783 uncertObs=weight_opt[1]*relativeDifference;
789 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
792 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
793 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
795 assert(kalmanGain<=1);
796 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
797 uncertWriteBuffer[icol]*=(1-kalmanGain);
800 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
801 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
802 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
803 pfnProgress(progress,pszMessage,pProgressArg);
806 imgWriterEst.close();
807 imgReaderEst.close();
810 imgReaderObs.close();
813 imgReaderModel1.close();
814 imgReaderModel2.close();
817 if(find(direction_opt.begin(),direction_opt.end(),
"backward")!=direction_opt.end()){
819 cout <<
"Running backward model" << endl;
820 obsindex=relobsindex.size()-1;
823 if(outputbw_opt.size()==model_opt.size())
824 output=outputbw_opt.back();
826 ostringstream outputstream;
827 outputstream << outputbw_opt[0] <<
"_" << tmodel_opt.back() <<
".tif";
828 output=outputstream.str();
831 cout <<
"Opening image " << output <<
" for writing " << endl;
832 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
833 imgWriterEst.setProjectionProj4(projection_opt[0]);
834 imgWriterEst.setGeoTransform(geotransform);
835 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
838 cout <<
"processing time " << tmodel_opt.back() << endl;
839 if(obsindex<relobsindex.size())
840 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
842 cout <<
"There is no next observation" << endl;
846 imgReaderModel1.open(model_opt.back());
847 imgReaderModel1.setNoData(modnodata_opt);
848 if(modoffset_opt.size())
849 imgReaderModel1.setOffset(modoffset_opt[0]);
850 if(modscale_opt.size())
851 imgReaderModel1.setScale(modscale_opt[0]);
853 catch(
string errorString){
854 cerr << errorString << endl;
857 cerr <<
"Error opening file " << model_opt[0] << endl;
861 GDALRasterBand* rasterBand;
862 rasterBand=imgReaderModel1.getRasterBand(0);
863 double minValue, maxValue, meanValue, stdDev;
865 rasterBand->ComputeStatistics(0,&minValue,&maxValue,&meanValue,&stdDev,pfnProgress,pProgressData);
868 if(relobsindex.back()<model_opt.size()-1){
871 cout <<
"write last model as output" << endl;
872 for(
int irow=0;irow<nrow;++irow){
873 vector<double> estReadBuffer;
874 vector<double> estWriteBuffer(ncol);
875 vector<double> uncertWriteBuffer(ncol);
877 imgWriterEst.image2geo(0,irow,geox,geoy);
878 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
879 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
881 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
886 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
887 imgWriterEst.image2geo(icol,irow,geox,geoy);
888 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
889 double modValue=estReadBuffer[modCol];
890 if(imgReaderModel1.isNoData(modValue)){
891 estWriteBuffer[icol]=obsnodata_opt[0];
892 uncertWriteBuffer[icol]=uncertNodata_opt[0];
895 estWriteBuffer[icol]=modValue;
896 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
899 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
900 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
902 catch(
string errorString){
903 cerr << errorString << endl;
906 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
912 cout <<
"we have an observation at end time" << endl;
913 imgReaderObs.open(observation_opt.back());
914 imgReaderObs.getGeoTransform(geotransform);
915 imgReaderObs.setNoData(obsnodata_opt);
916 if(obsoffset_opt.size())
917 imgReaderObs.setOffset(obsoffset_opt[0]);
918 if(obsscale_opt.size())
919 imgReaderObs.setScale(obsscale_opt[0]);
922 errObs=imgreg.getRMSE(imgReaderModel1,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
929 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
931 for(
int irow=0;irow<nrow;++irow){
932 vector<double> estReadBuffer;
933 imgWriterEst.image2geo(0,irow,geox,geoy);
934 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
935 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
936 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
937 vector<double> obsLineBuffer;
938 vector<double> estWriteBuffer(ncol);
939 vector<double> uncertWriteBuffer(ncol);
940 vector<double> uncertObsLineBuffer;
943 imgReaderObs.readData(obsLineBuffer,GDT_Float64,irow,0);
945 if(imgReaderObs.nrOfBand()>1)
946 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
948 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
949 imgWriterEst.image2geo(icol,irow,geox,geoy);
950 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
951 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
952 double modValue=estReadBuffer[modCol];
953 if(imgReaderModel1.isNoData(modValue)){
954 estWriteBuffer[icol]=obsLineBuffer[icol];
955 if(imgReaderObs.isNoData(obsLineBuffer[icol])){
956 estWriteBuffer[icol]=obsnodata_opt[0];
957 uncertWriteBuffer[icol]=uncertNodata_opt[0];
959 else if(uncertObsLineBuffer.size()>icol)
960 uncertWriteBuffer[icol]=uncertObsLineBuffer[icol];
962 uncertWriteBuffer[icol]=uncertObs_opt[0];
965 double errMod=uncertModel_opt[0]*stdDev;
966 double certNorm=(errMod*errMod+errObs*errObs);
967 double certMod=errObs*errObs/certNorm;
968 double certObs=errMod*errMod/certNorm;
970 double regSensor=(c0obs+c1obs*modValue)*certObs;
971 estWriteBuffer[icol]=regTime+regSensor;
972 double totalUncertainty=0;
973 if(errMod<eps_opt[0])
974 totalUncertainty=errObs;
975 else if(errObs<eps_opt[0])
976 totalUncertainty=errMod;
978 totalUncertainty=1.0/errMod/errMod+1/errObs/errObs;
979 totalUncertainty=sqrt(1.0/totalUncertainty);
981 uncertWriteBuffer[icol]=totalUncertainty;
984 if(!imgReaderObs.isNoData(obsLineBuffer[icol])){
986 double uncertObs=uncertObs_opt[0];
987 if(uncertObsLineBuffer.size()>icol)
988 uncertObs=uncertObsLineBuffer[icol];
989 else if(weight_opt.size()>1||deltaObs_opt.size()){
990 vector<double> obsWindowBuffer;
991 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
992 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
993 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
994 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
996 imgReaderObs.readDataBlock(obsWindowBuffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
998 statobs.setNoDataValues(obsnodata_opt);
999 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
1000 double difference=obsMeanValue-modValue;
1002 double relativeDifference=difference/modValue;
1003 if(deltaObs_opt.size()){
1004 assert(deltaObs_opt.size()>1);
1005 if(100*relativeDifference<deltaObs_opt[0])
1007 else if(100*relativeDifference>deltaObs_opt[1])
1010 else if(weight_opt.size()){
1011 assert(weight_opt.size()>1);
1012 if(obsMeanValue<modValue)
1013 uncertObs=weight_opt[0]*relativeDifference;
1014 else if(obsMeanValue>modValue)
1015 uncertObs=weight_opt[1]*relativeDifference;
1020 if(verbose_opt[0]>1)
1021 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
1024 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
1025 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
1027 assert(kalmanGain<=1);
1028 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1029 uncertWriteBuffer[icol]*=(1-kalmanGain);
1032 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1033 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1035 imgReaderObs.close();
1038 imgReaderModel1.close();
1039 imgWriterEst.close();
1041 for(
int modindex=model_opt.size()-2;modindex>=0;--modindex){
1043 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1044 if(obsindex<relobsindex.size())
1045 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1047 cout <<
"There is no next observation" << endl;
1050 if(outputbw_opt.size()==model_opt.size())
1051 output=outputbw_opt[modindex];
1053 ostringstream outputstream;
1054 outputstream << outputbw_opt[0] <<
"_" << tmodel_opt[modindex] <<
".tif";
1056 output=outputstream.str();
1060 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
1061 imgWriterEst.setProjectionProj4(projection_opt[0]);
1062 imgWriterEst.setGeoTransform(geotransform);
1063 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1066 imgReaderModel1.open(model_opt[modindex+1]);
1067 imgReaderModel1.setNoData(modnodata_opt);
1068 if(modoffset_opt.size())
1069 imgReaderModel1.setOffset(modoffset_opt[0]);
1070 if(modscale_opt.size())
1071 imgReaderModel1.setScale(modscale_opt[0]);
1072 imgReaderModel2.open(model_opt[modindex]);
1073 imgReaderModel2.setNoData(modnodata_opt);
1074 if(modoffset_opt.size())
1075 imgReaderModel2.setOffset(modoffset_opt[0]);
1076 if(modscale_opt.size())
1077 imgReaderModel2.setScale(modscale_opt[0]);
1082 pfnProgress(progress,pszMessage,pProgressArg);
1085 cout <<
"Calculating regression for " << imgReaderModel1.getFileName() <<
" " << imgReaderModel2.getFileName() << endl;
1087 double errMod=imgreg.getRMSE(imgReaderModel1,imgReaderModel2,c0modGlobal,c1modGlobal,0,0);
1090 cout <<
"c0modGlobal, c1modGlobal: " << c0modGlobal <<
", " << c1modGlobal << endl;
1093 if(obsindex<relobsindex.size()){
1094 update=(relobsindex[obsindex]==modindex);
1098 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
1100 imgReaderObs.open(observation_opt[obsindex]);
1101 imgReaderObs.getGeoTransform(geotransform);
1102 imgReaderObs.setNoData(obsnodata_opt);
1103 if(obsoffset_opt.size())
1104 imgReaderObs.setOffset(obsoffset_opt[0]);
1105 if(obsscale_opt.size())
1106 imgReaderObs.setScale(obsscale_opt[0]);
1109 cout <<
"Calculating regression for " << imgReaderModel2.getFileName() <<
" " << imgReaderObs.getFileName() << endl;
1110 if(regSensor_opt[0])
1111 errObs=imgreg.getRMSE(imgReaderModel2,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
1118 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
1122 if(outputbw_opt.size()==model_opt.size())
1123 input=outputbw_opt[modindex+1];
1125 ostringstream outputstream;
1126 outputstream << outputbw_opt[0] <<
"_" << tmodel_opt[modindex+1] <<
".tif";
1127 input=outputstream.str();
1130 imgReaderEst.setNoData(obsnodata_opt);
1131 if(obsoffset_opt.size())
1132 imgReaderEst.setOffset(obsoffset_opt[0]);
1133 if(obsscale_opt.size())
1134 imgReaderEst.setScale(obsscale_opt[0]);
1136 vector< vector<double> > obsLineVector(down_opt[0]);
1137 vector<double> obsLineBuffer;
1138 vector<double> obsWindowBuffer;
1139 vector<double> model1LineBuffer;
1140 vector<double> model2LineBuffer;
1141 vector<double> model1buffer;
1142 vector<double> model2buffer;
1143 vector<double> uncertObsLineBuffer;
1144 vector<double> estReadBuffer;
1146 vector<double> uncertReadBuffer;
1147 vector<double> estWriteBuffer(ncol);
1148 vector<double> uncertWriteBuffer(ncol);
1152 assert(down_opt[0]%2);
1153 for(
int iline=-down_opt[0]/2+1;iline<down_opt[0]/2+1;++iline){
1155 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
1157 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
1159 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
1160 assert(irow<imgReaderEst.nrOfRow());
1162 imgReaderEst.readData(estReadBuffer,GDT_Float64,irow,0);
1163 imgReaderEst.readData(uncertReadBuffer,GDT_Float64,irow,1);
1165 imgReaderEst.image2geo(0,irow,geox,geoy);
1166 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1167 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1168 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,0);
1170 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1171 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1172 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,0);
1175 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
1176 obsLineVector.erase(obsLineVector.begin());
1177 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
1178 obsLineVector.push_back(obsLineBuffer);
1179 obsLineBuffer=obsLineVector[down_opt[0]/2];
1181 if(imgReaderObs.nrOfBand()>1)
1182 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1185 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1186 imgReaderEst.image2geo(icol,irow,geox,geoy);
1187 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
1188 int maxCol=(icol+down_opt[0]/2<imgReaderEst.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderEst.nrOfCol()-1;
1189 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
1190 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
1192 obsWindowBuffer.clear();
1193 for(
int iline=0;iline<obsLineVector.size();++iline){
1194 for(
int isample=minCol;isample<=maxCol;++isample){
1195 assert(isample<obsLineVector[iline].size());
1196 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
1201 double estValue=estReadBuffer[icol];
1202 double estMeanValue=0;
1205 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1206 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1207 double modValue=model2LineBuffer[modCol];
1208 bool estNodata=imgReaderEst.isNoData(estValue);
1211 if(imgReaderModel2.isNoData(modValue)){
1212 estWriteBuffer[icol]=obsnodata_opt[0];
1213 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1216 estWriteBuffer[icol]=modValue;
1217 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
1221 if(window_opt[0]>0){
1224 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
1225 maxCol=(modCol+window_opt[0]/2<imgReaderModel2.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel2.nrOfCol()-1;
1226 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
1227 maxRow=(modRow+window_opt[0]/2<imgReaderModel2.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel2.nrOfRow()-1;
1228 imgReaderModel2.readDataBlock(model2buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
1230 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1231 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1232 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
1233 maxCol=(modCol+window_opt[0]/2<imgReaderModel1.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel1.nrOfCol()-1;
1234 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
1235 maxRow=(modRow+window_opt[0]/2<imgReaderModel1.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel1.nrOfRow()-1;
1236 imgReaderModel1.readDataBlock(model1buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
1239 catch(
string errorString){
1240 cerr <<
"Error reading data block for " << minCol <<
"-" << maxCol <<
", " << minRow <<
"-" << maxRow << endl;
1243 vector<double>::iterator it1=model1buffer.begin();
1244 vector<double>::iterator it2=model2buffer.begin();
1245 while(it1!=model1buffer.end()&&it2!=model2buffer.end()){
1247 bool modNodata=
false;
1248 modNodata=modNodata||imgReaderModel1.isNoData(*it1);
1249 modNodata=modNodata||imgReaderModel2.isNoData(*it2);
1251 model1buffer.erase(it1);
1252 model2buffer.erase(it2);
1259 if(model1buffer.size()>minreg_opt[0]&&model2buffer.size()>minreg_opt[0])
1260 errMod=stat.linear_regression_err(model1buffer,model2buffer,c0mod,c1mod);
1270 double certNorm=(errMod*errMod+errObs*errObs);
1271 double certMod=errObs*errObs/certNorm;
1272 double certObs=errMod*errMod/certNorm;
1273 double regTime=(c0mod+c1mod*estValue)*certMod;
1276 double regSensor=(c0obs+c1obs*modValue)*certObs;
1277 estWriteBuffer[icol]=regTime+regSensor;
1278 double totalUncertainty=0;
1279 if(errMod<eps_opt[0])
1280 totalUncertainty=errObs;
1281 else if(errObs<eps_opt[0])
1282 totalUncertainty=errMod;
1284 totalUncertainty=1.0/errMod/errMod+1/errObs/errObs;
1285 totalUncertainty=sqrt(1.0/totalUncertainty);
1287 uncertWriteBuffer[icol]=totalUncertainty+uncertReadBuffer[icol];
1290 if(update&&!imgReaderObs.isNoData(obsLineBuffer[icol])){
1291 double kalmanGain=1;
1292 double uncertObs=uncertObs_opt[0];
1293 if(uncertObsLineBuffer.size()>icol)
1294 uncertObs=uncertObsLineBuffer[icol];
1295 else if(weight_opt.size()>1||deltaObs_opt.size()){
1297 statobs.setNoDataValues(obsnodata_opt);
1298 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
1299 double difference=obsMeanValue-modValue;
1301 double relativeDifference=difference/modValue;
1302 if(deltaObs_opt.size()){
1303 assert(deltaObs_opt.size()>1);
1304 if(100*relativeDifference<deltaObs_opt[0])
1306 else if(100*relativeDifference>deltaObs_opt[1])
1309 else if(weight_opt.size()){
1310 assert(weight_opt.size()>1);
1311 if(obsMeanValue<modValue)
1312 uncertObs=weight_opt[0]*relativeDifference;
1313 else if(obsMeanValue>modValue)
1314 uncertObs=weight_opt[1]*relativeDifference;
1319 if(verbose_opt[0]>1)
1320 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
1323 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
1324 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
1326 assert(kalmanGain<=1);
1327 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1328 uncertWriteBuffer[icol]*=(1-kalmanGain);
1331 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1332 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1333 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
1334 pfnProgress(progress,pszMessage,pProgressArg);
1337 imgWriterEst.close();
1338 imgReaderEst.close();
1341 imgReaderObs.close();
1344 imgReaderModel1.close();
1345 imgReaderModel2.close();
1348 if(find(direction_opt.begin(),direction_opt.end(),
"smooth")!=direction_opt.end()){
1350 cout <<
"Running smooth model" << endl;
1352 for(
int modindex=0;modindex<model_opt.size();++modindex){
1354 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1355 if(obsindex<relobsindex.size())
1356 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1358 cout <<
"There is no next observation" << endl;
1361 if(outputfb_opt.size()==model_opt.size())
1362 output=outputfb_opt[modindex];
1364 ostringstream outputstream;
1365 outputstream << outputfb_opt[0] <<
"_" << tmodel_opt[modindex] <<
".tif";
1366 output=outputstream.str();
1370 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
1371 imgWriterEst.setProjectionProj4(projection_opt[0]);
1372 imgWriterEst.setGeoTransform(geotransform);
1373 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1380 if(outputfw_opt.size()==model_opt.size())
1381 inputfw=outputfw_opt[modindex];
1383 ostringstream outputstream;
1384 outputstream << outputfw_opt[0] <<
"_" << tmodel_opt[modindex] <<
".tif";
1385 inputfw=outputstream.str();
1387 if(outputbw_opt.size()==model_opt.size())
1388 inputbw=outputbw_opt[modindex];
1390 ostringstream outputstream;
1391 outputstream << outputbw_opt[0] <<
"_" << tmodel_opt[modindex] <<
".tif";
1392 inputbw=outputstream.str();
1396 imgReaderForward.setNoData(obsnodata_opt);
1397 if(obsoffset_opt.size())
1398 imgReaderForward.setOffset(obsoffset_opt[0]);
1399 if(obsscale_opt.size())
1400 imgReaderForward.setScale(obsscale_opt[0]);
1401 imgReaderBackward.setNoData(obsnodata_opt);
1402 if(obsoffset_opt.size())
1403 imgReaderBackward.setOffset(obsoffset_opt[0]);
1404 if(obsscale_opt.size())
1405 imgReaderBackward.setScale(obsscale_opt[0]);
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);
1428 if(obsoffset_opt.size())
1429 imgReaderObs.setOffset(obsoffset_opt[0]);
1430 if(obsscale_opt.size())
1431 imgReaderObs.setScale(obsscale_opt[0]);
1435 pfnProgress(progress,pszMessage,pProgressArg);
1437 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
1438 assert(irow<imgReaderForward.nrOfRow());
1439 assert(irow<imgReaderBackward.nrOfRow());
1440 imgReaderForward.readData(estForwardBuffer,GDT_Float64,irow,0);
1441 imgReaderBackward.readData(estBackwardBuffer,GDT_Float64,irow,0);
1442 imgReaderForward.readData(uncertForwardBuffer,GDT_Float64,irow,1);
1443 imgReaderBackward.readData(uncertBackwardBuffer,GDT_Float64,irow,1);
1446 imgReaderObs.readData(estWriteBuffer,GDT_Float64,irow,0);
1447 if(imgReaderObs.nrOfBand()>1)
1448 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1452 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1453 imgWriterEst.image2geo(icol,irow,geox,geoy);
1454 double A=estForwardBuffer[icol];
1455 double B=estBackwardBuffer[icol];
1456 double C=uncertForwardBuffer[icol]*uncertForwardBuffer[icol];
1457 double D=uncertBackwardBuffer[icol]*uncertBackwardBuffer[icol];
1458 double uncertObs=uncertObs_opt[0];
1467 double noemer=(C+D);
1469 if(imgReaderForward.isNoData(A)&&imgReaderBackward.isNoData(B)){
1470 estWriteBuffer[icol]=obsnodata_opt[0];
1471 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1473 else if(imgReaderForward.isNoData(A)){
1474 estWriteBuffer[icol]=B;
1475 uncertWriteBuffer[icol]=uncertBackwardBuffer[icol];
1477 else if(imgReaderForward.isNoData(B)){
1478 estWriteBuffer[icol]=A;
1479 uncertWriteBuffer[icol]=uncertForwardBuffer[icol];
1482 if(noemer<eps_opt[0]){
1483 estWriteBuffer[icol]=0.5*(A+B);
1484 uncertWriteBuffer[icol]=uncertObs;
1487 estWriteBuffer[icol]=(A*D+B*C)/noemer;
1493 if(uncertObs*uncertObs>eps_opt[0])
1494 P-=1.0/uncertObs/uncertObs;
1499 uncertWriteBuffer[icol]=P;
1503 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1504 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1505 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
1506 pfnProgress(progress,pszMessage,pProgressArg);
1509 imgWriterEst.close();
1510 imgReaderForward.close();
1511 imgReaderBackward.close();
1513 imgReaderObs.close();