LALInspiralBCVBank.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Thomas Cokelaer
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 /*  <lalVerbatim file="LALInspiralBCVBankCV">
00021 Author Cokelaer, T
00022 $Id: LALInspiralBCVBank.c,v 1.8 2007/06/13 13:33:10 thomas Exp $
00023 </lalVerbatim>  */
00024 
00025 /*  <lalLaTeX>
00026 
00027 \subsection{Module \texttt{LALInspiralCreateBCVBank.c}}
00028 Lay a flat grid of BCV templates in the user specified range
00029 of the parameters $(\psi_0, \psi_3)$ in {\tt coarseIn} structure
00030 (see below).
00031 \subsubsection*{Prototypes}
00032 \vspace{0.1in}
00033 \input{LALInspiralCreateBCVBankCP}
00034 \idx{LALInspiralCreateBCVBank()}
00035 \begin{itemize}
00036    \item \texttt{list,} Output, an array containing the template bank parameters.
00037    \item \texttt{nlist,} Output, the number of templates in bank.
00038 \end{itemize}
00039 
00040 \subsubsection*{Description}
00041 Given the range of the parameters $(\psi_0, \psi_3),$  
00042 the number of templates in the {\tt fCut} direction,
00043 {\it minimalMatch}, noise spectral density, upper and
00044 lower frequency cutoffs (all in the input structure {\tt coarseIn})
00045 this routine outputs the list of templates in the BCV bank
00046 for the parameters $(\psi_0, \psi_3, f_{\rm cut}).$  
00047 \subsubsection*{Algorithm}
00048 A flat signal manifold is assumed and templates are laid
00049 uniform in the three dimensions.  See below for an explanation
00050 of how templates are chosen in the {\tt fcut} direction.
00051 
00052 \subsubsection*{Uses}
00053 \begin{verbatim}
00054 LALInspiralUpdateParams()
00055 LALRalloc()
00056 \end{verbatim}
00057 
00058 \subsubsection*{Notes}
00059 \clearpage
00060 
00061 
00062 \subsection{Module \texttt{LALInspiralBCVFcutBank.c}}
00063 Given a grid of templates with distinct values of $(\psi_0, \psi_3)$
00064 this routine returns a new grid in which every template has {\tt numFcutTemplates}
00065 partners differing from one another in the ending frequency {\tt fendBCV.}
00066 A call to this function should be preceeded by a call to \texttt {LALInspiralCreateFlatBank.c},
00067 or a similar function, that gives a grid in $(\psi_0, \psi_3)$ space.
00068 \subsubsection*{Prototypes}
00069 \vspace{0.1in}
00070 \input{LALInspiralBCVFcutBankCP}
00071 \idx{LALInspiralBCVFcutBank()}
00072 \begin{itemize}
00073    \item \texttt{list,} Output/Input, an array initially containing the template 
00074    bank with the values of {\tt list[j]->psi0, list[j]->psi3, list[j]->fLower,} specified,
00075    is replaced on return with a re-sized array specifying also {\tt list->fFinal.}
00076    \item \texttt{Nlist,} Output/Input, the number of templates in the Input bank is
00077    replaced by the number of templates in the output bank.
00078    \item \texttt{numFcutTemplates,} Input, the largest number of templates for the
00079    parameter $f_{cut}$ of BCV.
00080 \end{itemize}
00081 
00082 \subsubsection*{Description}
00083 
00084 A lattice of templates for BCV models should include,
00085 in addition to the values of $(\psi_0, \psi_3)$ 
00086 a range of $f_{\rm cut}$ -- the cutoff frequency. 
00087 The right approach would be
00088 to compute the metric in the three-dimensional space of 
00089 $(\psi_0, \psi_3, f_{\rm cut})$ and to choose templates as
00090 dictated by the metric. However, analytic computation of the
00091 metric has not been easy. Therefore, it has become necessary
00092 (at least for the time being) to make alternate choice of
00093 the cutoff frequencies. 
00094 
00095 In this routine we implement a simple
00096 choice based on physical grounds: The post-Newtonian models
00097 predict an ending frequency that is larger than, but close to,
00098 the Schwarzschild last-stable orbit frequency
00099 $f_{\rm lso} = (6^{3/2} \pi M )^{-1}$ where $M$ is the total mass,
00100 while the effective one-body model has an ending frequency close
00101 to the light-ring, whose Schwarzschild value is 
00102 $f_{\rm lr} = (3^{3/2} \pi M )^{-1}.$ It is necessary to know
00103 the total mass of the system in both cases.  However, not all
00104 pairs of $(\psi_0, \psi_3)$ can be inverted to get a positive
00105 $M$ but only when $\psi_0 > 0$ and $\psi_3 < 0.$ Even then
00106 it is not guaranteed that the symmetric mass ratio will be
00107 less than $1/4,$ a necessary condition so that the component
00108 masses are found to be real. However, we do not demand that the
00109 symmetric mass ratio is less than a quarter. If the total mass 
00110 is non-negative then we compute the $(f_{\rm lso}, f_{\rm lr})$
00111 and choose a user specified {\tt numFcutTemplates} number of 
00112 templates with their cutoff frequency {\tt list->fFinal} defined
00113 uniformly spaced in the range $[f_{\rm lso},\ f_{\rm lr}].$
00114 
00115 Furthermore, this routine discards all templates for which
00116 either the mass is not defined or, when defined, {\tt list->fFinal} is
00117 smaller than the user defined lower frequency cutoff or larger
00118 than the Nyquist frequency of templates.
00119 Thus, the number of templates returned by this routine could 
00120 be larger or fewer than the input number of templates.
00121 
00122 \subsubsection*{Algorithm}
00123 Given $(\psi_0, \psi_3)$ one can solve for $(M, \eta)$ using:
00124 \begin{equation}
00125 M = \frac{-\psi_3}{16 \pi^2 \psi_0},\ \ \eta = \frac{3}{128 \psi_0 (\pi M)^{5/3}}.
00126 \end{equation}
00127 Given the total mass compute the last stable orbit and light-ring frequencies using
00128 \begin{equation}
00129 f_{\rm lso} = (6^{3/2} \pi M)^{-1},\ \  f_{\rm lr} = (3^{3/2} \pi M)^{-1}.
00130 \end{equation}
00131 Divide the range $(f_{\rm lso}, f_{\rm lr})$ so as to have $n_{\rm cut}={\tt numFcutTemplates}$
00132 templates over this range: 
00133 \begin{equation}
00134 df = f_{\rm lr} \frac {\left ( 1 - 2^{-3/2} \right ) }{ (n_{\rm cut} -1) }.
00135 \end{equation}
00136 Next, choose templates at $f_k = f_{\rm lr} - k \times df,$ where $k=0, \ldots, n_{\rm cut}-1.$
00137 Note that by definition $f_0 = f_{\rm lr}$ and $f_{n_{\rm cut}-1} = f_{\rm lso};$
00138 there are exatly $n_{\rm cut}$ templates in the range $(f_{\rm lso}, f_{\rm lr}).$
00139 We discard a template if either $M$ is not defined or if $f_{\rm cut}$ is smaller
00140 than the lower frequency cutoff specified in  \texttt{list[j]->fLower.}
00141 
00142 \subsubsection*{Uses}
00143 \begin{verbatim}
00144 LALRalloc()
00145 \end{verbatim}
00146 \subsubsection*{Notes}
00147 
00148 
00149 \vspace{0.1in}
00150 \vfill{\footnotesize\input{LALInspiralBCVBankCV}}
00151 </lalLaTeX>  */
00152 
00153 #include <stdio.h>
00154 #include <lal/LALInspiralBank.h>
00155 #include <lal/AVFactories.h>
00156 #include <lal/SeqFactories.h>
00157 #include <lal/LALStdio.h>
00158 #include <lal/FindRoot.h>
00159 
00160 
00161 NRCSID(LALINSPIRALBCVBANKC, "$Id: LALInspiralBCVBank.c,v 1.8 2007/06/13 13:33:10 thomas Exp $");
00162 
00163 /*  <lalVerbatim file="LALInspiralCreateBCVBankCP"> */
00164 void 
00165 LALInspiralCreateBCVBank (
00166     LALStatus            *status, 
00167     InspiralTemplateList **list, 
00168     INT4                 *nlist,
00169     InspiralCoarseBankIn coarseIn
00170     ) 
00171 /*  </lalVerbatim>  */
00172 {  
00173   INT4  j = 0;
00174   INT4  nlistOld = 0;
00175   /*do we really need static declaration here ? */
00176   static InspiralBankParams     bankParams;
00177   static InspiralMetric         metric;
00178   static InspiralTemplate       params;
00179   static CreateVectorSequenceIn in; 
00180   static REAL4VectorSequence    *tempList = NULL;
00181 
00182   INITSTATUS( status, "LALInspiralCreateBCVBank", 
00183       LALINSPIRALBCVBANKC );
00184   ATTATCHSTATUSPTR( status );
00185 
00186   ASSERT( coarseIn.psi0Min > 0., status,
00187       LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00188   ASSERT( coarseIn.psi0Max > coarseIn.psi0Min, status,
00189       LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00190   ASSERT( coarseIn.psi3Min < 0., status,
00191       LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00192   ASSERT( coarseIn.psi3Max > coarseIn.psi3Min, status,
00193       LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00194   ASSERT( coarseIn.LowGM < coarseIn.HighGM, status, 
00195       LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00196 
00197   /* populate the param structure so as to call
00198    * ComputeMetricBCV */
00199   params.fLower         = coarseIn.fLower;
00200   params.fCutoff        = coarseIn.fUpper;
00201   params.alpha          = coarseIn.alpha;
00202   /* Get the BCV metric in psi0psi3 plane. */
00203   LALInspiralComputeMetricBCV( status->statusPtr, 
00204       &metric, &coarseIn.shf, &params );
00205   CHECKSTATUSPTR( status );
00206 
00207   /* print the metric if lalinfo is on*/
00208   if ( lalDebugLevel & LALINFO ) 
00209   {
00210     REAL8 dx0 = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/metric.g00 );
00211     REAL8 dx1 = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/metric.g11 );
00212     LALPrintError( "G00=%e G01=%e G11=%e\n", 
00213         metric.G00, metric.G01, metric.G11 );
00214     LALPrintError( "g00=%e g11=%e theta=%e\n", 
00215         metric.g00, metric.g11, metric.theta );
00216     LALPrintError( "dp0=%e dp1=%e\n", dx0, dx1 );
00217   }
00218 
00219   /* We have the metric, which is constant. Now we need to place 
00220    * the templates in the parameter space which is define as follows by 
00221    * the psi0 and psi3 range: 
00222    * */
00223   bankParams.metric             = &metric;
00224   bankParams.minimalMatch       = coarseIn.mmCoarse;
00225   bankParams.x0Min              = coarseIn.psi0Min;
00226   bankParams.x0Max              = coarseIn.psi0Max;
00227   bankParams.x1Min              = coarseIn.psi3Min;
00228   bankParams.x1Max              = coarseIn.psi3Max;
00229   
00230   /* Let us define a temporary list of templates. */
00231   in.length             = 1;
00232   in.vectorLength       = 2;
00233   LALSCreateVectorSequence( status->statusPtr, &tempList, &in );
00234   CHECKSTATUSPTR( status );
00235 
00236   /* First we place templates in the psi0/psi3 plane.
00237    * 
00238    * Historically we had two template banks. If gridSpacing is set to 
00239    * S2BCV, then, the code generates the bank used during S2. This bank
00240    * uses a non-oriented square placement in psi0/psi3 plane and the 
00241    * fcut dimension placement is done BCVRegularFcutBank or BCVFCutBank 
00242    * function.
00243    * If gridSpacing is not S3BCV, then we have the choice between a 
00244    * square or an hexagonal placement, oriented or not and fcut is placed
00245    * using BankFcutS3S4.
00246    * */
00247   if (coarseIn.gridSpacing  != S2BCV)
00248   {
00249     LALInspiralCreateFlatBankS3S4( status->statusPtr, tempList, &bankParams , coarseIn);
00250     CHECKSTATUSPTR( status );
00251   }
00252   else 
00253   {
00254     LALInspiralCreateFlatBank( status->statusPtr, tempList, &bankParams);
00255     CHECKSTATUSPTR( status );
00256   }
00257 
00258   *nlist = tempList->length;
00259   *list = (InspiralTemplateList *) 
00260     LALCalloc( *nlist, sizeof(InspiralTemplateList) );
00261   if ( ! *list )
00262   {
00263     ABORT (status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00264   }
00265   /* We populate the output.
00266    * */
00267   for ( j = 0; j < *nlist; ++j )
00268   {
00269     (*list)[j].params.psi0                              = (REAL8) tempList->data[2*j];
00270     (*list)[j].params.psi3                              = (REAL8) tempList->data[2*j+1];
00271     (*list)[j].params.fLower                    = params.fLower;
00272     (*list)[j].params.nStartPad                 = 0;
00273     (*list)[j].params.nEndPad                   = 0;
00274     (*list)[j].params.tSampling                 = coarseIn.tSampling;
00275     (*list)[j].params.distance                  =  1.;
00276     (*list)[j].params.signalAmplitude   = 1.;
00277     (*list)[j].params.approximant               = BCV;
00278     (*list)[j].params.massChoice                = psi0Andpsi3;
00279     (*list)[j].params.order                             = twoPN;
00280     (*list)[j].metric                                   = metric;
00281     (*list)[j].params.alpha                     = coarseIn.alpha;
00282   }
00283   nlistOld = *nlist;
00284   
00285   /* Once the psi0/psi3 plane is populated, for each coordinate, we 
00286    * populate along the fcut dimension. Again, for historical reason,
00287    * we call one of the following functions which slightly differs 
00288    * from each other (see documentation).
00289    * */
00290    
00291   /* If coarseIn.lowGM == - 1 then LowGM is  unphysical. Hence, we use a 
00292    * Regular grid in cutoff frequency which is independant of LowGM or 
00293    * HighGM and which lays between Flower and Fsampling/2. If 
00294    * coarseIn.lowGM != -1 then, we populate between two frequencyies 
00295    * defines by low and high GM. (i.e lowGM = 6 means fLSO).
00296    *  */
00297   if (coarseIn.gridSpacing != S2BCV)
00298     {
00299       LALInspiralBCVBankFcutS3S4( status->statusPtr, 
00300                                 list, nlist, coarseIn);
00301       CHECKSTATUSPTR( status );
00302     }
00303   else  if (coarseIn.LowGM  == -1)
00304   {
00305           LALInspiralBCVRegularFcutBank( status->statusPtr, 
00306               list, nlist, coarseIn);
00307           CHECKSTATUSPTR( status );
00308   }
00309   else
00310   {
00311           LALInspiralBCVFcutBank( status->statusPtr, 
00312               list, nlist, coarseIn);
00313           CHECKSTATUSPTR( status );
00314   }
00315 
00316   if ( lalDebugLevel & LALINFO ) 
00317   {
00318     LALPrintError( 
00319         "LALInspiralBCVBank: template numbers before %d and after %d calling LALInspiralBCVBank\n", 
00320         nlistOld, *nlist );
00321   }
00322 
00323   LALSDestroyVectorSequence( status->statusPtr, &tempList );
00324   CHECKSTATUSPTR( status );
00325 
00326   DETATCHSTATUSPTR( status );
00327   RETURN( status );
00328 }
00329 
00330 /* <lalVerbatim file="LALInspiralCreateFlatBankCP"> */
00331 void 
00332 LALInspiralCreateFlatBank (
00333     LALStatus            *status, 
00334     REAL4VectorSequence  *list, 
00335     InspiralBankParams   *bankParams
00336     )
00337 /* </lalVerbatim> */
00338 {  
00339   InspiralMetric *metric; 
00340   REAL8 minimalMatch; 
00341   REAL8 x0, x1;
00342   UINT4 nlist = 0;
00343 
00344   INITSTATUS( status, "LALInspiralCreateFlatBank", 
00345       LALINSPIRALBCVBANKC );
00346   ATTATCHSTATUSPTR( status );
00347 
00348   /* From the knowledge of the metric and the minimal match find the */
00349   /* constant increments bankParams->dx0 and bankParmams->dx1        */
00350   metric = bankParams->metric;
00351   minimalMatch = bankParams->minimalMatch;
00352   LALInspiralUpdateParams( status->statusPtr, 
00353       bankParams, *metric, minimalMatch );
00354   CHECKSTATUSPTR( status );
00355 
00356   /* Construct the template bank */
00357   for (x1 = bankParams->x1Min; x1 <= bankParams->x1Max; x1 += bankParams->dx1)
00358   {
00359     for (x0 = bankParams->x0Min; x0 <= bankParams->x0Max; x0 += bankParams->dx0)
00360     {
00361       UINT4 ndx = 2 * nlist;
00362       list->data = (REAL4 *) LALRealloc( list->data, (ndx+2) * sizeof(REAL4) );
00363       if ( !list->data )
00364       {
00365         ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00366       }
00367       list->data[ndx] = x0;
00368       list->data[ndx + 1] = x1;
00369       ++nlist; 
00370     }
00371   }
00372 
00373   list->length = nlist;
00374 
00375   DETATCHSTATUSPTR(status);
00376   RETURN (status);
00377 }
00378 
00379 
00380 /*  <lalVerbatim file="LALInspiralBCVFcutBankCP"> */
00381 void 
00382 LALInspiralBCVFcutBank (
00383     LALStatus            *status, 
00384     InspiralTemplateList **list, 
00385     INT4                *NList, 
00386     InspiralCoarseBankIn coarseIn
00387     ) 
00388 /*  </lalVerbatim>  */
00389 {  
00390   UINT4 nf;     /* number of layers */
00391   UINT4 nlist;  /* number of final templates */
00392   UINT4 j;
00393   UINT4 ndx;    /* temporary number of templates */
00394   REAL8 frac;   /* general variable*/
00395   REAL8 fendBCV;
00396   REAL4 LowGM;
00397   REAL4 HighGM;
00398 
00399   INITSTATUS( status, "LALInspiralBCVFcutBank", LALINSPIRALBCVBANKC );
00400 
00401   nf            = coarseIn.numFcutTemplates;
00402   ndx           = nlist = *NList;
00403 
00404   LowGM         = coarseIn.LowGM;
00405   HighGM        = coarseIn.HighGM;
00406 
00407   /* if we have only one layer, we don't need HighGM. 
00408    * And default value for LowGM is  3GM*/
00409   if ( nf == 1 )
00410   {
00411     frac = 1;
00412   }
00413   else
00414   {
00415     frac = (1.L - 1.L/pow(HighGM/3., 1.5L)) / (nf-1.L);
00416   }
00417   
00418   /* for each psi0/psi3 pair, we generate the fcut layers */
00419   for ( j = 0; j < nlist; ++j )
00420   {
00421     UINT4 valid = 0;
00422     /* let us get the estimated params.fFinal*/    
00423     LALPSItoMasses(status,  &((*list)[j].params), &valid , LowGM);
00424     
00425     if ( valid )
00426     {
00427       UINT4 i;
00428       REAL8 fMax; 
00429 
00430       fMax = (*list)[j].params.fFinal;
00431       /* for each fcut layer */
00432       for ( i = 0; i < nf; ++i )
00433       {
00434                 fendBCV = fMax * (1.L - (REAL8) i * frac);
00435 
00436         if ( (*list)[j].params.tSampling <= 0 )
00437         {
00438           ABORT( status, LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00439         }
00440         /* the fFinal must be > flower and less than Nyquist. 
00441          * if not, no template is generated. */
00442         if ( fendBCV > (*list)[j].params.fLower && 
00443             fendBCV < (*list)[j].params.tSampling / 2.0 )
00444         {
00445           ++ndx;
00446 
00447                   *list = (InspiralTemplateList *) 
00448           LALRealloc( *list, ndx * sizeof(InspiralTemplateList) );
00449           if ( ! *list )
00450           {
00451             ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00452           }
00453           memset( *list + ndx - 1, 0, sizeof(InspiralTemplate) );
00454           (*list)[ndx-1]                                = (*list)[j];
00455           (*list)[ndx-1].params.fFinal  = fendBCV;
00456           (*list)[ndx-1].metric                 = (*list)[0].metric;
00457           (*list)[ndx-1].nLayer                 = i;
00458         }
00459       }
00460     }
00461   }
00462   /**/
00463   for ( j = nlist; j < ndx; ++j )
00464   {
00465     (*list)[j-nlist] = (*list)[j];
00466   }
00467   /**/
00468   *NList = ndx - nlist;
00469   *list = LALRealloc( *list, *NList * sizeof(InspiralTemplateList) );
00470   if ( ! *list )
00471   {
00472     ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00473   }
00474 
00475   RETURN( status );
00476 }
00477 
00478 
00479 void
00480 LALPSItoMasses (
00481     LALStatus                   *status, 
00482     InspiralTemplate    *params,
00483     UINT4               *valid,
00484     REAL4               HighGM
00485     )
00486 {
00487 
00488   INITSTATUS( status, "LALPSItoMasses", 
00489       LALINSPIRALBCVBANKC );
00490   ATTATCHSTATUSPTR( status );
00491   
00492   if ( params->psi0 <= 0.L || params->psi3 >= 0.L )
00493   {
00494     *valid = 0;
00495   }
00496   else
00497   {
00498     REAL8 totalMass; 
00499     REAL8 eta; 
00500     REAL8 eightBy3      = 8.L/3.L;
00501     REAL8 twoBy3        = 2.L/3.L;
00502     REAL8 fiveBy3       = 5.L/3.L;
00503         /*we estimate the total mass and then fFinal*/
00504     params->totalMass = -params->psi3/(16.L*LAL_PI * LAL_PI * params->psi0);
00505     eta = params->eta = 
00506       3.L/(128.L * params->psi0 * pow(LAL_PI*params->totalMass, fiveBy3));
00507     totalMass = params->totalMass;
00508     params->fFinal = 1.L/( LAL_PI * pow(HighGM, 1.5L) * params->totalMass );
00509     params->totalMass /= LAL_MTSUN_SI;
00510     *valid = 1;
00511 
00512 #if 0
00513     if (params->eta > 0.25L) 
00514     {
00515       *valid = 0;
00516     }
00517     else
00518     {
00519       LALInspiralParameterCalc( status->statusPtr, params );
00520       CHECKSTATUSPTR( status );
00521       *valid = 1;
00522     }
00523 #endif
00524 
00525     params->t0 = 5.0 / ( 256.0*eta*pow(totalMass, fiveby3) * 
00526         pow(LAL_PI * params->fLower, eightBy3));
00527     params->t3 = LAL_PI/(8.0*eta*pow(totalMass, twoBy3) * 
00528         pow(LAL_PI * params->fLower, fiveBy3));
00529   }
00530   DETATCHSTATUSPTR(status);
00531   RETURN (status);
00532 }
00533 
00534 
00535 
00536 
00537 
00538 
00539 /*  <lalVerbatim file="LALInspiralBCVFcutBankCP"> */
00540 void 
00541 LALInspiralBCVBankFcutS3S4 (
00542     LALStatus                   *status, 
00543     InspiralTemplateList        **list, 
00544     INT4                                        *NList, 
00545     InspiralCoarseBankIn        coarseIn
00546     ) 
00547 /*  </lalVerbatim>  */
00548 {  
00549   UINT4 nf;     /* number of layers */
00550   UINT4 nlist;  /* number of final templates */
00551   UINT4 j;
00552   UINT4 ndx;    /* temporary number of templates */
00553   REAL8 frac;   /* general variable*/
00554   REAL8 fendBCV;
00555   REAL4 LowGM;
00556   REAL4 HighGM;
00557   
00558   INITSTATUS( status, "LALInspiralBCVBankFcutS3S4", LALINSPIRALBCVBANKC );
00559 
00560   nf            = coarseIn.numFcutTemplates;
00561   ndx           = nlist = *NList;
00562   LowGM         =  3.;
00563   HighGM    = coarseIn.HighGM;
00564 
00565   /* for each template, we get the fcut layers*/
00566   for ( j = 0; j < nlist; ++j )
00567   {
00568     UINT4 valid = 0;
00569     LALEmpiricalPSItoMassesConversion(status, 
00570         &((*list)[j].params), &valid , LowGM);   
00571     
00572     if (valid)
00573     {
00574           UINT4 i;
00575           REAL8 fMax; 
00576 
00577           fMax = (*list)[j].params.fFinal; 
00578           if ( (*list)[j].params.tSampling <= 0 )
00579           {
00580             ABORT( status, LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00581           }
00582         /* the user might request only one layer */     
00583           if (nf == 1)
00584           {
00585                   frac = 1;
00586           }
00587           else 
00588           {
00589             frac = (1.L - 1.L/pow(HighGM/3., 1.5L)) / (nf-1.L);
00590           }
00591          
00592       /* sometimes since fMin is greater than the nyquist frequency, there
00593        * is no template generated. This is not acceptable. We need at least
00594        * one frequency at the nyquist frequency otherwise low masses
00595        * systems are missed. */
00596       if (((fMax * (1.L - (REAL4) (nf-1) * frac)) >= (*list)[j].params.tSampling/2.0)) 
00597       {
00598         fMax = (*list)[j].params.tSampling/2.0 - 1. ;
00599         frac = -1;
00600       }
00601          
00602       /*Similarly, for high masses. */
00603       /*if (((fMax * (1.L - (REAL4) (nf-1) * frac)) <= (*list)[j].params.fLower * 1.5)) 
00604        {
00605           fMax = (*list)[j].params.fLower * 1.5 ;           
00606         }
00607         */
00608       for (i=0; i<nf; i++)
00609       {
00610         fendBCV = fMax * (1.L - (REAL4) i * frac);
00611             /* we search for valid expression of fendBCV and populate the bank */
00612             if ( fendBCV >= (*list)[j].params.fLower * 1.5 && 
00613                   fendBCV < (*list)[j].params.tSampling / 2.0 )
00614             {           
00615                   ++ndx;
00616                   *list = (InspiralTemplateList *) 
00617                   LALRealloc( *list, ndx * sizeof(InspiralTemplateList) );
00618                   if ( ! *list )
00619                   {
00620                     ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00621                   }
00622                   memset( *list + ndx - 1, 0, sizeof(InspiralTemplate) );
00623                   (*list)[ndx-1] = (*list)[j];
00624                   (*list)[ndx-1].params.fFinal = fendBCV;
00625                   (*list)[ndx-1].metric = (*list)[0].metric;
00626                   (*list)[ndx-1].nLayer = i;
00627                 }
00628           }
00629         }
00630   }
00631   for ( j = nlist; j < ndx; ++j )
00632   {
00633     (*list)[j-nlist] = (*list)[j];
00634   }
00635   *NList = ndx - nlist;
00636   *list = LALRealloc( *list, *NList * sizeof(InspiralTemplateList) );
00637   if ( ! *list )
00638   {
00639     ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00640   }
00641 
00642 
00643   RETURN( status );
00644 }
00645 
00646 
00647 
00648 /*  <lalVerbatim file="LALInspiralBCVRegularFcutBankCP"> */
00649 void 
00650 LALInspiralBCVRegularFcutBank (
00651     LALStatus                   *status, 
00652     InspiralTemplateList        **list, 
00653     INT4                        *NList, 
00654     InspiralCoarseBankIn        coarseIn
00655     ) 
00656 /*  </lalVerbatim>  */
00657 {  
00658   /* no restriction of  physical masses. 
00659    * And regular layer of templates in the Frequency dimension */
00660   UINT4 i,nf, nlist, j, ndx;
00661   REAL8 fendBCV;
00662 
00663   INITSTATUS( status, "LALInspiralBCVFcutBank", LALINSPIRALBCVBANKC );
00664 
00665   nf = coarseIn.numFcutTemplates;
00666   ndx = nlist = *NList;
00667   
00668   for ( j = 0; j < nlist; ++j )
00669   {     
00670     for ( i = 1; i <=nf; ++i )
00671     {
00672           fendBCV = (*list)[j].params.fLower 
00673                 + i * ((*list)[j].params.tSampling/2.0 - (*list)[j].params.fLower) / nf ;
00674       ++ndx;
00675 
00676           *list = (InspiralTemplateList *) 
00677       LALRealloc( *list, ndx * sizeof(InspiralTemplateList) );
00678       if ( ! *list )
00679       {
00680         ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00681       }
00682       memset( *list + ndx - 1, 0, sizeof(InspiralTemplate) );
00683       (*list)[ndx-1] = (*list)[j];
00684       (*list)[ndx-1].params.fFinal = fendBCV;
00685       (*list)[ndx-1].metric = (*list)[0].metric;
00686       (*list)[ndx-1].nLayer = i;
00687     }
00688   }
00689     
00690   
00691   for ( j = nlist; j < ndx; ++j )
00692   {
00693     (*list)[j-nlist] = (*list)[j];
00694   }
00695 
00696  *NList = ndx - nlist;
00697   *list = LALRealloc( *list, *NList * sizeof(InspiralTemplateList) );
00698   if ( ! *list )
00699   {
00700     ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00701   }
00702 
00703   RETURN( status );
00704 }
00705 
00706 
00707 
00708 
00709 
00710 
00711 
00712 void
00713 LALEmpiricalPSItoMassesConversion (
00714     LALStatus                   *status,
00715     InspiralTemplate    *params,
00716     UINT4               *valid,
00717     REAL4               lightring
00718     )
00719 {
00720 
00721   INITSTATUS( status, "LALEmpiricalPSItoMassesConversion", 
00722       LALINSPIRALBCVBANKC );
00723   ATTATCHSTATUSPTR( status );
00724   
00725   if ( params->psi0 <= 0.L || params->psi3 >= 0.L )
00726   {
00727     *valid = 0;
00728   }
00729   else
00730   {
00731     params->totalMass = -params->psi3/(16.L*LAL_PI * LAL_PI * params->psi0);
00732     params->totalMass = params->totalMass * 2.  ; /* The factor 2 is purely empiricail and 
00733                                                       comes from simulaitons. ?It seems indeed
00734                                                       tyhat the relation between psi0 and psi3 
00735                                                       which gives the total mass is not really
00736                                                       suitable. Ususally, the total mass is 
00737                                                       twice as much as the estimated one.
00738                                                    */
00739     params->fFinal = 1.L/( LAL_PI * pow(lightring, 1.5L) * params->totalMass );
00740     params->totalMass /= LAL_MTSUN_SI; /* it it used later ? */
00741 
00742     *valid = 1;
00743   }
00744   
00745   DETATCHSTATUSPTR(status);
00746   RETURN (status);
00747 }
00748 
00749 
00750 
00751 /* <lalVerbatim file="LALInspiralCreateFlatBankS3S4CP"> */
00752 void 
00753 LALInspiralCreateFlatBankS3S4 (
00754     LALStatus            *status, 
00755     REAL4VectorSequence  *list, 
00756     InspiralBankParams   *bankParams,
00757     InspiralCoarseBankIn coarseIn
00758     )
00759 /* </lalVerbatim> */
00760 {  
00761   InspiralMetric *metric; 
00762   REAL8 minimalMatch; 
00763   REAL8 x0, x1, dx1=0, dx0=0, x=0, y=0;
00764   UINT4 nlist = 0;
00765   INT4 layer  = 1;
00766   INT4 valid = -1;
00767   REAL4 xp[8] = {3000, 40000, 100000, 300000, 550000, 550000, 250000,3000};
00768   REAL4 yp[8] = {0, -3000, -3000, -2000, -1500, -300, -300, 0};
00769   INT4 npol = 8;
00770 
00771   
00772   INITSTATUS( status, "LALInspiralCreateFlatBankS3S4", 
00773       LALINSPIRALBCVBANKC );
00774   ATTATCHSTATUSPTR( status );
00775 
00776   
00777   /* From the knowledge of the metric and the minimal match 
00778      find the constant increments bankParams->dx0 and 
00779      bankParmams->dx1        */
00780   metric = bankParams->metric;
00781   minimalMatch = bankParams->minimalMatch;
00782 
00783   switch (coarseIn.gridSpacing){
00784     case HybridHexagonal:
00785     case S2BCV:
00786     case Hexagonal:
00787       dx0 = sqrt(2.L * (1.L - minimalMatch)/metric->g00 );
00788       dx1 = sqrt(2.L * (1.L - minimalMatch)/metric->g11 );
00789       dx0 *=3./2./sqrt(2.);
00790       dx1 *=sqrt(3./2.);
00791       break;
00792     case Square:
00793       dx0 = sqrt(2.L * (1.L - minimalMatch)/metric->g00 );
00794       dx1 = sqrt(2.L * (1.L - minimalMatch)/metric->g11 );
00795       break;
00796     case  HexagonalNotOriented:
00797       LALInspiralUpdateParams( status->statusPtr, 
00798                              bankParams, *metric, minimalMatch );
00799       CHECKSTATUSPTR( status );
00800       dx0 = bankParams->dx0 * 3./2./sqrt(2.);
00801       dx1 = bankParams->dx1 * sqrt(3./2.);
00802       break;
00803 
00804     case  SquareNotOriented:
00805       LALInspiralUpdateParams( status->statusPtr, 
00806                              bankParams, *metric, minimalMatch );
00807       CHECKSTATUSPTR( status );
00808       dx0 = bankParams->dx0;
00809       dx1 = bankParams->dx1;
00810       break;
00811   }
00812 
00813   
00814   switch (coarseIn.gridSpacing)
00815   {
00816     case HybridHexagonal:
00817     case S2BCV:
00818     case Hexagonal:
00819     case HexagonalNotOriented:
00820     
00821     /* x1==psi3 and x0==psi0 */
00822     for (x1 = bankParams->x1Min -1e6;  x1 <= bankParams->x1Max + 1e6; x1 += dx1)
00823       {
00824         layer++;
00825         for (x0 = bankParams->x0Min - 1e6 +dx0/2.*(layer%2); x0 <= bankParams->x0Max+1e6; x0 += dx0 )
00826         {
00827           UINT4 ndx = 2 * nlist;
00828           if ( coarseIn.gridSpacing == Hexagonal) 
00829           {
00830             x =  x0 *cos(metric->theta) + sin(metric->theta)* x1;
00831                 y =  x0 *sin(metric->theta) - cos(metric->theta)* x1;
00832           }
00833           else
00834           {
00835                 x = x0;
00836                 y = x1;
00837           }
00838             
00839           if ( (x > bankParams->x0Min -dx0/2.) && (y < bankParams->x1Max + dx1/2.) && 
00840                  (x < bankParams->x0Max +dx0/2.) && (y > bankParams->x1Min - dx1/2.))
00841           {
00842 
00843                 if (coarseIn.insidePolygon == True)
00844                 {
00845           LALInsidePolygon(status->statusPtr, xp, yp, npol, x, y, &valid);
00846                 }
00847         else
00848                 {
00849                   LALExcludeTemplate(status->statusPtr, &valid, bankParams, x, y);
00850                 }
00851                 
00852 
00853         if (valid == 1)
00854         {
00855           list->data = (REAL4 *) LALRealloc( list->data, (ndx+2) * sizeof(REAL4) );
00856           if ( !list->data )
00857           {
00858             ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00859           }
00860           list->data[ndx] = x;
00861           list->data[ndx + 1] = y;
00862           ++nlist;                 
00863         } 
00864       } 
00865         }      
00866   }
00867   break;
00868   
00869   case  Square:
00870   case  SquareNotOriented:
00871 
00872     /* !! dx1 and dx0 are computed in a different way de[pending on the 
00873        value of BANKGRId */
00874     for (x1 = bankParams->x1Min -1e6;  x1 <= bankParams->x1Max + 1e6; x1 += dx1)
00875     {
00876           for (x0 = bankParams->x0Min - 1e6 ; x0 <= bankParams->x0Max+1e6; x0 += dx0 )
00877           {
00878             UINT4 ndx = 2 * nlist; 
00879 
00880             if (coarseIn.gridSpacing == Square)
00881             {
00882                   x =  x0 *cos(metric->theta) + sin(metric->theta)* x1 ;
00883                   y =  x0 *sin(metric->theta) - cos(metric->theta)* x1;
00884             }
00885             else if (coarseIn.gridSpacing == SquareNotOriented)
00886             {
00887                   x = x0;
00888                   y = x1;
00889             }
00890             if ( (x > bankParams->x0Min - dx0/2.) && (y < bankParams->x1Max + dx1/2.) && 
00891                  (x < bankParams->x0Max + dx0/2.) && (y > bankParams->x1Min - dx1/2.))
00892             
00893             {
00894 
00895                   if (coarseIn.insidePolygon == True) 
00896                     {
00897                       LALInsidePolygon(status->statusPtr, xp, yp, npol, x, y, &valid);
00898             }
00899                   else
00900                   {
00901                     LALExcludeTemplate(status->statusPtr, &valid, bankParams, x, y);
00902                   }
00903           if (valid)
00904           {
00905             list->data = (REAL4 *) LALRealloc( list->data, (ndx+2) * sizeof(REAL4) );
00906             if ( !list->data )
00907             {
00908               ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00909                     }
00910             list->data[ndx] = x;
00911             list->data[ndx + 1] = y;
00912             ++nlist; 
00913           }
00914             }
00915           }
00916      }
00917   break;
00918   }
00919   
00920   list->length = nlist;
00921 
00922   DETATCHSTATUSPTR(status);
00923   RETURN (status);
00924 }
00925 
00926 
00927 /* Thomas: 31 Aug 2006. This function is redundant with the polygon fit. 
00928 It was design for BBH and therefore had tight boundary. For a more general 
00929 purpose, I extended the range to generous values
00930  */
00931 void
00932 LALExcludeTemplate(
00933     LALStatus            *status, 
00934     INT4                 *valid, 
00935     InspiralBankParams   *bankParams,
00936     REAL4                 x,
00937     REAL4                 y)
00938 {
00939   REAL4 psi0Int = 2500000.;
00940   REAL4 psi3Int = -10000.;
00941 
00942   INITSTATUS( status, "LALExcludeTemplate", 
00943       LALINSPIRALBCVBANKC );
00944   ATTATCHSTATUSPTR( status );
00945  
00946   if (x > psi0Int && y < psi3Int )
00947   {
00948     *valid = 0 ;
00949   }
00950   else 
00951   {
00952     *valid = 1;
00953   }
00954 
00955   DETATCHSTATUSPTR(status);
00956   RETURN (status);
00957 }
00958 
00959 
00960 

Generated on Fri Sep 5 03:07:05 2008 for LAL by  doxygen 1.5.2