23 #include "base/Optionpk.h"
24 #include "base/Vector2d.h"
25 #include "imageclasses/ImgReaderGdal.h"
26 #include "imageclasses/ImgWriterGdal.h"
27 #include "imageclasses/ImgUpdaterGdal.h"
28 #include "algorithms/StatFactory.h"
95 int main(
int argc,
char **argv) {
96 Optionpk<string> direction_opt(
"dir",
"direction",
"direction to run model (forward|backward|smooth)",
"forward");
97 Optionpk<string> model_opt(
"mod",
"model",
"coarse spatial resolution input datasets(s) used as model. Use either multi-band input (-model multiband_model.tif) or multiple single-band inputs (-mod model1 -mod model2 etc.)");
98 Optionpk<string> modelmask_opt(
"modmask",
"modmask",
"model mask datasets(s). Must have same dimension as model input. Use either multi-band input or multiple single-band inputs");
99 Optionpk<string> observation_opt(
"obs",
"observation",
"fine spatial resolution input dataset(s) used as observation. Use either multi-band input (-obs multiband_obs.tif) or multiple single-band inputs (-obs obs1 -obs obs2 etc.)");
100 Optionpk<string> observationmask_opt(
"obsmask",
"obsmask",
"observation mask dataset(s). Must have same dimension as observation input (use multi-band input or multiple single-band inputs");
101 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.");
102 Optionpk<int> tobservation_opt(
"tobs",
"tobservation",
"time sequence of observation input. Sequence must have exact same length as observation input)");
103 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");
104 Optionpk<string> outputfw_opt(
"ofw",
"outputfw",
"Output raster dataset for forward model");
105 Optionpk<string> uncertfw_opt(
"u_ofw",
"u_outputfw",
"Uncertainty output raster dataset for forward model");
106 Optionpk<string> outputbw_opt(
"obw",
"outputbw",
"Output raster dataset for backward model");
107 Optionpk<string> uncertbw_opt(
"u_obw",
"u_outputbw",
"Uncertainty output raster dataset for backward model");
108 Optionpk<string> outputfb_opt(
"ofb",
"outputfb",
"Output raster dataset for smooth model");
109 Optionpk<string> uncertfb_opt(
"u_ofb",
"u_outputfb",
"Uncertainty output raster dataset for smooth model");
110 Optionpk<string> gain_opt(
"gain",
"gain",
"Output raster dataset for gain");
111 Optionpk<double> modnodata_opt(
"modnodata",
"modnodata",
"invalid value for model input", 0);
112 Optionpk<double> obsnodata_opt(
"obsnodata",
"obsnodata",
"invalid value for observation input", 0);
113 Optionpk<double> obsmin_opt(
"obsmin",
"obsmin",
"Minimum value for observation data");
114 Optionpk<double> obsmax_opt(
"obsmax",
"obsmax",
"Maximum value for observation data");
115 Optionpk<double> msknodata_opt(
"msknodata",
"msknodata",
"Mask value not to consider", 0);
116 Optionpk<short> mskband_opt(
"mskband",
"mskband",
"Mask band to read (0 indexed)", 0);
117 Optionpk<double> eps_opt(
"eps",
"eps",
"epsilon for non zero division", 0.00001);
118 Optionpk<double> uncertModel_opt(
"um",
"uncertmodel",
"Uncertainty of model",1);
119 Optionpk<double> uncertObs_opt(
"uo",
"uncertobs",
"Uncertainty of valid observations",1);
120 Optionpk<double> processNoise_opt(
"q",
"q",
"Process noise: expresses instability (variance) of proportions of fine res pixels within a moderate resolution pixel",1);
121 Optionpk<double> uncertNodata_opt(
"unodata",
"uncertnodata",
"Uncertainty in case of no-data values in observation", 100);
122 Optionpk<int> down_opt(
"down",
"down",
"Downsampling factor for reading model data to calculate regression");
123 Optionpk<string> otype_opt(
"ot",
"otype",
"Data type for output image ({Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/CInt16/CInt32/CFloat32/CFloat64}). Empty string: inherit type from input image",
"");
124 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate).",
"GTiff",2);
125 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
126 Optionpk<short> verbose_opt(
"v",
"verbose",
"verbose mode when positive", 0);
128 observationmask_opt.setHide(1);
129 modelmask_opt.setHide(1);
130 tmodel_opt.setHide(1);
131 tobservation_opt.setHide(1);
132 projection_opt.setHide(1);
133 uncertfw_opt.setHide(1);
134 uncertbw_opt.setHide(1);
135 uncertfb_opt.setHide(1);
136 obsmin_opt.setHide(1);
137 obsmax_opt.setHide(1);
138 msknodata_opt.setHide(1);
139 mskband_opt.setHide(1);
141 uncertNodata_opt.setHide(1);
143 otype_opt.setHide(1);
144 oformat_opt.setHide(1);
145 option_opt.setHide(1);
146 verbose_opt.setHide(1);
151 doProcess=direction_opt.retrieveOption(argc,argv);
152 model_opt.retrieveOption(argc,argv);
153 modelmask_opt.retrieveOption(argc,argv);
154 observation_opt.retrieveOption(argc,argv);
155 observationmask_opt.retrieveOption(argc,argv);
156 tmodel_opt.retrieveOption(argc,argv);
157 tobservation_opt.retrieveOption(argc,argv);
158 projection_opt.retrieveOption(argc,argv);
159 outputfw_opt.retrieveOption(argc,argv);
160 uncertfw_opt.retrieveOption(argc,argv);
161 outputbw_opt.retrieveOption(argc,argv);
162 uncertbw_opt.retrieveOption(argc,argv);
163 outputfb_opt.retrieveOption(argc,argv);
164 uncertfb_opt.retrieveOption(argc,argv);
165 gain_opt.retrieveOption(argc,argv);
166 modnodata_opt.retrieveOption(argc,argv);
167 obsnodata_opt.retrieveOption(argc,argv);
168 obsmin_opt.retrieveOption(argc,argv);
169 obsmax_opt.retrieveOption(argc,argv);
170 msknodata_opt.retrieveOption(argc,argv);
171 mskband_opt.retrieveOption(argc,argv);
172 eps_opt.retrieveOption(argc,argv);
173 uncertModel_opt.retrieveOption(argc,argv);
174 uncertObs_opt.retrieveOption(argc,argv);
175 processNoise_opt.retrieveOption(argc,argv);
176 uncertNodata_opt.retrieveOption(argc,argv);
177 down_opt.retrieveOption(argc,argv);
178 otype_opt.retrieveOption(argc,argv);
179 oformat_opt.retrieveOption(argc,argv);
180 option_opt.retrieveOption(argc,argv);
181 verbose_opt.retrieveOption(argc,argv);
183 catch(
string predefinedString){
184 std::cout << predefinedString << std::endl;
188 std::cerr <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
193 ostringstream errorStream;
194 if(model_opt.size()<1){
195 errorStream <<
"Error: no model dataset selected, use option -mod" << endl;
196 throw(errorStream.str());
198 if(observation_opt.size()<1){
199 errorStream <<
"Error: no observation dataset selected, use option -obs" << endl;
200 throw(errorStream.str());
202 if(find(direction_opt.begin(),direction_opt.end(),
"forward")!=direction_opt.end()){
203 if(outputfw_opt.empty()){
204 errorStream <<
"Error: output forward datasets is not provided, use option -ofw" << endl;
205 throw(errorStream.str());
207 if(uncertfw_opt.empty()){
208 ostringstream uncertStream;
209 uncertStream << outputfw_opt[0] <<
"_uncert";
210 uncertfw_opt.push_back(uncertStream.str());
213 if(find(direction_opt.begin(),direction_opt.end(),
"backward")!=direction_opt.end()){
214 if(outputbw_opt.empty()){
215 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
216 throw(errorStream.str());
218 if(uncertbw_opt.empty()){
219 ostringstream uncertStream;
220 uncertStream << outputbw_opt[0] <<
"_uncert";
221 uncertbw_opt.push_back(uncertStream.str());
228 if(tmodel_opt.empty()){
229 cout <<
"Warning: model time sequence is not provided, self generating time sequence from model input" << endl;
231 if(tobservation_opt.empty()){
232 cout <<
"Warning: observation time sequence is not provided, self generating time sequence from observation input" << endl;
234 if(find(direction_opt.begin(),direction_opt.end(),
"smooth")!=direction_opt.end()){
235 if(outputfw_opt.empty()){
236 errorStream <<
"Error: output forward dataset is not provided, use option -ofw" << endl;
237 throw(errorStream.str());
239 if(outputbw_opt.empty()){
240 errorStream <<
"Error: output backward datasets is not provided, use option -obw" << endl;
241 throw(errorStream.str());
243 if(outputfb_opt.empty()){
244 errorStream <<
"Error: output smooth datasets is not provided, use option -ofb" << endl;
245 throw(errorStream.str());
247 if(uncertfb_opt.empty()){
248 ostringstream uncertStream;
249 uncertStream << outputfb_opt[0] <<
"_uncert";
250 uncertfb_opt.push_back(uncertStream.str());
254 catch(
string errorString){
255 std::cout << errorString << std::endl;
260 stat.setNoDataValues(modnodata_opt);
270 imgReaderModel1.open(model_opt[0]);
271 imgReaderModel1.setNoData(modnodata_opt);
272 imgReaderObs.open(observation_opt[0]);
273 imgReaderObs.setNoData(obsnodata_opt);
276 if(modelmask_opt.size()){
277 imgReaderModel1Mask.open(modelmask_opt[0]);
278 imgReaderModel1Mask.setNoData(msknodata_opt);
280 if(observationmask_opt.size()){
281 imgReaderObsMask.open(observationmask_opt[0]);
282 imgReaderObsMask.setNoData(msknodata_opt);
285 unsigned int nobs=(observation_opt.size()>1)? observation_opt.size() : imgReaderObs.nrOfBand();
286 unsigned int nmodel=(model_opt.size()>1)? model_opt.size() : imgReaderModel1.nrOfBand();
289 cout <<
"number of observations: " << nobs << endl;
290 cout <<
"number of models: " << nmodel << endl;
293 int ncol=imgReaderObs.nrOfCol();
294 int nrow=imgReaderObs.nrOfRow();
295 if(projection_opt.empty())
296 projection_opt.push_back(imgReaderObs.getProjection());
297 double geotransform[6];
298 imgReaderObs.getGeoTransform(geotransform);
300 GDALDataType theType=GDT_Unknown;
302 cout <<
"possible output data types: ";
303 for(
int iType = 0; iType < GDT_TypeCount; ++iType){
305 cout <<
" " << GDALGetDataTypeName((GDALDataType)iType);
306 if( GDALGetDataTypeName((GDALDataType)iType) != NULL
307 && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
308 otype_opt[0].c_str()))
309 theType=(GDALDataType) iType;
311 if(theType==GDT_Unknown)
312 theType=imgReaderObs.getDataType();
315 if(oformat_opt.size())
316 imageType=oformat_opt[0];
317 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
318 string theInterleave=
"INTERLEAVE=";
319 theInterleave+=imgReaderObs.getInterleave();
320 option_opt.push_back(theInterleave);
323 if(down_opt.empty()){
324 double resModel=imgReaderModel1.getDeltaX();
325 double resObs=imgReaderObs.getDeltaX();
326 int down=
static_cast<int>(ceil(resModel/resObs));
329 down_opt.push_back(down);
334 const char* pszMessage;
335 void* pProgressArg=NULL;
336 GDALProgressFunc pfnProgress=GDALTermProgress;
339 double errObs=uncertNodata_opt[0];
341 while(tmodel_opt.size()<nmodel)
342 tmodel_opt.push_back(tmodel_opt.size());
344 if(tobservation_opt.size()<nobs){
346 while(tobservation_opt.size()<nobs)
347 tobservation_opt.push_back(tobservation_opt.size());
350 ostringstream errorStream;
351 errorStream <<
"Error: please provide time sequence for observation using option tobs" << endl;
352 throw(errorStream.str());
356 catch(
string errorString){
357 std::cout << errorString << std::endl;
361 vector<int> relobsindex;
363 for(
int tindex=0;tindex<tobservation_opt.size();++tindex){
364 vector<int>::iterator modit;
365 modit=upper_bound(tmodel_opt.begin(),tmodel_opt.end(),tobservation_opt[tindex]);
366 int relpos=modit-tmodel_opt.begin()-1;
368 relobsindex.push_back(relpos);
370 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();
371 if(observation_opt.size()>tindex)
372 cout <<
", filename observation: " << observation_opt[tindex];
374 cout <<
", observation band index: " << tindex;
375 if(model_opt.size()>relpos)
376 cout <<
", filename of corresponding model: " << model_opt[relpos] << endl;
378 cout <<
", band index of corresponding model: " << relpos;
382 int ndigit=log(1.0*tmodel_opt.back())/log(10.0)+1;
387 if(model_opt.size()==nmodel)
388 imgReaderModel1.close();
389 if(modelmask_opt.size()==nmodel)
390 imgReaderModel1Mask.close();
391 if(observation_opt.size()==nobs)
392 imgReaderObs.close();
393 if(observationmask_opt.size()==nobs)
394 imgReaderObsMask.close();
397 if(find(direction_opt.begin(),direction_opt.end(),
"forward")!=direction_opt.end()){
399 cout <<
"Running forward model" << endl;
402 cout <<
"Opening image " << outputfw_opt[0] <<
" for writing " << endl << flush;
407 imgWriterEst.open(outputfw_opt[0],ncol,nrow,nmodel,theType,imageType,option_opt);
408 imgWriterEst.setProjectionProj4(projection_opt[0]);
409 imgWriterEst.setGeoTransform(geotransform);
410 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
411 imgWriterUncert.open(uncertfw_opt[0],ncol,nrow,nmodel,theType,imageType,option_opt);
412 imgWriterUncert.setProjectionProj4(projection_opt[0]);
413 imgWriterUncert.setGeoTransform(geotransform);
418 imgWriterGain.open(gain_opt[0],ncol,nrow,nmodel,GDT_Float64,imageType,option_opt);
419 imgWriterGain.setProjectionProj4(projection_opt[0]);
420 imgWriterGain.setGeoTransform(geotransform);
421 imgWriterGain.GDALSetNoDataValue(obsnodata_opt[0]);
425 cout <<
"processing time " << tmodel_opt[0] << endl;
426 if(obsindex<relobsindex.size()){
427 assert(tmodel_opt.size()>relobsindex[obsindex]);
428 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
431 cout <<
"There is no next observation" << endl;
433 if(model_opt.size()==nmodel){
434 imgReaderModel1.open(model_opt[0]);
435 imgReaderModel1.setNoData(modnodata_opt);
437 if(modelmask_opt.size()==nmodel){
438 imgReaderModel1Mask.open(modelmask_opt[0]);
439 imgReaderModel1Mask.setNoData(msknodata_opt);
442 catch(
string errorString){
443 cerr << errorString << endl;
446 cerr <<
"Error opening file " << model_opt[0] << endl;
453 RESAMPLE theResample=BILINEAR;
455 if(relobsindex[0]>0){
458 cout <<
"write first model as output" << endl;
459 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
460 vector<double> estReadBuffer;
461 vector<double> lineModelMask;
462 vector<double> estWriteBuffer(ncol);
463 vector<double> uncertWriteBuffer(ncol);
465 vector<double> gainWriteBuffer(ncol);
467 for(
int irow=jrow;irow<jrow+down_opt[0]&&irow<nrow;++irow){
468 imgWriterEst.image2geo(0,irow,geox,geoy);
469 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
470 if(modRow<0||modRow>=imgReaderModel1.nrOfRow()){
471 cerr <<
"Error: geo coordinates (" << geox <<
"," << geoy <<
") not covered in model image " << imgReaderModel1.getFileName() << endl;
472 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
476 int readModelBand=(model_opt.size()==nmodel)? 0:0;
477 int readModelMaskBand=(modelmask_opt.size()==nmodel)? mskband_opt[0]:0;
478 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow,readModelBand,theResample);
479 if(modelmask_opt.size())
480 imgReaderModel1Mask.readData(lineModelMask,GDT_Float64,modRow,readModelMaskBand,theResample);
481 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
482 for(
int icol=jcol;icol<jcol+down_opt[0]&&icol<ncol;++icol){
483 imgWriterEst.image2geo(icol,irow,geox,geoy);
484 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
485 if(modelmask_opt.size()){
486 if(imgReaderModel1Mask.isNoData(lineModelMask[modCol])){
487 estWriteBuffer[icol]=obsnodata_opt[0];
488 uncertWriteBuffer[icol]=uncertNodata_opt[0];
490 gainWriteBuffer[icol]=obsnodata_opt[0];
495 lowerCol=
static_cast<int>(lowerCol);
497 upperCol=
static_cast<int>(upperCol);
500 if(upperCol>=imgReaderModel1.nrOfCol())
501 upperCol=imgReaderModel1.nrOfCol()-1;
502 double modValue=(modCol-0.5-lowerCol)*estReadBuffer[upperCol]+(1-modCol+0.5+lowerCol)*estReadBuffer[lowerCol];
504 if(imgReaderModel1.isNoData(modValue)){
505 estWriteBuffer[icol]=obsnodata_opt[0];
506 uncertWriteBuffer[icol]=uncertNodata_opt[0];
508 gainWriteBuffer[icol]=obsnodata_opt[0];
511 estWriteBuffer[icol]=modValue;
512 if(obsmin_opt.size()){
513 if(estWriteBuffer[icol]<obsmin_opt[0])
514 estWriteBuffer[icol]=obsmin_opt[0];
516 if(obsmax_opt.size()){
517 if(estWriteBuffer[icol]>obsmax_opt[0])
518 estWriteBuffer[icol]=obsmax_opt[0];
520 uncertWriteBuffer[icol]=uncertModel_opt[0];
522 gainWriteBuffer[icol]=0;
525 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
526 imgWriterUncert.writeData(uncertWriteBuffer,GDT_Float64,irow,0);
529 imgWriterGain.writeData(gainWriteBuffer,GDT_Float64,irow,0);
532 catch(
string errorString){
533 cerr << errorString << endl;
536 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
542 cout <<
"we have a measurement at initial time" << endl;
543 if(observation_opt.size()==nobs){
544 imgReaderObs.open(observation_opt[0]);
545 imgReaderObs.setNoData(obsnodata_opt);
547 if(observationmask_opt.size()==nobs){
548 imgReaderObsMask.open(observationmask_opt[0]);
549 imgReaderObsMask.setNoData(msknodata_opt);
551 imgReaderObs.getGeoTransform(geotransform);
553 vector< vector<double> > obsLineVector(down_opt[0]);
554 vector<double> obsLineBuffer;
555 vector<double> obsMaskLineBuffer;
556 vector<double> modelMaskLineBuffer;
557 vector<double> obsWindowBuffer;
558 vector<double> estReadBuffer;
559 vector<double> estWriteBuffer(ncol);
560 vector<double> uncertWriteBuffer(ncol);
561 vector<double> uncertObsLineBuffer;
563 vector<double> gainWriteBuffer(ncol);
566 cout <<
"initialize obsLineVector" << endl;
567 assert(down_opt[0]%2);
568 int readObsBand=(observation_opt.size()==nobs)? 0:0;
569 int readObsMaskBand=(observationmask_opt.size()==nobs)? mskband_opt[0]:0;
570 int readModelBand=(model_opt.size()==nmodel)? 0:0;
571 int readModelMaskBand=(modelmask_opt.size()==nmodel)? mskband_opt[0]:0;
572 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
574 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,readObsBand);
576 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,readObsBand);
578 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
579 for(
int irow=jrow;irow<jrow+down_opt[0]&&irow<nrow;++irow){
580 imgWriterEst.image2geo(0,irow,geox,geoy);
581 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
582 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
583 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow,readModelBand,theResample);
584 if(modelmask_opt.size())
585 imgReaderModel1Mask.readData(modelMaskLineBuffer,GDT_Float64,modRow,readModelMaskBand);
586 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
587 obsLineVector.erase(obsLineVector.begin());
588 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,readObsBand);
589 obsLineVector.push_back(obsLineBuffer);
591 if(observationmask_opt.size())
592 imgReaderObsMask.readData(obsMaskLineBuffer,GDT_Float64,irow,readObsMaskBand);
594 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
595 for(
int icol=jcol;icol<jcol+down_opt[0]&&icol<ncol;++icol){
596 imgWriterEst.image2geo(icol,irow,geox,geoy);
597 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
598 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
599 bool modelIsNoData=
false;
600 if(modelmask_opt.size())
601 modelIsNoData=imgReaderModel1Mask.isNoData(modelMaskLineBuffer[modCol]);
603 lowerCol=
static_cast<int>(lowerCol);
605 upperCol=
static_cast<int>(upperCol);
608 if(upperCol>=imgReaderModel1.nrOfCol())
609 upperCol=imgReaderModel1.nrOfCol()-1;
610 double modValue=(modCol-0.5-lowerCol)*estReadBuffer[upperCol]+(1-modCol+0.5+lowerCol)*estReadBuffer[lowerCol];
612 double errMod=uncertModel_opt[0];
613 modelIsNoData=modelIsNoData||imgReaderModel1.isNoData(modValue);
614 bool obsIsNoData=
false;
615 if(observationmask_opt.size())
616 obsIsNoData=imgReaderObsMask.isNoData(obsMaskLineBuffer[icol]);
617 obsIsNoData=obsIsNoData||imgReaderObs.isNoData(obsLineBuffer[icol]);
620 estWriteBuffer[icol]=obsnodata_opt[0];
621 uncertWriteBuffer[icol]=uncertNodata_opt[0];
623 gainWriteBuffer[icol]=obsnodata_opt[0];
626 estWriteBuffer[icol]=obsLineBuffer[icol];
627 if(obsmin_opt.size()){
628 if(estWriteBuffer[icol]<obsmin_opt[0])
629 estWriteBuffer[icol]=obsmin_opt[0];
631 if(obsmax_opt.size()){
632 if(estWriteBuffer[icol]>obsmax_opt[0])
633 estWriteBuffer[icol]=obsmax_opt[0];
635 uncertWriteBuffer[icol]=uncertObs_opt[0];
639 estWriteBuffer[icol]=modValue;
640 uncertWriteBuffer[icol]=errMod;
642 gainWriteBuffer[icol]=0;
648 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
649 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
650 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
651 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
652 obsWindowBuffer.clear();
653 for(
int iline=0;iline<obsLineVector.size();++iline){
654 for(
int isample=minCol;isample<=maxCol;++isample){
655 assert(isample<obsLineVector[iline].size());
656 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
661 statobs.setNoDataValues(obsnodata_opt);
662 double obsMeanValue=0;
663 double obsVarValue=0;
664 statobs.meanVar(obsWindowBuffer,obsMeanValue,obsVarValue);
666 difference=obsMeanValue-modValue;
668 errObs=uncertObs_opt[0]*difference*difference;
670 double errorCovariance=processNoise_opt[0]*obsVarValue;
671 if(errorCovariance+errObs>eps_opt[0])
672 kalmanGain=errorCovariance/(errorCovariance+errObs);
675 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
676 if(obsmin_opt.size()){
677 if(estWriteBuffer[icol]<obsmin_opt[0])
678 estWriteBuffer[icol]=obsmin_opt[0];
680 if(obsmax_opt.size()){
681 if(estWriteBuffer[icol]>obsmax_opt[0])
682 estWriteBuffer[icol]=obsmax_opt[0];
683 if(uncertWriteBuffer[icol]>obsmax_opt[0])
684 uncertWriteBuffer[icol]=obsmax_opt[0];
687 assert(kalmanGain<=1);
689 gainWriteBuffer[icol]=kalmanGain;
693 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,0);
694 imgWriterUncert.writeData(uncertWriteBuffer,GDT_Float64,irow,0);
697 imgWriterGain.writeData(gainWriteBuffer,GDT_Float64,irow,0);
700 if(observation_opt.size()==nobs)
701 imgReaderObs.close();
702 if(observationmask_opt.size()==nobs)
703 imgReaderObsMask.close();
706 if(model_opt.size()==nmodel)
707 imgReaderModel1.close();
708 if(modelmask_opt.size()==nmodel)
709 imgReaderModel1Mask.close();
710 imgWriterEst.close();
711 imgWriterUncert.close();
715 for(
int modindex=1;modindex<nmodel;++modindex){
716 imgUpdaterEst.open(outputfw_opt[0]);
717 imgUpdaterEst.setNoData(obsnodata_opt);
718 imgUpdaterUncert.open(uncertfw_opt[0]);
720 cout <<
"processing time " << tmodel_opt[modindex] << endl;
721 if(obsindex<relobsindex.size())
722 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
724 cout <<
"There is no next observation" << endl;
728 if(model_opt.size()==nmodel){
729 imgReaderModel1.open(model_opt[modindex-1]);
730 imgReaderModel1.setNoData(modnodata_opt);
731 imgReaderModel2.open(model_opt[modindex]);
732 imgReaderModel2.setNoData(modnodata_opt);
734 if(modelmask_opt.size()==nmodel){
735 imgReaderModel1Mask.open(modelmask_opt[modindex-1]);
736 imgReaderModel1Mask.setNoData(msknodata_opt);
737 imgReaderModel2Mask.open(modelmask_opt[modindex]);
738 imgReaderModel2Mask.setNoData(msknodata_opt);
741 pfnProgress(progress,pszMessage,pProgressArg);
744 if(obsindex<relobsindex.size()){
745 update=(relobsindex[obsindex]==modindex);
748 if(observation_opt.size()==nobs){
750 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
751 imgReaderObs.open(observation_opt[obsindex]);
752 imgReaderObs.getGeoTransform(geotransform);
753 imgReaderObs.setNoData(obsnodata_opt);
755 if(observationmask_opt.size()==nobs){
756 imgReaderObsMask.open(observationmask_opt[obsindex]);
757 imgReaderObsMask.setNoData(msknodata_opt);
762 input=outputfw_opt[0];
764 vector< vector<double> > obsLineVector(down_opt[0]);
765 vector<double> obsLineBuffer;
766 vector<double> obsMaskLineBuffer;
767 vector<double> model1MaskLineBuffer;
768 vector<double> model2MaskLineBuffer;
769 vector<double> obsWindowBuffer;
770 vector<double> model1LineBuffer;
771 vector<double> model2LineBuffer;
772 vector<double> model1buffer;
773 vector<double> model2buffer;
774 vector<double> uncertObsLineBuffer;
775 vector< vector<double> > estLineVector(down_opt[0]);
776 vector<double> estLineBuffer;
777 vector<double> estWindowBuffer;
778 vector<double> uncertReadBuffer;
779 vector<double> estWriteBuffer(ncol);
780 vector<double> uncertWriteBuffer(ncol);
782 vector<double> gainWriteBuffer(ncol);
784 int readObsBand=(observation_opt.size()==nobs)? 0:obsindex;
785 int readObsMaskBand=(observationmask_opt.size()==nobs)? mskband_opt[0]:obsindex;
786 int readModel1Band=(model_opt.size()==nmodel)? 0:modindex-1;
787 int readModel2Band=(model_opt.size()==nmodel)? 0:modindex;
788 int readModel1MaskBand=(modelmask_opt.size()==nmodel)? mskband_opt[0]:modindex-1;
789 int readModel2MaskBand=(modelmask_opt.size()==nmodel)? mskband_opt[0]:modindex;
794 cout <<
"initialize obsLineVector" << endl;
795 assert(down_opt[0]%2);
796 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
798 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,readObsBand);
800 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,readObsBand);
805 cout <<
"initialize estLineVector" << endl;
806 assert(down_opt[0]%2);
808 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
810 imgUpdaterEst.readData(estLineVector[iline+down_opt[0]/2],GDT_Float64,0,modindex-1);
812 imgUpdaterEst.readData(estLineVector[iline+down_opt[0]/2],GDT_Float64,iline,modindex-1);
815 statobs.setNoDataValues(obsnodata_opt);
816 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
818 for(
int irow=jrow;irow<jrow+down_opt[0]&&irow<nrow;++irow){
819 imgUpdaterUncert.readData(uncertReadBuffer,GDT_Float64,irow,modindex-1);
820 imgUpdaterUncert.image2geo(0,irow,geox,geoy);
821 if(model_opt.size()==nmodel){
822 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
823 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
824 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,readModel2Band,theResample);
825 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
828 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
829 imgReaderModel1.readData(model2LineBuffer,GDT_Float64,modRow,readModel2Band,theResample);
831 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
832 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,readModel1Band,theResample);
834 if(modelmask_opt.size()){
835 imgReaderModel1Mask.readData(model1MaskLineBuffer,GDT_Float64,modRow,readModel1MaskBand);
836 if(modelmask_opt.size()==nmodel)
837 imgReaderModel2Mask.readData(model2MaskLineBuffer,GDT_Float64,modRow,readModel2MaskBand);
839 imgReaderModel1Mask.readData(model2MaskLineBuffer,GDT_Float64,modRow,readModel2MaskBand);
842 int maxRow=(irow+down_opt[0]/2<imgUpdaterEst.nrOfRow()) ? irow+down_opt[0]/2 : imgUpdaterEst.nrOfRow()-1;
843 estLineVector.erase(estLineVector.begin());
844 imgUpdaterEst.readData(estLineBuffer,GDT_Float64,maxRow,modindex-1);
845 estLineVector.push_back(estLineBuffer);
846 estLineBuffer=estLineVector[down_opt[0]/2];
849 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
850 obsLineVector.erase(obsLineVector.begin());
851 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,readObsBand);
852 obsLineVector.push_back(obsLineBuffer);
853 obsLineBuffer=obsLineVector[down_opt[0]/2];
855 if(observationmask_opt.size())
856 imgReaderObsMask.readData(obsMaskLineBuffer,GDT_Float64,irow,readObsMaskBand);
859 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
860 for(
int icol=jcol;icol<jcol+down_opt[0]&&icol<ncol;++icol){
861 imgUpdaterEst.image2geo(icol,irow,geox,geoy);
862 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
863 int maxCol=(icol+down_opt[0]/2<imgUpdaterEst.nrOfCol()) ? icol+down_opt[0]/2 : imgUpdaterEst.nrOfCol()-1;
864 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
865 int maxRow=(irow+down_opt[0]/2<imgUpdaterEst.nrOfRow()) ? irow+down_opt[0]/2 : imgUpdaterEst.nrOfRow()-1;
866 estWindowBuffer.clear();
867 for(
int iline=0;iline<estLineVector.size();++iline){
868 for(
int isample=minCol;isample<=maxCol;++isample){
869 assert(isample<estLineVector[iline].size());
870 estWindowBuffer.push_back(estLineVector[iline][isample]);
874 obsWindowBuffer.clear();
875 for(
int iline=0;iline<obsLineVector.size();++iline){
876 for(
int isample=minCol;isample<=maxCol;++isample){
877 assert(isample<obsLineVector[iline].size());
878 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
882 double estValue=estLineBuffer[icol];
883 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
884 bool model1IsNoData=
false;
885 if(modelmask_opt.size())
886 model1IsNoData=imgReaderModel1Mask.isNoData(model1MaskLineBuffer[modCol]);
888 lowerCol=
static_cast<int>(lowerCol);
890 upperCol=
static_cast<int>(upperCol);
893 if(upperCol>=imgReaderModel1.nrOfCol())
894 upperCol=imgReaderModel1.nrOfCol()-1;
895 double modValue1=(modCol-0.5-lowerCol)*model1LineBuffer[upperCol]+(1-modCol+0.5+lowerCol)*model1LineBuffer[lowerCol];
896 model1IsNoData=model1IsNoData||imgReaderModel1.isNoData(modValue1);
897 if(model_opt.size()==nmodel)
898 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
900 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
901 bool model2IsNoData=
false;
902 if(modelmask_opt.size())
903 model2IsNoData=imgReaderModel1Mask.isNoData(model2MaskLineBuffer[modCol]);
905 lowerCol=
static_cast<int>(lowerCol);
907 upperCol=
static_cast<int>(upperCol);
910 if(upperCol>=imgReaderModel1.nrOfCol())
911 upperCol=imgReaderModel1.nrOfCol()-1;
912 double modValue2=(modCol-0.5-lowerCol)*model2LineBuffer[upperCol]+(1-modCol+0.5+lowerCol)*model2LineBuffer[lowerCol];
913 model2IsNoData=model2IsNoData||imgReaderModel1.isNoData(modValue2);
914 bool obsIsNoData=
false;
915 if(observationmask_opt.size())
916 obsIsNoData=imgReaderObsMask.isNoData(obsMaskLineBuffer[icol]);
917 obsIsNoData=obsIsNoData||imgReaderObs.isNoData(obsLineBuffer[icol]);
919 if(imgUpdaterEst.isNoData(estValue)){
922 estWriteBuffer[icol]=obsnodata_opt[0];
923 uncertWriteBuffer[icol]=uncertNodata_opt[0];
925 gainWriteBuffer[icol]=0;
928 estWriteBuffer[icol]=modValue2;
929 uncertWriteBuffer[icol]=uncertModel_opt[0];
930 if(obsmin_opt.size()){
931 if(estWriteBuffer[icol]<obsmin_opt[0])
932 estWriteBuffer[icol]=obsmin_opt[0];
934 if(obsmax_opt.size()){
935 if(estWriteBuffer[icol]>obsmax_opt[0])
936 estWriteBuffer[icol]=obsmax_opt[0];
937 if(uncertWriteBuffer[icol]>obsmax_opt[0])
938 uncertWriteBuffer[icol]=obsmax_opt[0];
941 gainWriteBuffer[icol]=0;
945 double estMeanValue=0;
946 double estVarValue=0;
947 statobs.meanVar(estWindowBuffer,estMeanValue,estVarValue);
950 double processNoiseVariance=processNoise_opt[0]*estVarValue;
953 if(model1IsNoData||model2IsNoData){
954 estWriteBuffer[icol]=estValue;
957 uncertWriteBuffer[icol]=uncertReadBuffer[icol]+uncertObs_opt[0];
960 double modRatio=modValue2/modValue1;
961 estWriteBuffer[icol]=estValue*modRatio;
962 uncertWriteBuffer[icol]=uncertReadBuffer[icol]*modRatio*modRatio+processNoiseVariance;
964 if(obsmin_opt.size()){
965 if(estWriteBuffer[icol]<obsmin_opt[0])
966 estWriteBuffer[icol]=obsmin_opt[0];
968 if(obsmax_opt.size()){
969 if(estWriteBuffer[icol]>obsmax_opt[0])
970 estWriteBuffer[icol]=obsmax_opt[0];
971 if(uncertWriteBuffer[icol]>obsmax_opt[0])
972 uncertWriteBuffer[icol]=obsmax_opt[0];
976 if(update&&!obsIsNoData){
980 statobs.setNoDataValues(obsnodata_opt);
981 double obsMeanValue=0;
982 double obsVarValue=0;
984 statobs.meanVar(obsWindowBuffer,obsMeanValue,obsVarValue);
985 difference=obsMeanValue-modValue2;
987 errObs=uncertObs_opt[0]*difference*difference;
989 if(errObs<eps_opt[0])
991 double errorCovariance=uncertWriteBuffer[icol];
993 if(errorCovariance+errObs>eps_opt[0])
994 kalmanGain=errorCovariance/(errorCovariance+errObs);
997 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
998 uncertWriteBuffer[icol]*=(1-kalmanGain);
999 if(obsmin_opt.size()){
1000 if(estWriteBuffer[icol]<obsmin_opt[0])
1001 estWriteBuffer[icol]=obsmin_opt[0];
1003 if(obsmax_opt.size()){
1004 if(estWriteBuffer[icol]>obsmax_opt[0])
1005 estWriteBuffer[icol]=obsmax_opt[0];
1006 if(uncertWriteBuffer[icol]>obsmax_opt[0])
1007 uncertWriteBuffer[icol]=obsmax_opt[0];
1010 assert(kalmanGain<=1);
1012 gainWriteBuffer[icol]=kalmanGain;
1019 imgWriterGain.writeData(gainWriteBuffer,GDT_Float64,irow,modindex);
1020 imgUpdaterEst.writeData(estWriteBuffer,GDT_Float64,irow,modindex);
1021 imgUpdaterUncert.writeData(uncertWriteBuffer,GDT_Float64,irow,modindex);
1022 progress=
static_cast<float>((irow+1.0)/imgUpdaterEst.nrOfRow());
1023 pfnProgress(progress,pszMessage,pProgressArg);
1028 imgUpdaterEst.close();
1029 imgUpdaterUncert.close();
1034 if(observation_opt.size()==nobs)
1035 imgReaderObs.close();
1036 if(observationmask_opt.size()==nobs)
1037 imgReaderObsMask.close();
1040 if(model_opt.size()==nmodel){
1041 imgReaderModel1.close();
1042 imgReaderModel2.close();
1044 if(modelmask_opt.size()==nmodel){
1045 imgReaderModel1Mask.close();
1046 imgReaderModel2Mask.close();
1051 imgWriterGain.close();
1054 catch(
string errorString){
1055 cerr << errorString << endl;
1059 cerr <<
"Error in forward direction " << endl;
1063 if(find(direction_opt.begin(),direction_opt.end(),
"backward")!=direction_opt.end()){
1065 cout <<
"Running backward model" << endl;
1066 obsindex=relobsindex.size()-1;
1068 cout <<
"Opening image " << outputbw_opt[0] <<
" for writing " << endl;
1073 imgWriterEst.open(outputbw_opt[0],ncol,nrow,nmodel,theType,imageType,option_opt);
1074 imgWriterEst.setProjectionProj4(projection_opt[0]);
1075 imgWriterEst.setGeoTransform(geotransform);
1076 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1077 imgWriterUncert.open(uncertbw_opt[0],ncol,nrow,nmodel,theType,imageType,option_opt);
1078 imgWriterUncert.setProjectionProj4(projection_opt[0]);
1079 imgWriterUncert.setGeoTransform(geotransform);
1091 cout <<
"processing time " << tmodel_opt.back() << endl;
1092 if(obsindex<relobsindex.size()){
1093 assert(tmodel_opt.size()>relobsindex[obsindex]);
1094 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1097 cout <<
"There is no next observation" << endl;
1099 if(model_opt.size()==nmodel){
1100 imgReaderModel1.open(model_opt.back());
1101 imgReaderModel1.setNoData(modnodata_opt);
1103 if(modelmask_opt.size()==nmodel){
1104 imgReaderModel1Mask.open(modelmask_opt[0]);
1105 imgReaderModel1Mask.setNoData(msknodata_opt);
1108 catch(
string errorString){
1109 cerr << errorString << endl;
1112 cerr <<
"Error opening file " << model_opt[0] << endl;
1119 RESAMPLE theResample=BILINEAR;
1121 if(relobsindex.back()<nmodel-1){
1124 cout <<
"write last model as output" << endl;
1125 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
1126 vector<double> estReadBuffer;
1127 vector<double> lineModelMask;
1128 vector<double> estWriteBuffer(ncol);
1129 vector<double> uncertWriteBuffer(ncol);
1133 for(
int irow=jrow;irow<jrow+down_opt[0]&&irow<nrow;++irow){
1134 imgWriterEst.image2geo(0,irow,geox,geoy);
1135 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1136 if(modRow<0||modRow>=imgReaderModel1.nrOfRow()){
1137 cerr <<
"Error: geo coordinates (" << geox <<
"," << geoy <<
") not covered in model image " << imgReaderModel1.getFileName() << endl;
1138 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1141 int readModelBand=(model_opt.size()==nmodel)? 0:nmodel-1;
1142 int readModelMaskBand=(modelmask_opt.size()==nmodel)? mskband_opt[0]:0;
1143 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow,readModelBand,theResample);
1144 if(modelmask_opt.size())
1145 imgReaderModel1Mask.readData(lineModelMask,GDT_Float64,modRow,readModelMaskBand,theResample);
1146 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
1147 for(
int icol=jcol;icol<jcol+down_opt[0]&&icol<ncol;++icol){
1148 imgWriterEst.image2geo(icol,irow,geox,geoy);
1149 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1150 if(lineModelMask.size()>modCol){
1151 if(imgReaderModel1Mask.isNoData(lineModelMask[modCol])){
1152 estWriteBuffer[icol]=obsnodata_opt[0];
1153 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1159 lowerCol=modCol-0.5;
1160 lowerCol=
static_cast<int>(lowerCol);
1161 upperCol=modCol+0.5;
1162 upperCol=
static_cast<int>(upperCol);
1165 if(upperCol>=imgReaderModel1.nrOfCol())
1166 upperCol=imgReaderModel1.nrOfCol()-1;
1167 double modValue=(modCol-0.5-lowerCol)*estReadBuffer[upperCol]+(1-modCol+0.5+lowerCol)*estReadBuffer[lowerCol];
1169 if(imgReaderModel1.isNoData(modValue)){
1170 estWriteBuffer[icol]=obsnodata_opt[0];
1171 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1176 estWriteBuffer[icol]=modValue;
1177 if(obsmin_opt.size()){
1178 if(estWriteBuffer[icol]<obsmin_opt[0])
1179 estWriteBuffer[icol]=obsmin_opt[0];
1181 if(obsmax_opt.size()){
1182 if(estWriteBuffer[icol]>obsmax_opt[0])
1183 estWriteBuffer[icol]=obsmax_opt[0];
1185 uncertWriteBuffer[icol]=uncertModel_opt[0];
1190 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,nmodel-1);
1191 imgWriterUncert.writeData(uncertWriteBuffer,GDT_Float64,irow,nmodel-1);
1197 catch(
string errorString){
1198 cerr << errorString << endl;
1201 cerr <<
"Error writing file " << imgWriterEst.getFileName() << endl;
1207 cout <<
"we have a measurement at end time" << endl;
1208 if(observation_opt.size()==nobs){
1209 imgReaderObs.open(observation_opt.back());
1210 imgReaderObs.setNoData(obsnodata_opt);
1212 if(observationmask_opt.size()==nobs){
1213 imgReaderObsMask.open(observationmask_opt.back());
1214 imgReaderObsMask.setNoData(msknodata_opt);
1216 imgReaderObs.getGeoTransform(geotransform);
1218 vector< vector<double> > obsLineVector(down_opt[0]);
1219 vector<double> obsLineBuffer;
1220 vector<double> obsMaskLineBuffer;
1221 vector<double> modelMaskLineBuffer;
1222 vector<double> obsWindowBuffer;
1223 vector<double> estReadBuffer;
1224 vector<double> estWriteBuffer(ncol);
1225 vector<double> uncertWriteBuffer(ncol);
1226 vector<double> uncertObsLineBuffer;
1231 cout <<
"initialize obsLineVector" << endl;
1232 assert(down_opt[0]%2);
1233 int readObsBand=(observation_opt.size()==nobs)? 0:nobs-1;
1234 int readObsMaskBand=(observationmask_opt.size()==nobs)? mskband_opt[0]:nobs-1;
1235 int readModelBand=(model_opt.size()==nmodel)? 0:nmodel-1;
1236 int readModelMaskBand=(modelmask_opt.size()==nmodel)? mskband_opt[0]:nmodel-1;
1237 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
1239 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,readObsBand);
1241 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,readObsBand);
1243 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
1244 for(
int irow=jrow;irow<jrow+down_opt[0]&&irow<nrow;++irow){
1245 imgWriterEst.image2geo(0,irow,geox,geoy);
1246 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1247 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1248 imgReaderModel1.readData(estReadBuffer,GDT_Float64,modRow,readModelBand,theResample);
1249 if(modelmask_opt.size())
1250 imgReaderModel1Mask.readData(modelMaskLineBuffer,GDT_Float64,modRow,readModelMaskBand);
1251 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
1252 obsLineVector.erase(obsLineVector.begin());
1253 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,readObsBand);
1254 obsLineVector.push_back(obsLineBuffer);
1256 if(observationmask_opt.size())
1257 imgReaderObsMask.readData(obsMaskLineBuffer,GDT_Float64,irow,readObsMaskBand);
1259 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
1260 for(
int icol=jcol;icol<jcol+down_opt[0]&&icol<ncol;++icol){
1261 imgWriterEst.image2geo(icol,irow,geox,geoy);
1262 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1263 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1264 bool modelIsNoData=
false;
1265 if(modelmask_opt.size())
1266 modelIsNoData=imgReaderModel1Mask.isNoData(modelMaskLineBuffer[modCol]);
1267 lowerCol=modCol-0.5;
1268 lowerCol=
static_cast<int>(lowerCol);
1269 upperCol=modCol+0.5;
1270 upperCol=
static_cast<int>(upperCol);
1273 if(upperCol>=imgReaderModel1.nrOfCol())
1274 upperCol=imgReaderModel1.nrOfCol()-1;
1275 double modValue=(modCol-0.5-lowerCol)*estReadBuffer[upperCol]+(1-modCol+0.5+lowerCol)*estReadBuffer[lowerCol];
1277 double errMod=uncertModel_opt[0];
1278 modelIsNoData=modelIsNoData||imgReaderModel1.isNoData(modValue);
1279 bool obsIsNoData=
false;
1280 if(observationmask_opt.size())
1281 obsIsNoData=imgReaderObsMask.isNoData(obsMaskLineBuffer[icol]);
1282 obsIsNoData=obsIsNoData||imgReaderObs.isNoData(obsLineBuffer[icol]);
1285 estWriteBuffer[icol]=obsnodata_opt[0];
1286 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1291 estWriteBuffer[icol]=obsLineBuffer[icol];
1292 if(obsmin_opt.size()){
1293 if(estWriteBuffer[icol]<obsmin_opt[0])
1294 estWriteBuffer[icol]=obsmin_opt[0];
1296 if(obsmax_opt.size()){
1297 if(estWriteBuffer[icol]>obsmax_opt[0])
1298 estWriteBuffer[icol]=obsmax_opt[0];
1300 uncertWriteBuffer[icol]=uncertObs_opt[0];
1304 estWriteBuffer[icol]=modValue;
1305 uncertWriteBuffer[icol]=errMod;
1312 double kalmanGain=1;
1313 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
1314 int maxCol=(icol+down_opt[0]/2<imgReaderObs.nrOfCol()) ? icol+down_opt[0]/2 : imgReaderObs.nrOfCol()-1;
1315 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
1316 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
1317 obsWindowBuffer.clear();
1318 for(
int iline=0;iline<obsLineVector.size();++iline){
1319 for(
int isample=minCol;isample<=maxCol;++isample){
1320 assert(isample<obsLineVector[iline].size());
1321 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
1326 statobs.setNoDataValues(obsnodata_opt);
1327 double obsMeanValue=0;
1328 double obsVarValue=0;
1329 statobs.meanVar(obsWindowBuffer,obsMeanValue,obsVarValue);
1330 double difference=0;
1331 difference=obsMeanValue-modValue;
1333 errObs=uncertObs_opt[0]*difference*difference;
1335 double errorCovariance=processNoise_opt[0]*obsVarValue;
1336 if(errorCovariance+errObs>eps_opt[0])
1337 kalmanGain=errorCovariance/(errorCovariance+errObs);
1340 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1341 if(obsmin_opt.size()){
1342 if(estWriteBuffer[icol]<obsmin_opt[0])
1343 estWriteBuffer[icol]=obsmin_opt[0];
1345 if(obsmax_opt.size()){
1346 if(estWriteBuffer[icol]>obsmax_opt[0])
1347 estWriteBuffer[icol]=obsmax_opt[0];
1348 if(uncertWriteBuffer[icol]>obsmax_opt[0])
1349 uncertWriteBuffer[icol]=obsmax_opt[0];
1352 assert(kalmanGain<=1);
1358 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,nmodel-1);
1359 imgWriterUncert.writeData(uncertWriteBuffer,GDT_Float64,irow,nmodel-1);
1365 if(observation_opt.size()==nobs)
1366 imgReaderObs.close();
1367 if(observationmask_opt.size()==nobs)
1368 imgReaderObsMask.close();
1372 if(model_opt.size()==nmodel)
1373 imgReaderModel1.close();
1374 if(modelmask_opt.size()==nmodel)
1375 imgReaderModel1Mask.close();
1376 imgWriterEst.close();
1377 imgWriterUncert.close();
1381 for(
int modindex=nmodel-2;modindex>=0;--modindex){
1382 imgUpdaterEst.open(outputbw_opt[0]);
1383 imgUpdaterEst.setNoData(obsnodata_opt);
1384 imgUpdaterUncert.open(uncertbw_opt[0]);
1386 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1387 if(obsindex<relobsindex.size())
1388 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1390 cout <<
"There is no next observation" << endl;
1394 if(model_opt.size()==nmodel){
1395 imgReaderModel1.open(model_opt[modindex+1]);
1396 imgReaderModel1.setNoData(modnodata_opt);
1397 imgReaderModel2.open(model_opt[modindex]);
1398 imgReaderModel2.setNoData(modnodata_opt);
1400 if(modelmask_opt.size()==nmodel){
1401 imgReaderModel1Mask.open(modelmask_opt[modindex-1]);
1402 imgReaderModel1Mask.setNoData(msknodata_opt);
1403 imgReaderModel2Mask.open(modelmask_opt[modindex]);
1404 imgReaderModel2Mask.setNoData(msknodata_opt);
1407 pfnProgress(progress,pszMessage,pProgressArg);
1410 if(obsindex<relobsindex.size()){
1411 update=(relobsindex[obsindex]==modindex);
1414 if(observation_opt.size()==nobs){
1416 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
1417 imgReaderObs.open(observation_opt[obsindex]);
1418 imgReaderObs.getGeoTransform(geotransform);
1419 imgReaderObs.setNoData(obsnodata_opt);
1421 if(observationmask_opt.size()==nobs){
1422 imgReaderObsMask.open(observationmask_opt[obsindex]);
1423 imgReaderObsMask.setNoData(msknodata_opt);
1428 input=outputbw_opt[0];
1430 vector< vector<double> > obsLineVector(down_opt[0]);
1431 vector<double> obsLineBuffer;
1432 vector<double> obsMaskLineBuffer;
1433 vector<double> model1MaskLineBuffer;
1434 vector<double> model2MaskLineBuffer;
1435 vector<double> obsWindowBuffer;
1436 vector<double> model1LineBuffer;
1437 vector<double> model2LineBuffer;
1438 vector<double> model1buffer;
1439 vector<double> model2buffer;
1440 vector<double> uncertObsLineBuffer;
1441 vector< vector<double> > estLineVector(down_opt[0]);
1442 vector<double> estLineBuffer;
1443 vector<double> estWindowBuffer;
1444 vector<double> uncertReadBuffer;
1445 vector<double> estWriteBuffer(ncol);
1446 vector<double> uncertWriteBuffer(ncol);
1450 int readObsBand=(observation_opt.size()==nobs)? 0:obsindex;
1451 int readObsMaskBand=(observationmask_opt.size()==nobs)? mskband_opt[0]:obsindex;
1452 int readModel1Band=(model_opt.size()==nmodel)? 0:modindex+1;
1453 int readModel2Band=(model_opt.size()==nmodel)? 0:modindex;
1454 int readModel1MaskBand=(modelmask_opt.size()==nmodel)? mskband_opt[0]:modindex+1;
1455 int readModel2MaskBand=(modelmask_opt.size()==nmodel)? mskband_opt[0]:modindex;
1460 cout <<
"initialize obsLineVector" << endl;
1461 assert(down_opt[0]%2);
1462 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
1464 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,0,readObsBand);
1466 imgReaderObs.readData(obsLineVector[iline+down_opt[0]/2],GDT_Float64,iline,readObsBand);
1471 cout <<
"initialize estLineVector" << endl;
1472 assert(down_opt[0]%2);
1474 for(
int iline=-down_opt[0]/2;iline<down_opt[0]/2+1;++iline){
1476 imgUpdaterEst.readData(estLineVector[iline+down_opt[0]/2],GDT_Float64,0,modindex+1);
1478 imgUpdaterEst.readData(estLineVector[iline+down_opt[0]/2],GDT_Float64,iline,modindex+1);
1481 statobs.setNoDataValues(obsnodata_opt);
1483 for(
int jrow=0;jrow<nrow;jrow+=down_opt[0]){
1485 for(
int irow=jrow;irow<jrow+down_opt[0]&&irow<nrow;++irow){
1486 imgUpdaterUncert.readData(uncertReadBuffer,GDT_Float64,irow,modindex+1);
1487 imgUpdaterUncert.image2geo(0,irow,geox,geoy);
1488 if(model_opt.size()==nmodel){
1489 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1490 assert(modRow>=0&&modRow<imgReaderModel2.nrOfRow());
1491 imgReaderModel2.readData(model2LineBuffer,GDT_Float64,modRow,readModel2Band,theResample);
1492 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1495 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1496 imgReaderModel1.readData(model2LineBuffer,GDT_Float64,modRow,readModel2Band,theResample);
1499 assert(modRow>=0&&modRow<imgReaderModel1.nrOfRow());
1500 imgReaderModel1.readData(model1LineBuffer,GDT_Float64,modRow,readModel1Band,theResample);
1501 if(modelmask_opt.size()){
1502 imgReaderModel1Mask.readData(model1MaskLineBuffer,GDT_Float64,modRow,readModel1MaskBand);
1503 if(modelmask_opt.size()==nmodel)
1504 imgReaderModel2Mask.readData(model2MaskLineBuffer,GDT_Float64,modRow,readModel2MaskBand);
1506 imgReaderModel1Mask.readData(model2MaskLineBuffer,GDT_Float64,modRow,readModel2MaskBand);
1508 int maxRow=(irow+down_opt[0]/2<imgUpdaterEst.nrOfRow()) ? irow+down_opt[0]/2 : imgUpdaterEst.nrOfRow()-1;
1509 estLineVector.erase(estLineVector.begin());
1510 imgUpdaterEst.readData(estLineBuffer,GDT_Float64,maxRow,modindex+1);
1511 estLineVector.push_back(estLineBuffer);
1512 estLineBuffer=estLineVector[down_opt[0]/2];
1515 int maxRow=(irow+down_opt[0]/2<imgReaderObs.nrOfRow()) ? irow+down_opt[0]/2 : imgReaderObs.nrOfRow()-1;
1516 obsLineVector.erase(obsLineVector.begin());
1517 imgReaderObs.readData(obsLineBuffer,GDT_Float64,maxRow,readObsBand);
1518 obsLineVector.push_back(obsLineBuffer);
1519 obsLineBuffer=obsLineVector[down_opt[0]/2];
1521 if(observationmask_opt.size())
1522 imgReaderObsMask.readData(obsMaskLineBuffer,GDT_Float64,irow,readObsBand);
1524 for(
int jcol=0;jcol<ncol;jcol+=down_opt[0]){
1525 for(
int icol=jcol;icol<jcol+down_opt[0]&&icol<ncol;++icol){
1526 imgUpdaterEst.image2geo(icol,irow,geox,geoy);
1527 int minCol=(icol>down_opt[0]/2) ? icol-down_opt[0]/2 : 0;
1528 int maxCol=(icol+down_opt[0]/2<imgUpdaterEst.nrOfCol()) ? icol+down_opt[0]/2 : imgUpdaterEst.nrOfCol()-1;
1529 int minRow=(irow>down_opt[0]/2) ? irow-down_opt[0]/2 : 0;
1530 int maxRow=(irow+down_opt[0]/2<imgUpdaterEst.nrOfRow()) ? irow+down_opt[0]/2 : imgUpdaterEst.nrOfRow()-1;
1531 estWindowBuffer.clear();
1532 for(
int iline=0;iline<estLineVector.size();++iline){
1533 for(
int isample=minCol;isample<=maxCol;++isample){
1534 assert(isample<estLineVector[iline].size());
1535 estWindowBuffer.push_back(estLineVector[iline][isample]);
1539 obsWindowBuffer.clear();
1540 for(
int iline=0;iline<obsLineVector.size();++iline){
1541 for(
int isample=minCol;isample<=maxCol;++isample){
1542 assert(isample<obsLineVector[iline].size());
1543 obsWindowBuffer.push_back(obsLineVector[iline][isample]);
1548 double estValue=estLineBuffer[icol];
1549 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1550 bool model1IsNoData=
false;
1552 if(modelmask_opt.size())
1553 model1IsNoData=imgReaderModel1Mask.isNoData(model1MaskLineBuffer[modCol]);
1555 lowerCol=modCol-0.5;
1556 lowerCol=
static_cast<int>(lowerCol);
1557 upperCol=modCol+0.5;
1558 upperCol=
static_cast<int>(upperCol);
1561 if(upperCol>=imgReaderModel1.nrOfCol())
1562 upperCol=imgReaderModel1.nrOfCol()-1;
1563 double modValue1=(modCol-0.5-lowerCol)*model1LineBuffer[upperCol]+(1-modCol+0.5+lowerCol)*model1LineBuffer[lowerCol];
1564 model1IsNoData=model1IsNoData||imgReaderModel1.isNoData(modValue1);
1565 if(model_opt.size()==nmodel)
1566 imgReaderModel2.geo2image(geox,geoy,modCol,modRow);
1568 imgReaderModel1.geo2image(geox,geoy,modCol,modRow);
1569 bool model2IsNoData=
false;
1571 if(modelmask_opt.size())
1572 model2IsNoData=imgReaderModel1Mask.isNoData(model2MaskLineBuffer[modCol]);
1573 lowerCol=modCol-0.5;
1574 lowerCol=
static_cast<int>(lowerCol);
1575 upperCol=modCol+0.5;
1576 upperCol=
static_cast<int>(upperCol);
1579 if(upperCol>=imgReaderModel1.nrOfCol())
1580 upperCol=imgReaderModel1.nrOfCol()-1;
1581 double modValue2=(modCol-0.5-lowerCol)*model2LineBuffer[upperCol]+(1-modCol+0.5+lowerCol)*model2LineBuffer[lowerCol];
1582 model2IsNoData=model2IsNoData||imgReaderModel1.isNoData(modValue2);
1583 bool obsIsNoData=
false;
1584 if(observationmask_opt.size())
1585 obsIsNoData=imgReaderObsMask.isNoData(obsMaskLineBuffer[icol]);
1586 obsIsNoData=obsIsNoData||imgReaderObs.isNoData(obsLineBuffer[icol]);
1588 if(imgUpdaterEst.isNoData(estValue)){
1591 estWriteBuffer[icol]=obsnodata_opt[0];
1592 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1597 estWriteBuffer[icol]=modValue2;
1598 uncertWriteBuffer[icol]=uncertModel_opt[0];
1599 if(obsmin_opt.size()){
1600 if(estWriteBuffer[icol]<obsmin_opt[0])
1601 estWriteBuffer[icol]=obsmin_opt[0];
1603 if(obsmax_opt.size()){
1604 if(estWriteBuffer[icol]>obsmax_opt[0])
1605 estWriteBuffer[icol]=obsmax_opt[0];
1606 if(uncertWriteBuffer[icol]>obsmax_opt[0])
1607 uncertWriteBuffer[icol]=obsmax_opt[0];
1614 double estMeanValue=0;
1615 double estVarValue=0;
1616 statobs.meanVar(estWindowBuffer,estMeanValue,estVarValue);
1619 double processNoiseVariance=processNoise_opt[0]*estVarValue;
1622 if(model1IsNoData||model2IsNoData){
1623 estWriteBuffer[icol]=estValue;
1626 uncertWriteBuffer[icol]=uncertReadBuffer[icol]+uncertObs_opt[0];
1629 double modRatio=modValue2/modValue1;
1630 estWriteBuffer[icol]=estValue*modRatio;
1631 uncertWriteBuffer[icol]=uncertReadBuffer[icol]*modRatio*modRatio+processNoiseVariance;
1633 if(obsmin_opt.size()){
1634 if(estWriteBuffer[icol]<obsmin_opt[0])
1635 estWriteBuffer[icol]=obsmin_opt[0];
1637 if(obsmax_opt.size()){
1638 if(estWriteBuffer[icol]>obsmax_opt[0])
1639 estWriteBuffer[icol]=obsmax_opt[0];
1640 if(uncertWriteBuffer[icol]>obsmax_opt[0])
1641 uncertWriteBuffer[icol]=obsmax_opt[0];
1645 if(update&&!imgReaderObs.isNoData(obsLineBuffer[icol])){
1646 double kalmanGain=1;
1647 if(!imgReaderModel1.isNoData(modValue2)){
1649 statobs.setNoDataValues(obsnodata_opt);
1650 double obsMeanValue=0;
1651 double obsVarValue=0;
1652 double difference=0;
1653 statobs.meanVar(obsWindowBuffer,obsMeanValue,obsVarValue);
1654 difference=obsMeanValue-modValue2;
1656 errObs=uncertObs_opt[0]*difference*difference;
1658 if(errObs<eps_opt[0])
1660 double errorCovariance=uncertWriteBuffer[icol];
1662 if(errorCovariance+errObs>eps_opt[0])
1663 kalmanGain=errorCovariance/(errorCovariance+errObs);
1666 estWriteBuffer[icol]+=kalmanGain*(obsLineBuffer[icol]-estWriteBuffer[icol]);
1667 uncertWriteBuffer[icol]*=(1-kalmanGain);
1668 if(obsmin_opt.size()){
1669 if(estWriteBuffer[icol]<obsmin_opt[0])
1670 estWriteBuffer[icol]=obsmin_opt[0];
1672 if(obsmax_opt.size()){
1673 if(estWriteBuffer[icol]>obsmax_opt[0])
1674 estWriteBuffer[icol]=obsmax_opt[0];
1675 if(uncertWriteBuffer[icol]>obsmax_opt[0])
1676 uncertWriteBuffer[icol]=obsmax_opt[0];
1679 assert(kalmanGain<=1);
1688 imgUpdaterEst.writeData(estWriteBuffer,GDT_Float64,irow,modindex);
1689 imgUpdaterUncert.writeData(uncertWriteBuffer,GDT_Float64,irow,modindex);
1690 progress=
static_cast<float>((irow+1.0)/imgUpdaterEst.nrOfRow());
1691 pfnProgress(progress,pszMessage,pProgressArg);
1695 imgUpdaterEst.close();
1696 imgUpdaterUncert.close();
1701 if(observation_opt.size()==nobs)
1702 imgReaderObs.close();
1703 if(observationmask_opt.size()==nobs)
1704 imgReaderObsMask.close();
1707 if(model_opt.size()==nmodel){
1708 imgReaderModel1.close();
1709 imgReaderModel2.close();
1711 if(modelmask_opt.size()==nmodel){
1712 imgReaderModel1Mask.close();
1713 imgReaderModel2Mask.close();
1721 catch(
string errorString){
1722 cerr << errorString << endl;
1726 cerr <<
"Error in backward direction " << endl;
1729 if(find(direction_opt.begin(),direction_opt.end(),
"smooth")!=direction_opt.end()){
1731 cout <<
"Running smooth model" << endl;
1738 imgReaderForward.setNoData(obsnodata_opt);
1739 imgReaderBackward.setNoData(obsnodata_opt);
1741 assert(imgReaderForward.nrOfBand()==nmodel);
1742 assert(imgReaderForwardUncert.nrOfBand()==nmodel);
1743 assert(imgReaderBackward.nrOfBand()==nmodel);
1744 assert(imgReaderBackwardUncert.nrOfBand()==nmodel);
1746 imgWriterEst.setNoData(obsnodata_opt);
1748 imgWriterEst.open(outputfb_opt[0],ncol,nrow,nmodel,theType,imageType,option_opt);
1749 imgWriterEst.setProjectionProj4(projection_opt[0]);
1750 imgWriterEst.setGeoTransform(geotransform);
1751 imgWriterEst.GDALSetNoDataValue(obsnodata_opt[0]);
1753 imgWriterUncert.open(uncertfb_opt[0],ncol,nrow,nmodel,theType,imageType,option_opt);
1754 imgWriterUncert.setProjectionProj4(projection_opt[0]);
1755 imgWriterUncert.setGeoTransform(geotransform);
1756 for(
int modindex=0;modindex<nmodel;++modindex){
1758 cout <<
"processing time " << tmodel_opt[modindex] << endl;
1759 if(obsindex<relobsindex.size())
1760 cout <<
"next observation " << tmodel_opt[relobsindex[obsindex]] << endl;
1762 cout <<
"There is no next observation" << endl;
1802 vector<double> estForwardBuffer;
1803 vector<double> estBackwardBuffer;
1804 vector<double> uncertObsLineBuffer;
1805 vector<double> uncertForwardBuffer;
1806 vector<double> uncertBackwardBuffer;
1807 vector<double> uncertReadBuffer;
1808 vector<double> estWriteBuffer(ncol);
1809 vector<double> uncertWriteBuffer(ncol);
1813 if(obsindex<relobsindex.size()){
1814 update=(relobsindex[obsindex]==modindex);
1817 int readObsBand=(observation_opt.size()==nobs)? 0:obsindex;
1820 if(observation_opt.size()==nobs){
1822 cout <<
"***update " << relobsindex[obsindex] <<
" = " << modindex <<
" " << observation_opt[obsindex] <<
" ***" << endl;
1823 imgReaderObs.open(observation_opt[obsindex]);
1824 imgReaderObs.setNoData(obsnodata_opt);
1825 imgReaderObs.getGeoTransform(geotransform);
1827 if(observationmask_opt.size()==nobs){
1828 imgReaderObsMask.open(observationmask_opt[obsindex]);
1829 imgReaderObsMask.setNoData(msknodata_opt);
1837 pfnProgress(progress,pszMessage,pProgressArg);
1839 for(
int irow=0;irow<imgWriterEst.nrOfRow();++irow){
1840 assert(irow<imgReaderForward.nrOfRow());
1841 assert(irow<imgReaderBackward.nrOfRow());
1842 imgReaderForward.readData(estForwardBuffer,GDT_Float64,irow,modindex);
1843 imgReaderBackward.readData(estBackwardBuffer,GDT_Float64,irow,modindex);
1844 imgReaderForwardUncert.readData(uncertForwardBuffer,GDT_Float64,irow,modindex);
1845 imgReaderBackwardUncert.readData(uncertBackwardBuffer,GDT_Float64,irow,modindex);
1852 if(observation_opt.size()==nobs)
1853 imgReaderObs.readData(estWriteBuffer,GDT_Float64,irow,readObsBand);
1854 if(observationmask_opt.size())
1855 imgReaderObsMask.readData(uncertObsLineBuffer,GDT_Float64,irow,readObsBand);
1859 for(
int icol=0;icol<imgWriterEst.nrOfCol();++icol){
1860 imgWriterEst.image2geo(icol,irow,geox,geoy);
1861 double A=estForwardBuffer[icol];
1862 double B=estBackwardBuffer[icol];
1863 double C=uncertForwardBuffer[icol];
1864 double D=uncertBackwardBuffer[icol];
1865 double uncertObs=uncertObs_opt[0];
1874 double noemer=(C+D);
1876 if(imgReaderForward.isNoData(A)&&imgReaderBackward.isNoData(B)){
1877 estWriteBuffer[icol]=obsnodata_opt[0];
1878 uncertWriteBuffer[icol]=uncertNodata_opt[0];
1880 else if(imgReaderForward.isNoData(A)){
1881 estWriteBuffer[icol]=B;
1882 uncertWriteBuffer[icol]=uncertBackwardBuffer[icol];
1884 else if(imgReaderForward.isNoData(B)){
1885 estWriteBuffer[icol]=A;
1886 uncertWriteBuffer[icol]=uncertForwardBuffer[icol];
1889 if(noemer<eps_opt[0]){
1890 estWriteBuffer[icol]=0.5*(A+B);
1891 uncertWriteBuffer[icol]=eps_opt[0];
1894 estWriteBuffer[icol]=(A*D+B*C)/noemer;
1895 uncertWriteBuffer[icol]=C*D/noemer;
1896 if(obsmin_opt.size()){
1897 if(estWriteBuffer[icol]<obsmin_opt[0])
1898 estWriteBuffer[icol]=obsmin_opt[0];
1900 if(obsmax_opt.size()){
1901 if(estWriteBuffer[icol]>obsmax_opt[0])
1902 estWriteBuffer[icol]=obsmax_opt[0];
1903 if(uncertWriteBuffer[icol]>obsmax_opt[0])
1904 uncertWriteBuffer[icol]=obsmax_opt[0];
1919 imgWriterEst.writeData(estWriteBuffer,GDT_Float64,irow,modindex);
1920 imgWriterUncert.writeData(uncertWriteBuffer,GDT_Float64,irow,modindex);
1921 progress=
static_cast<float>((irow+1.0)/imgWriterEst.nrOfRow());
1922 pfnProgress(progress,pszMessage,pProgressArg);
1925 if(observation_opt.size()==nobs)
1926 imgReaderObs.close();
1930 imgReaderForward.close();
1931 imgReaderBackward.close();
1932 imgWriterEst.close();
1933 imgWriterUncert.close();
1935 if(observation_opt.size()<nobs)
1936 imgReaderObs.close();
1937 if(model_opt.size()<nmodel)
1938 imgReaderModel1.close();