ConstructPLUT.c

Go to the documentation of this file.
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</