23 #include "base/Optionpk.h"
24 #include "base/Vector2d.h"
25 #include "imageclasses/ImgReaderGdal.h"
26 #include "imageclasses/ImgWriterGdal.h"
27 #include "algorithms/StatFactory.h"
28 #include "algorithms/ImgRegression.h"
80 int main(
int argc,
char **argv) {
81 Optionpk<string> direction_opt(
"dir",
"direction",
"direction to run model (forward|backward|smooth)",
"forward");
82 Optionpk<string> model_opt(
"mod",
"model",
"model input datasets, e.g., MODIS (use: -mod model1 -mod model2 etc.)");
83 Optionpk<string> observation_opt(
"obs",
"observation",
"observation input datasets, e.g., landsat (use: -obs obs1 -obs obs2 etc.)");
84 Optionpk<int> tmodel_opt(
"tmod",
"tmodel",
"time sequence of model input. Sequence must have exact same length as model input. Leave empty to have default sequence 0,1,2,etc.");
85 Optionpk<int> tobservation_opt(
"tobs",
"tobservation",
"time sequence of observation input. Sequence must have exact same length as observation input)");
86 Optionpk<string> projection_opt(
"a_srs",
"a_srs",
"Override the projection for the output file (leave blank to copy from input file, use epsg:3035 to use European projection and force to European grid");
87 Optionpk<string> outputfw_opt(
"ofw",
"outputfw",
"Output raster dataset for forward model");
88 Optionpk<string> outputbw_opt(
"obw",
"outputbw",
"Output raster dataset for backward model");
89 Optionpk<string> outputfb_opt(
"ofb",
"outputfb",
"Output raster dataset for smooth model");
90 Optionpk<double> modnodata_opt(
"modnodata",
"modnodata",
"invalid value for model input", 0);
91 Optionpk<double> obsnodata_opt(
"obsnodata",
"obsnodata",
"invalid value for observation input", 0);
92 Optionpk<double> modoffset_opt(
"modoffset",
"modoffset",
"offset used to read model input dataset (value=offset+scale*readValue)");
93 Optionpk<double> obsoffset_opt(
"obsoffset",
"obsoffset",
"offset used to read observation input dataset (value=offset+scale*readValue)");
94 Optionpk<double> modscale_opt(
"modscale",
"modscale",
"scale used to read model input dataset (value=offset+scale*readValue)");
95 Optionpk<double> obsscale_opt(
"obsscale",
"obsscale",
"scale used to read observation input dataset (value=offset+scale*readValue)");
96 Optionpk<double> eps_opt(
"eps",
"eps",
"epsilon for non zero division", 0.00001);
97 Optionpk<double> uncertModel_opt(
"um",
"uncertmodel",
"Multiply this value with std dev of first model image to obtain uncertainty of model",2);
98 Optionpk<double> uncertObs_opt(
"uo",
"uncertobs",
"Uncertainty of valid observations",0);
99 Optionpk<double> weight_opt(
"w",
"weight",
"Penalize outliers in measurement via weights. Use first weight to penalize small measurements wrt model and second weight to penalize large measurements wrt model");
100 Optionpk<double> deltaObs_opt(
"dobs",
"deltaobs",
"Lower and upper thresholds for relative pixel differences (in percentage): (observation-model)/model. For instance to force the observation within a +/- 10 % interval, use: -dobs -10 -dobs 10 (equivalent to -dobs 10). Leave empty to always update on observation");
101 Optionpk<double> uncertNodata_opt(
"unodata",
"uncertnodata",
"Uncertainty in case of no-data values in observation", 10000);
102 Optionpk<double> regTime_opt(
"rt",
"regtime",
"Weight for regression in time series", 1.0);
103 Optionpk<double> regSensor_opt(
"rs",
"regsensor",
"Weight for regression model - measurement (model - observation).");
104 Optionpk<int> down_opt(
"down",
"down",
"Downsampling factor for reading model data to calculate regression");
105 Optionpk<float> threshold_opt(
"th",
"threshold",
"threshold for selecting samples (randomly). Provide probability in percentage (>0) or absolute (<0).", 0);
106 Optionpk<int> minreg_opt(
"minreg",
"minreg",
"Minimum number of pixels to take into account for regression", 5, 2);
109 Optionpk<unsigned short> window_opt(
"win",
"window",
"window size for calculating regression (use 0 for global)", 0);
113 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate). Empty string: inherit from input image",
"GTiff",2);
114 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
115 Optionpk<short> verbose_opt(
"v",
"verbose",
"verbose mode when positive", 0);
119 doProcess=direction_opt.retrieveOption(argc,argv);
120 model_opt.retrieveOption(argc,argv);
121 observation_opt.retrieveOption(argc,argv);
122 tmodel_opt.retrieveOption(argc,argv);
123 tobservation_opt.retrieveOption(argc,argv);
124 projection_opt.retrieveOption(argc,argv);
125 outputfw_opt.retrieveOption(argc,argv);
126 outputbw_opt.retrieveOption(argc,argv);
127 outputfb_opt.retrieveOption(argc,argv);
128 modnodata_opt.retrieveOption(argc,argv);
129 obsnodata_opt.retrieveOption(argc,argv);
130 modoffset_opt.retrieveOption(argc,argv);
131 modscale_opt.retrieveOption(argc,argv);
132 obsoffset_opt.retrieveOption(argc,argv);
133 obsscale_opt.retrieveOption(argc,argv);
134 eps_opt.retrieveOption(argc,argv);
135 uncertModel_opt.retrieveOption(argc,argv);
136 uncertObs_opt.retrieveOption(argc,argv);
137 weight_opt.retrieveOption(argc,argv);
138 deltaObs_opt.retrieveOption(argc,argv);
139 uncertNodata_opt.retrieveOption(argc,argv);
140 regTime_opt.retrieveOption(argc,argv);
141 regSensor_opt.retrieveOption(argc,argv);
142 down_opt.retrieveOption(argc,argv);
143 threshold_opt.retrieveOption(argc,argv);
144 minreg_opt.retrieveOption(argc,argv);
147 window_opt.retrieveOption(argc,argv);
150 oformat_opt.retrieveOption(argc,argv);
151 option_opt.retrieveOption(argc,argv);
152 verbose_opt.retrieveOption(argc,argv);
154 catch(
string predefinedString){
155 std::cout << predefinedString << std::endl;
159 std::cerr <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
163 if(deltaObs_opt.size()==1){
164 if(deltaObs_opt[0]<=0)
165 deltaObs_opt.push_back(-deltaObs_opt[0]);
167 deltaObs_opt.insert(deltaObs_opt.begin(),-deltaObs_opt[0]);
169 if(weight_opt.size()==1){
170 weight_opt.push_back(weight_opt[0]);
173 if(down_opt.empty()){
174 std::cerr <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
178 ostringstream errorStream;
179 if(model_opt.size()<2){
180 errorStream <<
"Error: no model dataset selected, use option -mod" << endl;
181 throw(errorStream.str());
183 if(observation_opt.size()<1){
184 errorStream <<
"Error: no observation dataset selected, use option -obs" << endl;
185 throw(errorStream.str());
187 if(direction_opt[0]==
"smooth"){
188 if(outputfw_opt.empty()){
189 errorStream <<
"Error: output forward datasets is not provided, use option -ofw" << endl;
190 throw(errorStream.str());
192 if(outputbw_opt.empty()){
193 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
194 throw(errorStream.str());
196 if(outputfb_opt.empty()){
197 errorStream <<
"Error: output smooth datasets is not provided, use option -ofb" << endl;
198 throw(errorStream.str());
202 if(direction_opt[0]==
"forward"&&outputfw_opt.empty()){
203 errorStream <<
"Error: output forward datasets is not provided, use option -ofw" << endl;
204 throw(errorStream.str());
206 else if(direction_opt[0]==
"backward"&&outputbw_opt.empty()){
207 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
208 throw(errorStream.str());
211 if(model_opt.size()<observation_opt.size()){
212 errorStream <<
"Error: sequence of models should be larger than observations" << endl;
213 throw(errorStream.str());
215 if(tmodel_opt.size()!=model_opt.size()){
216 if(tmodel_opt.empty())
217 cout <<
"Warning: time sequence is not provided, self generating time sequence from 0 to " << model_opt.size() << endl;
219 cout <<
"Warning: time sequence provided (" << tmodel_opt.size() <<
") does not match number of model raster datasets (" << model_opt.size() <<
")" << endl;
221 for(
int tindex=0;tindex<model_opt.size();++tindex)
222 tmodel_opt.push_back(tindex);
224 if(tobservation_opt.size()!=observation_opt.size()){
225 errorStream <<
"Error: time sequence for observation must match size of observation dataset" << endl;
226 throw(errorStream.str());
230 catch(
string errorString){
231 std::cout << errorString << std::endl;
236 stat.setNoDataValues(modnodata_opt);
245 imgReaderObs.open(observation_opt[0]);
247 int ncol=imgReaderObs.nrOfCol();
248 int nrow=imgReaderObs.nrOfRow();
249 if(projection_opt.empty())
250 projection_opt.push_back(imgReaderObs.getProjection());
251 double geotransform[6];
252 imgReaderObs.getGeoTransform(geotransform);
254 string imageType=imgReaderObs.getImageType();
255 if(oformat_opt.size())
256 imageType=oformat_opt[0];
257 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
258 string theInterleave=
"INTERLEAVE=";
259 theInterleave+=imgReaderObs.getInterleave();
260 option_opt.push_back(theInterleave);
263 if(down_opt.empty()){
264 imgReaderModel1.open(model_opt[0]);
265 double resModel=imgReaderModel1.getDeltaX();
266 double resObs=imgReaderObs.getDeltaX();
267 int down=
static_cast<int>(ceil(resModel/resObs));
270 down_opt.push_back(down);
271 imgReaderModel1.close();
273 imgReaderObs.close();
275 if(regSensor_opt.empty())
276 regSensor_opt.push_back(1.0/down_opt[0]);
301 const char* pszMessage;
302 void* pProgressArg=NULL;
303 GDALProgressFunc pfnProgress=GDALTermProgress;
306 imgreg.setDown(down_opt[0]);
307 imgreg.setThreshold(threshold_opt[0]);
309 double c0modGlobal=0;
310 double c1modGlobal=1;
316 double errObs=uncertNodata_opt[0];
318 vector<int> relobsindex;
322 for(
int tindex=0;tindex<tobservation_opt.size();++tindex){
323 vector<int>::iterator modit;
324 modit=upper_bound(tmodel_opt.begin(),tmodel_opt.end(),tobservation_opt[tindex]);
325 int relpos=modit-tmodel_opt.begin()-1;
327 relobsindex.push_back(relpos);
329 cout <<
"observation " << tindex <<
": " <<
"relative position in model time series is " << relpos <<
", date of observation is (tobservation_opt[tindex]): " << tobservation_opt[tindex] <<
", relobsindex.back(): " << relobsindex.back() <<
", filename observation: " << observation_opt[tindex] <<
", filename of corresponding model: " << model_opt[relpos] << endl;
334 int ndigit=log(1.0*tmodel_opt.back())/log(10.0)+1;
339 if(find(direction_opt.begin(),direction_opt.end(),
"forward")!=direction_opt.end()){
341 cout <<
"Running forward model" << endl;
345 if(outputfw_opt.size()==model_opt.size()){
346 output=outputfw_opt[0];
349 ostringstream outputstream;
350 outputstream << outputfw_opt[0] <<
"_";
351 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[0];
352 outputstream <<
".tif";
355 output=outputstream.str();
358 cout <<
"Opening image " << output <<
" for writing " << endl;
360 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
361 imgWriterEst.setProjectionProj4(projection_opt[0]);
362 imgWriterEst.setGeoTransform(geotransform);
363 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
366 cout <<
"processing time " << tmodel_opt[0] << endl;
367 if(obsindex<relobsindex.size())
368 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
370 cout <<
"There is no next observation" << endl;
374 imgReaderModel1.open(model_opt[0]);
375 imgReaderModel1.setNoData(modnodata_opt);
376 if(modoffset_opt.size())
377 imgReaderModel1.setOffset(modoffset_opt[0]);
378 if(modscale_opt.size())
379 imgReaderModel1.setScale(modscale_opt[0]);
381 catch(
string errorString){
382 cerr << errorString << endl;
385 cerr <<
"Error opening file " << model_opt[0] << endl;
389 GDALRasterBand* rasterBand;
390 rasterBand=imgReaderModel1.getRasterBand(0);
391 double minValue, maxValue, meanValue, stdDev;
393 rasterBand->ComputeStatistics(0,&minValue,&maxValue,&meanValue,&stdDev,pfnProgress,pProgressData);
396 if(relobsindex[0]>0){
399 cout <<
"write first model as output" << endl;
400 for(
int irow=0;irow<nrow;++irow){
401 vector<double> estReadBuffer;
402 vector<double> estWriteBuffer(ncol);
403 vector<double> uncertWriteBuffer(ncol);
405 imgWriterEst.image2geo(0,irow,geox,geoy);
406 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
407 if(modRow<0||modRow>=imgReaderModel1.nrOfRow()){
408 cerr <<
"Error: geo coordinates (" << geox <<
"," << geoy <<
") not covered in model image " << imgReaderModel1.getFileName() << endl;
409 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
412 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
417 for(
int icol=0;icol<ncol;++icol){
418 imgWriterEst.image2geo(icol,irow,geox,geoy);
419 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
420 double modValue=estReadBuffer[modCol];
421 if(imgReaderModel1.isNoData(modValue)){
422 estWriteBuffer[icol]=obsnodata_opt[0];
423 uncertWriteBuffer[icol]=uncertNodata_opt[0];
427 estWriteBuffer[icol]=modValue;
428 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
431 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
432 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
434 catch(
string errorString){
435 cerr << errorString << endl;
438 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
444 cout <<
"we have a measurement at initial time" << endl;
445 imgReaderObs.open(observation_opt[0]);
446 imgReaderObs.getGeoTransform(geotransform);
447 imgReaderObs.setNoData(obsnodata_opt);
448 if(obsoffset_opt.size())
449 imgReaderObs.setOffset(obsoffset_opt[0]);
450 if(obsscale_opt.size())
451 imgReaderObs.setScale(obsscale_opt[0]);
453 if(regSensor_opt[0]>0){
454 errObs=regSensor_opt[0]*imgreg.getRMSE(imgReaderModel1,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
466 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
468 for(
int irow=0;irow<nrow;++irow){
469 vector<double> estReadBuffer;
470 imgWriterEst.image2geo(0,irow,geox,geoy);
471 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
472 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
473 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
474 vector<double> obsLineBuffer;
475 vector<double> estWriteBuffer(ncol);
476 vector<double> uncertWriteBuffer(ncol);
477 vector<double> uncertObsLineBuffer;
480 imgReaderObs.readData(obsLineBuffer,GDT_Float64,irow,0);
482 if(imgReaderObs.nrOfBand()>1)
483 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
485 for(
int icol=0;icol<ncol;++icol){
486 imgWriterEst.image2geo(icol,irow,geox,geoy);
487 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
488 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
489 double modValue=estReadBuffer[modCol];
490 if(imgReaderModel1.isNoData(modValue)){
491 estWriteBuffer[icol]=obsLineBuffer[icol];
492 if(imgReaderObs.isNoData(obsLineBuffer[icol])){
493 estWriteBuffer[icol]=obsnodata_opt[0];
494 uncertWriteBuffer[icol]=uncertNodata_opt[0];
496 else if(uncertObsLineBuffer.size()>icol)
497 uncertWriteBuffer[icol]=uncertObsLineBuffer[icol];
499 uncertWriteBuffer[icol]=uncertObs_opt[0];
502 double errMod=uncertModel_opt[0]*stdDev;
503 errMod*=regTime_opt[0];
510 estWriteBuffer[icol]=modValue;
511 double totalUncertainty=errMod;
520 uncertWriteBuffer[icol]=totalUncertainty;
524 if(!imgReaderObs.isNoData(obsLineBuffer[icol])){
526 double uncertObs=uncertObs_opt[0];
527 if(uncertObsLineBuffer.size()>icol)
528 uncertObs=uncertObsLineBuffer[icol];
529 else if(weight_opt.size()||deltaObs_opt.size()){
530 vector<double> obsWindowBuffer;
531 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
532 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
533 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
534 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
536 imgReaderObs.readDataBlock(obsWindowBuffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
538 statobs.setNoDataValues(obsnodata_opt);
539 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
540 double difference=obsMeanValue-modValue;
542 double relativeDifference=difference/modValue;
543 if(deltaObs_opt.size()){
544 assert(deltaObs_opt.size()>1);
545 if(100*relativeDifference<deltaObs_opt[0])
547 else if(100*relativeDifference>deltaObs_opt[1])
550 else if(weight_opt.size()){
551 assert(weight_opt.size()>1);
552 if(obsMeanValue<modValue)
553 uncertObs=weight_opt[0]*relativeDifference;
554 else if(obsMeanValue>modValue)
555 uncertObs=weight_opt[1]*relativeDifference;
561 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
564 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
565 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
567 assert(kalmanGain<=1);
568 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
569 uncertWriteBuffer[icol]*=(1-kalmanGain);
572 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
573 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
575 imgReaderObs.close();
578 imgReaderModel1.close();
579 imgWriterEst.close();
581 for(
int modindex=1;modindex<model_opt.size();++modindex){
583 cout <<
"processing time " << tmodel_opt[modindex] << endl;
584 if(obsindex<relobsindex.size())
585 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
587 cout <<
"There is no next observation" << endl;
590 if(outputfw_opt.size()==model_opt.size())
591 output=outputfw_opt[modindex];
593 ostringstream outputstream;
594 outputstream << outputfw_opt[0] <<
"_";
595 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
596 outputstream <<
".tif";
598 output=outputstream.str();
602 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
603 imgWriterEst.setProjectionProj4(projection_opt[0]);
604 imgWriterEst.setGeoTransform(geotransform);
605 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
608 imgReaderModel1.open(model_opt[modindex-1]);
609 imgReaderModel1.setNoData(modnodata_opt);
610 if(modoffset_opt.size())
611 imgReaderModel1.setOffset(modoffset_opt[0]);
612 if(modscale_opt.size())
613 imgReaderModel1.setScale(modscale_opt[0]);
614 imgReaderModel2.open(model_opt[modindex]);
615 imgReaderModel2.setNoData(modnodata_opt);
616 if(modoffset_opt.size())
617 imgReaderModel2.setOffset(modoffset_opt[0]);
618 if(modscale_opt.size())
619 imgReaderModel2.setScale(modscale_opt[0]);
624 pfnProgress(progress,pszMessage,pProgressArg);
627 cout <<
"Calculating regression for " << imgReaderModel1.getFileName() <<
" " << imgReaderModel2.getFileName() << endl;
629 double errMod=imgreg.getRMSE(imgReaderModel1,imgReaderModel2,c0modGlobal,c1modGlobal,0,0);
630 errMod*=regTime_opt[0];
634 cout <<
"c0modGlobal, c1modGlobal: " << c0modGlobal <<
", " << c1modGlobal << endl;
637 if(obsindex<relobsindex.size()){
638 update=(relobsindex[obsindex]==modindex);
642 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
644 imgReaderObs.open(observation_opt[obsindex]);
645 imgReaderObs.getGeoTransform(geotransform);
646 imgReaderObs.setNoData(obsnodata_opt);
647 if(obsoffset_opt.size())
648 imgReaderObs.setOffset(obsoffset_opt[0]);
649 if(obsscale_opt.size())
650 imgReaderObs.setScale(obsscale_opt[0]);
653 cout <<
"Calculating regression for " << imgReaderModel2.getFileName() <<
" " << imgReaderObs.getFileName() << endl;
654 if(regSensor_opt[0]>0){
655 errObs=regSensor_opt[0]*imgreg.getRMSE(imgReaderModel2,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
667 cout <<
"c0obs, c1obs, errObs: " << c0obs <<
", " << c1obs <<
", " << errObs << endl;
671 if(outputfw_opt.size()==model_opt.size())
672 input=outputfw_opt[modindex-1];
674 ostringstream outputstream;
675 outputstream << outputfw_opt[0] <<
"_";
676 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex-1];
677 outputstream <<
".tif";
679 input=outputstream.str();
682 cout <<
"opening " << input << endl;
684 imgReaderEst.setNoData(obsnodata_opt);
685 if(obsoffset_opt.size())
686 imgReaderEst.setOffset(obsoffset_opt[0]);
687 if(obsscale_opt.size())
688 imgReaderEst.setScale(obsscale_opt[0]);
690 vector< vector<double> > obsLineVector(down_opt[0]);
691 vector<double> obsLineBuffer;
692 vector<double> obsWindowBuffer;
693 vector<double> model1LineBuffer;
694 vector<double> model2LineBuffer;
695 vector<double> model1buffer;
696 vector<double> model2buffer;
697 vector<double> uncertObsLineBuffer;
698 vector<double> estReadBuffer;
700 vector<double> uncertReadBuffer;
701 vector<double> estWriteBuffer(ncol);
702 vector<double> uncertWriteBuffer(ncol);
708 cout <<
"initialize obsLineVector" << endl;
709 assert(down_opt[0]%2);
710 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
712 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
714 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
717 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
719 imgReaderEst.readData(estReadBuffer,GDT_Float64,irow,0);
720 imgReaderEst.readData(uncertReadBuffer,GDT_Float64,irow,1);
722 imgReaderEst.image2geo(0,irow,geox,geoy);
723 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
724 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
725 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,0);
727 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
728 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
729 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,0);
732 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
733 obsLineVector.erase(obsLineVector.begin());
734 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
735 obsLineVector.push_back(obsLineBuffer);
736 obsLineBuffer=obsLineVector[down_opt[0]/2];
738 if(imgReaderObs.nrOfBand()>1)
739 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
742 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
743 imgReaderEst.image2geo(icol,irow,geox,geoy);
744 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
745 int maxCol=(icol+down_opt[0]/2<imgReaderEst.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderEst.nrOfCol()-1;
746 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
747 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
749 obsWindowBuffer.clear();
750 for(
int iline=0;iline<obsLineVector.size();++iline){
751 for(
int isample=minCol;isample<=maxCol;++isample){
752 assert(isample<obsLineVector[iline].size());
753 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
758 double estValue=estReadBuffer[icol];
759 double estMeanValue=0;
762 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
763 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
764 double modValue=model2LineBuffer[modCol];
765 bool estNodata=imgReaderEst.isNoData(estValue);
768 if(imgReaderModel2.isNoData(modValue)){
769 estWriteBuffer[icol]=obsnodata_opt[0];
770 uncertWriteBuffer[icol]=uncertNodata_opt[0];
773 estWriteBuffer[icol]=modValue;
774 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
781 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
782 maxCol=(modCol+window_opt[0]/2<imgReaderModel2.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel2.nrOfCol()-1;
783 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
784 maxRow=(modRow+window_opt[0]/2<imgReaderModel2.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel2.nrOfRow()-1;
785 imgReaderModel2.readDataBlock(model2buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
787 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
788 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
789 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
790 maxCol=(modCol+window_opt[0]/2<imgReaderModel1.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel1.nrOfCol()-1;
791 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
792 maxRow=(modRow+window_opt[0]/2<imgReaderModel1.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel1.nrOfRow()-1;
793 imgReaderModel1.readDataBlock(model1buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
796 catch(
string errorString){
797 cerr <<
"Error reading data block for " << minCol <<
"-" << maxCol <<
", " << minRow <<
"-" << maxRow << endl;
800 vector<double>::iterator it1=model1buffer.begin();
801 vector<double>::iterator it2=model2buffer.begin();
802 while(it1!=model1buffer.end()&&it2!=model2buffer.end()){
804 bool modNodata=
false;
805 modNodata=modNodata||imgReaderModel1.isNoData(*it1);
806 modNodata=modNodata||imgReaderModel2.isNoData(*it2);
808 model1buffer.erase(it1);
809 model2buffer.erase(it2);
816 if(model1buffer.size()>minreg_opt[0]&&model2buffer.size()>minreg_opt[0]){
817 errMod=stat.linear_regression_err(model1buffer,model2buffer,c0mod,c1mod);
818 errMod*=regTime_opt[0];
829 double certNorm=(errMod*errMod+errObs*errObs);
830 double certMod=errObs*errObs/certNorm;
831 double certObs=errMod*errMod/certNorm;
832 double regTime=(c0mod+c1mod*estValue)*certObs;
833 double regSensor=(c0obs+c1obs*modValue)*certMod;
835 estWriteBuffer[icol]=regTime+regSensor;
844 double totalUncertainty=0;
845 if(errMod<eps_opt[0])
846 totalUncertainty=errObs;
847 else if(errObs<eps_opt[0])
848 totalUncertainty=errMod;
850 totalUncertainty=1.0/errMod/errMod+1/errObs/errObs;
851 totalUncertainty=sqrt(1.0/totalUncertainty);
853 uncertWriteBuffer[icol]=totalUncertainty+uncertReadBuffer[icol];
856 if(update&&!imgReaderObs.isNoData(obsLineBuffer[icol])){
858 double uncertObs=uncertObs_opt[0];
859 if(uncertObsLineBuffer.size()>icol)
860 uncertObs=uncertObsLineBuffer[icol];
861 else if(weight_opt.size()>1||deltaObs_opt.size()){
863 statobs.setNoDataValues(obsnodata_opt);
864 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
865 double difference=obsMeanValue-modValue;
867 double relativeDifference=difference/modValue;
868 if(deltaObs_opt.size()){
869 assert(deltaObs_opt.size()>1);
870 if(100*relativeDifference<deltaObs_opt[0])
872 else if(100*relativeDifference>deltaObs_opt[1])
875 else if(weight_opt.size()){
876 assert(weight_opt.size()>1);
877 if(obsMeanValue<modValue)
878 uncertObs=weight_opt[0]*relativeDifference;
879 else if(obsMeanValue>modValue)
880 uncertObs=weight_opt[1]*relativeDifference;
886 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
889 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
890 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
892 assert(kalmanGain<=1);
893 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
894 uncertWriteBuffer[icol]*=(1-kalmanGain);
897 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
898 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
899 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
900 pfnProgress(progress,pszMessage,pProgressArg);
903 imgWriterEst.close();
904 imgReaderEst.close();
907 imgReaderObs.close();
910 imgReaderModel1.close();
911 imgReaderModel2.close();
914 if(find(direction_opt.begin(),direction_opt.end(),
"backward")!=direction_opt.end()){
916 cout <<
"Running backward model" << endl;
917 obsindex=relobsindex.size()-1;
920 if(outputbw_opt.size()==model_opt.size())
921 output=outputbw_opt.back();
923 ostringstream outputstream;
924 outputstream << outputbw_opt[0] <<
"_";
925 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt.back();
926 outputstream <<
".tif";
928 output=outputstream.str();
931 cout <<
"Opening image " << output <<
" for writing " << endl;
932 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
933 imgWriterEst.setProjectionProj4(projection_opt[0]);
934 imgWriterEst.setGeoTransform(geotransform);
935 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
938 cout <<
"processing time " << tmodel_opt.back() << endl;
939 if(obsindex<relobsindex.size())
940 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
942 cout <<
"There is no next observation" << endl;
946 imgReaderModel1.open(model_opt.back());
947 imgReaderModel1.setNoData(modnodata_opt);
948 if(modoffset_opt.size())
949 imgReaderModel1.setOffset(modoffset_opt[0]);
950 if(modscale_opt.size())
951 imgReaderModel1.setScale(modscale_opt[0]);
953 catch(
string errorString){
954 cerr << errorString << endl;
957 cerr <<
"Error opening file " << model_opt[0] << endl;
961 GDALRasterBand* rasterBand;
962 rasterBand=imgReaderModel1.getRasterBand(0);
963 double minValue, maxValue, meanValue, stdDev;
965 rasterBand->ComputeStatistics(0,&minValue,&maxValue,&meanValue,&stdDev,pfnProgress,pProgressData);
968 if(relobsindex.back()<model_opt.size()-1){
971 cout <<
"write last model as output" << endl;
972 for(
int irow=0;irow<nrow;++irow){
973 vector<double> estReadBuffer;
974 vector<double> estWriteBuffer(ncol);
975 vector<double> uncertWriteBuffer(ncol);
977 imgWriterEst.image2geo(0,irow,geox,geoy);
978 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
979 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
981 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
986 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
987 imgWriterEst.image2geo(icol,irow,geox,geoy);
988 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
989 double modValue=estReadBuffer[modCol];
990 if(imgReaderModel1.isNoData(modValue)){
991 estWriteBuffer[icol]=obsnodata_opt[0];
992 uncertWriteBuffer[icol]=uncertNodata_opt[0];
995 estWriteBuffer[icol]=modValue;
996 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
999 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1000 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1002 catch(
string errorString){
1003 cerr << errorString << endl;
1006 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
1012 cout <<
"we have an measurement at end time" << endl;
1013 imgReaderObs.open(observation_opt.back());
1014 imgReaderObs.getGeoTransform(geotransform);
1015 imgReaderObs.setNoData(obsnodata_opt);
1016 if(obsoffset_opt.size())
1017 imgReaderObs.setOffset(obsoffset_opt[0]);
1018 if(obsscale_opt.size())
1019 imgReaderObs.setScale(obsscale_opt[0]);
1021 if(regSensor_opt[0]>0){
1022 errObs=regSensor_opt[0]*imgreg.getRMSE(imgReaderModel1,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
1034 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
1036 for(
int irow=0;irow<nrow;++irow){
1037 vector<double> estReadBuffer;
1038 imgWriterEst.image2geo(0,irow,geox,geoy);
1039 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1040 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1041 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow);
1042 vector<double> obsLineBuffer;
1043 vector<double> estWriteBuffer(ncol);
1044 vector<double> uncertWriteBuffer(ncol);
1045 vector<double> uncertObsLineBuffer;
1048 imgReaderObs.readData(obsLineBuffer,GDT_Float64,irow,0);
1050 if(imgReaderObs.nrOfBand()>1)
1051 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1053 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1054 imgWriterEst.image2geo(icol,irow,geox,geoy);
1055 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1056 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1057 double modValue=estReadBuffer[modCol];
1058 if(imgReaderModel1.isNoData(modValue)){
1059 estWriteBuffer[icol]=obsLineBuffer[icol];
1060 if(imgReaderObs.isNoData(obsLineBuffer[icol])){
1061 estWriteBuffer[icol]=obsnodata_opt[0];
1062 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1064 else if(uncertObsLineBuffer.size()>icol)
1065 uncertWriteBuffer[icol]=uncertObsLineBuffer[icol];
1067 uncertWriteBuffer[icol]=uncertObs_opt[0];
1070 double errMod=uncertModel_opt[0]*stdDev;
1071 errMod*=regTime_opt[0];
1078 estWriteBuffer[icol]=modValue;
1079 double totalUncertainty=errMod;
1088 uncertWriteBuffer[icol]=totalUncertainty;
1091 if(!imgReaderObs.isNoData(obsLineBuffer[icol])){
1092 double kalmanGain=1;
1093 double uncertObs=uncertObs_opt[0];
1094 if(uncertObsLineBuffer.size()>icol)
1095 uncertObs=uncertObsLineBuffer[icol];
1096 else if(weight_opt.size()>1||deltaObs_opt.size()){
1097 vector<double> obsWindowBuffer;
1098 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
1099 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
1100 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
1101 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
1103 imgReaderObs.readDataBlock(obsWindowBuffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
1105 statobs.setNoDataValues(obsnodata_opt);
1106 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
1107 double difference=obsMeanValue-modValue;
1109 double relativeDifference=difference/modValue;
1110 if(deltaObs_opt.size()){
1111 assert(deltaObs_opt.size()>1);
1112 if(100*relativeDifference<deltaObs_opt[0])
1114 else if(100*relativeDifference>deltaObs_opt[1])
1117 else if(weight_opt.size()){
1118 assert(weight_opt.size()>1);
1119 if(obsMeanValue<modValue)
1120 uncertObs=weight_opt[0]*relativeDifference;
1121 else if(obsMeanValue>modValue)
1122 uncertObs=weight_opt[1]*relativeDifference;
1127 if(verbose_opt[0]>1)
1128 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
1131 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
1132 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
1134 assert(kalmanGain<=1);
1135 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1136 uncertWriteBuffer[icol]*=(1-kalmanGain);
1139 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1140 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1142 imgReaderObs.close();
1145 imgReaderModel1.close();
1146 imgWriterEst.close();
1148 for(
int modindex=model_opt.size()-2;modindex>=0;--modindex){
1150 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1151 if(obsindex<relobsindex.size())
1152 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1154 cout <<
"There is no next observation" << endl;
1157 if(outputbw_opt.size()==model_opt.size())
1158 output=outputbw_opt[modindex];
1160 ostringstream outputstream;
1161 outputstream << outputbw_opt[0] <<
"_";
1162 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1163 outputstream <<
".tif";
1165 output=outputstream.str();
1169 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
1170 imgWriterEst.setProjectionProj4(projection_opt[0]);
1171 imgWriterEst.setGeoTransform(geotransform);
1172 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1175 imgReaderModel1.open(model_opt[modindex+1]);
1176 imgReaderModel1.setNoData(modnodata_opt);
1177 if(modoffset_opt.size())
1178 imgReaderModel1.setOffset(modoffset_opt[0]);
1179 if(modscale_opt.size())
1180 imgReaderModel1.setScale(modscale_opt[0]);
1181 imgReaderModel2.open(model_opt[modindex]);
1182 imgReaderModel2.setNoData(modnodata_opt);
1183 if(modoffset_opt.size())
1184 imgReaderModel2.setOffset(modoffset_opt[0]);
1185 if(modscale_opt.size())
1186 imgReaderModel2.setScale(modscale_opt[0]);
1191 pfnProgress(progress,pszMessage,pProgressArg);
1194 cout <<
"Calculating regression for " << imgReaderModel1.getFileName() <<
" " << imgReaderModel2.getFileName() << endl;
1196 double errMod=imgreg.getRMSE(imgReaderModel1,imgReaderModel2,c0modGlobal,c1modGlobal,0,0);
1197 errMod*=regTime_opt[0];
1201 cout <<
"c0modGlobal, c1modGlobal: " << c0modGlobal <<
", " << c1modGlobal << endl;
1204 if(obsindex<relobsindex.size()){
1205 update=(relobsindex[obsindex]==modindex);
1209 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
1211 imgReaderObs.open(observation_opt[obsindex]);
1212 imgReaderObs.getGeoTransform(geotransform);
1213 imgReaderObs.setNoData(obsnodata_opt);
1214 if(obsoffset_opt.size())
1215 imgReaderObs.setOffset(obsoffset_opt[0]);
1216 if(obsscale_opt.size())
1217 imgReaderObs.setScale(obsscale_opt[0]);
1220 cout <<
"Calculating regression for " << imgReaderModel2.getFileName() <<
" " << imgReaderObs.getFileName() << endl;
1221 if(regSensor_opt[0]>0){
1222 errObs=regSensor_opt[0]*imgreg.getRMSE(imgReaderModel2,imgReaderObs,c0obs,c1obs,0,0,verbose_opt[0]);
1234 cout <<
"c0obs, c1obs: " << c0obs <<
", " << c1obs << endl;
1238 if(outputbw_opt.size()==model_opt.size())
1239 input=outputbw_opt[modindex+1];
1241 ostringstream outputstream;
1242 outputstream << outputbw_opt[0] <<
"_";
1243 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex+1];
1244 outputstream <<
".tif";
1246 input=outputstream.str();
1249 imgReaderEst.setNoData(obsnodata_opt);
1250 if(obsoffset_opt.size())
1251 imgReaderEst.setOffset(obsoffset_opt[0]);
1252 if(obsscale_opt.size())
1253 imgReaderEst.setScale(obsscale_opt[0]);
1255 vector< vector<double> > obsLineVector(down_opt[0]);
1256 vector<double> obsLineBuffer;
1257 vector<double> obsWindowBuffer;
1258 vector<double> model1LineBuffer;
1259 vector<double> model2LineBuffer;
1260 vector<double> model1buffer;
1261 vector<double> model2buffer;
1262 vector<double> uncertObsLineBuffer;
1263 vector<double> estReadBuffer;
1265 vector<double> uncertReadBuffer;
1266 vector<double> estWriteBuffer(ncol);
1267 vector<double> uncertWriteBuffer(ncol);
1272 assert(down_opt[0]%2);
1273 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
1275 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,0);
1277 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,0);
1280 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
1281 assert(irow<imgReaderEst.nrOfRow());
1283 imgReaderEst.readData(estReadBuffer,GDT_Float64,irow,0);
1284 imgReaderEst.readData(uncertReadBuffer,GDT_Float64,irow,1);
1286 imgReaderEst.image2geo(0,irow,geox,geoy);
1287 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1288 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1289 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,0);
1291 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1292 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1293 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,0);
1296 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
1297 obsLineVector.erase(obsLineVector.begin());
1298 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,0);
1299 obsLineVector.push_back(obsLineBuffer);
1300 obsLineBuffer=obsLineVector[down_opt[0]/2];
1302 if(imgReaderObs.nrOfBand()>1)
1303 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1306 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1307 imgReaderEst.image2geo(icol,irow,geox,geoy);
1308 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
1309 int maxCol=(icol+down_opt[0]/2<imgReaderEst.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderEst.nrOfCol()-1;
1310 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
1311 int maxRow=(irow+down_opt[0]/2<imgReaderEst.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderEst.nrOfRow()-1;
1313 obsWindowBuffer.clear();
1314 for(
int iline=0;iline<obsLineVector.size();++iline){
1315 for(
int isample=minCol;isample<=maxCol;++isample){
1316 assert(isample<obsLineVector[iline].size());
1317 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
1322 double estValue=estReadBuffer[icol];
1323 double estMeanValue=0;
1326 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1327 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1328 double modValue=model2LineBuffer[modCol];
1329 bool estNodata=imgReaderEst.isNoData(estValue);
1332 if(imgReaderModel2.isNoData(modValue)){
1333 estWriteBuffer[icol]=obsnodata_opt[0];
1334 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1337 estWriteBuffer[icol]=modValue;
1338 uncertWriteBuffer[icol]=uncertModel_opt[0]*stdDev;
1342 if(window_opt[0]>0){
1345 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
1346 maxCol=(modCol+window_opt[0]/2<imgReaderModel2.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel2.nrOfCol()-1;
1347 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
1348 maxRow=(modRow+window_opt[0]/2<imgReaderModel2.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel2.nrOfRow()-1;
1349 imgReaderModel2.readDataBlock(model2buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
1351 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1352 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1353 minCol=(modCol>window_opt[0]/2) ? modCol-window_opt[0]/2 : 0;
1354 maxCol=(modCol+window_opt[0]/2<imgReaderModel1.nrOfCol()) ? modCol+window_opt[0]/2 : imgReaderModel1.nrOfCol()-1;
1355 minRow=(modRow>window_opt[0]/2) ? modRow-window_opt[0]/2 : 0;
1356 maxRow=(modRow+window_opt[0]/2<imgReaderModel1.nrOfRow()) ? modRow+window_opt[0]/2 : imgReaderModel1.nrOfRow()-1;
1357 imgReaderModel1.readDataBlock(model1buffer,GDT_Float64,minCol,maxCol,minRow,maxRow,0);
1360 catch(
string errorString){
1361 cerr <<
"Error reading data block for " << minCol <<
"-" << maxCol <<
", " << minRow <<
"-" << maxRow << endl;
1364 vector<double>::iterator it1=model1buffer.begin();
1365 vector<double>::iterator it2=model2buffer.begin();
1366 while(it1!=model1buffer.end()&&it2!=model2buffer.end()){
1368 bool modNodata=
false;
1369 modNodata=modNodata||imgReaderModel1.isNoData(*it1);
1370 modNodata=modNodata||imgReaderModel2.isNoData(*it2);
1372 model1buffer.erase(it1);
1373 model2buffer.erase(it2);
1380 if(model1buffer.size()>minreg_opt[0]&&model2buffer.size()>minreg_opt[0]){
1381 errMod=stat.linear_regression_err(model1buffer,model2buffer,c0mod,c1mod);
1382 errMod*=regTime_opt[0];
1393 double certNorm=(errMod*errMod+errObs*errObs);
1394 double certMod=errObs*errObs/certNorm;
1395 double certObs=errMod*errMod/certNorm;
1396 double regTime=(c0mod+c1mod*estValue)*certObs;
1399 double regSensor=(c0obs+c1obs*modValue)*certMod;
1400 estWriteBuffer[icol]=regTime+regSensor;
1401 double totalUncertainty=0;
1402 if(errMod<eps_opt[0])
1403 totalUncertainty=errObs;
1404 else if(errObs<eps_opt[0])
1405 totalUncertainty=errMod;
1407 totalUncertainty=1.0/errMod/errMod+1/errObs/errObs;
1408 totalUncertainty=sqrt(1.0/totalUncertainty);
1410 uncertWriteBuffer[icol]=totalUncertainty+uncertReadBuffer[icol];
1413 if(update&&!imgReaderObs.isNoData(obsLineBuffer[icol])){
1414 double kalmanGain=1;
1415 double uncertObs=uncertObs_opt[0];
1416 if(uncertObsLineBuffer.size()>icol)
1417 uncertObs=uncertObsLineBuffer[icol];
1418 else if(weight_opt.size()>1||deltaObs_opt.size()){
1420 statobs.setNoDataValues(obsnodata_opt);
1421 double obsMeanValue=(statobs.mean(obsWindowBuffer)-c0obs)/c1obs;
1422 double difference=obsMeanValue-modValue;
1424 double relativeDifference=difference/modValue;
1425 if(deltaObs_opt.size()){
1426 assert(deltaObs_opt.size()>1);
1427 if(100*relativeDifference<deltaObs_opt[0])
1429 else if(100*relativeDifference>deltaObs_opt[1])
1432 else if(weight_opt.size()){
1433 assert(weight_opt.size()>1);
1434 if(obsMeanValue<modValue)
1435 uncertObs=weight_opt[0]*relativeDifference;
1436 else if(obsMeanValue>modValue)
1437 uncertObs=weight_opt[1]*relativeDifference;
1442 if(verbose_opt[0]>1)
1443 cout <<
"obsMeanValue:" << obsMeanValue <<
", modValue: " << modValue << endl;
1446 if((uncertWriteBuffer[icol]+uncertObs)>eps_opt[0])
1447 kalmanGain=uncertWriteBuffer[icol]/(uncertWriteBuffer[icol]+uncertObs);
1449 assert(kalmanGain<=1);
1450 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1451 uncertWriteBuffer[icol]*=(1-kalmanGain);
1454 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1455 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1456 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
1457 pfnProgress(progress,pszMessage,pProgressArg);
1460 imgWriterEst.close();
1461 imgReaderEst.close();
1464 imgReaderObs.close();
1467 imgReaderModel1.close();
1468 imgReaderModel2.close();
1471 if(find(direction_opt.begin(),direction_opt.end(),
"smooth")!=direction_opt.end()){
1473 cout <<
"Running smooth model" << endl;
1475 for(
int modindex=0;modindex<model_opt.size();++modindex){
1477 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1478 if(obsindex<relobsindex.size())
1479 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1481 cout <<
"There is no next observation" << endl;
1484 if(outputfb_opt.size()==model_opt.size())
1485 output=outputfb_opt[modindex];
1487 ostringstream outputstream;
1488 outputstream << outputfb_opt[0] <<
"_";
1489 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1490 outputstream <<
".tif";
1492 output=outputstream.str();
1496 imgWriterEst.open(output,ncol,nrow,2,GDT_Float32,imageType,option_opt);
1497 imgWriterEst.setProjectionProj4(projection_opt[0]);
1498 imgWriterEst.setGeoTransform(geotransform);
1499 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1506 if(outputfw_opt.size()==model_opt.size())
1507 inputfw=outputfw_opt[modindex];
1509 ostringstream outputstream;
1510 outputstream << outputfw_opt[0] <<
"_";
1511 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1512 outputstream <<
".tif";
1514 inputfw=outputstream.str();
1516 if(outputbw_opt.size()==model_opt.size())
1517 inputbw=outputbw_opt[modindex];
1519 ostringstream outputstream;
1520 outputstream << outputbw_opt[0] <<
"_";
1521 outputstream << setfill(
'0') << setw(ndigit) << tmodel_opt[modindex];
1522 outputstream <<
".tif";
1524 inputbw=outputstream.str();
1528 imgReaderForward.setNoData(obsnodata_opt);
1529 if(obsoffset_opt.size())
1530 imgReaderForward.setOffset(obsoffset_opt[0]);
1531 if(obsscale_opt.size())
1532 imgReaderForward.setScale(obsscale_opt[0]);
1533 imgReaderBackward.setNoData(obsnodata_opt);
1534 if(obsoffset_opt.size())
1535 imgReaderBackward.setOffset(obsoffset_opt[0]);
1536 if(obsscale_opt.size())
1537 imgReaderBackward.setScale(obsscale_opt[0]);
1539 vector<double> estForwardBuffer;
1540 vector<double> estBackwardBuffer;
1541 vector<double> uncertObsLineBuffer;
1542 vector<double> uncertForwardBuffer;
1543 vector<double> uncertBackwardBuffer;
1544 vector<double> uncertReadBuffer;
1545 vector<double> estWriteBuffer(ncol);
1546 vector<double> uncertWriteBuffer(ncol);
1550 if(obsindex<relobsindex.size()){
1551 update=(relobsindex[obsindex]==modindex);
1556 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
1557 imgReaderObs.open(observation_opt[obsindex]);
1558 imgReaderObs.getGeoTransform(geotransform);
1559 imgReaderObs.setNoData(obsnodata_opt);
1560 if(obsoffset_opt.size())
1561 imgReaderObs.setOffset(obsoffset_opt[0]);
1562 if(obsscale_opt.size())
1563 imgReaderObs.setScale(obsscale_opt[0]);
1567 pfnProgress(progress,pszMessage,pProgressArg);
1569 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
1570 assert(irow<imgReaderForward.nrOfRow());
1571 assert(irow<imgReaderBackward.nrOfRow());
1572 imgReaderForward.readData(estForwardBuffer,GDT_Float64,irow,0);
1573 imgReaderBackward.readData(estBackwardBuffer,GDT_Float64,irow,0);
1574 imgReaderForward.readData(uncertForwardBuffer,GDT_Float64,irow,1);
1575 imgReaderBackward.readData(uncertBackwardBuffer,GDT_Float64,irow,1);
1578 imgReaderObs.readData(estWriteBuffer,GDT_Float64,irow,0);
1579 if(imgReaderObs.nrOfBand()>1)
1580 imgReaderObs.readData(uncertObsLineBuffer,GDT_Float64,irow,1);
1584 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1585 imgWriterEst.image2geo(icol,irow,geox,geoy);
1586 double A=estForwardBuffer[icol];
1587 double B=estBackwardBuffer[icol];
1588 double C=uncertForwardBuffer[icol]*uncertForwardBuffer[icol];
1589 double D=uncertBackwardBuffer[icol]*uncertBackwardBuffer[icol];
1590 double uncertObs=uncertObs_opt[0];
1599 double noemer=(C+D);
1601 if(imgReaderForward.isNoData(A)&&imgReaderBackward.isNoData(B)){
1602 estWriteBuffer[icol]=obsnodata_opt[0];
1603 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1605 else if(imgReaderForward.isNoData(A)){
1606 estWriteBuffer[icol]=B;
1607 uncertWriteBuffer[icol]=uncertBackwardBuffer[icol];
1609 else if(imgReaderForward.isNoData(B)){
1610 estWriteBuffer[icol]=A;
1611 uncertWriteBuffer[icol]=uncertForwardBuffer[icol];
1614 if(noemer<eps_opt[0]){
1615 estWriteBuffer[icol]=0.5*(A+B);
1616 uncertWriteBuffer[icol]=uncertObs;
1619 estWriteBuffer[icol]=(A*D+B*C)/noemer;
1625 if(uncertObs*uncertObs>eps_opt[0])
1626 P-=1.0/uncertObs/uncertObs;
1631 uncertWriteBuffer[icol]=P;
1635 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
1636 imgWriterEst.writeData(uncertWriteBuffer,GDT_Float64,irow,1);
1637 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
1638 pfnProgress(progress,pszMessage,pProgressArg);
1641 imgWriterEst.close();
1642 imgReaderForward.close();
1643 imgReaderBackward.close();
1645 imgReaderObs.close();