00001 /* 00002 * Copyright (C) 2005 Badri Krishnan, Alicia Sintes, Bernd Machenschalk 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with with program; see the file COPYING. If not, write to the 00016 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00017 * MA 02111-1307 USA 00018 */ 00019 00020 /** \file ConstructPLUT.c 00021 * \ingroup pulsarHough 00022 * \author Sintes, A and Krishnan, B 00023 * \brief Core routines for constructing the Hough Look-Up-Tables 00024 * \date $Date: 2007/08/21 14:27:41 $ 00025 * Revision: $Id: ConstructPLUT.c,v 1.28 2007/08/21 14:27:41 badri Exp $ 00026 * 00027 * History: Created by Sintes June 7, 2001 00028 * Modified by Badri Krishnan Feb 2003 00029 *----------------------------------------------------------------------- 00030 * 00031 \par Description 00032 00033 This module is the core of the Hough transform. The LAL function 00034 LALHOUGHConstructPLUT() 00035 constructs the look up tables that will be used to build the so-called 00036 partial-Hough maps. Each look up table is valid for a given sky-patch, time, and 00037 frequency range around a certain \verb@f0@ value. The look up table contains 00038 all the necessary information regarding the borders of the annuli clipped on 00039 the \lq projected' two dimensional sky-patch. 00040 00041 The inputs are: HOUGHPatchGrid containing the grid patch 00042 information. This is independent of the sky location of the 00043 patch, And HOUGHParamPLUT with all the other parameters needed. 00044 00045 The output is the look up table HOUGHptfLUT 00046 00047 00048 \par Uses 00049 \code 00050 PLUTInitialize(HOUGHptfLUT *) 00051 FillPLUT(HOUGHParamPLUT *, HOUGHptfLUT *, HOUGHPatchGrid *) 00052 CheckLeftCircle(REAL8, REAL8, REAL8, INT4 *, INT4 *, INT4 *, 00053 HOUGHPatchGrid *) 00054 CheckRightCircle(REAL8, REAL8, REAL8, INT4 *, INT4 *, INT4 *, 00055 HOUGHPatchGrid *) 00056 DrawRightCircle(REAL8, REAL8, REAL8, INT4, INT4, COORType *, 00057 HOUGHPatchGrid *) 00058 DrawLeftCircle(REAL8, REAL8, REAL8, INT4, INT4, COORType *, 00059 HOUGHPatchGrid *) 00060 CheckLineCase(REAL8, REAL8, REAL8, REAL8 *, INT4 *) 00061 FindExactLine(REAL8, REAL8, REAL8 *, REAL8 *) 00062 FindLine(REAL8, REAL8, REAL8, REAL8 *, REAL8 *) 00063 CheckLineIntersection(REAL8, REAL8, REAL8, INT4 *, INT4 *, INT4 *, 00064 HOUGHPatchGrid *) 00065 DrawLine(REAL8, REAL8, REAL8,INT4, INT4, COORType *, HOUGHPatchGrid *) 00066 Fill1Column(INT4, INT4*, HOUGHptfLUT *, HOUGHPatchGrid *) 00067 FillCaseN1(INT4, INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *) 00068 FillCaseN2(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *) 00069 FillCaseN3(INT4, INT4, INT4, INT4 *, HOUGHptfLUT *, HOUGHPatchGrid *) 00070 FillCaseN4(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *) 00071 FillCaseN5(INT4, INT4, INT4, HOUGHptfLUT *) 00072 FillCaseN6(INT4, INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *) 00073 FillCaseN7(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *) 00074 FillCaseN8(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *) 00075 Fill1ColumnAnor(INT4, HOUGHptfLUT *, HOUGHPatchGrid *) 00076 FillCaseA1(INT4, INT4, INT4, HOUGHptfLUT *) 00077 FillCaseA2(INT4, INT4, INT4, HOUGHptfLUT *) 00078 FillCaseA3(INT4, INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *) 00079 InitialCircleCase(INT4 *,REAL8, REAL8, REAL8, REAL8 *, INT4 *, INT4 *, 00080 HOUGHptfLUT *, HOUGHPatchGrid *) 00081 SecondCircleCase(INT4, INT4*, REAL8, REAL8, REAL8, INT4, REAL8 *, 00082 INT4*,INT4 *,INT4*, HOUGHptfLUT *, HOUGHPatchGrid *) 00083 FollowCircleCase(INT4,INT4 *,REAL8,REAL8,REAL8,REAL8,REAL8,INT4 *, 00084 INT4 *,INT4 *, HOUGHptfLUT *, HOUGHPatchGrid *) 00085 InitialLineCase(INT4 *, REAL8, REAL8, REAL8, INT4 *, HOUGHptfLUT *, 00086 HOUGHPatchGrid *) 00087 SecondLineCase(INT4, INT4 *, REAL8, REAL8, REAL8, INT4 *, HOUGHptfLUT *, 00088 HOUGHPatchGrid *) 00089 FollowLineCase(INT4, INT4 *, REAL8, REAL8, REAL8, REAL8, INT4, INT4 *, 00090 HOUGHptfLUT *, HOUGHPatchGrid *) 00091 \endcode 00092 00093 00094 */ 00095 00096 00097 /* 00098 * 1. An author and Id block 00099 */ 00100 00101 /************************************ <lalVerbatim file="ConstructPLUTCV"> 00102 Author: Sintes, A. M., Krishnan, B. 00103 $Id: ConstructPLUT.c,v 1.28 2007/08/21 14:27:41 badri Exp $ 00104 ************************************* </lalVerbatim> */ 00105 00106 /* 00107 * 2. Commented block with the documetation of this module 00108 */ 00109 00110 00111 /* <lalLaTeX> 00112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00113 \subsection{Module \texttt{ConstructPLUT.c}} 00114 \label{ss:ConstructPLUT.c} 00115 Construction of the look up table for generating partial Hough maps assuming the 00116 use of the stereographic projection. 00117 00118 00119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00120 \subsubsection*{Prototypes} 00121 \vspace{0.1in} 00122 \input{ConstructPLUTD} 00123 \index{\verb&LALHOUGHConstructPLUT()&} 00124 00125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00126 \subsubsection*{Macros (used only internally)} 00127 00128 \begin{verbatim} 00129 #define MAX(A, B) (((A) < (B)) ? (B) : (A)) 00130 #define MIN(A, B) (((A) < (B)) ? (A) : (B)) 00131 #define cot(A) (1./tan(A)) 00132 #define rint(x) floor((x)+0.5) 00133 \end{verbatim} 00134 00135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00136 \subsubsection*{Static function declarations} 00137 \begin{verbatim} 00138 static void PLUTInitialize(HOUGHptfLUT *); 00139 static void FillPLUT(HOUGHParamPLUT *, HOUGHptfLUT *, HOUGHPatchGrid *); 00140 static void CheckLeftCircle(REAL8, REAL8, REAL8, INT4 *, INT4 *, INT4 *, 00141 HOUGHPatchGrid *); 00142 static void CheckRightCircle(REAL8, REAL8, REAL8, INT4 *, INT4 *, INT4 *, 00143 HOUGHPatchGrid *); 00144 static void DrawRightCircle(REAL8, REAL8, REAL8, INT4, INT4, COORType *, 00145 HOUGHPatchGrid *); 00146 static void DrawLeftCircle(REAL8, REAL8, REAL8, INT4, INT4, COORType *, 00147 HOUGHPatchGrid *); 00148 static void CheckLineCase(REAL8, REAL8, REAL8, REAL8 *, INT4 *); 00149 static void FindExactLine(REAL8, REAL8, REAL8 *, REAL8 *); 00150 static void FindLine(REAL8, REAL8, REAL8, REAL8 *, REAL8 *); 00151 static void CheckLineIntersection(REAL8, REAL8, REAL8, INT4 *, INT4 *, INT4 *, 00152 HOUGHPatchGrid *); 00153 static void DrawLine(REAL8, REAL8, REAL8,INT4, INT4, COORType *, HOUGHPatchGrid *); 00154 static void Fill1Column(INT4, INT4*, HOUGHptfLUT *, HOUGHPatchGrid *); 00155 static void FillCaseN1(INT4, INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00156 static void FillCaseN2(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00157 static void FillCaseN3(INT4, INT4, INT4, INT4 *, HOUGHptfLUT *, HOUGHPatchGrid *); 00158 static void FillCaseN4(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00159 static void FillCaseN5(INT4, INT4, INT4, HOUGHptfLUT *); 00160 static void FillCaseN6(INT4, INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00161 static void FillCaseN7(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00162 static void FillCaseN8(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00163 static void Fill1ColumnAnor(INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00164 static void FillCaseA1(INT4, INT4, INT4, HOUGHptfLUT *); 00165 static void FillCaseA2(INT4, INT4, INT4, HOUGHptfLUT *); 00166 static void FillCaseA3(INT4, INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00167 static void InitialCircleCase(INT4 *,REAL8, REAL8, REAL8, REAL8 *, INT4 *, INT4 *, 00168 HOUGHptfLUT *, HOUGHPatchGrid *); 00169 static void SecondCircleCase(INT4, INT4*, REAL8, REAL8, REAL8, INT4, REAL8 *, 00170 INT4*,INT4 *,INT4*, HOUGHptfLUT *, HOUGHPatchGrid *); 00171 static void FollowCircleCase(INT4,INT4 *,REAL8,REAL8,REAL8,REAL8,REAL8,INT4 *, 00172 INT4 *,INT4 *, HOUGHptfLUT *, HOUGHPatchGrid *); 00173 static void InitialLineCase(INT4 *, REAL8, REAL8, REAL8, INT4 *, HOUGHptfLUT *, 00174 HOUGHPatchGrid *); 00175 static void SecondLineCase(INT4, INT4 *, REAL8, REAL8, REAL8, INT4 *, HOUGHptfLUT *, 00176 HOUGHPatchGrid *); 00177 static void FollowLineCase(INT4, INT4 *, REAL8, REAL8, REAL8, REAL8, INT4, INT4 *, 00178 HOUGHptfLUT *, HOUGHPatchGrid *); 00179 \end{verbatim} 00180 00181 00182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00183 \subsubsection*{Description} 00184 00185 This module is the core of the Hough transform. The LAL function \verb&LALHOUGHConstructPLUT()& 00186 constructs the look up tables that will be used to build the so-called 00187 partial-Hough maps. Each look up table is valid for a given sky-patch, time, and 00188 frequency range around a certain \verb@f0@ value. The look up table contains 00189 all the necessary information regarding the borders of the annuli clipped on 00190 the \lq projected' two dimensional sky-patch. 00191 00192 The inputs are: \verb@HOUGHPatchGrid *patch@ containing the grid patch 00193 information. This is independent of the sky location of the 00194 patch. And \verb@HOUGHParamPLUT *par@ with all the other parameters needed. 00195 00196 The output is: \verb@HOUGHptfLUT *lut@. The fields are: 00197 00198 \begin{description} 00199 \item[\texttt{lut-> timeIndex }] Time index of the {\sc lut}. 00200 \item[\texttt{lut->f0Bin }] Frequency bin for which it has been 00201 constructed. 00202 \item[\texttt{lut->deltaF }] Frequency resolution: \texttt{df=1/TCOH} 00203 \item[\texttt{lut->nFreqValid }] \verb@ = PIXERR * f0Bin * VEPI / VTOT@: 00204 Number of frequencies where the {\sc lut} is 00205 valid. 00206 \item[\texttt{lut->iniBin }] First bin affecting the patch with respect to 00207 \verb@f0@. 00208 \item[\texttt{lut->nBin }] Exact number of bins affecting the patch. 00209 \item[\texttt{lut->maxNBins }] Maximum number of bins affecting the patch (for 00210 memory allocation purposes), i.e. length of \texttt{lut->bin}. 00211 \item[\texttt{lut->maxNorders }] Maximum number of borders affecting the patch (for 00212 memory allocation purposes), i.e. length of \texttt{lut->border}. 00213 \item[\texttt{lut->border} ] The annulus borders. 00214 \item[\texttt{lut->bin} ] Bin to border correspondence. 00215 \end{description} 00216 00217 00218 00219 More detailed documentation can be found in the source code itself. 00220 00221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00222 \subsubsection*{Uses} 00223 %\begin{verbatim} 00224 %LALZDestroyVector() 00225 %\end{verbatim} 00226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00227 \subsubsection*{Notes} 00228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00229 \vfill{\footnotesize\input{ConstructPLUTCV}} 00230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00231 </lalLaTeX> */ 00232 00233 00234 /* 00235 * 3. Includes. These should appear in the following order: 00236 * a. Standard library includes 00237 * b. LDAS includes 00238 * c. LAL includes 00239 */ 00240 00241 00242 #include <lal/LUT.h> 00243 00244 00245 /* 00246 * 4. Assignment of Id string using NRCSID() 00247 */ 00248 00249 NRCSID (CONSTRUCTPLUTC, "$Id: ConstructPLUT.c,v 1.28 2007/08/21 14:27:41 badri Exp $"); 00250 00251 00252 00253 /* 00254 * 5.a) Constants, structures (used only internally in this module) 00255 */ 00256 00257 /* 00258 * 5.b) Type declarations (used only internally) 00259 */ 00260 00261 /* 00262 * 5.c) Macros (used only internally) 00263 */ 00264 00265 #define MAX(A, B) (((A) < (B)) ? (B) : (A)) 00266 #define MIN(A, B) (((A) < (B)) ? (A) : (B)) 00267 #define cot(A) (1./tan(A)) 00268 #define rint(x) floor((x)+0.5) 00269 00270 00271 /* 00272 * 5.d) Extern global variable declarations (strongly discouraged) 00273 */ 00274 00275 00276 /* 00277 * 5.e) static Global variables 00278 */ 00279 00280 00281 /* 00282 * 5.f) Static function declarations 00283 */ 00284 00285 static void PLUTInitialize(HOUGHptfLUT *); 00286 static void FillPLUT(HOUGHParamPLUT *, HOUGHptfLUT *, HOUGHPatchGrid *); 00287 00288 static void CheckLeftCircle(REAL8,REAL8,REAL8,INT4 *,INT4 *,INT4 *, 00289 HOUGHPatchGrid *); 00290 static void CheckRightCircle(REAL8,REAL8,REAL8,INT4 *,INT4 *,INT4 *, 00291 HOUGHPatchGrid *); 00292 static void DrawRightCircle(REAL8,REAL8,REAL8,INT4,INT4, COORType *, 00293 HOUGHPatchGrid *); 00294 static void DrawLeftCircle(REAL8,REAL8,REAL8,INT4,INT4,COORType *, 00295 HOUGHPatchGrid *); 00296 static void CheckLineCase(REAL8, REAL8, REAL8,REAL8 *, INT4 *); 00297 /* static void FindExactLine(REAL8,REAL8,REAL8 *,REAL8 *); */ 00298 static void FindLine(REAL8,REAL8,REAL8,REAL8 *,REAL8 *); 00299 static void CheckLineIntersection(REAL8,REAL8,REAL8,INT4 *,INT4 *,INT4 *, 00300 HOUGHPatchGrid *); 00301 static void DrawLine(REAL8, REAL8, REAL8,INT4, INT4, COORType *, HOUGHPatchGrid *); 00302 static void Fill1Column(INT4, INT4*, HOUGHptfLUT *, HOUGHPatchGrid *); 00303 static void FillCaseN1(INT4, INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00304 static void FillCaseN2(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00305 static void FillCaseN3(INT4, INT4, INT4, INT4 *, HOUGHptfLUT *, HOUGHPatchGrid *); 00306 static void FillCaseN4(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00307 static void FillCaseN5(INT4, INT4, INT4, HOUGHptfLUT *); 00308 static void FillCaseN6(INT4, INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00309 static void FillCaseN7(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00310 static void FillCaseN8(INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00311 static void Fill1ColumnAnor(INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00312 static void FillCaseA1(INT4, INT4, INT4, HOUGHptfLUT *); 00313 static void FillCaseA2(INT4, INT4, INT4, HOUGHptfLUT *); 00314 static void FillCaseA3(INT4, INT4, INT4, HOUGHptfLUT *, HOUGHPatchGrid *); 00315 00316 static void InitialCircleCase(INT4 *,REAL8, REAL8, REAL8, REAL8 *, INT4 *, INT4 *, 00317 HOUGHptfLUT *, HOUGHPatchGrid *); 00318 static void SecondCircleCase(INT4, INT4*,REAL8,REAL8, REAL8,INT4,REAL8*, 00319 INT4*,INT4 *,INT4*, HOUGHptfLUT *, HOUGHPatchGrid *); 00320 static void FollowCircleCase(INT4,INT4 *,REAL8,REAL8,REAL8,REAL8,REAL8,INT4 *, 00321 INT4 *,INT4 *, HOUGHptfLUT *, HOUGHPatchGrid *); 00322 static void InitialLineCase(INT4 *, REAL8, REAL8, REAL8, INT4 *, HOUGHptfLUT *, 00323 HOUGHPatchGrid *); 00324 static void SecondLineCase(INT4, INT4 *, REAL8, REAL8, REAL8, INT4 *, HOUGHptfLUT *, 00325 HOUGHPatchGrid *); 00326 static void FollowLineCase(INT4, INT4 *,REAL8, REAL8, REAL8,REAL8,INT4,INT4 *, 00327 HOUGHptfLUT *, HOUGHPatchGrid *); 00328 00329 00330 /* 00331 * 5.g) The functions that make up the guts of this module 00332 */ 00333 00334 00335 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00336 /* ***************************** <lalVerbatim file="ConstructPLUTD"> */ 00337 void LALHOUGHConstructPLUT(LALStatus *status, 00338 HOUGHptfLUT *lut, 00339 HOUGHPatchGrid *patch, 00340 HOUGHParamPLUT *par) 00341 { /* ************************************************ </lalVerbatim> */ 00342 00343 INT8 f0Bin; 00344 00345 /* --------------------------------------------- */ 00346 INITSTATUS (status, " LALHOUGHConstructPLUT", CONSTRUCTPLUTC); 00347 /* ATTATCHSTATUSPTR (status); */ 00348 00349 /* Make sure the arguments are not NULL: */ 00350 /* use aborts instead of asserts */ 00351 if (lut == NULL) { 00352 ABORT( status, LUTH_ENULL, LUTH_MSGENULL); 00353 } 00354 /* ASSERT (lut, status, LUTH_ENULL, LUTH_MSGENULL); */ 00355 00356 if (patch == NULL) { 00357 ABORT( status, LUTH_ENULL, LUTH_MSGENULL); 00358 } 00359 /* ASSERT (patch, status, LUTH_ENULL, LUTH_MSGENULL); */ 00360 00361 if (par == NULL) { 00362 ABORT( status, LUTH_ENULL, LUTH_MSGENULL); 00363 } 00364 /* ASSERT (par, status, LUTH_ENULL, LUTH_MSGENULL); */ 00365 00366 if ( fabs((REAL4)par->deltaF - (REAL4)patch->deltaF) > 1.0e-6) { 00367 ABORT( status, LUTH_EVAL, LUTH_MSGEVAL); 00368 } 00369 /* ASSERT (par->deltaF == patch->deltaF, status, LUTH_EVAL, LUTH_MSGEVAL); */ 00370 00371 /* ------------------------------------------- */ 00372 00373 f0Bin = par->f0Bin; 00374 00375 lut->deltaF = par->deltaF; 00376 lut->f0Bin = f0Bin; 00377 00378 lut->nFreqValid = par->nFreqValid; 00379 /* lut->nFreqValid = PIXERR * f0Bin *VEPI/VTOT; */ 00380 00381 /* ------------------------------------------- */ 00382 00383 PLUTInitialize(lut); 00384 FillPLUT(par, lut, patch); 00385 00386 00387 /* Make sure number of bins makes sense with the dimensions */ 00388 if (lut->nBin <= 0) { 00389 ABORT( status, LUTH_ESIZE, LUTH_MSGESIZE); 00390 } 00391 /* ASSERT (lut->nBin >0, status, LUTH_ESIZE, LUTH_MSGESIZE); */ 00392 00393 if (lut->nBin > lut->maxNBins) { 00394 ABORT( status, LUTH_ESIZE, LUTH_MSGESIZE); 00395 } 00396 /* ASSERT (lut->nBin <= lut->maxNBins, status, LUTH_ESIZE, LUTH_MSGESIZE); */ 00397 00398 00399 /* ------------------------------------------- */ 00400 /* DETATCHSTATUSPTR (status); */ 00401 00402 /* normal exit */ 00403 RETURN (status); 00404 } 00405 00406 00407 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00408 00409 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00410 /* >>>>>>>> FUNCTIONS ONLY USED INTERNALLY <<<<<< */ 00411 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00412 00413 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00414 00415 00416 00417 00418 /***************************************************************/ 00419 /* Subroutine to initialize the partial LUT */ 00420 /* Authors: Sintes, A.M */ 00421 /* June 7, 2001 */ 00422 /***************************************************************/ 00423 00424 static void PLUTInitialize(HOUGHptfLUT *lut){ 00425 UINT4 i; 00426 UINT4 maxNBins, maxNBorders; 00427 00428 maxNBins = lut->maxNBins; 00429 maxNBorders = lut->maxNBorders; 00430 00431 for(i=0;i<maxNBins;++i){ 00432 00433 /* check lut->bin is not null */ 00434 if ( lut->bin + i == NULL ) { 00435 fprintf(stderr," pointer lut->bin+%d is null [ConstructPLUT.c %d]\n", i, __LINE__); 00436 } 00437 00438 lut->bin[i].leftB1 = 0; 00439 lut->bin[i].rightB1 = 0; 00440 lut->bin[i].leftB2 = 0; 00441 lut->bin[i].rightB2 = 0; 00442 lut->bin[i].piece1max = -1; 00443 lut->bin[i].piece1min = 0; 00444 lut->bin[i].piece2max = -1; 00445 lut->bin[i].piece2min = 0; 00446 } 00447 00448 for(i=0;i<maxNBorders;++i){ 00449 00450 /* check lut->border is not null */ 00451 if ( lut->border + i == NULL ) { 00452 fprintf(stderr," pointer lut->border+%d is null [ConstructPLUT.c %d]\n", i, __LINE__); 00453 } 00454 00455 lut->border[i].yUpper = -1; 00456 lut->border[i].yLower = 0; 00457 } 00458 return; 00459 } 00460 00461 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00462 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00463 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00464 00465 /****************************************************************/ 00466 /* subroutine to fill the LUT */ 00467 /* */ 00468 /* Authors: Sintes, A.M */ 00469 /* March 16, 2001 */ 00470 /****************************************************************/ 00471 00472 /* ******************* Some explanations *********************** */ 00473 /* The program should go like this: */ 00474 00475 /* First call subroutine XXXXXXXXXX.c */ 00476 /* to calculate xi(t) for a given f0 (and demodulation parameters). */ 00477 /* Then rotate that vector to our new coordinates, if it was not */ 00478 /* constructed in that way. */ 00479 00480 /* We need here |xi|, alpha, delta[-pi/2,pi/2], on the sphere. */ 00481 /* or its cartesian coordiantes */ 00482 00483 /* The master equation to solve is: */ 00484 /* f(t)-f0 = xi*n - xi*N */ 00485 /* or */ 00486 /* cos( phi)= [f(t)-f0 +xi*N]/|xi| */ 00487 00488 /* where: xi*N= -|xi|* sin(delta) */ 00489 00490 /* Given a bin in the peakgram with */ 00491 /* Deltaf= f(t)(center bin)- f0= k df */ 00492 /* (df => frequency resolution =1/TCOH) */ 00493 /* Then */ 00494 /* [cos(phi)]max = min[ 1, k (df/|xi|) + (xi*N +df/2)/|xi| ] */ 00495 /* and */ 00496 /* [cos(phi)]min = max[-1, k (df/|xi|) + (xi*N -df/2)/|xi| ] */ 00497 /* Note */ 00498 /* if [cos(phi)]max = 1, do not increase k !!! */ 00499 /* if [cos(phi)]min =-1, do not decrease k !!! */ 00500 00501 /* [cos(phi)]max(k) = min[ 1, df/|xi|+[cos(phi)]max(k-1) ] */ 00502 /* [cos(phi)]min(k) = max[ 1, df/|xi|+[cos(phi)]min(k-1) ] */ 00503 /* ********************************************************************* */ 00504 /* for a bin,peak or border: */ 00505 00506 /* if cos(phi)=+-1 => nothing to be drawn! */ 00507 /* otherwise */ 00508 /* obtain phi in the interval [0, LAL_PI] */ 00509 /* if delta+phi= pi/2, or delta-phi=pi/2 (carefull, with +2*pi) */ 00510 /* draw line */ 00511 /* otherwise draw a circle */ 00512 /* ******************************************************************* */ 00513 /* a pixel j , corresponds to x(j)= patch->deltaX*(0.5+j- patch->xSide/2.) */ 00514 /* the nearest center of a pixel is j = round[ x/patch->deltaX +patch->xSide/2.-0.5] */ 00515 /* ******************************************************************* */ 00516 /* The way to convert k into the bin index is the following: */ 00517 /* for k>=0, binindex= k */ 00518 /* for k<0, binindex= nBin+iniBin-1-k */ 00519 /* f0 corresponds to k=0 */ 00520 /* This will be used when reading the peakgram! */ 00521 /* ******************************************************************* */ 00522 00523 static void FillPLUT(HOUGHParamPLUT *par, HOUGHptfLUT *lut, 00524 HOUGHPatchGrid *patch){ 00525 00526 /********************************************************/ 00527 /* variables that need to be calculated before */ 00528 /********************************************************/ 00529 00530 REAL8 cosDelta; /* = df/|xi| */ 00531 REAL8 cosPhiMax0; /* max val of cosPhi of freq bin containing patch center */ 00532 REAL8 cosPhiMin0; /* mix val of cosPhi of freq bin containing patch center */ 00533 REAL8 alpha; /* = xi.alpha in the rotated coordinates */ 00534 REAL8 delta; /* = xi.delta */ 00535 REAL8 epsilon; /* = 8 * LINERR/(f0Bin * VTOT * patchSize^2) */ 00536 00537 00538 /********************************************************/ 00539 UINT4 maxNBins; 00540 UINT4 maxNBorders; 00541 00542 INT4 lastBorder =0; /* counter of the last build border */ 00543 INT4 currentBin =0; /* counter of the bin studied */ 00544 00545 INT4 ifailPlus = 1; /* =1 (ok, continue to next bin), =0 (stop) */ 00546 INT4 ifailMinus = 1; /* =1 (ok, continue to previous bin), =0 (stop) */ 00547 00548 INT4 directionPlus=-1; /* = +1,or -1 */ 00549 INT4 directionPlusZero=-1; /* = +1,or -1 */ 00550 INT4 directionMinus; /* = +1,or -1 */ 00551 00552 INT4 pathology=1; /* =1 (normal), =0 (anormal case) */ 00553 INT4 lineCase; /* =1 line Case, =0 circle case */ 00554 INT4 nBinPos; 00555 00556 /********************************************************/ 00557 00558 REAL8 rCritic; 00559 REAL8 lambda; 00560 REAL8 rcOldPlus; 00561 REAL8 rcOldMinus; 00562 REAL8 cosPhiMax, cosPhiMin, phi; 00563 REAL8 ang1,ang2; 00564 REAL8 eps; 00565 00566 /********************************************************/ 00567 maxNBins = lut->maxNBins; 00568 maxNBorders = lut->maxNBorders; 00569 00570 alpha = par->xi.alpha; 00571 delta = par->xi.delta; 00572 cosDelta = par->cosDelta; 00573 cosPhiMax0 = par->cosPhiMax0; 00574 cosPhiMin0 = par->cosPhiMin0; 00575 epsilon = par->epsilon; 00576 00577 /********************************************************/ 00578 00579 /* Copy value of offset */ 00580 lut->offset = par->offset; 00581 00582 /********************************************************/ 00583 00584 lambda = 2* delta -LAL_PI*0.5; 00585 rCritic = 2* cos(lambda) /(1 - sin(lambda) ); 00586 00587 /* Initializing variables to irrelevant values, 00588 since these values should never be used */ 00589 rcOldPlus = rCritic; 00590 rcOldMinus = rCritic; 00591 /********************************************************/ 00592 /* starting with the (central) bin corresponding to: */ 00593 /* Delta_f(t) =0 (k=0), border cosPhiMax */ 00594 /********************************************************/ 00595 00596 /* cosPhiMax = MIN(1, cosPhiMax0); */ 00597 cosPhiMax = cosPhiMax0; 00598 00599 if(cosPhiMax > 0.99999999){ /* avoid points or small circles */ 00600 ifailPlus = 0; /* do not go to the next bin */ 00601 directionPlus = -1; 00602 } else{ 00603 00604 phi = acos(cosPhiMax); /* in the interval (0,PI) */ 00605 ang1 = delta + phi; 00606 ang2 = delta - phi; 00607 00608 /* check for lines, or numerical lines! */ 00609 CheckLineCase(epsilon, ang1, ang2, &eps, &lineCase); 00610 00611 if( lineCase ){ 00612 /* line case */ 00613 InitialLineCase(&lastBorder,alpha,delta,eps, &ifailPlus,lut, patch); 00614 directionPlus = -1; 00615 } else{ 00616 /* circle case */ 00617 InitialCircleCase(&lastBorder,alpha, ang1, ang2, 00618 &rcOldPlus, &directionPlus, &ifailPlus,lut, patch); 00619 } 00620 } 00621 00622 directionPlusZero= directionPlus; 00623 00624 /********************************************************/ 00625 /* moving to the other bins */ 00626 /********************************************************/ 00627 00628 /********************************************************/ 00629 /* Plus direction: increasing cosPhiMax */ 00630 /********************************************************/ 00631 00632 00633 00634 while (ifailPlus){ 00635 00636 ++currentBin; 00637 pathology = 1; 00638 00639 /* Some checks */ 00640 /* #ifdef CHECKHOUGHINDEX */ 00641 if (currentBin > maxNBins || lastBorder>= maxNBorders ){ 00642 fprintf(stderr,"currentBin=%d not in range 1 to maxNBins=%d\n" 00643 "or lastborder=%d >= maxNBorders=%d [ConstructPLUT.c %d]\n", 00644 currentBin,maxNBins,lastBorder,maxNBorders, __LINE__); 00645 } 00646 /* #endif */ 00647 00648 cosPhiMax = cosPhiMax + cosDelta; 00649 /* or cosPhiMax = MIN(1,cosPhiMax + cosDelta ); */ 00650 00651 if( cosPhiMax > 0.99999999){ /* check appropiate value */ 00652 ifailPlus = 0; 00653 } else { 00654 00655 phi = acos(cosPhiMax); /* it is in the interval (0,pi) */ 00656 ang1 = delta + phi; 00657 ang2 = delta - phi; 00658 00659 /* check for lines, or numerical lines! */ 00660 CheckLineCase(epsilon, ang1, ang2, &eps, &lineCase); 00661 00662 if( lineCase ){ 00663 /* line case */ 00664 FollowLineCase(currentBin, &lastBorder,alpha,delta,eps, 00665 rcOldPlus, directionPlus, &ifailPlus,lut, patch); 00666 } else{ 00667 /* circle case */ 00668 FollowCircleCase(currentBin, &lastBorder,alpha, ang1, ang2,rCritic, 00669 rcOldPlus, &pathology, &directionPlus, 00670 &ifailPlus, lut, patch); 00671 } 00672 } 00673 00674 if(pathology){ 00675 Fill1Column(currentBin, &lastBorder, lut, patch); 00676 }else{ 00677 Fill1ColumnAnor(currentBin, lut, patch); 00678 } 00679 } 00680 00681 nBinPos = currentBin; 00682 00683 00684 /********************************************************/ 00685 /* starting with the (central) bin corresponding to: */ 00686 /* Delta_f(t) =0 (k=0), border cosPhiMin */ 00687 /********************************************************/ 00688 00689 /* cosPhiMin = MAX(-1, cosPhiMin0); */ 00690 cosPhiMin = cosPhiMin0; 00691 00692 if(cosPhiMin < -0.99999999){ /* avoid points or small circles */ 00693 ifailMinus = 0; /* do not go to the next bin */ 00694 } else{ 00695 00696 phi = acos(cosPhiMin); /* in the interval (0,PI) */ 00697 ang1 = delta + phi; 00698 ang2 = delta - phi; 00699 00700 /* check for lines, or numerical lines! */ 00701 CheckLineCase(epsilon, ang1, ang2, &eps, &lineCase); 00702 00703 if( lineCase ){ 00704 /* line case */ 00705 SecondLineCase(currentBin,&lastBorder,alpha,delta,eps, &ifailMinus, 00706 lut, patch); 00707 directionMinus = -1; 00708 pathology = 0; 00709 } else{ 00710 /* circle case */ 00711 pathology = 1; /* provisionally */ 00712 SecondCircleCase(currentBin, &lastBorder,alpha, ang1, ang2, 00713 directionPlusZero, &rcOldMinus, 00714 &pathology, &directionMinus, 00715 &ifailMinus, lut, patch); 00716 } 00717 } 00718 00719 /********************************************************/ 00720 /* the way to identify initial pathologies: */ 00721 /* initial or second case being a line ! */ 00722 /* or two circles, both with direction=-1 */ 00723 /********************************************************/ 00724 00725 if(pathology){ 00726 Fill1Column(0, &lastBorder,lut, patch); 00727 }else{ 00728 Fill1ColumnAnor(0, lut, patch); 00729 } 00730 00731 /********************************************************/ 00732 /* moving to the other bins */ 00733 /********************************************************/ 00734 00735 /********************************************************/ 00736 /* Minus direction: decreasing cosPhiMin */ 00737 /********************************************************/ 00738 00739 while(ifailMinus){ 00740 00741 ++currentBin; 00742 pathology = 1; 00743 00744 /* Some checks */ 00745 /* #ifdef CHECKHOUGHINDEX */ 00746 if (currentBin > maxNBins || lastBorder>= maxNBorders ){ 00747 fprintf(stderr,"currentBin=%d not in range 1 to maxNBins=%d\n" 00748 "or lastborder=%d >= maxNBorders=%d [ConstructPLUT.c %d]\n", 00749 currentBin,maxNBins,lastBorder,maxNBorders, __LINE__); 00750 } 00751 /* #endif */ 00752 00753 00754 cosPhiMin = cosPhiMin - cosDelta; 00755 00756 if( cosPhiMin < -0.99999999){ /* check appropiate value */ 00757 ifailMinus = 0; 00758 } else { 00759 00760 phi = acos(cosPhiMin); /* it is in the interval (0,pi) */ 00761 ang1 = delta + phi; 00762 ang2 = delta - phi; 00763 00764 /* check for lines, or numerical lines! */ 00765 CheckLineCase(epsilon, ang1, ang2, &eps, &lineCase); 00766 00767 if( lineCase ){ 00768 /* line case */ 00769 FollowLineCase(currentBin, &lastBorder,alpha,delta,eps, 00770 rcOldMinus, directionMinus, &ifailMinus,lut, patch); 00771 } else{ 00772 /* circle case */ 00773 FollowCircleCase(currentBin, &lastBorder,alpha, ang1, ang2,rCritic, 00774 rcOldMinus, &pathology, &directionMinus, 00775 &ifailMinus, lut, patch); 00776 } 00777 } 00778 00779 if(pathology){ 00780 Fill1Column(currentBin, &lastBorder, lut, patch); 00781 }else{ 00782 Fill1ColumnAnor(currentBin, lut, patch); 00783 } 00784 } 00785 00786 /********************************************************/ 00787 /* set iniBin,nBin etc */ 00788 /********************************************************/ 00789 00790 lut->nBin = currentBin + 1; 00791 lut->iniBin = nBinPos - currentBin; 00792 00793 return; 00794 } 00795 00796 /* end of the subroutine*/ 00797 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00798 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00799 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00800 00801 00802 /****************************************************************/ 00803 /* */ 00804 /* from initialLineCase.c March 16, 2001 */ 00805 /* */ 00806 /* program to find and identify bins and borders */ 00807 /* in the initial line case */ 00808 /* */ 00809 /* Authors: Sintes, A.M */ 00810 /* */ 00811 /****************************************************************/ 00812 00813 00814 /****************************************************************/ 00815 00816 static void InitialLineCase(INT4 *lastBorderP, REAL8 alpha, REAL8 delta, 00817 REAL8 eps, INT4 *ifailP, HOUGHptfLUT *lut, 00818 HOUGHPatchGrid *patch){ 00819 00820 00821 INT4 lastBorder; 00822 00823 00824 REAL8 xA,yA; 00825 INT4 yymin,yymax; 00826 REAL8 xRel, slope; 00827 INT4 noIn; /* if no intersection occurs noIn=0 */ 00828 00829 /* some paranoid error checking */ 00830 if (patch == NULL ) { 00831 fprintf(stderr, "pointer patch is null [ConstructPLUT.c %d]\n", __LINE__); 00832 } 00833 00834 if (lut == NULL ) { 00835 fprintf(stderr, "pointer lut is null [ConstructPLUT.c %d]\n",__LINE__); 00836 } 00837 00838 if (ifailP == NULL ) { 00839 fprintf(stderr, "pointer ifailP is null [ConstructPLUT.c %d]\n",__LINE__); 00840 } 00841 00842 if (lastBorderP == NULL ) { 00843 fprintf(stderr, "pointer lastBorderP is null [ConstructPLUT.c %d]\n",__LINE__); 00844 } 00845 lastBorder = *lastBorderP; 00846 00847 00848 00849 /************************************************/ 00850 FindLine(alpha, delta, eps, &xA, &yA); 00851 CheckLineIntersection(alpha, xA, yA, &yymin, &yymax, &noIn, patch); 00852 00853 if( noIn ==0 ){ 00854 *ifailP = 0; /* =1 (ok), =0 (stop) */ 00855 return; 00856 } 00857 ++lastBorder; 00858 00859 if (yymin < 0) { 00860 fprintf(stderr,"WARNING: Fixing yymin (%d -> 0) [ConstructPLUT.c %d]\n", 00861 yymin, __LINE__); 00862 yymin = 0; 00863 } 00864 if (yymax >= patch->ySide) { 00865 fprintf(stderr,"WARNING: Fixing yymax (%d -> %d) [ConstructPLUT.c %d]\n", 00866 yymax, patch->ySide-1, __LINE__); 00867 yymax = patch->ySide - 1; 00868 } 00869 00870 lut->border[lastBorder].yUpper = yymax; 00871 lut->border[lastBorder].yLower = yymin; 00872 00873 DrawLine(alpha, xA, yA, yymin, yymax, 00874 &lut->border[lastBorder].xPixel[0] , patch); 00875 00876 /************************************************/ 00877 00878 if( (alpha == LAL_PI*0.5) || (alpha == LAL_PI*1.5) || 00879 (alpha == -LAL_PI*0.5) ){ /* horizontal line */ 00880 00881 if( yA < 0 ){ /* convention */ 00882 lut->bin[0].rightB1 = lastBorder; 00883 lut->bin[1].leftB1 = lastBorder; 00884 lut->border[lastBorder].yCenter = 0; /*or smaller*/ 00885 } else { 00886 lut->bin[0].leftB2 = lastBorder; 00887 lut->bin[1].rightB2 = lastBorder; 00888 lut->border[lastBorder].yCenter = patch->ySide -1;/*or bigger */ 00889 } 00890 } 00891 else { /* non- horizontal line */ 00892 xRel = xA + tan(alpha)*yA; 00893 00894 if( (alpha == 0) || (alpha == LAL_PI) || (alpha == -LAL_PI) ){ 00895 /* vertical line */ 00896 slope = +1; /* arbitrary number, just to avoid overflow */ 00897 } else { 00898 slope = - cot(alpha); 00899 } 00900 00901 if( xRel < 0 ){ 00902 lut->bin[0].leftB2 = lastBorder; 00903 lut->bin[1].rightB2= lastBorder; 00904 00905 if ( slope < 0 ){ 00906 lut->border[lastBorder].yCenter = 0; /*or smaller*/ 00907 } else { 00908 lut->border[lastBorder].yCenter = patch->ySide -1;/*or bigger */ 00909 } 00910 00911 } else { 00912 lut->bin[0].rightB1 = lastBorder; 00913 lut->bin[1].leftB1 = lastBorder; 00914 00915 if ( slope > 0 ){ 00916 lut->border[lastBorder].yCenter = 0; /*or smaller*/ 00917 } else { 00918 lut->border[lastBorder].yCenter = patch->ySide -1;/*or bigger */ 00919 } 00920 } 00921 } /* end non-horizontal line */ 00922 00923 00924 /************************************************/ 00925 00926 *lastBorderP = lastBorder; 00927 00928 return; 00929 } 00930 00931 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00932 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00933 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ 00934 00935 /****************************************************************/ 00936 /* */ 00937 /* from secondLineCase.c March 16, 2001 */ 00938 /* */ 00939 /* program to find and identify bins and borders */ 00940 /* in the second line case */ 00941 /* */ 00942 /* Authors: Sintes, A.M */ 00943 /* */ 00944 /****************************************************************/ 00945 00946 00947 /****************************************************************/ 00948 00949 static void SecondLineCase(INT4 currentBin, INT4 *lastBorderP, 00950 REAL8 alpha, REAL8 delta, 00951 REAL8 eps, INT4 *ifailP, HOUGHptfLUT *lut, 00952 HOUGHPatchGrid *patch){ 00953 00954 /* we are for sure in a pathological case. Border names are 00955 changed accordingly */ 00956 00957 INT4 lastBorder; 00958 00959 00960 REAL8 xA,yA; 00961 INT4 yymin,yymax; 00962 REAL8 xRel, slope; 00963 INT4 noIn; /* if no intersection occurs noIn=0 */ 00964 00965 00966 /* some paranoid error checking */ 00967 if (patch == NULL ) { 00968 fprintf(stderr, "pointer patch is null [ConstructPLUT.c %d]\n",__LINE__); 00969 } 00970 00971 if (lut == NULL ) { 00972 fprintf(stderr, "pointer lut is null [ConstructPLUT.c %d]\n",__LINE__); 00973 } 00974 00975 if