Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

referencephase.cc

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999-2003 Bert Kampes
00003  * Copyright (c) 1999-2003 Delft University of Technology, The Netherlands
00004  *
00005  * This file is part of Doris, the Delft o-o radar interferometric software.
00006  *
00007  * Doris program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * Doris is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * Publications that contain results produced by the Doris software should
00022  * contain an acknowledgment. (For example: The interferometric processing
00023  * was performed using the freely available Doris software package developed
00024  * by the Delft Institute for Earth-Oriented Space Research (DEOS), Delft
00025  * University of Technology, or include a reference to: Bert Kampes and
00026  * Stefania Usai. \"Doris: The Delft Object-oriented Radar Interferometric
00027  * software.\" In: proceedings 2nd ITC ORS symposium, August 1999. (cdrom)).
00028  *
00029  */
00030 /****************************************************************
00031  * $Source: /users/kampes/DEVELOP/DORIS/doris/src/RCS/referencephase.cc,v $ *
00032  * $Revision: 3.18 $                                            *
00033  * $Date: 2005/04/16 20:47:55 $                                 *
00034  * $Author: kampes $                                            *
00035  *                                                              *
00036  * -computation flat earth correction.                          *
00037  * -computation radarcoding dem + interpolation to (1,1) grid   *
00038  ****************************************************************/
00039 
00040 #include "matrixbk.hh"
00041 #include "orbitbk.hh"
00042 #include "slcimage.hh"                  // my slc image class
00043 #include "productinfo.hh"               // my 'products' class
00044 #include "constants.hh"
00045 #include "referencephase.hh"            // proto types
00046 #include "ioroutines.hh"                // error etc.
00047 #include "utilities.hh"                 // isodd; ones(), etc.
00048 #include "coregistration.hh"            // distribute points
00049 #include "conversion.hh"                // lp2xyz etc.
00050 #include "refsystems.hh"                // for dsk WGS84
00051 #include "exceptions.hh"                 // my exceptions class
00052 
00053 #include <iomanip>                      // setw only for test..
00054 #include <cstdlib>                      // system
00055 #include <algorithm>                    // max
00056 #include <netinet/in.h>                 // ntohl byteorder x86-HP unix
00057 
00058 
00059 
00060 /****************************************************************
00061  *    flatearth                                                 *
00062  *                                                              *
00063  * Compute polynomial model for 'flat earth' correction.        *
00064  *  fie(l,p) = sumj=0:d sumk=0:d Ajk l^j p^k (NOT bert 8sept99) *
00065  * precise orbits are used to compute delta range for Npoints   *
00066  * after which the polynomial model is fitted (LS).             *
00067  *                                                              *
00068  * input:                                                       *
00069  *  - inputoptions                                              *
00070  *  - info structs                                              *
00071  *  - platform data points                                      *
00072  * output:                                                      *
00073  *  - void (result to file "scratchresflat")                    *
00074  *  - coefficients normalized wrt. original window of master    *
00075  *                                                              *
00076  *    Bert Kampes, 09-Mar-1999                                  *
00077  *    Bert Kampes, 26-Oct-1999 normalization of coeff.,         *
00078  *    dump to logfile: var(unknowns) == diag(inv(AtA))          *
00079  ****************************************************************/
00080 void flatearth(
00081         const input_comprefpha &comprefphainput,
00082         const input_ell        &ellips,
00083         const slcimage         &master,
00084         const slcimage         &slave,
00085         const productinfo      &interferogram,
00086         orbit                  &masterorbit,
00087         orbit                  &slaveorbit)
00088   {
00089   TRACE_FUNCTION("flatearth (BK 26-Oct-1999)")
00090   const int32 MAXITER   = 10;
00091   const real8 CRITERPOS = 1e-6;
00092   const real8 CRITERTIM = 1e-10;
00093   char                  dummyline[ONE27];
00094 
00095   INFO << "FLATEARTH: MAXITER: "   << MAXITER   << "; "
00096                   << "CRITERPOS: " << CRITERPOS << " m; "
00097                   << "CRITERTIM: " << CRITERTIM << " s";
00098   INFO.print();
00099 
00100 // ______ Normalization factors for polynomial ______
00101   const real8 minL = master.originalwindow.linelo;
00102   const real8 maxL = master.originalwindow.linehi;
00103   const real8 minP = master.originalwindow.pixlo;
00104   const real8 maxP = master.originalwindow.pixhi;
00105   INFO << "flatearth: polynomial normalized by factors: "
00106        << minL << " " << maxL << " " << minP << " " << maxP
00107        << " to [-2,2]";
00108   INFO.print();
00109 
00110 // ______Handling of input______
00111   const real8 m_minpi4cdivlam = (-4.0*PI*SOL)/master.wavelength;
00112   const real8 s_minpi4cdivlam = (-4.0*PI*SOL)/slave.wavelength;
00113   DEBUG << "master wavelength = " << master.wavelength;
00114   DEBUG.print();
00115   DEBUG << "slave  wavelength = " << slave.wavelength;
00116   DEBUG.print();
00117   const int32 DEGREE    = comprefphainput.degree;
00118   const int32 Nunk      = Ncoeffs(DEGREE);              // Number of unknowns
00119   bool pointsrandom = true;
00120   if (specified(comprefphainput.ifpositions))
00121     pointsrandom = false;                       // only use those points
00122 
00123 
00124 
00125 // ______ Distribute points wel distributed over win ______
00126 // ______ or read from ascii file ______
00127 // ______(i,0): line, (i,1): pixel, (i,2) flagfromdisk______
00128   matrix<uint> Position;
00129   const uint  Npoints = comprefphainput.Npoints;
00130   register int32 i,j,k,index;
00131 
00132   if (pointsrandom)                             // no filename specified
00133     {
00134     Position = distributepoints(Npoints,interferogram.win);
00135     }
00136   else // read from file
00137     {
00138     Position.resize(Npoints,3);
00139     //ifstream ifpos(comprefphainput.ifpositions, ios::in);
00140     ifstream ifpos;
00141     openfstream(ifpos,comprefphainput.ifpositions);
00142     bk_assert(ifpos,comprefphainput.ifpositions,__FILE__,__LINE__);
00143     uint ll,pp;
00144     for (i=0; i<Npoints; ++i)
00145       {
00146       ifpos >> ll >> pp;
00147       Position(i,0) = uint(ll);
00148       Position(i,1) = uint(pp);
00149       Position(i,2) = uint(1);                // flag from file
00150       ifpos.getline(dummyline,ONE27,'\n');       // goto next line.
00151       }
00152     ifpos.close();
00153 
00154 // ______ Check last point ivm. EOL after last position in file ______
00155     if (Position(Npoints-1,0) == Position(Npoints-2,0) &&
00156         Position(Npoints-1,1) == Position(Npoints-2,1))
00157       {
00158       Position(Npoints-1,0) = uint(.5*(minL + maxL) + 27);      // random
00159       Position(Npoints-1,1) = uint(.5*(minP + maxP) + 37);      // random
00160       WARNING << "refpha: there should be no EOL after last point in file: "
00161            << comprefphainput.ifpositions;
00162       WARNING.print();
00163       }
00164 
00165     // ______ Check if points are in overlap ______
00166     // ______ no check for uniqueness of points ______
00167     }
00168 
00169   matrix<real8>         y(Npoints,1);                   // observation
00170   matrix<real8>         A(Npoints,Nunk);                // designmatrix
00171 
00172 // ______Check redundancy______
00173   if (Npoints < Nunk)
00174     {
00175     PRINT_ERROR("flatearth: Number of points is smaller than parameters solved for.")
00176     throw(input_error);
00177     }
00178 
00179 
00180 
00181 // ======Compute delta r for all points======
00182   for (i=0; i<Npoints; ++i)
00183     {
00184     const real8 line  = Position(i,0);
00185     const real8 pixel = Position(i,1);
00186    
00187 // ______ Compute azimuth/range time of this pixel______
00188     //const real8 m_trange = pix2tr(pixel,master.t_range1,master.rsr2x);
00189     const real8 m_trange = master.pix2tr(pixel);
00190    
00191 // ______ Compute xyz of this point P from position in image ______
00192     cn P;                                       // point, returned by lp2xyz
00193     lp2xyz(line,pixel,ellips,master,masterorbit,
00194            P,MAXITER,CRITERPOS);
00195  
00196 // ______ Compute xyz for slave satelite from P ______
00197     real8 s_tazi;                               // returned
00198     real8 s_trange;                             // returned
00199     xyz2t(s_tazi,s_trange,slave,
00200           slaveorbit,
00201           P,MAXITER,CRITERTIM);
00202    
00203 
00204 // ______Compute delta range ~= phase______
00205 // ______ real8 dr = dist(m_possat,pospoint) - dist(s_possat,pospoint);
00206 // ______ real8 phase = -pi4*(dr/LAMBDA);
00207 // ______  dr    == M-S         want if no flatearth M-S - flatearth = M-S-(M-S)=0
00208 // ______  phase == -4pi*dr/lambda == 4pi*(S-M)/lambda
00209 // BK: 24-9: actually defined as: phi = +pi4/lambda * (r1-r2) ???
00210     // real8 phase = pi4*((dist(s_possat,pospoint)-dist(m_possat,pospoint))/LAMBDA);
00211     //y(i,0) = pi4*((dist(s_possat,pospoint)-dist(m_possat,pospoint))/LAMBDA);
00212     //y(i,0) = pi4divlam*(s_possat.dist(pospoint)-m_possat.dist(pospoint));
00213     //y(i,0) = minpi4cdivlam * (m_trange - s_trange);
00214     y(i,0) = m_minpi4cdivlam*m_trange - s_minpi4cdivlam*s_trange;
00215     DEBUG << "l="   << line     << " p="  << pixel 
00216           << " t1=" << m_trange << " t2=" << s_trange
00217           << " fe=" << y(i,0) << " [rad]";
00218     DEBUG.print();
00219 
00220 
00221 // ______Set up system of equations______
00222 // ______Order unknowns: A00 A10 A01 A20 A11 A02 A30 A21 A12 A03 for degree=3______
00223 // ______  normalize data [-2,2] ______
00224     //real8 posP                = (Position(i,1) - minP) / (maxP - minP);
00225     real8 posL          = normalize(line,minL,maxL);
00226     real8 posP          = normalize(pixel,minP,maxP);
00227  
00228     index = 0;
00229     for (j=0; j<=DEGREE; j++)
00230       {
00231       for (k=0; k<=j; k++)
00232         {
00233         A(i,index) = pow(posL,real8(j-k)) * pow(posP,real8(k));
00234         index++;
00235         }
00236       }
00237     }
00238 
00239 
00240 // ======Compute polynomial for these phases (LS)======
00241 // ______Compute Normalmatrix, rghthandside______
00242   matrix<real8> N   = matTxmat(A,A);
00243   matrix<real8> rhs = matTxmat(A,y);
00244 
00245 
00246 // ______Compute solution______
00247   matrix<real8> Qx_hat = N;
00248   choles(Qx_hat);               // Cholesky factorisation normalmatrix
00249   solvechol(Qx_hat,rhs);        // Estimate of unknowns in rhs
00250   invertchol(Qx_hat);           // Covariance matrix
00251 
00252 
00253 // ______Test inverse______
00254   for (i=0; i<Qx_hat.lines(); i++)
00255     for (j=0; j<i; j++)
00256       Qx_hat(j,i) = Qx_hat(i,j);// repair Qx_hat
00257   const real8 maxdev = max(abs(N*Qx_hat-eye(real8(Qx_hat.lines()))));
00258   INFO << "flatearth: max(abs(N*inv(N)-I)) = " << maxdev;
00259   INFO.print();
00260   /*
00261   matrix<real8> unity = N * Qx_hat;
00262   real8 maxdev = abs(unity(0,0)-1);
00263   for (i=1; i<unity.lines(); i++)
00264     {
00265     if (abs(unity(i,i)-1) > maxdev)
00266       maxdev = abs(unity(i,i)-1);
00267     for (j=0; j<i-1; j++)
00268       {
00269       if (abs(unity(i,j)) > maxdev)
00270         maxdev = abs(unity(i,j));
00271       if (abs(unity(j,i)) > maxdev)
00272         maxdev = abs(unity(j,i));
00273       }
00274     }
00275 */
00276   if (maxdev > .01) 
00277     {
00278     ERROR << "Deviation too large. Decrease degree or number of points?";
00279     PRINT_ERROR(ERROR.get_str())
00280     throw(some_error);
00281     }
00282   else if (maxdev > .001) 
00283     {
00284     WARNING << "Deviation quite large. Decrease degree or number of points?";
00285     WARNING.print();
00286     }
00287   else
00288     {
00289     INFO.print("Deviation is OK.");
00290     }
00291 
00292 // ______Some other stuff, scale is ok______
00293 //  matrix<real8> Qy_hat        = A * (matxmatT(Qx_hat,A));
00294   matrix<real8> y_hat   = A * rhs;
00295   matrix<real8> e_hat   = y - y_hat;
00296 
00297 
00298 // ______Overall model test (variance factor)______
00299 // ... ?
00300 
00301 
00302 
00303 
00304 
00305 // ______ Wrap offset ______ 
00306 // BK 30/9/99 do not do this, later absolute ref. phase is used.
00307 // in s2h rodriguez for example.
00308 // it does not change anything for compinterfero etc.
00309 //  rhs(0,0) = remainder(rhs(0,0),2*PI);
00310 
00311 
00312 
00313 // ______Write results to file______
00314   ofstream scratchlogfile("scratchlogflat", ios::out | ios::trunc);
00315   bk_assert(scratchlogfile,"flatearth: scratchlogflat",__FILE__,__LINE__);
00316 
00317   scratchlogfile << "\n\n*******************************************************************"
00318                  //<< "\n*_Start_flatearth"
00319                  << "\n*_Start_" << processcontrol[pr_i_comprefpha]
00320                  << "\nDegree_flat:\t" << DEGREE
00321                  << "\nEstimated coefficients:\n"
00322                  << "\nx_hat \tstd:\n";
00323   for (i=0; i<Nunk; i++)
00324     scratchlogfile
00325                  << setiosflags(ios::fixed)
00326                  << setiosflags(ios::showpoint)
00327                  << setiosflags(ios::right)
00328                  << setw(8) << setprecision(4) 
00329                  <<  rhs(i,0) << " \t" << sqrt(Qx_hat(i,i)) << endl;
00330 
00331   scratchlogfile << "\nCovariance matrix estimated parameters:"
00332                  << "\n---------------------------------------\n";
00333   for (i=0; i<Nunk; i++)
00334     {
00335     for (j=0; j<Nunk; j++)
00336       {
00337       scratchlogfile 
00338                  << setiosflags(ios::fixed)
00339                  << setiosflags(ios::showpoint)
00340                  << setiosflags(ios::right)
00341                  << setw(8) << setprecision(4) 
00342                  << Qx_hat(i,j) << " ";
00343       }
00344     scratchlogfile << endl;
00345     }
00346 
00347   scratchlogfile << "\nMaximum deviation N*inv(N):"
00348                  << setiosflags(ios::scientific)
00349                  << maxdev
00350                  << "\nSome more info for each observation:"
00351                  << "\nline \tpixel \tobs \t\tobs_hat \t\t err_hat\n";
00352   for (i=0; i<Npoints; i++)
00353     scratchlogfile <<  Position(i,0) << "\t" <<  Position(i,1) << "\t"
00354                    << y(i,0) << "\t" << y_hat(i,0) << "\t"
00355                    << setiosflags(ios::fixed)
00356                    << setiosflags(ios::showpoint)
00357                    << setiosflags(ios::right)
00358                    << setw(8) << setprecision(4) 
00359                    << e_hat(i,0) << "\n";
00360   scratchlogfile << "\nMaximum absolute error: \t\t\t"
00361                  <<  max(abs(e_hat))
00362                  << "\n*******************************************************************\n";
00363   scratchlogfile.close();
00364 
00365   ofstream scratchresfile("scratchresflat", ios::out | ios::trunc);
00366   bk_assert(scratchresfile,"flatearth: scratchresflat",__FILE__,__LINE__);
00367 
00368   scratchresfile.setf(ios::scientific, ios::floatfield);
00369   scratchresfile.setf(ios::right, ios::adjustfield);
00370   scratchresfile.precision(8);
00371   scratchresfile.width(18);
00372 
00373   scratchresfile << "\n\n*******************************************************************"
00374                  //<< "\n*_Start_flat_earth"
00375                  << "\n*_Start_" << processcontrol[pr_i_comprefpha]
00376                  << "\n*******************************************************************"
00377                  << "\nDegree_flat:\t" << DEGREE
00378                  << "\nEstimated_coefficients_flatearth:\n";
00379   int32 coeffL = 0;
00380   int32 coeffP = 0;
00381   for (i=0; i<Nunk; i++)
00382     {
00383     if (rhs(i,0) < 0.)
00384       scratchresfile <<         rhs(i,0);
00385     else
00386       scratchresfile << " " <<  rhs(i,0);
00387 
00388 // ______ Add coefficient number behind value ______
00389     scratchresfile << " \t" <<  coeffL << " " << coeffP << "\n";
00390     coeffL--;
00391     coeffP++;
00392     if (coeffL == -1)
00393       {
00394       coeffL = coeffP;
00395       coeffP = 0;
00396       }
00397     }
00398 
00399   scratchresfile << "*******************************************************************"
00400                  << "\n* End_" << processcontrol[pr_i_comprefpha] << "_NORMAL"
00401                  << "\n*******************************************************************\n";
00402 
00403 
00404 // ====== Compute coordinates of corners of interferogram here ======
00405 // ______ (though better place this somewhere else ....
00406   real8 phi,lambda,height;                              // rad, returned
00407   lp2ell(interferogram.win.linelo,interferogram.win.pixlo,
00408          ellips,master,masterorbit,
00409          phi,lambda,height,MAXITER,CRITERPOS);
00410   INFO << "Coordinates of corner interferogram: "
00411        << interferogram.win.linelo << ", " << interferogram.win.pixlo
00412        << " = " << rad2deg(phi) << ", " << rad2deg(lambda);
00413   INFO.print();
00414   lp2ell(interferogram.win.linehi,interferogram.win.pixlo,
00415          ellips,master,masterorbit,
00416          phi,lambda,height,MAXITER,CRITERPOS);
00417   INFO << "Coordinates of corner interferogram: "
00418        << interferogram.win.linehi << ", " << interferogram.win.pixlo
00419        << " = " << rad2deg(phi) << ", " << rad2deg(lambda);
00420   INFO.print();
00421   lp2ell(interferogram.win.linelo,interferogram.win.pixhi,
00422          ellips,master,masterorbit,
00423          phi,lambda,height,MAXITER,CRITERPOS);
00424   INFO << "Coordinates of corner interferogram: "
00425        << interferogram.win.linelo << ", " << interferogram.win.pixhi
00426        << " = " << rad2deg(phi) << ", " << rad2deg(lambda);
00427   INFO.print();
00428   lp2ell(interferogram.win.linehi,interferogram.win.pixhi,
00429          ellips,master,masterorbit,
00430          phi,lambda,height,MAXITER,CRITERPOS);
00431   INFO << "Coordinates of corner interferogram: "
00432        << interferogram.win.linehi << ", " << interferogram.win.pixhi
00433        << " = " << rad2deg(phi) << ", " << rad2deg(lambda);
00434   INFO.print();
00435 
00436 // ______Tidy up______
00437   scratchresfile.close();
00438   } // END flatearth
00439 
00440 
00441 
00442 /****************************************************************
00443  *    radarcodedem                                              *
00444  *                                                              *
00445  * Compute reference phase based on DEM (gtopo30)               *
00446  * DEM on equiangular grid (lat/lon) assumed                    *
00447  * DEM seems stored from North to South                         *
00448  *                                                              *
00449  * Implementation:                                              *
00450  * 0) find out dphi,dlambda for multilooked interferogram       *
00451  * 1) get dem on equidistant grid into matrix                   *
00452  * 2) interpolate this DEM dense enough                         *
00453  * 3) convert interpolated DEM to l,p,refpha                    *
00454  * 3) for line=first:mlL:last                                   *
00455  *        pixel=first:mlP:last  (interferogram window)          *
00456  *      nearest neighbour to l,p from dem                       *
00457  *                                                              *
00458  * input:                                                       *
00459  * output:                                                      *
00460  *                                                              *
00461  *    Bert Kampes, 18-Jan-2000                                  *
00462  *                                                              *
00463  * small changes wrt formats, more verbose, error checking.     *
00464  #%// BK 13-Apr-2002                                            *
00465  * phi is latitude, lambda is longitude                         *
00466  #%// BK 19-Apr-2002                                            *
00467  ****************************************************************/
00468 void radarcodedem(
00469         const input_gen        &generalinput,
00470         const input_ell        &ellips,
00471         const input_comprefdem &refdeminput,
00472         const slcimage         &master,
00473         const slcimage         &slave,
00474         const productinfo      &interferogram,
00475         orbit                  &masterorbit,
00476         orbit                  &slaveorbit)
00477   {
00478   TRACE_FUNCTION("radarcodedem (BK 18-Jan-2000)")
00479   const int32 MAXITER   = 10;
00480   const real8 CRITERPOS = 1e-6;
00481   const real8 CRITERTIM = 1e-10;
00482 
00483   // ====== Handle input ======
00484   // ______ See gtopo30.HDR file, assume equiangular grid ______
00485   //  // ______ Equi angular grid with spacing delatlat/lon ______
00486   //  // ______ Assume increasing lon per row ______
00487   //    NROWS         6000
00488   //    NCOLS         4800
00489   //    NBANDS        1
00490   //    NBITS         16
00491   //    NODATA        -9999
00492   //    ULXMAP        -19.99583333333333
00493   //    ULYMAP        89.99583333333334
00494   //    XDIM          0.00833333333333
00495   //    YDIM          0.00833333333333
00496   //    format=...
00497   //const real8 lat0file    = deg2rad(89.99583333333334);// first pix on disk w02090
00498   //const real8 DEMdeltalat = deg2rad(0.00833333333);   // in radians
00499 
00500   char demfilename[ONE27];
00501   char refdemofilename[ONE27];
00502 
00503   strcpy (demfilename,refdeminput.firefdem);
00504   strcpy (refdemofilename,refdeminput.forefdem);
00505   const real8 lat0file    = refdeminput.demlatleftupper;// first pix on disk w02090
00506   const real8 lon0file    = refdeminput.demlonleftupper;// first pix on disk
00507   const real8 DEMdeltalat = refdeminput.demdeltalat;    // in radians
00508   const real8 DEMdeltalon = refdeminput.demdeltalon;    // in radians
00509   const int32 numberoflonpixels = refdeminput.demcols;  // NCOLS on file
00510   const int32 numberoflatpixels = refdeminput.demrows;  // NROWS on file
00511   const real8 NODATA      =  refdeminput.demnodata;     // (BK 4 may 2001)
00512   bool onlyrefphasetopo   = !refdeminput.includerefpha; // true: phase DEM w.r.t. ellipsoid
00513   const real8 EXTRADENSE  =  refdeminput.extradense;    // account for overlay etc.
00514   const bool outputdem    =  specified(refdeminput.fodem);// if spec. then output
00515   const bool outputdemi   =  specified(refdeminput.fodemi);// if spec. then output
00516   // Bert Kampes, 16-Apr-2005: addition output for geocoding using
00517   // an external DEM; you can dump the height in meters in radarcoordinates
00518   // then use geocode to obtain lat/lon matrices.
00519   // extra output for Zbigniew Perski (04/2005)
00520   // if specified, then output (always do phase too)
00521   const bool outputrefdemhei   =  specified(refdeminput.forefdemhei);
00522   const bool do_nearest   = (refdeminput.method==crd_nearest) ? true : false;
00523 
00524   // ______ Some other variables ______
00525   const int32 mlL = interferogram.multilookL;   // multilookfactor interferogram
00526   const int32 mlP = interferogram.multilookP;   // multilookfactor interferogram
00527   const real8 m_min4picdivlam = (-4.0*PI*SOL)/master.wavelength;
00528   const real8 s_min4picdivlam = (-4.0*PI*SOL)/slave.wavelength;
00529   DEBUG << "master wavelength = " << master.wavelength;
00530   DEBUG.print();
00531   DEBUG << "slave  wavelength = " << slave.wavelength;
00532   DEBUG.print();
00533 
00534   const real8 latNfile = lat0file-DEMdeltalat*(numberoflatpixels-1); // upper=max. lat value
00535   const real8 lonNfile = lon0file+DEMdeltalon*(numberoflonpixels-1); // left=min. lon value
00536   real8 phi, lambda, height;                            // latitude longitude height
00537 
00538   // ______ Extra info ______
00539   INFO << "DEM input: w/e/s/n:          \t"
00540        << rad2deg(lon0file) << "/" << rad2deg(lonNfile) << "/"
00541        << rad2deg(latNfile) << "/" << rad2deg(lat0file);
00542   INFO.print();
00543 
00544 
00545   // ______ Open output file ______
00546   ofstream refdemofile;
00547   openfstream(refdemofile,refdemofilename,generalinput.overwrit);
00548   bk_assert(refdemofile,refdemofilename,__FILE__,__LINE__);
00549   // if request for height in radar coordinates l,p
00550   ofstream refdemheiofile;// for Zbigniew Perski
00551   if (outputrefdemhei==true)
00552     {
00553     openfstream(refdemheiofile,refdeminput.forefdemhei,generalinput.overwrit);
00554     bk_assert(refdemheiofile,refdeminput.forefdemhei,__FILE__,__LINE__);
00555     }
00556 
00557   // ______ Get corners of interferogram (approx) to select DEM ______
00558   // ______ in radians (if height were zero)______
00559   lp2ell(interferogram.win.linelo, interferogram.win.pixlo,
00560          ellips, master, masterorbit,
00561          phi, lambda, height);          // returned
00562   real8 phil0p0    = phi;
00563   real8 lambdal0p0 = lambda;
00564 
00565   lp2ell(interferogram.win.linehi, interferogram.win.pixlo,
00566          ellips, master, masterorbit,
00567          phi, lambda, height);          // returned
00568   real8 philNp0    = phi;
00569   real8 lambdalNp0 = lambda;
00570 
00571   lp2ell(interferogram.win.linehi, interferogram.win.pixhi,
00572          ellips, master, masterorbit,
00573          phi, lambda, height);          // returned
00574   real8 philNpN    = phi;
00575   real8 lambdalNpN = lambda;
00576 
00577   lp2ell(interferogram.win.linelo, interferogram.win.pixhi,
00578          ellips, master, masterorbit,
00579          phi, lambda, height);          // returned
00580   real8 phil0pN    = phi;
00581   real8 lambdal0pN = lambda;
00582 
00583   // find out spacing of interferogram, use last pixel for densest gridding.
00584   lp2ell(interferogram.win.linelo+mlL, interferogram.win.pixhi-mlP,
00585          ellips, master, masterorbit,
00586          phi, lambda, height);          // returned
00587   const real8 dphi_interferogram    = abs(phi-phil0pN);
00588   const real8 dlambda_interferogram = abs(lambda-lambdal0pN);
00589 
00590   // ______ Select DEM values based on rectangle outside l,p border ______
00591   real8 phimin    = min(min(min(phil0p0,philNp0),philNpN),phil0pN);
00592   real8 phimax    = max(max(max(phil0p0,philNp0),philNpN),phil0pN);
00593   real8 lambdamin = min(min(min(lambdal0p0,lambdalNp0),lambdalNpN),lambdal0pN);
00594   real8 lambdamax = max(max(max(lambdal0p0,lambdalNp0),lambdalNpN),lambdal0pN);
00595 
00596   // ______ a little bit extra at edges to be sure ______ 
00597   const real8 extrafarrange = (1.5*DEMdeltalon + deg2rad(1.0/25.0));
00598   const real8 extralatitude = (1.5*DEMdeltalon + deg2rad(1.0/25.0));
00599   phimin    -= extralatitude;
00600   phimax    += extralatitude;
00601   lambdamax += extrafarrange;
00602   lambdamin -= extrafarrange;
00603 
00604   // ______ Extra info ______
00605   INFO << "DEM input required: w/e/s/n: \t"
00606        << rad2deg(lambdamin) << "/" << rad2deg(lambdamax) << "/"
00607        << rad2deg(phimin)    << "/" << rad2deg(phimax);
00608   INFO.print();
00609   INFO << "For window (l0,lN,p0,pN):    \t"
00610        << interferogram.win.linelo << " "
00611        << interferogram.win.linehi << " "
00612        << interferogram.win.pixlo << " "
00613        << interferogram.win.pixhi;
00614   INFO.print();
00615 
00616 
00617   // ______ Check corners of DEM ______
00618   // check if DEM is appropriate for interferogram
00619   // DEM should at least partially cover IFG
00620   // note: phi is [90:-90]
00621   if (phimax <= latNfile)// DEM is more north than IFG
00622     {
00623     ERROR << "IFG outside DEM: most South latitude: " << rad2deg(latNfile)
00624          << " [deg]; IFG requires: " << rad2deg(phimax) 
00625          << " [deg]";
00626     PRINT_ERROR(ERROR.get_str())
00627     throw(some_error);
00628     }
00629   // DEM is more south than IFG
00630   if (phimin >= lat0file)// largest latitude at first line of file
00631     {
00632     ERROR << "IFG outside DEM: most North latitude: " << rad2deg(lat0file)
00633          << " [deg]; IFG requires: " << rad2deg(phimax)
00634          << " [deg]";
00635     PRINT_ERROR(ERROR.get_str())
00636     throw(some_error);
00637     }
00638   if (lambdamax <= lon0file)
00639     {
00640     ERROR << "IFG outside DEM: most West longitude: " << rad2deg(lon0file)
00641          << " [deg]; IFG window requires: " << rad2deg(lambdamax)
00642          << " [deg]";
00643     PRINT_ERROR(ERROR.get_str())
00644     throw(some_error);
00645     }
00646   if (lambdamin >= lonNfile)
00647     {
00648     ERROR << "IFG outside DEM: most East longitude: " << rad2deg(lonNfile)
00649          << " [deg]; IFG window requires: " << rad2deg(lambdamin)
00650          << " [deg]";
00651     PRINT_ERROR(ERROR.get_str())
00652     throw(some_error);
00653     }
00654 
00655 
00656   // ______ Line/pixel of first point in original master coordinates ______
00657   // ______ maybe this should be changed to be x+(ml/2) ?? but depends on
00658   // ______ definition of range_to_first_bin is to center or start..
00659   // Bert Kampes, 08-Apr-2005: chose center by adding ml/2
00660   const int32 numlinesml    = interferogram.win.lines()  / mlL;
00661   const int32 numpixelsml   = interferogram.win.pixels() / mlP;
00662   const real8 veryfirstline = real8(interferogram.win.linelo) + real8(mlL)/2.0;
00663                                 //(real8(mlL)-1.0) / 2.0;
00664   const real8 firstpixel    = real8(interferogram.win.pixlo)  + real8(mlP)/2.0;
00665                                 //(real8(mlP)-1.0) / 2.0;
00666   const real8 lastpixel     = firstpixel + real8((numpixelsml-1)*mlP);
00667 
00668   // ______ Compute oversamplefactor for interpolation of DEM ______
00669   const int32 DEMphioversamplefactor =                  // e.g. 4.2 -> 5
00670     int32(ceil(EXTRADENSE * DEMdeltalat / dphi_interferogram));// >=1
00671   const int32 DEMlambdaoversamplefactor =
00672     int32(ceil(EXTRADENSE * DEMdeltalon / dlambda_interferogram));// >=1
00673   if (DEMphioversamplefactor > 20)
00674     {
00675     WARNING << "Resolution IFG latitude much higher than DEM: "
00676          << rad2deg(dphi_interferogram) << " [deg] <--> "
00677          << rad2deg(DEMdeltalat) << " [deg].";
00678     WARNING.print();
00679     }
00680   if (DEMlambdaoversamplefactor > 20)
00681     {
00682     WARNING << "Resolution IFG longitude much higher than DEM: "
00683          << rad2deg(dlambda_interferogram) << " [deg] <--> "
00684          << rad2deg(DEMdeltalon) << " [deg].";
00685     WARNING.print();
00686     }
00687 
00688   // ______ Extra info ______
00689   INFO << "Approximate longitude resolution IFG: "
00690        << rad2deg(dlambda_interferogram) << " [deg].";
00691   INFO.print();
00692   INFO << "Approximate latitude resolution IFG:  "
00693        << rad2deg(dphi_interferogram) << " [deg].";
00694   INFO.print();
00695   INFO << "DEM oversampled with factors (lat/lon): "
00696        << DEMphioversamplefactor << " " << DEMlambdaoversamplefactor;
00697   INFO.print();
00698 
00699   // ______ Added some variables for verboser output BK 13-Apr-2002 ______
00700   int32 numNOneighbor   = 0;// number of no neigbor points. in buffer
00701   int32 totalNOneighbor = 0;// number of no neigbor points.
00702   int32 numvalid        = 0;// number of good values, not NODATA in buffer
00703   int32 numNODATA       = 0;// number of NODATA values in buffer
00704   real8 meancroppedDEM  = 0.0;// to detect byte order problems, formats
00705   real8 min_input_dem   =  100000.0;// stats
00706   real8 max_input_dem   = -100000.0;// stats
00707 
00708 
00709   // ______ Buffer variables ______
00710   // memory usage is approximately 4arrays*8Byte*ofsize(DEMinterp)
00711   // and size of DEMinterp = sizeDEM*oversamplingfactors
00712   // approximate this a bit by saying DEMinterp
00713   // the input DEM is cropped a little bit larger in far range,
00714   // account for this here. by multiplying with a factor.
00715   const real8 BUFFERMEMSIZE    = generalinput.memory;// Bytes
00716   const real8 numelements_line_DEMI = 
00717     ((lambdamax-lambdamin)/DEMdeltalat) * DEMlambdaoversamplefactor;
00718   // ______ 4 arrays required of this size, of 8B doubles ______
00719   const real8 numlines_possible_DEMi =
00720     BUFFERMEMSIZE / (4*8*numelements_line_DEMI);
00721   // ______ bufferlines are of output IFG ______
00722   int32 bufferlines = 
00723     int32(ceil(numlines_possible_DEMi/DEMphioversamplefactor));
00724   if (bufferlines>numlinesml) bufferlines=numlinesml;
00725   int32 numfullbuffers = numlinesml / bufferlines;
00726   int32 restlines      = numlinesml % bufferlines;
00727   // ______ Avoid a very small last buffer (max. 20% of normal size) ______
00728   if (real8(restlines)/real8(bufferlines) < 0.20)
00729     if (restlines!=0)
00730       bufferlines = int32((numlinesml/numfullbuffers)); 
00731   // ______ And compute the buffersizes finally ______
00732   numfullbuffers = numlinesml / bufferlines;
00733   restlines      = numlinesml % bufferlines;
00734   const int32 EXTRABUFFER = (restlines == 0) ? 0 : 1;   // smaller last buffer
00735  
00736   // ______ Extra info ______
00737   INFO << "Computatation in: " << numfullbuffers << " buffers of " << bufferlines
00738        << " lines and " << EXTRABUFFER << " extra buffer of "
00739        << restlines << " lines.";
00740   INFO.print();
00741   if (bufferlines < 50) 
00742     WARNING.print("Small buffersize: increase MEMORY or decrease EXTRADENSE?");
00743 
00744   // ______ The big loop per buffer ______
00745   register int32 i,j;// DEM index grid counter
00746   for (register int32 buffer=0; buffer<numfullbuffers+EXTRABUFFER; ++buffer)
00747     {
00748     const real8 firstline = veryfirstline + real8(buffer*bufferlines*mlL);
00749     const int32 blines = (buffer == numfullbuffers) ? restlines : bufferlines;
00750     matrix<real4> OBUFFER(blines,numpixelsml);
00751     if (buffer == numfullbuffers) // smaller last one, EXTRABUFFER==1
00752       OBUFFER.resize(restlines,numpixelsml);
00753     const real8 lastline  = firstline + real8((OBUFFER.lines()-1)*mlL);
00754 
00755     // ______ Extra info ______
00756     PROGRESS << "Buffer# [l0:lN, p0:pN]: " << buffer+1 << " ["
00757          << firstline  << ": " << lastline  << ", "
00758          << firstpixel << ": " << lastpixel << "]";
00759     PROGRESS.print();
00760 
00761     // ______ find out corners of this buffer in phi/lambda ______
00762     lp2ell(firstline, firstpixel,
00763            ellips, master, masterorbit,
00764            phi, lambda, height);                // returned
00765     phil0p0    = phi;
00766     lambdal0p0 = lambda;
00767     lp2ell(lastline, firstpixel,
00768            ellips, master, masterorbit,
00769            phi, lambda, height);                // returned
00770     philNp0    = phi;
00771     lambdalNp0 = lambda;
00772     lp2ell(lastline,lastpixel,
00773            ellips, master, masterorbit,
00774            phi, lambda, height);                // returned
00775     philNpN    = phi;
00776     lambdalNpN = lambda;
00777     lp2ell(firstline,lastpixel,
00778            ellips, master, masterorbit,
00779            phi, lambda, height);                // returned
00780     phil0pN    = phi;
00781     lambdal0pN = lambda;
00782 
00783     // ______ Corners for DEM 2b read from disk ______
00784     // BK 14-Feb-00
00785     phimin    = min(min(min(phil0p0,philNp0),philNpN),phil0pN);
00786     phimax    = max(max(max(phil0p0,philNp0),philNpN),phil0pN);
00787     lambdamin = min(min(min(lambdal0p0,lambdalNp0),lambdalNpN),lambdal0pN);
00788     lambdamax = max(max(max(lambdal0p0,lambdalNp0),lambdalNpN),lambdal0pN);
00789 
00790     // ______ Read extra large part from DEM because due to layover etc. ______
00791     // BK 20-Apr-2002
00792     //phimin    -= deg2rad(1/200.); // 1 degree is 100 km (equator)
00793     // longitude far range can be problem if height, say 2 km extra.)
00794     // because of skewed geometry of IFG over DEM North/South.
00795     // 1 degree is 100 km, 2 km extra should do it, if mountain is < 2 km?.
00796     //phimin    -= 1.5*DEMdeltalat;
00797     //const real8 extrafarrange = (1.5*DEMdeltalon + deg2rad(1.0/100.0));
00798     //const real8 extralatitude = (1.5*DEMdeltalon + deg2rad(1.0/100.0));
00799     phimin    -= extralatitude;
00800     phimax    += extralatitude;
00801     lambdamax += extrafarrange;
00802     lambdamin -= extrafarrange;
00803     INFO << "Using larger DEM input for far range: "
00804          << rad2deg(extrafarrange) << " [deg]";
00805     INFO.print();
00806 
00807 
00808     // ====== Read DEM from file ======
00809     // ______ Get index of first line/pixel to load from file ______
00810     // ______ Index boundary: [0:numberofx-1] ______
00811     // ______ upperleft == max_lat,min_lon ______
00812     int32 indexphi0DEM = int32(floor((lat0file-phimax)/DEMdeltalat));
00813     if (indexphi0DEM < 0) 
00814       {
00815       indexphi0DEM=0;           // default start at first
00816       WARNING.print("DEM does not cover entire interferogram.");
00817       WARNING.print("input DEM should be extended to the North.");
00818       }
00819     int32 indexphiNDEM = int32(ceil((lat0file-phimin)/DEMdeltalat));
00820     if (indexphiNDEM > numberoflatpixels-1)
00821       {
00822       indexphiNDEM=numberoflatpixels-1;
00823       WARNING.print("DEM does not cover entire interferogram.");
00824       WARNING.print("input DEM should be extended to the South.");
00825       }
00826     int32 indexlambda0DEM = int32(floor((lambdamin-lon0file)/DEMdeltalon));
00827     if (indexlambda0DEM < 0)
00828       {
00829       indexlambda0DEM=0;                // default start at first
00830       WARNING.print("DEM does not cover entire interferogram.");
00831       WARNING.print("input DEM should be extended to the West.");
00832       }
00833     int32 indexlambdaNDEM = int32(ceil((lambdamax-lon0file)/DEMdeltalon));
00834     if (indexlambdaNDEM > numberoflonpixels-1)
00835       {
00836       indexlambdaNDEM=numberoflonpixels-1;
00837       WARNING.print("DEM does not cover entire interferogram.");
00838       WARNING.print("input DEM should be extended to the East.");
00839       }
00840 
00841     // ______ lat/lon for first pixel in matrix read from file ______
00842     // ______ upper is max. latitude, left is min. longitude ______
00843     const real8 upperleftphi    = lat0file-indexphi0DEM*DEMdeltalat;
00844     const real8 upperleftlambda = lon0file+indexlambda0DEM*DEMdeltalon;
00845 
00846     window zerooffset  (0,0,0,0);
00847     window winfromfile (indexphi0DEM,indexphiNDEM,
00848                         indexlambda0DEM,indexlambdaNDEM);
00849 
00850     // BK: COMMENTED OUT 4may2001, see below.
00851     //      // gtopo30 (lat,lon) ... format signed short
00852     //      // leftupper is first
00853     //      // ?? assume lat 0:90, what if 0:-90 ?
00854     //      // check how to with other formats?
00855     //      matrix<int16> DEM(indexphiNDEM-indexphi0DEM+1,indexlambdaNDEM-indexlambda0DEM+1);
00856     //      readfile(DEM,demfilename,numberoflatpixels,winfromfile,zerooffset);
00857     //      // phi (latitude) is stored rowwise, starting at leftupperphi
00858     //      // lambda (longitude) are the columns, start=leftupperlambda.
00859 
00860     // ______ Read in grdfile of DEM in matrix R4 (raw data, no header) _______
00861     // ______ added formats (BK 4-May-2001) ______
00862     PROGRESS << "Reading crop of DEM for buffer: " << buffer+1;
00863     PROGRESS.print();
00864     DEBUG.print("Reading input DEM into real4 matrix (buffer).");
00865     matrix<real4> DEM(indexphiNDEM-indexphi0DEM+1,indexlambdaNDEM-indexlambda0DEM+1);
00866     switch (refdeminput.iformatflag)
00867       {
00868       // ______ Read as short BE, then convert to host order ______
00869       case FORMATI2_BIGENDIAN:
00870         {
00871         matrix<int16> DEMi2(indexphiNDEM-indexphi0DEM+1,indexlambdaNDEM-indexlambda0DEM+1);
00872         readfile(DEMi2,demfilename,numberoflatpixels,winfromfile,zerooffset);
00873         for (int32 iii=0; iii<DEM.lines(); ++iii)
00874           for (int32 jjj=0; jjj<DEM.pixels(); ++jjj)
00875             DEM(iii,jjj) = real4(ntohs(DEMi2(iii,jjj)));// cast to real4
00876         DEMi2.resize(1,1);// dealloc...
00877         INFO.print("Read crop of input DEM: format: SHORT SIGNED INT.");
00878         break;
00879         }
00880 
00881       case FORMATI2:
00882         {
00883         matrix<int16> DEMi2(indexphiNDEM-indexphi0DEM+1,indexlambdaNDEM-indexlambda0DEM+1);
00884         readfile(DEMi2,demfilename,numberoflatpixels,winfromfile,zerooffset);
00885         for (int32 iii=0; iii<DEM.lines(); ++iii)
00886           for (int32 jjj=0; jjj<DEM.pixels(); ++jjj)
00887             DEM(iii,jjj) = DEMi2(iii,jjj);// cast to real4
00888         DEMi2.resize(1,1);// dealloc...
00889         INFO.print("Read crop of input DEM: format: SHORT SIGNED INT.");
00890         break;
00891         }
00892 
00893       case FORMATR4:
00894         readfile(DEM,demfilename,numberoflatpixels,winfromfile,zerooffset);
00895         INFO.print("Read crop of input DEM: format: REAL4.");
00896         break;
00897       case FORMATR8:
00898         {
00899         matrix<real8> DEMr8(indexphiNDEM-indexphi0DEM+1,indexlambdaNDEM-indexlambda0DEM+1);
00900         readfile(DEMr8,demfilename,numberoflatpixels,winfromfile,zerooffset);
00901         for (int32 iii=0; iii<DEM.lines(); ++iii)
00902           for (int32 jjj=0; jjj<DEM.pixels(); ++jjj)
00903             DEM(iii,jjj) = DEMr8(iii,jjj);// cast to real4
00904         DEMr8.resize(1,1);// dealloc...
00905         INFO.print("Read crop of input DEM: format: REAL8.");
00906         break;
00907         }
00908       default:
00909         PRINT_ERROR("totally impossible, checked input.")
00910         throw(unhandled_case_error);
00911       }
00912 
00913 
00914 
00915     // ----- Loop over DEM for stats ------------------------
00916     real8 min_dem_buffer =  100000.0;
00917     real8 max_dem_buffer = -100000.0;
00918     for (i=0; i<DEM.lines(); ++i)
00919       {
00920       // ----- Loop over oversampled matrix in x ------
00921       for (j=0; j<DEM.pixels(); ++j)
00922         {
00923         if(DEM(i,j)!=NODATA)
00924           {
00925           numvalid++;
00926           meancroppedDEM += DEM(i,j);// divide by numvalid later
00927           if (DEM(i,j)<min_dem_buffer) min_dem_buffer=DEM(i,j);//buffer
00928           if (DEM(i,j)>max_dem_buffer) max_dem_buffer=DEM(i,j);// stats
00929           }
00930         else
00931           {
00932           numNODATA++;
00933           }
00934         }//loop dem for stats
00935       }//loop dem for stats
00936     min_input_dem = min(min_input_dem,min_dem_buffer);//global stats
00937     max_input_dem = max(max_input_dem,max_dem_buffer);//global stats
00938 
00939 
00940     // ______ Interpolate DEM with dense enough grid spacing ______
00941     // ______ Cubic conv. first point upto (not including) last one ______
00942     PROGRESS << "Oversampling DEM by bilinear splines for buffer: "
00943          << buffer+1;
00944     PROGRESS.print();
00945     matrix<real4> DEMinterpolated(
00946       (DEM.lines()-1)*DEMphioversamplefactor,
00947       (DEM.pixels()-1)*DEMlambdaoversamplefactor);
00948 
00949     const real8 deltalatDEMinterpolated = 
00950       DEMdeltalat/real8(DEMphioversamplefactor);
00951     const real8 deltalonDEMinterpolated = 
00952       DEMdeltalon/real8(DEMlambdaoversamplefactor);
00953     // ------ Check if they are equal, due to small extradense, -----
00954     // ------ high input resolution, or large multilooking ------
00955     if (DEMphioversamplefactor==1 && DEMlambdaoversamplefactor==1)
00956       {
00957       INFO.print("Interpolated DEM same as input DEM, making a copy");
00958       INFO.print("-> extradense small, e.g., method trilinear");
00959       INFO.print("-> or maybe input dem has already high resolution");
00960       INFO.print("-> or maybe large multilooking factors.");
00961       DEMinterpolated = DEM;// could be done with swap?
00962       }
00963     // ______ Do bilinear interpolation ______
00964     else
00965       {
00966       // ______ Do bilinear interpolation ______
00967       // f(row,col) = a00 + a01*c + a10*r +a11*r*c 
00968       // P1(0,0); P2(0,1); P3(1,0); P4(1,1); P[0:1,0:1];
00969       //
00970       //         cols->  
00971       //      r P1    P2
00972       //      o    .P
00973       //      w P3    P4
00974       //      s
00975       // ----- Loop over oversampled matrix in y ------
00976       for (i=0; i<DEM.lines()-1; ++i)   // bi-c: use i,i+1 -> 4 points
00977           {
00978         if ((i%100)==0)
00979           {
00980           PROGRESS << "Interpolation of DEM: line: " << i << " (" 
00981                << floor(.5+(100.*real8(i)/real8(DEM.lines())))
00982                << "%)";
00983           PROGRESS.print();
00984           }
00985         // ----- Loop over oversampled matrix in x ------
00986         for (j=0; j<DEM.pixels()-1; ++j)
00987           {
00988           // ______ 4 points required for bilinear ______
00989           // ______ other interpolators may need more points ______
00990           // ______ We assume the user can externally oversample ______
00991           // ______ the input DEM to high enough resolution  ______
00992           const real4 P1 = DEM(i,j);
00993           const real4 P2 = DEM(i,j+1);
00994           const real4 P3 = DEM(i+1,j);
00995           const real4 P4 = DEM(i+1,j+1);
00996           // ______ check if NODATA then set h=zero -> flatearth correction ______
00997           if (P1==NODATA || P2==NODATA || P3==NODATA || P4==NODATA)
00998             {
00999             // for (k=i*factor; k<(i+1)*factor; ++k)
01000             //   for (l=j*factor; l<(j-1)factor; ++l)
01001             //     DEMinterpolated(k,l)=0.;
01002             // DEMinterpolated is already 0 initialized.
01003             //break;
01004             continue;   // with next j
01005             }
01006           // ______ Else bilinear interpolation to finer grid ______
01007           // ______ ignore last line/row for speed. ______
01008           const real4 a00 = P1;
01009           const real4 a01 = P2-P1;
01010           const real4 a10 = P3-P1;
01011           const real4 a11 = P4-P3-P2+P1;
01012           const int indexrowinterpolated = i*DEMphioversamplefactor;
01013           const int indexcolinterpolated = j*DEMlambdaoversamplefactor;
01014           register real4 row = 0.0;
01015           for (int32 k=indexrowinterpolated;
01016                      k<indexrowinterpolated+DEMphioversamplefactor;
01017                      ++k)
01018             {
01019             register real4 col = 0.0;
01020             for (int32 l=indexcolinterpolated;
01021                        l<indexcolinterpolated+DEMlambdaoversamplefactor;
01022                        ++l)
01023               {
01024               DEMinterpolated(k,l) = a00 + a01*col + a10*row + a11*col*row;
01025               col += 1.0/DEMlambdaoversamplefactor;
01026               }
01027             row += 1.0/DEMphioversamplefactor;
01028             }
01029           } // loop DEM pixels
01030         } // loop DEM lines
01031       }// End check interpolation required
01032 
01033 
01034     // ====== Output debugging matrices if requested ======
01035     if (outputdem)
01036       {
01037       // create a new file per buffer for cropped DEM that is used.
01038       ofstream demofile;                                // input DEM
01039       char            newfilename[ONE27];
01040       ostrstream      qomem(newfilename,ONE27);
01041       qomem << refdeminput.fodem << "_buffer_" << buffer << ends;
01042       char filename[ONE27];
01043       strcpy(filename,newfilename);
01044       openfstream(demofile,filename,generalinput.overwrit);
01045       bk_assert(demofile,filename,__FILE__,__LINE__);
01046       // ___ Give info to debug user ___
01047       DEBUG << "DEM output to file: " << filename
01048            << "; format: real4;  size (l,p): "
01049            << DEM.lines() << ", " << DEM.pixels();
01050       DEBUG.print();
01051       demofile << DEM;
01052       demofile.close();
01053       }
01054     if (outputdemi)
01055       {
01056       ofstream demiofile;                               // interpolated input DEM
01057       char            newfilename[ONE27];
01058       ostrstream      qomem(newfilename,ONE27);
01059       qomem << refdeminput.fodemi << "_buffer_" << buffer << ends;
01060       char filename[ONE27];
01061       strcpy(filename,newfilename);
01062       openfstream(demiofile,filename,generalinput.overwrit);
01063       bk_assert(demiofile,filename,__FILE__,__LINE__);
01064       // ___ Give info to debug user ___
01065       DEBUG << "Interpolated DEM file: " << filename
01066            << "; format: real4; size (l,p): "
01067            << DEMinterpolated.lines() << " " << DEMinterpolated.pixels();
01068       DEBUG.print();
01069       demiofile << DEMinterpolated;
01070       demiofile.close();
01071       }
01072     // --- remove DEM, from now use DEMinterpolated ---
01073     DEBUG.print("resizing DEM to 1,1 to reduce memory requirements");
01074     DEM.resize(1,1);// "dealloc"
01075 
01076     // ====== DEMinterpolated contains now values from leftupper with ======
01077     // ______ spacing (deltalatDEMinterpolated,deltalonDEMinterpolated) ______
01078     // ______ Transform DEM to l,p,refphase; store in LPPHASE ______
01079     PROGRESS.print("Converting oversampled DEM to radar system for this buffer.");
01080     const int32 numpointsDEMinterpolated = DEMinterpolated.size();
01081     const int32 numpointsBUFFER = OBUFFER.size();
01082     // ______ Extra info ______
01083     INFO << "Number of points in BUFFER (IFG):    "
01084          << numpointsBUFFER;
01085     INFO.print();
01086     INFO << "Number of points in oversampled DEM: "
01087          << numpointsDEMinterpolated;
01088     INFO.print();
01089     if (numpointsBUFFER > numpointsDEMinterpolated)
01090       if (do_nearest==true)
01091         WARNING.print("N points IFG OBUFFER > N_points interpolated DEM (increase EXTRADENSE?)");
01092       else
01093         INFO.print("N points IFG OBUFFER > N_points interp. dem (is ok)");
01094 
01095     matrix<real8> LPPHASE(numpointsDEMinterpolated,3);// real8 is important
01096     if (outputrefdemhei==true)
01097       {
01098       DEBUG.print("Adding column for height in radar coordinates.");
01099       LPPHASE.resize(numpointsDEMinterpolated,4);// extra column for height
01100       }
01101 
01102     // --- Loop bilinearly interpolated DEM ---
01103     cn P;
01104     int32 LPPHASEindex=0;
01105     phi = upperleftphi;
01106     for (i=0; i<DEMinterpolated.lines(); ++i)
01107       {
01108       if ((i%100)==0)
01109         {
01110         // ______ Extra info ______
01111         PROGRESS << "Radarcoding interpolated DEM line: " << i << " ("
01112              << floor(.5+(100.*real8(i)/real8(DEMinterpolated.lines())))
01113              << "%)";
01114         PROGRESS.print();
01115         }
01116 
01117       lambda = upperleftlambda;
01118       for (j=0; j<DEMinterpolated.pixels(); ++j)
01119         {
01120         height = DEMinterpolated(i,j);
01121         ell2xyz(ellips,P,phi,lambda,height);            // returns P(x,y,z)
01122         real8 t_range_master;                           // range (fast) time
01123         real8 t_azi_master;                             // azimuth (slow) time
01124         xyz2t(t_azi_master,t_range_master,              // t returned for (l,p)
01125               master,masterorbit,
01126               P,MAXITER,CRITERTIM);
01127         real8 t_azi_dummy;
01128         real8 t_range_slave;
01129         xyz2t(t_azi_dummy,t_range_slave,                // t returned
01130               slave,slaveorbit,
01131               P,MAXITER,CRITERTIM);
01132 
01133         // ______ (line,pixel) in master system ______
01134         LPPHASE(LPPHASEindex,0) = master.ta2line(t_azi_master);
01135         LPPHASE(LPPHASEindex,1) = master.tr2pix(t_range_master);
01136         // only store t_range_slave here, compute ref_phase later!
01137         LPPHASE(LPPHASEindex,2) = t_range_slave;
01138         if (outputrefdemhei==true)
01139           LPPHASE(LPPHASEindex,3) = height;// for Zbigniew Perski
01140 
01141         // ______ update longitude of next pixel ______
01142         lambda += deltalonDEMinterpolated;
01143         ++LPPHASEindex;
01144         } // loop DEMinterpolated pixels
01145 
01146       // ______ update latitude of next line ______
01147       phi -= deltalatDEMinterpolated;           // upper left is max. value
01148       } // loop DEMinterpolated lines
01149 
01150 
01151     // ====== Nearest neighbor to get reference phase to OBUFFER ======
01152     PROGRESS << "Start nearest neighbor for buffer: " << buffer+1;
01153     PROGRESS.print();
01154     // tested PNT2 as a real8* matrix, no gain in speed... BK 15-feb-00
01155     // matrix<real8*> PNT2LPPHI(numlinesOBUFFER,numpixelsOBUFFER);// pointers
01156     // Store squared distances in DISTANCES, OBUFFER could be used if cleaned.
01157     const int32 numlinesOBUFFER  = OBUFFER.lines();
01158     const int32 numpixelsOBUFFER = OBUFFER.pixels();
01159     matrix<int32> PNT2LPPHI(numlinesOBUFFER,numpixelsOBUFFER);// 'pointers' ...
01160     matrix<real4> DISTANCES(numlinesOBUFFER,numpixelsOBUFFER);  // not really required..
01161     const real4 DEFAULTDIST      = 99999.;// must be a positive large number
01162     DISTANCES.setdata(DEFAULTDIST);// store here the pixel distance for nearest neighbor.
01163     for (i=0; i<numpointsDEMinterpolated; ++i)
01164       {
01165       if ((i%100000)==0)
01166         {
01167         // ______ Extra info ______
01168         PROGRESS << "Nearest neighbor point number: " << i << " ("
01169              << floor(.5+(100.*real8(i)/real8(numpointsDEMinterpolated)))
01170              << "%)";
01171         PROGRESS.print();
01172         }
01173       // ______ Index in output buffer ______
01174       // ______ firstline/pixel is center of multilooked pixel in original radar coord. ___
01175       // ______ distance of radarcoded point to the center is important ______
01176       // --- compute distance with center location of multilooked pixel
01177       // --- firstline is center; want correct bin in multilooked output buffer
01178       //real8(mlL)/2.0 was added to get center of firstline, so subtract it again
01179       const int32 Y_in_obuffer = 
01180         int32((LPPHASE(i,0)-(firstline-real8(mlL)/2.0))/real8(mlL));// bin
01181       const int32 X_in_obuffer = 
01182         int32((LPPHASE(i,1)-(firstpixel-real8(mlP)/2.0))/real8(mlP));// bin
01183       //
01184       //const real8 indexobufferLr8 = (real8(LPPHASE(i,0))-firstline) /real8(mlL);
01185       //const real8 indexobufferPr8 = (real8(LPPHASE(i,1))-firstpixel)/real8(mlP);
01186       //const int32 indexobufferL   =  int32(indexobufferLr8+0.5); // round
01187       //const int32 indexobufferP   =  int32(indexobufferPr8+0.5); // round
01188       // ______ Check if index is within boundaries ______
01189       // ______ It is possible that the index is negative since ______
01190       // ______ the whole DEM is radarcoded, also outside the IFG ______
01191       if (Y_in_obuffer>=0 && Y_in_obuffer<numlinesOBUFFER &&
01192           X_in_obuffer>=0 && X_in_obuffer<numpixelsOBUFFER  )
01193         {
01194         //const real4 squareddistance = sqr(indexobufferLr8-indexobufferL) +
01195         //                            sqr(indexobufferPr8-indexobufferP);
01196         //const real4 dist = sqrt(sqr(indexobufferLr8-real8(indexobufferL)) +
01197         //                      sqr(indexobufferPr8-real8(indexobufferP)));
01198         const real8 line_desired  = firstline  + real8(Y_in_obuffer*mlL);// 
01199         const real8 pixel_desired = firstpixel + real8(X_in_obuffer*mlP);
01200         const real4 dist = sqrt(sqr(real8(LPPHASE(i,0))-line_desired) +
01201                                 sqr(real8(LPPHASE(i,1))-pixel_desired));
01202         if (dist < DISTANCES(Y_in_obuffer,X_in_obuffer)) 
01203           {
01204           DISTANCES(Y_in_obuffer,X_in_obuffer) = dist;
01205           PNT2LPPHI(Y_in_obuffer,X_in_obuffer) = i;// 'pointer' to range time slave
01206           }
01207         }
01208       } // all points in LPPHASE
01209 
01210  
01211 // ______ Check if all points are assigned a value (?) ______
01212 // ______ And compute reference phase ______
01213     PROGRESS << "Start reference phase computation for buffer: "
01214          << buffer+1;
01215     PROGRESS.print();
01216     // ======================================================================
01217     // ====== OLD METHOD; USES NEAREST NEIGHBOR DIRECTLY ====================
01218     // Bert Kampes, 08-Apr-2005
01219     // ======================================================================
01220     matrix<real4> OBUFFERHEI;// buffer for Zbigniew Perski
01221     if (outputrefdemhei==true) OBUFFERHEI.resize(1,numpixelsml);
01222     if (do_nearest==true)
01223       {
01224       WARNING.print("Using old method; please consider using TRI_LINEAR.");
01225       for (i=0; i<numlinesOBUFFER; ++i)
01226         {
01227         if ((i%25)==0)
01228           {
01229           // ______ Extra info ______
01230           PROGRESS << "Computing reference phase for nearest neighbor line: " << i 
01231                << " (" << floor(.5+(100.*real8(i)/real8(numlinesOBUFFER))) 
01232                << "%)";
01233           PROGRESS.print();
01234           }
01235         // --- Loop in range direction ---
01236         for (j=0; j<numpixelsOBUFFER; ++j)
01237           {
01238           if (DISTANCES(i,j) == DEFAULTDIST)
01239             {
01240             numNOneighbor++;
01241             WARNING << "No nearest neighbor for pixel at: "
01242                  << buffer*bufferlines+i << ", " << j
01243                  << "(i.e., " << firstline + real8(i*mlL) 
01244                  << ", " << firstpixel + real8(j*mlP) << ").";
01245             WARNING.print();
01246             continue; // with next j, leave 0 in OBUFFER.
01247             }
01248           // ______ Compute ref phase, nearest neighbor is known ______
01249           const int32 lpindex       = PNT2LPPHI(i,j);// index ('pointer') to LPP matrix
01250           const real8 line          = LPPHASE(lpindex,0);
01251           const real8 pixel         = LPPHASE(lpindex,1);
01252           const real8 t_range_slave = LPPHASE(lpindex,2);
01253           // ______ Compute master time for this pixel ______
01254           // ______ If appropriate, ref.phase = phi_topo ______
01255           real8 ref_phase;
01256           if (onlyrefphasetopo)                 // do not include flat earth phase
01257             {
01258             lp2xyz(line,pixel,
01259                    ellips,                      // h==0
01260                    master, masterorbit,
01261                    P,MAXITER,CRITERPOS);                        // P returned
01262             real8 t_range_flatearth;
01263             real8 t_azi_dummy;
01264             xyz2t(t_azi_dummy,t_range_flatearth,
01265                   slave,slaveorbit,
01266                   P,MAXITER,CRITERTIM);                 // P on h=0
01267             ref_phase = m_min4picdivlam*t_range_flatearth-
01268                         s_min4picdivlam*t_range_slave;
01269             }
01270           else // include flatearth, ref.pha = phi_topo+phi_flatearth
01271             {
01272             ref_phase = 
01273               m_min4picdivlam*master.pix2tr(pixel)-
01274               s_min4picdivlam*t_range_slave;
01275             }
01276           OBUFFER(i,j) = real4(ref_phase);
01277 
01278           // --- Dump height in radarcoordinates directly if requested
01279           if (outputrefdemhei==true)// For Zbigniew Perski
01280             {
01281             OBUFFERHEI(0,j) = real4(LPPHASE(lpindex,3));// output line buffer
01282             }
01283           } // j pixel loop OBUFFER
01284         // For Zbigniew Perski
01285         if (outputrefdemhei==true)// For Zbigniew Perski
01286           {
01287           DEBUG.print("Writing buffer line for Zbigniew Perski");
01288           refdemheiofile << OBUFFERHEI;
01289           }
01290         } // i line loop OBUFFER
01291       }
01292     // ======================================================================
01293     // ====== NEW METHOD, USES TRI-LINEAR INTERPOLATION OF NEAREST POINTS ===
01294     // Bert Kampes, 08-Apr-2005
01295     // ====== Now find 3 closest points A,B,C and do trigrid lin. interpolation
01296     // ====== point of interpolation is "+", local coordinate system has origin there.
01297     // ====== Then, cn A.z = f(x,y) = a00+a10*A.x+a01*A.y;
01298     // ======       cn B.z = f(x,y) = a00+a10*B.x+a01*B.y;
01299     // ======       cn C.z = f(x,y) = a00+a10*C.x+a01*C.y;
01300     // ====== and solve for a00, which is the Z value at origin, i.e., it!
01301     //
01302     //     A
01303     //       +   C
01304     //  B
01305     //
01306     // ====== To find A,B,C close to +, I first do neareast neighbor
01307     // ====== and then a local search from the output grid in each direction.
01308     // ====== Note that all interpolations are linear, i.e., the input
01309     // ====== DEM should contain all peaks and should be dense.
01310     // ====== also note that this throws out some of the points that
01311     // ====== were previously oversampled.
01312     // ====== In future, using this framework with DD,
01313     // ------- it is very simple to create a better interpolator...
01314     // Bert Kampes, 07-Apr-2005
01315     // ======================================================================
01316     else
01317       {
01318       DEBUG.print("Using new comprefdem interpolator method.");
01319       // --- Set up matrices that specify order for search of closeby points ---
01320       const int search_radius = 20;// in x,y smaller is faster, but risky?
01321       const real4 radius      = real4(search_radius);// for Type templates
01322       const real4 NX          = 2*search_radius+1;// in x,y
01323       const real4 NY          = NX;// square matrix; used for Type ones()
01324       const real4 one         = real4(1);// used for Type ones()
01325       // --- Compare meshgrid in matlab:// define matrix from -10:10
01326       const matrix<real4> XX  = ones(NX,one)*(indgen(NX)-real4(radius));// [-10:10]
01327       const matrix<real4> YY  = matTxmat((indgen(NY)-radius),ones(one,NY));
01328       // 1 pixel increase in line direction is what in multilooked?
01329       // XX*ml_X.^2 *ground_resolution??  or use Euclidian distance?
01330       DEBUG.print("Assuming that multilooked interferogram has more or less square pixels");
01331       DEBUG.print("i.e., going in X or Y with 1 pixel is same distance (?)");
01332       const matrix<real4> DD  = dotmult(XX,XX)+dotmult(YY,YY);// sqr.distances
01333       // --- now sort the distances and go through them until border of input matrix;
01334       matrix<real4> SORTED_DD(DD.size(),3);// distance,Y,X
01335       int32 cnt=0;
01336       for (int32 y=0; y<XX.lines();++y)
01337         {
01338         for (int32 x=0; x<XX.pixels();++x)
01339           {
01340           SORTED_DD(cnt,0) = DD(y,x);// distance
01341           SORTED_DD(cnt,1) = YY(y,x);// delta Y to go to
01342           SORTED_DD(cnt,2) = XX(y,x);// delta X to go to
01343           ++cnt;
01344           }
01345         }
01346       // --- qsort the distances in ascending order ---
01347       mysort2(SORTED_DD);// sort ascending on distance to center
01348       // --- Loop over output grid in azimuth direction --------------
01349       real8 height_A=0.0, height_B, height_C;// For Zbigniew Perski
01350       for (i=0; i<numlinesOBUFFER; ++i)
01351         {
01352         // non-multilooked center (close to LPP)
01353         const real8 line_desired = firstline + real8(i*mlL);
01354         if ((i%100)==0)
01355           {
01356           // ______ Extra info ______
01357           PROGRESS << "Computing reference phase trilinear for line: " << i 
01358                << " (" << floor(.5+(100.*real8(i)/real8(numlinesOBUFFER))) 
01359                << "%)";
01360           PROGRESS.print();
01361           }
01362         // --- Loop over output grid in range direction ---------------
01363         for (j=0; j<numpixelsOBUFFER; ++j)
01364           {
01365           // non-multilooked center (close to LPP)
01366           const real8 pixel_desired = firstpixel + real8(j*mlP);
01367           // --- Find 3 closest points that have a nearest neighbor assigned ---
01368           // --- Could easily find 10 if you'd like ---
01369           int32 n_found = 0;// number of points found closeby
01370           cn A,B,C;// {x,y,phase} triplet of nearest three points
01371           //cerr << endl;
01372           for (cnt=0; cnt<XX.size(); ++cnt)
01373             {
01374             //const real4 this_D = SORTED_DD(cnt,0);// distance to next closest point in matrix
01375             const int32 this_Y = i + int32(SORTED_DD(cnt,1));// next closest point
01376             const int32 this_X = j + int32(SORTED_DD(cnt,2));// next closest point
01377             if (this_Y>=0 && this_Y<numlinesOBUFFER &&
01378                 this_X>=0 && this_X<numpixelsOBUFFER)
01379               {
01380               // --- Check if this is a point that has a nearest neighbor: ---
01381               if (DISTANCES(this_Y,this_X) != DEFAULTDIST)
01382                 {
01383                 // ______ Compute ref phase for this point ______
01384                 const int32 lpindex       = PNT2LPPHI(this_Y,this_X);// index ('pointer') to LPP matrix
01385                 const real8 line          = LPPHASE(lpindex,0);
01386                 const real8 pixel         = LPPHASE(lpindex,1);
01387                 const real8 t_range_slave = LPPHASE(lpindex,2);
01388                 // ______ Compute master time for this pixel ______
01389                 // ______ If appropriate, ref.phase = phi_topo ______
01390                 real8 ref_phase;
01391                 if (onlyrefphasetopo)// do not include flat earth phase
01392                   {
01393                   lp2xyz(line,pixel,
01394                          ellips,                        // h==0
01395                          master, masterorbit,
01396                          P,MAXITER,CRITERPOS);                  // P returned
01397                   real8 t_range_flatearth;
01398                   real8 t_azi_dummy;
01399                   xyz2t(t_azi_dummy,t_range_flatearth,
01400                         slave,slaveorbit,
01401                         P,MAXITER,CRITERTIM);                   // P on h=0
01402                   ref_phase = m_min4picdivlam*t_range_flatearth-
01403                               s_min4picdivlam*t_range_slave;
01404                   }
01405                 else // include flatearth, ref.pha = phi_topo+phi_flatearth
01406                   {
01407                   ref_phase = 
01408                     m_min4picdivlam*master.pix2tr(pixel)-
01409                     s_min4picdivlam*t_range_slave;
01410                   }
01411                 switch (n_found)
01412                   {
01413                   case 0:
01414                     A.x = pixel - pixel_desired;// center desired position 
01415                     A.y = line  - line_desired;// ordinate
01416                     A.z = ref_phase;// functional value
01417                     if (outputrefdemhei==true)// For Zbigniew Perski
01418                       height_A = LPPHASE(lpindex,3);
01419                     break;
01420                   case 1:
01421                     B.x = pixel - pixel_desired;// center desired position 
01422                     B.y = line  - line_desired;// ordinate
01423                     B.z = ref_phase;// functional value
01424                     if (outputrefdemhei==true)// For Zbigniew Perski
01425                       height_B = LPPHASE(lpindex,3);
01426                     break;
01427                   case 2:
01428                     C.x = pixel - pixel_desired;// center desired position 
01429                     C.y = line  - line_desired;// ordinate
01430                     C.z = ref_phase;// functional value
01431                     if (outputrefdemhei==true)// For Zbigniew Perski
01432                       height_C = LPPHASE(lpindex,3);
01433                     break;
01434                   default:
01435                     ;// impossible
01436                   }// switch
01437                 n_found++;
01438                 }// point found
01439               }//index within matrix
01440             if (n_found==3) break;
01441             }
01442           // --- Interpolate phase to pixel position ---
01443           // +++ here add tri-interpolation of closest three points
01444           // +++ Bert Kampes, 07-Apr-2005
01445           real8 interpolated_refphase = 0.0;
01446           if (n_found==3)
01447             {
01448             interpolated_refphase = interp_trilinear(A,B,C);// optimized inline
01449             }
01450           else if (n_found>=1)
01451             {
01452             interpolated_refphase = A.z;// first point found is closest
01453             }
01454           // === Store in output buffer ===
01455           OBUFFER(i,j) = real4(interpolated_refphase);
01456           // --- Dump height in radarcoordinates directly if requested
01457           // Bert Kampes, 16-Apr-2005
01458           if (outputrefdemhei==true)// For Zbigniew Perski
01459             {
01460             real4 closest_refphase = A.z;// tmp copy
01461             real8 interpolated_refheight;
01462             A.z = height_A;// height of first point
01463             B.z = height_B;// height of second point
01464             C.z = height_C;// height of third point
01465             if (n_found==3)
01466               {
01467               // could be optimized to compute a00 for hei/refpha at same time.
01468               interpolated_refheight = interp_trilinear(A,B,C);
01469               // --- do not trust result, e.g. points on line  ---
01470               if (abs(interpolated_refheight-A.z)>500.0 || //[m]
01471                   interpolated_refheight > 10000.0 ||      //[m]
01472                   interpolated_refheight < -1000.0)//[m]
01473                 {
01474                 DEBUG.print("Following interpolated value is suspect (using A.z):");
01475                 A.showdata();
01476                 B.showdata();
01477                 C.showdata();
01478                 DEBUG << "interpolated P.z = " << interpolated_refheight;
01479                 DEBUG.print();
01480                 interpolated_refheight = A.z;//
01481                 OBUFFER(i,j) = closest_refphase;
01482                 }
01483               }
01484             else
01485               {
01486               interpolated_refheight = A.z;// use nearest point
01487               }
01488             // --- write the height to file (hopefully real4?) ---
01489             OBUFFERHEI(0,j) = real4(interpolated_refheight);//
01490             }
01491           } // j pixel loop OBUFFER
01492         // For Zbigniew Perski
01493         if (outputrefdemhei==true)// For Zbigniew Perski
01494           {
01495           DEBUG.print("Writing buffer line for Zbigniew Perski");
01496           refdemheiofile << OBUFFERHEI;
01497           }
01498         } // i line loop OBUFFER
01499       }// method selector nn or interp
01500 
01501 
01502     // ___ Give statistics for this buffer ___ 
01503     if (numvalid<50) WARNING.print("Less than 50 valid pixels in input DEM.");
01504     meancroppedDEM    /= numvalid;
01505     real8 numpoints    = real8(numvalid+numNODATA);// in this buffer DEM
01506     real8 numpointsOUT = real8(OBUFFER.lines()*OBUFFER.pixels());
01507     INFO << "Number of points with NODATA value: " << numNODATA 
01508          << " (" << 100.0*numNODATA/numpoints << "%)";
01509     INFO.print();
01510     if (numNODATA/numpoints>0.5)
01511       WARNING.print(INFO.get_str());
01512     INFO << "Number of points w/o nearest neighbor: " << numNOneighbor
01513          << " (" << 100.0*numNOneighbor/numpointsOUT << "%)";
01514     INFO.print();
01515     if (numNOneighbor/numpointsOUT>0.5)
01516       WARNING.print(INFO.get_str());
01517     INFO << "Min. value of cropped input DEM: " << min_dem_buffer; 
01518     INFO.print();
01519     INFO << "Max. value of cropped input DEM: " << max_dem_buffer; 
01520     INFO.print();
01521     INFO << "Mean value of cropped input DEM: " << meancroppedDEM 
01522          << " (over " << numvalid << " valid pixels.)";
01523     INFO.print();
01524     if (meancroppedDEM>5000)
01525       WARNING.print("I suspect byte order problem, mean of DEM>5000");
01526     if (meancroppedDEM<-100)
01527       WARNING.print("I suspect byte order problem, mean of DEM<-100");
01528     if (abs(meancroppedDEM)<1)
01529       {
01530       WARNING.print("I suspect input format error, abs(mean of DEM)<1");
01531       WARNING.print("Or are you subtracting ellipsoid reference phase like this?");
01532       }
01533     if (numvalid==0)
01534       WARNING.print("NO valid pixels found in crop of input DEM.");
01535     // ______ Nearest neighbor distances stats ______
01536     int32 num_stat  = 0;
01537     real8 stat_dist = 0;
01538     for (i=0; i<numlinesOBUFFER ;++i)
01539       {
01540       for (j=0; j<numpixelsOBUFFER ;++j)
01541         {
01542         if (DISTANCES(i,j) != DEFAULTDIST)
01543           num_stat++;
01544           stat_dist += DISTANCES(i,j);// squared distance was stored.
01545         }
01546       }
01547     INFO << "Mean distance for " << num_stat << " nearest neighbors: "
01548          << stat_dist/num_stat << " [pixels]";
01549     INFO.print();
01550 
01551     // ______ Reset counters for next buffer ______
01552     totalNOneighbor += numNOneighbor;
01553     numvalid         = 0;
01554     numNODATA        = 0;
01555     numNOneighbor    = 0;
01556     meancroppedDEM   = 0.;
01557 
01558     // ====== Write OBUFFER to ofile ======
01559     PROGRESS << "Writing reference phase for buffer: " << buffer+1;
01560     PROGRESS.print();
01561     refdemofile << OBUFFER;
01562     } // buffer loop
01563   refdemofile.close();  // OBUFFER
01564   if (outputrefdemhei==true)// For Zbigniew Perski
01565     {
01566     INFO.print("Closing file for additional output");
01567     refdemheiofile.close();// OBUFFERHEI
01568     }
01569 
01570 
01571 
01572 // ====== Write output information ======
01573   char croppeddem[ONE27];
01574   char croppeddemi[ONE27];
01575   strcpy(croppeddem, "NO output requested");
01576   strcpy(croppeddemi,"NO output requested");
01577   if (outputdem)  strcpy(croppeddem,refdeminput.fodem);
01578   if (outputdemi) strcpy(croppeddemi,refdeminput.fodemi);
01579   INFO << "Min. value of input DEM covering interferogram: " << min_input_dem; 
01580   INFO.print();
01581   INFO << "Max. value of input DEM covering interferogram: " << max_input_dem; 
01582   INFO.print();
01583 
01584   ofstream scratchlogfile("scratchlogcomprefdem", ios::out | ios::trunc);
01585   bk_assert(scratchlogfile,"comprefdem: scratchlogcomprefdem",__FILE__,__LINE__);
01586   scratchlogfile
01587     << "\n*_Start_" << processcontrol[pr_i_comprefdem]
01588     << "\n*******************************************************************"
01589     << "\n1) DEM source file:                   \t" <<  demfilename
01590     << "\nFormat:                               \t";
01591     switch (refdeminput.iformatflag)
01592       {
01593       case FORMATI2:
01594         {
01595         scratchlogfile << "SHORT SIGNED INTEGER (HOST ENDIANNESS)";
01596         break;
01597         }
01598       case FORMATI2_BIGENDIAN:
01599         {
01600         scratchlogfile << "SHORT SIGNED INTEGER, BIG ENDIAN";
01601         break;
01602         }
01603       case FORMATR4:
01604         {
01605         scratchlogfile << "REAL4 SIGNED FLOAT";
01606         break;
01607         }
01608       case FORMATR8:
01609         {
01610         scratchlogfile << "REAL8 SIGNED DOUBLE";
01611         break;
01612         }
01613       default:
01614         {
01615         scratchlogfile << "UNKNOWN? IMPOSSIBLE...";
01616         break;
01617         }
01618       }
01619   scratchlogfile
01620     << "\nByte order:                           \t" <<  "check yourself..."
01621     << "\nNumber of lines:                      \t" <<  numberoflatpixels
01622     << "\nNumber of pixels:                     \t" <<  numberoflonpixels
01623     << "\nResolution latitude:                  \t" 
01624     << rad2deg(DEMdeltalat) << " [deg]"
01625     << "\nResolution longitude:                 \t" 
01626     << rad2deg(DEMdeltalon) << " [deg]"
01627     << "\nMost West point in input DEM:         \t" << rad2deg(lon0file)
01628     << "\nMost East point in input DEM:         \t" << rad2deg(lonNfile)
01629     << "\nMost South point in input DEM:        \t" << rad2deg(latNfile)
01630     << "\nMost North point in input DEM:        \t" << rad2deg(lat0file)
01631     << "\nMin. value of input DEM covering interferogram: " << min_input_dem
01632     << "\nMax. value of input DEM covering interferogram: " << max_input_dem
01633     << "\n2) Output file cropped DEM:           \t" <<  croppeddem
01634     << "\nFormat:                               \t" << "REAL4"
01635     << "\nByte order:                           \t" << "(same as host)"
01636 //    << "\nMean value:                           \t" <<  meancroppedDEM
01637     << "\n3) Output file interpolated crop DEM: \t" <<  croppeddemi
01638     << "\nFormat:                               \t" << "REAL4"
01639     << "\nByte order:                           \t" << "(same as host)"
01640     << "\nOversampling factor latitude:         \t" << DEMphioversamplefactor
01641     << "\nOversampling factor longitude:        \t" << DEMlambdaoversamplefactor
01642     << "\nApproximate resolution latitude:      \t" 
01643     << rad2deg(DEMdeltalat/DEMphioversamplefactor) << " [deg]"
01644     << "\nApproximate resolution longitude:     \t" 
01645     << rad2deg(DEMdeltalon/DEMlambdaoversamplefactor) << " [deg]"
01646     << "\n4) Output file synthetic phase:       \t" <<  refdemofilename
01647     << "\nFormat:                               \t" << "REAL4"
01648     << "\nByte order:                           \t" << "(same as host)"
01649     << "\nApproximate resolution latitude:      \t" 
01650     << rad2deg(dphi_interferogram) << " [deg]"
01651     << "\nApproximate resolution longitude:     \t" 
01652     << rad2deg(dlambda_interferogram) << " [deg]"
01653     << "\nNumber of lines (multilooked):        \t" <<  numlinesml
01654     << "\nNumber of pixels (multilooked):       \t" <<  numpixelsml
01655     << "\nNumber of points w/o nearest neighbor:\t" << totalNOneighbor
01656     << " (" << 100*totalNOneighbor/(numlinesml*numpixelsml) << "%)"
01657 
01658 // this is not correct, only stats per buffer...
01659 //    << "\n\n----- Other STATS -----"
01660 //    << "\nTotal points in cropped DEM:          \t" << numpoints
01661 //    << "\nNumber of valid points in DEM:        \t" << numvalid
01662 //    << " (" << 100*numvalid/numpoints << "%)"
01663 //    << "\nNumber of NODATA points in DEM:       \t" << numNODATA
01664 //    << " (" << 100*numNODATA/numpoints << "%)"
01665 //    << "\nMean height in meters at valid points:\t" << meancroppedDEM
01666     << "\n*******************************************************************\n\n";
01667   scratchlogfile.close();
01668 
01669 
01670   ofstream scratchresfile("scratchrescomprefdem", ios::out | ios::trunc);
01671   bk_assert(scratchresfile,"comprefdem: scratchrescomprefdem",__FILE__,__LINE__);
01672   scratchresfile
01673     << "\n\n*******************************************************************"
01674     << "\n*_Start_" << processcontrol[pr_i_comprefdem]
01675     << "\n*******************************************************************";
01676   if (do_nearest==true) scratchresfile
01677     << "\nMethod:                               \tNEAREST";
01678   else scratchresfile
01679     << "\nMethod:                               \tTRILINEAR";
01680   if (onlyrefphasetopo==true) scratchresfile
01681     << "\nInclude 'flat earth':                 \tNo";
01682   else scratchresfile
01683     << "\nInclude 'flat earth':                 \tYes";
01684   scratchresfile
01685     << "\nDEM source file:                      \t" <<  demfilename
01686     << "\nMin. of input DEM:                    \t" << min_input_dem
01687     << "\nMax. of input DEM:                    \t" << max_input_dem
01688     << "\nData_output_file:                     \t" <<  refdemofilename
01689     << "\nData_output_format:                   \t" << "real4"
01690     << "\nFirst_line (w.r.t. original_master):  \t"
01691     <<  interferogram.win.linelo
01692     << "\nLast_line (w.r.t. original_master):   \t"
01693     <<  interferogram.win.linehi
01694     << "\nFirst_pixel (w.r.t. original_master): \t"
01695     <<  interferogram.win.pixlo
01696     << "\nLast_pixel (w.r.t. original_master):  \t"
01697     <<  interferogram.win.pixhi
01698     << "\nMultilookfactor_azimuth_direction:    \t" <<  mlL
01699     << "\nMultilookfactor_range_direction:      \t" <<  mlP
01700     << "\nNumber of lines (multilooked):        \t" <<  numlinesml
01701     << "\nNumber of pixels (multilooked):       \t" <<  numpixelsml
01702     << "\n*******************************************************************"
01703     << "\n* End_" << processcontrol[pr_i_comprefdem] << "_NORMAL"
01704     << "\n*******************************************************************\n";
01705   scratchresfile.close();
01706 
01707   } // END radarcodedem
01708 

Generated on Fri Apr 22 15:58:00 2005 for Doris by doxygen 1.3.6