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/utilities.hh,v $ 00032 * $Revision: 3.12 $ * 00033 * $Date: 2005/04/11 13:47:45 $ * 00034 * $Author: kampes $ * 00035 * * 00036 * - Some utilities. * 00037 ****************************************************************/ 00038 00039 00040 #ifndef UTILITIES_H // guard 00041 #define UTILITIES_H 00042 00043 #include "constants.hh" // typedefs 00044 #include "slcimage.hh" // my slc image class 00045 #include "ioroutines.hh" // ERROR 00046 #include "exceptions.hh" // exceptions class 00047 #include <cmath> // floor, sqr 00048 00049 00050 // === prototype requires below, so put first/. 00051 // ______ Solve system of 3 equations ______ 00052 void solve33( 00053 matrix<real8> &Result, 00054 const matrix<real8> &rhs, 00055 const matrix<real8> &partials); 00056 00057 00058 // ______ Solve set of 2 equations ______ 00059 matrix<real8> solve22( 00060 const matrix<real8> &rhs, 00061 const matrix<real8> &partials); 00062 00063 00064 00065 00066 // ====== Inline ====== 00067 inline bool iseven(int16 w) {return (w+1)%2;} 00068 inline bool iseven(int32 w) {return (w+1)%2;} 00069 inline bool iseven(uint w) {return (w+1)%2;} 00070 inline bool isodd (int16 w) {return w%2;} 00071 inline bool isodd (int32 w) {return w%2;} 00072 inline bool isodd (uint w) {return w%2;} 00073 00074 inline bool ispower2 (uint w) 00075 {if (w==2 || w==4 || w==8 || w==16 || 00076 w==32 || w==64 || w==128 || w==256 || 00077 w==512 || w==1024 || w==2048 || w==4096 ) 00078 return true; 00079 return false;} 00080 00081 inline int32 Ncoeffs(int32 degree) 00082 {return int32(.5*(sqr(degree+1)+degree+1));} 00083 00084 inline int32 degree(int32 Ncoeffs) 00085 { return int32(.5*(-1 + int32(sqrt(real4(1+8*Ncoeffs)))))-1;} 00086 00087 inline real4 remainder(real4 number, real4 divisor) 00088 {return number-floor(number/divisor)*divisor;} 00089 00090 inline real8 remainder(real8 number, real8 divisor) 00091 {return number-floor(number/divisor)*divisor;} 00092 00093 inline real4 sinc(real4 x) 00094 {return ((x==0) ? 1 : sin(PI*x)/(PI*x));} 00095 00096 //____RaffaeleNutricato START MODIFICATION SECTION 1 00097 inline real8 sinc(real8 x) 00098 {return ((x==0) ? 1 : sin(PI*x)/(PI*x));} 00099 //____RaffaeleNutricato END MODIFICATION SECTION 1 00100 00101 inline real4 rect(real4 x) 00102 {real4 ans = 0.; 00103 if (x<.5 && x>-.5) ans = 1; 00104 else if (x==.5 || x==-.5) ans = .5; 00105 return ans;} 00106 00107 inline real4 tri(real4 x) 00108 {real4 ans = 0.; 00109 if (x<1. && x>-1.) 00110 {(x<0) ? ans=1+x : ans=1-x;} 00111 return ans;} 00112 00113 inline real8 onedecimal(real8 x) 00114 {return real8(int32(x*10+.5))/10.;} 00115 inline real4 onedecimal(real4 x) 00116 {return real4(int32(x*10+.5))/10.;} 00117 00118 00119 /**************************************************************** 00120 * myrect * 00121 * rect window, lying vector * 00122 * r(i) = 1 if abs(i)<=.5 * 00123 * used in filtering, see curlander, swabisch, geudtner * 00124 * Bert Kampes, 31-Mar-2000 * 00125 ****************************************************************/ 00126 inline matrix<real4> myrect(const matrix<real4> &X) 00127 { 00128 TRACE_FUNCTION("myrect (BK 31-Mar-2000)") 00129 #ifdef __DEBUG 00130 if (X.lines()!=1) 00131 { 00132 PRINT_ERROR("myrect: only lying vectors.") 00133 throw(argument_error); 00134 } 00135 #endif 00136 matrix<real4> Res(1,X.pixels()); // init2zero 00137 real4 *pntX = X[0]; 00138 real4 *pntR = Res[0]; 00139 for (register int32 i=0; i<int32(X.pixels()); ++i) 00140 { 00141 if (abs(*pntX++)<=0.5) 00142 *pntR=1.; 00143 pntR++; 00144 } 00145 // BK 01-Nov-2000: better: ?? 00146 //for (real4 *pntX=&X[0][0]; pntX<=&X[X.lines()-1][X.pixels()-1]; ++pntX) 00147 // *pntR++ = (abs(*pntX)<=0.5) ? 1 : 0; 00148 // rather something like: R(find(abs(X)<.5))=1; 00149 return Res; 00150 } 00151 00152 00153 /**************************************************************** 00154 * myhamming * 00155 * hamming window, lying vector * 00156 * w = (a + (1.-a).*cos((2.*pi/fs).*fr)) .* myrect(fr./Br); * 00157 * scale/shift filter by g(x)=f((x-xo)/s) * 00158 * alpha==1 yields a myrect window * 00159 * Bert Kampes, 31-Mar-2000 * 00160 ****************************************************************/ 00161 inline matrix<real4> myhamming( 00162 const matrix<real4> &fr, 00163 real8 RBW, 00164 real8 RSR, 00165 real8 alpha) 00166 { 00167 TRACE_FUNCTION("myhamming (BK 31-Mar-200)") 00168 #ifdef __DEBUG 00169 if (fr.lines()!=1) 00170 { 00171 PRINT_ERROR("myhamming: only lying vectors.") 00172 throw(argument_error); 00173 } 00174 if (alpha<0.0 || alpha>1.0) 00175 { 00176 PRINT_ERROR("myhamming: !alpha e{0..1}.") 00177 throw(argument_error); 00178 } 00179 if (RBW>RSR) 00180 { 00181 PRINT_ERROR("myhamming: RBW>RSR.") 00182 throw(argument_error); 00183 } 00184 #endif 00185 matrix<real4> Res(1,fr.pixels()); 00186 real4 *pntfr = fr[0]; 00187 real4 *pntR = Res[0]; 00188 for (register int32 i=0; i<int32(fr.pixels()); ++i) 00189 { 00190 if (abs((*pntfr)/RBW)<0.5) // rect window 00191 *pntR = alpha+(1.-alpha)*cos((2*PI/RSR)*(*pntfr)); 00192 pntfr++; 00193 pntR++; 00194 } 00195 // w = (a + (1.-a).*cos((2.*pi/fs).*fr)) .* myrect(fr./Br); 00196 return Res; 00197 } 00198 00199 00200 /**************************************************************** 00201 * interpbilinear * 00202 * bilinear interpolation with NORMALIZED data on grid. * 00203 * f(row,col) = a00 + a01*c + a10*r +a11*r*c * 00204 * P1(0,0); P2(0,1); P3(1,0); P4(1,1); P[0:1,0:1]; * 00205 * * 00206 * cols-> * 00207 * r P1 P2 * 00208 * o .P * 00209 * w P3 P4 * 00210 * s * 00211 * * 00212 * input: * 00213 * - normalized coordinates of point (row,col). * 00214 * - functional values at 4 corners. * 00215 * output: * 00216 * - interpolated value * 00217 * * 00218 * Bert Kampes, 19-Jan-2000 * 00219 #%// BK 25-Sep-2000 00220 ****************************************************************/ 00221 inline real8 interpbilinear( 00222 const real8 r, 00223 const real8 c, 00224 const real8 P1, 00225 const real8 P2, 00226 const real8 P3, 00227 const real8 P4) 00228 {return P1 + (P2-P1)*c + (P3-P1)*r + (P4-P3-P2+P1)*r*c;} 00229 00230 00231 /**************************************************************** 00232 * interp_trilinear * 00233 * trilinear interpolation using relative coordinates. * 00234 * * 00235 * ====== Points A,B,C and do trigrid lin. interpolation at "+" * 00236 * ====== "+", origin of local coordinate system * 00237 * * 00238 * A * 00239 * * 00240 * + * 00241 * B * 00242 * * 00243 * C * 00244 * * 00245 * ====== Then, cn A.z = f(x,y) = a00+a10*A.x+a01*A.y; * 00246 * ====== cn B.z = f(x,y) = a00+a10*B.x+a01*B.y; * 00247 * ====== cn C.z = f(x,y) = a00+a10*C.x+a01*C.y; * 00248 * ====== solve for a00; the Z value at origin, i.e., it! * 00249 * * 00250 * input: * 00251 * - normalized coordinates of point (row,col). * 00252 * - cn A,B,C with relative coordinates and functional values * 00253 * output: * 00254 * - interpolated value * 00255 * * 00256 * Bert Kampes, 07-Apr-2005 * 00257 ****************************************************************/ 00258 inline real8 interp_trilinear( 00259 const cn &A, 00260 const cn &B, 00261 const cn &C) 00262 { 00263 // --- check if points are on line or are all same... --- 00264 // --- maybe simply add eps to A.x, A.y and subtract it from B.x, B.y? 00265 // --- since how else can we guarantee solve33 won't crash? 00266 //if (A.x==B.x && A.y==B.y) 00267 // if (A.x==C.x && A.y==C.y) 00268 // return (A.z+B.z+C.z)/3.0; 00269 // else // 2 same points? 00270 //const real8 EPS = 0.00001;// assume points are pixels 00271 // --- Vandermonde matrix --- 00272 // matrix<real8> DESIGNMAT(3,3); 00273 // DESIGNMAT(0,0)=1.0; DESIGNMAT(0,1)=A.x + EPS; DESIGNMAT(0,2) = A.y + EPS; 00274 // DESIGNMAT(1,0)=1.0; DESIGNMAT(1,1)=B.x - EPS; DESIGNMAT(1,2) = B.y - EPS; 00275 // DESIGNMAT(2,0)=1.0; DESIGNMAT(2,1)=C.x; DESIGNMAT(2,2) = C.y; 00276 // // --- Right hand side --- 00277 // matrix<real8> RHS(3,1); 00278 // RHS(0,0)=A.z; 00279 // RHS(1,0)=B.z; 00280 // RHS(2,0)=C.z; 00281 // // --- Solve system using library for all coefficients --- 00282 // matrix<real8> RESULT(3,1);// returned 00283 // solve33(RESULT,RHS,DESIGNMAT);// return result = a00,a10,a01 00284 // const real8 a00 = RESULT(0,0); 00285 // return a00; 00286 // 00287 // since first the last element is solved, turn it around and do it locally: 00288 //* ====== Then, cn A.z = f(x,y) = [ya,xa,1][a01] 00289 //* ====== cn B.z = f(x,y) = [yb,xb,1][a10] 00290 //* ====== cn C.z = f(x,y) = [yc,xc,1][a00] <--- solve this on by LU 00291 //* ====== solve for a00; the Z value at origin, i.e., it! 00292 // ______ LU decomposition ______ 00293 const real8 one = real8(1.0); 00294 const real8 EPS = 0.00001;// assume points are pixels 00295 const real8 L10 = (B.y-EPS)/(A.y+EPS);// DESIGN(1,0)/DESIGN(0,0); 00296 const real8 L20 = (C.y)/(A.y+EPS);// DESIGN(2,0)/DESIGN(0,0); 00297 const real8 U11 = (B.x-EPS)-L10*(A.x+EPS);// DESIGN(1,1)-L10*DESIGN(0,1); 00298 const real8 L21 = ((C.x)-(A.x+EPS))*L20/U11;// (DESIGN(2,1)-(DESIGN(0,1)*L20))/U11; 00299 const real8 U12 = one-L10;// DESIGN(1,2)-L10*DESIGN(0,2); 00300 const real8 U22 = one-L20-L21*U12;// DESIGN(2,2)-L20*DESIGN(0,2)-L21*U12; 00301 00302 // ______Solution: forward substitution______ 00303 const real8 b0 = A.z;// rhs(0,0); 00304 const real8 b1 = B.z-b0*L10;// rhs(1,0)-b0*L10; 00305 const real8 b2 = C.z-b0*L20-b1*L21;// rhs(2,0)-b0*L20-b1*L21; 00306 00307 // ______Solution: backwards substitution______ 00308 const real8 a00 = b2/U22;//RESULT(2,0) = b2/U22; 00309 //RESULT(1,0) = (b1-U12*RESULT(2,0))/U11; 00310 //RESULT(0,0) = (b0-A(0,1)*RESULT(1,0)-A(0,2)*RESULT(2,0))/A(0,0); 00311 return a00; 00312 } 00313 00314 00315 /**************************************************************** 00316 * ProjectPointOnLine * 00317 * Computes Projection of a 3D point M * 00318 * on to a vector in 3D. The vector is directed * 00319 * from P to S * 00320 * this can be useed in baseline computation * 00321 #%// KKM 09-March-2005 * 00322 ****************************************************************/ 00323 inline cn ProjectPointOnLine( 00324 cn M, 00325 cn P, 00326 cn S) 00327 { 00328 cn U = P.min(S);// direction cosines of PS 00329 const real8 U_2 = U.in(U); 00330 U = U.scale(1.0/sqrt(U_2)); 00331 // --- Umat is the matrix representation of U to compute U*U' --- 00332 matrix<real4> Umat(3,1); 00333 Umat(0,0) = U.x; 00334 Umat(1,0 ) = U.y; 00335 Umat(2,0) = U.z; 00336 const matrix<real4> UU = matxmatT(Umat,Umat);// [3x3] 00337 // --- X is returned, base of perpendicular from M to PS 00338 matrix<real4> UmatT(1,3); 00339 UmatT(0,0) = M.x-S.x; 00340 UmatT(0,1) = M.y-S.y; 00341 UmatT(0,2) = M.z-S.z; 00342 UmatT = UmatT*UU;// [1x3] 00343 // --- X is returned, base of perpendicular from M to PS 00344 //cn X; 00345 //X.x = UmatT(0,0)+S.x; 00346 //X.y = UmatT(0,1)+S.y; 00347 //X.z = UmatT(0,2)+S.z; 00348 //return X; 00349 return cn(UmatT(0,0)+S.x, UmatT(0,1)+S.y, UmatT(0,2)+S.z); 00350 } 00351 00352 00353 00354 /**************************************************************** 00355 * matrix<real4> I = indgen(real4(10)) * 00356 * matrix<int32> I = indgen(int32(10)), etc. * 00357 * create lying matrix [0,1,2,..N-1] * 00358 * Bert Kampes, 08-Apr-2005 * 00359 ****************************************************************/ 00360 template <class Type> 00361 inline 00362 matrix<Type> indgen( 00363 const Type N) // use Type of N to create appropriate matrix 00364 { 00365 matrix<Type> e(1,N); 00366 for(int32 i=0; i<N; ++i) e(0,i)=Type(i); 00367 return e; 00368 } 00369 /**************************************************************** 00370 * matrix<real4> I = linspace(x0,xn,N) * 00371 * create lying matrix [x0:xn] equally space N samples * 00372 * Bert Kampes, 08-Apr-2005 * 00373 ****************************************************************/ 00374 template <class Type> 00375 inline 00376 matrix<Type> linspace( 00377 const Type x0, 00378 const Type xN, 00379 const int32 N) 00380 { 00381 return x0+indgen(Type(N))*((xN-x0)/Type(N-1));// use Type(N) to get ok. 00382 } 00383 /**************************************************************** 00384 * matrix<real4> E = ones(10,10) * 00385 * create matrix filled with ones. * 00386 * Bert Kampes, 08-Apr-2005 * 00387 ****************************************************************/ 00388 template <class Type> 00389 inline 00390 matrix<Type> ones( 00391 const Type Ny, 00392 const Type Nx)// use Type of N to create appropriate matrix 00393 { 00394 matrix<Type> E(Ny,Nx); 00395 E.setdata(Type(1)); 00396 return E; 00397 } 00398 /**************************************************************** 00399 * matrix<real4> I = eye(10) * 00400 * create identity matrix with ones on main diagonal. * 00401 * Bert Kampes, 08-Apr-2005 * 00402 ****************************************************************/ 00403 template <class Type> 00404 inline 00405 matrix<Type> eye( 00406 const Type N)// use Type of N to create appropriate matrix 00407 { 00408 matrix<Type> I(N,N); 00409 for(int32 i=0; i<N; ++i) I(i,i)=Type(1); 00410 return I; 00411 } 00412 00413 00414 00415 00416 // ====== Prototypes ============================================ 00417 // ______ Call getorb for precise orbits ______ 00418 void getorb( 00419 const slcimage &image, 00420 const input_pr_orbits &inputorb, 00421 int16 FILEID); 00422 00423 00424 // ______ Converts output to desired format ______ 00425 void convertgetorbout( 00426 int16 FILEID, 00427 const char* file="scratchorbit"); 00428 00429 // ______ Return next power of 2 ______ 00430 uint nextpow2 ( 00431 real8 w); 00432 00433 00434 // ______ Evaluate 2d polynomial on grid ______ 00435 matrix<real4> polyval( 00436 const matrix<real4> &x, 00437 const matrix<real4> &y, 00438 const matrix<real8> &coeff, 00439 int32 degree = -1); 00440 00441 00442 // ______ Evaluate 2d polynomial ______ 00443 real8 polyval( 00444 real8 x, 00445 real8 y, 00446 const matrix<real8> &coeff); 00447 00448 00449 // ______ Evaluate 2d polynomial ______ 00450 real8 polyval( 00451 real8 x, 00452 real8 y, 00453 const matrix<real8> &coeff, 00454 int32 degree); 00455 00456 00457 // ______ Evaluate 1d polynomial ______ 00458 real8 polyval1d( 00459 real8 x, 00460 const matrix<real8> &coeff); 00461 // int32 degree); 00462 00463 00464 // ______ Normalize a matrix data -> [-2,2] ______ 00465 void normalize( 00466 matrix<real4> &data, 00467 real8 min, 00468 real8 max 00469 ); 00470 00471 00472 // ______ Normalize a matrix data -> [-2,2] ______ 00473 void normalize( 00474 matrix<real8> &data, 00475 real8 min, 00476 real8 max 00477 ); 00478 00479 00480 // ______ Normalize data from [min,max] to [-2,2] ______ 00481 inline real4 normalize(real4 data, real8 min, real8 max) 00482 {return real4((data-(.5*(min+max)))/(.25*(max-min)));} 00483 00484 00485 // ______ Normalize data from [min,max] to [-2,2] ______ 00486 inline real8 normalize(real8 data, real8 min, real8 max) 00487 {return (data-(.5*(min+max)))/(.25*(max-min));} 00488 00489 00490 // ______ Use this to compute Bperp for a few points, slow! ______ 00491 void BBparBperp( 00492 real8 &B, real8 &Bpar, real8 &Berp, // returned 00493 const cn Master, const cn Point, const cn Slave); 00494 00495 // ______ Sign not computed, slow! ______ 00496 void BBhBv( 00497 real8 &B, real8 &Bh, real8 &Bv, // returned 00498 const cn Master, const cn Slave); 00499 00500 // ______ Temporal baseline in days returned ______ 00501 // ______ (positive for master earlier than slave) ______ 00502 int32 Btemp( 00503 const char *utc_master, const char *utc_slave); 00504 00505 // ______ Baseline parametrizations returned ______ 00506 void BalphaBhBvBparBperpTheta( 00507 real8 &B, real8 &alpha, real8 &Bh, real8 &Bv, 00508 real8 &Bpar, real8 &Bperp, real8 &theta, 00509 const cn M, const cn P, const cn S); 00510 00511 // ______ Shift azimuth spectrum from fDC to zero, and vv. ______ 00512 void shiftazispectrum( 00513 matrix<complr4> &data, // slcdata sin space domain 00514 const slcimage &slave, // polynomial fDC 00515 const real4 shift);// abs(shift==firstpix in slave system) 00516 // if shift>0 then shift from zero to fDC 00517 00518 #endif // UTILITIES_H 00519 00520 00521