Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALInspiral 5.0.3.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALInspiralHexagonalBank.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Thomas Cokelaer
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20/**
21 * \author Cokelaer Thomas
22 * \file
23 * \brief NONE
24 *
25 * ### Description ###
26 *
27 *
28 * ### Algorithm ###
29 *
30 *
31 * ### Uses ###
32 *
33 * \code
34 * LALInspiralParameterCalc()
35 * LALInspiralComputeMetric()
36 * \endcode
37 *
38 * ### Notes ###
39 *
40 */
41
42#include <stdio.h>
43#include <lal/LALInspiralBank.h>
44#include <lal/AVFactories.h>
45#include <lal/SeqFactories.h>
46#include <lal/LALStdio.h>
47#include <lal/FindRoot.h>
48
49#ifdef __GNUC__
50#define UNUSED __attribute__ ((unused))
51#else
52#define UNUSED
53#endif
54
55/* Thomas:: definition for hexagonal grid. */
56
57void
61 INT4 *nlist,
63 )
64{
65 INT4 i;
66 INT4 firstId = 0;
67 REAL4 piFl;
68 REAL4 A0, A3;
69 InspiralBankParams bankPars;
70 InspiralTemplate *tempPars;
71 InspiralMomentsEtc moments;
72 InspiralCell *cells=NULL;
73 HexaGridParam gridParam;
74 CellEvolution cellEvolution;
75 CellList *cellList = NULL;
76
79
80 ASSERT( coarseIn.mMin > 0., status,
81 LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
82 ASSERT( coarseIn.mMax > 0., status,
83 LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
84 ASSERT( coarseIn.MMax >= 2.*coarseIn.mMin, status,
85 LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
86
87 /* Set the elements of the metric and tempPars structures in */
88 /* conformity with the coarseIn structure */
89 if ( !(tempPars = (InspiralTemplate *)
90 LALCalloc( 1, sizeof(InspiralTemplate))))
91 {
92 LALFree(tempPars);
93 LALFree(cells);
94 ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
95 }
96
97
98 LALInspiralSetParams( status->statusPtr, tempPars, coarseIn );
100
101 /* Identify the boundary of search and parameters for the */
102 /* first lattice point */
103 LALInspiralSetSearchLimits( status->statusPtr, &bankPars, coarseIn );
105
106 tempPars->totalMass = coarseIn.MMax;
107 tempPars->eta = 0.25;
108 tempPars->ieta = 1.L;
109 tempPars->fLower = coarseIn.fLower;
110 tempPars->massChoice = m1Andm2;
111 tempPars->mass1 = coarseIn.mMin;
112 tempPars->mass2 = coarseIn.mMax;
113
114 LALInspiralParameterCalc( status->statusPtr, tempPars );
116
117 /* Get the moments of the PSD integrand and other parameters */
118 /* required in the computation of the metric once for all. */
120 status->statusPtr,
121 &moments,
122 &coarseIn.shf,
123 tempPars );
125
126 /* Allocate memory for one cell */
127 cells = (InspiralCell*)
128 LALCalloc(1, sizeof(InspiralCell) );
129
130 /*define gridParam*/
131 gridParam.mm = coarseIn.mmCoarse;
132 gridParam.x0Min = bankPars.x0Min;
133 gridParam.x0Max = bankPars.x0Max;
134 gridParam.x1Min = bankPars.x1Min;
135 gridParam.x1Max = bankPars.x1Max;
136 gridParam.mMin = coarseIn.mMin;
137 gridParam.mMax = coarseIn.mMax;
138 gridParam.MMin = coarseIn.MMin;
139 gridParam.MMax = coarseIn.MMax;
140 gridParam.etaMin = coarseIn.etamin;
141 gridParam.space = coarseIn.space;
142 gridParam.massRange = coarseIn.massRange;
143 gridParam.gridSpacing = coarseIn.gridSpacing;
144
145
146 cellEvolution.nTemplate = 1;
147 cellEvolution.nTemplateMax = 1;
148 cellEvolution.fertile = 0;
149
150 /* initialise that first cell */
151 tempPars->massChoice = t03;
152 cells[0].t0 = tempPars->t0;
153 cells[0].t3 = tempPars->t3;
154
155 /* some aliases */
156 piFl = LAL_PI * tempPars->fLower;
157 A0 = 5. / pow(piFl, 8./3.) / 256.;
158 A3 = LAL_PI / pow(piFl, 5./3.)/8.;
159
160
161 /* Initialise the first template */
163 status->statusPtr,
164 &cells, firstId,
165 &moments, tempPars,
166 &gridParam, &cellEvolution,
167 &cellList);
169
170 {
171 INT4 k, kk; /*some indexes*/
172 INT4 *new_list = NULL;
173 CellList *ptr = NULL;
174 INT4 length = 1; /* default size of the bank when we
175 start the bank generation. */
176
177 /* we re-allocate an array which size equals the
178 * template bank size. */
179 if (! (new_list = LALMalloc(length*sizeof(INT4))))
180 {
181 ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
182 }
183
184 /* while there are cells/template which can propagate, we carry on the loop.*/
185 while (cellEvolution.fertile)
186 {
187 length = LALListLength(cellList);
188 /*realloc some memory for the next template*/
189 if (! (new_list = LALRealloc(new_list, length*sizeof(INT4))))
190 {
191 ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
192 /* freeing memory here ? */
193 }
194 ptr = cellList;
195 /* we extract the ids which might change within the LALPopulateCell
196 * function. Indeed the bank might grow and then we will lost track
197 * of ids/bank size and so on. */
198 for ( k = 0; k < length; k++)
199 {
200 new_list[k] = ptr->id;
201 ptr = ptr->next;
202 }
203 /* look at all the template/ids in the current bank to search for fertile cells */
204 for (kk = 0; kk < length; kk++)
205 {
206 k = new_list[kk];
207 if ( cells[k].status == Fertile)
208 {
209 LALPopulateCell(status->statusPtr, &moments, &cells,
210 k, tempPars, &gridParam, &cellEvolution, &cellList);
212 /* now the bank might have grown, but we only look at the
213 * template created before this for loop, when we entered
214 * in the while loop
215 * */
216 }
217 }
218 }
219 LALFree(new_list);
220 }
221
222 if (cellList != NULL)
223 ABORT(status, LALINSPIRALBANKH_EHEXAINIT,LALINSPIRALBANKH_MSGEHEXAINIT);
224 /* Here is the current number of template generated. Now, we need
225 * to clean some of them which might be redundant.
226 * */
227 *nlist = cellEvolution.nTemplate;
228
229 {
230 INT4 k ;
231 INT4 length;
232 length = cellEvolution.nTemplate;
233
234 for ( k = 0; k < length; k++)
235 {
236 REAL4 a;
237 REAL4 b;
238 REAL4 x0;
239 REAL4 tempA3;
240 SFindRootIn input;
241 INT4 valid;
242
243 PRIN prin;
244
245 tempA3 = pow(A3, -5./2.)/pow(0.25,-1.5);
246 tempPars->t0 = cells[k].t0;
247 tempPars->t3 = cells[k].t3;
248
249 /* if non physical parameter i.e below eta=0.25*/
250 if(cells[k].RectPosition[0] == Below )
251 {
252 INT4 above=0;
253
254 /*first, we define the line which is along the long semi-axis of the
255 * ambiguity function, defined by the angle theta and the position of
256 * the template.
257 * */
258 a = tan(cells[k].metric.theta);
259 b = cells[k].t3 - a * cells[k].t0;
260 /* and call a function to search for a solution along eta=1/4 */
261 input.function = LALSPAF;
262 input.xmin = cells[k].t3-1e-3;
263 input.xmax = 1000;
264 input.xacc = 1e-6;
265
266 prin.ct = a * A0 * tempA3;
267 prin.b = b;
268
269 LALSBisectionFindRoot(status->statusPtr,
270 &x0, &input, (void *)&prin);
272
273 tempPars->t3 = x0 + 1e-3; /* to be sure it is physical */
274 tempPars->t0 = (tempPars->t3 - b)/a;
275 if (tempPars->t0 > 0)
276 {
277 LALInspiralParameterCalc(status->statusPtr, tempPars);
279 }
280 cells[k].t0 = tempPars->t0;
281 cells[k].t3 = tempPars->t3;
282
283 /* update its position values */
284 valid = 1;
285 GetPositionRectangle(status->statusPtr, &cells, k, tempPars ,
286 &gridParam,
287 &cellEvolution,
288 &cellList,
289 &valid);
290
291 {
292 switch (cells[k].RectPosition[1]){
293 case Above: above +=1; break;
294 case Below:
295 case In:
296 case Out:
297 case Edge: break;
298 }
299 switch (cells[k].RectPosition[2]){
300 case Above: above +=1; break;
301 case In:
302 case Below:
303 case Out:
304 case Edge: break;
305 }
306 switch (cells[k].RectPosition[3]){
307 case Above: above +=1; break;
308 case In:
309 case Below:
310 case Out:
311 case Edge: break;
312 }
313 switch (cells[k].RectPosition[4]){
314 case Above: above +=1; break;
315 case In:
316 case Below:
317 case Out:
318 case Edge: break;
319 }
320 }
321
322 if (above == 2 && cells[k].position == In)
323 {
324 cells[cells[k].child[0]].position = Out;
325 }
326 }
327 }
328 }
329
330 for (i=0; i<cellEvolution.nTemplate; i++) {
331 if (cells[i].position == In ) {
332 *nlist = *nlist +1;
333 }
334 }
335;
336
337
338 /* allocate appropriate memory and fill the output bank */
339 *list = (InspiralTemplateList*)
340 LALRealloc( *list, sizeof(InspiralTemplateList) * (*nlist+1) );
341 if ( ! *list )
342 {
343 LALFree( tempPars );
344 ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
345 }
346 memset( *list + *nlist, 0, sizeof(InspiralTemplateList) );
347 {
348 *nlist = 0 ;
349 for (i=0; i<cellEvolution.nTemplate; i++)
350 {
351 if (cells[i].position == In)
352 {
353 tempPars->t0 = cells[i].t0;
354 tempPars->t3 = cells[i].t3;
355 tempPars->massChoice = t03;
356 tempPars->fLower = coarseIn.fLower;
357
358 LALInspiralParameterCalc( status->statusPtr, tempPars );
360
361 (*list)[*nlist].ID = *nlist;
362 (*list)[*nlist].params = *tempPars;
363 (*list)[*nlist].metric = cells[i].metric;
364 ++(*nlist);
365 }
366 }
367 }
368
369 LALFree( cells );
370 LALFree( tempPars );
371
373 RETURN ( status );
374}
375
376
377
378
379
380void
383 InspiralMomentsEtc *moments,
384 InspiralCell **cell,
385 INT4 headId,
386 InspiralTemplate *paramsIn,
387 HexaGridParam *gridParam,
388 CellEvolution *cellEvolution,
389 CellList **cellList
390 )
391{
392 REAL4 dx0, dx1;
393 REAL4 newt0, newt3;
394 INT4 i, id1, id2;
395 REAL4 theta, ctheta, stheta;
396 INT4 offSpring;
397 INT4 it;
398 INT4 add = 0;
399
402
403 /* aliases to get the characteristics of the parent template,
404 * that we refer to its ID (headId) */
405 dx0 = (*cell)[headId].dx0;
406 dx1 = (*cell)[headId].dx1;
407 theta = (*cell)[headId].metric.theta;
408 ctheta = cos(theta);
409 stheta = sin(theta);
410 offSpring = cellEvolution->nTemplate;
411
412 /* Around the parent, the offspring can be at most 6 (hexagonal grid).
413 * By default the child are unset. If so it is created and have the
414 * properties of its parents. However, a child migh have been created
415 * earlier. In that case, we do not do anything. */
416 it = 0 ;
417
418 for (i = 0; i < 6; i++)
419 {
420 if ((*cell)[headId].child[i] == -1)
421 {
422 add++;
423 /* reallocate memory by set of 1000 cells if needed*/
424 if ( (offSpring+add)>cellEvolution->nTemplateMax)
425 {
426 *cell = (InspiralCell*)
427 LALRealloc( *cell,
428 sizeof(InspiralCell) * (cellEvolution->nTemplateMax + 1000) );
429 if ( !cell ) {
430 ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
431 }
432 cellEvolution->nTemplateMax += 1000;
433 }
434
435 /* creates the child connection if needed. A child heritates the
436 * properties of its parent */
437 switch ( i ){
438 case 0:
439 newt0 = dx0 ;
440 newt3 = 0 ;
441 (*cell)[offSpring + it].t0 = (*cell)[headId].t0;
442 (*cell)[offSpring + it].t3 = (*cell)[headId].t3;
443 (*cell)[offSpring + it].t0 += newt0 *ctheta + stheta* newt3;
444 (*cell)[offSpring + it].t3 += newt0 *stheta - ctheta* newt3;
445 LALInitHexagonalBank(status->statusPtr, cell, offSpring+it,
446 moments, paramsIn, gridParam, cellEvolution, cellList);
447 break;
448 case 1:
449 newt0 = dx0/2. ;
450 newt3 = -dx1 *sqrt(3./2) ;
451 (*cell)[offSpring + it].t0 = (*cell)[headId].t0;
452 (*cell)[offSpring + it].t3 = (*cell)[headId].t3;
453 (*cell)[offSpring + it].t0 += newt0 * ctheta + stheta * newt3;
454 (*cell)[offSpring + it].t3 += newt0 * stheta - ctheta * newt3;
455 LALInitHexagonalBank(status->statusPtr, cell, offSpring+it,
456 moments, paramsIn, gridParam, cellEvolution, cellList);
457 break;
458 case 2:
459 newt0 = -dx0/2 ;
460 newt3 = -dx1 *sqrt(3./2);
461 (*cell)[offSpring + it].t0 = (*cell)[headId].t0;
462 (*cell)[offSpring + it].t3 = (*cell)[headId].t3;
463 (*cell)[offSpring + it].t0 += newt0 * ctheta + stheta * newt3;
464 (*cell)[offSpring + it].t3 += newt0 * stheta - ctheta * newt3;
465 LALInitHexagonalBank(status->statusPtr, cell, offSpring+it,
466 moments, paramsIn, gridParam, cellEvolution, cellList);
467 break;
468 case 3:
469 newt0 = -dx0 ;
470 newt3 = 0;
471 (*cell)[offSpring + it].t0 = (*cell)[headId].t0;
472 (*cell)[offSpring + it].t3 = (*cell)[headId].t3;
473 (*cell)[offSpring + it].t0 += newt0 * ctheta + stheta * newt3;
474 (*cell)[offSpring + it].t3 += newt0 * stheta - ctheta * newt3;
475 LALInitHexagonalBank(status->statusPtr, cell, offSpring+it,
476 moments, paramsIn, gridParam, cellEvolution, cellList);
477 break;
478 case 4:
479 newt0 = -dx0/2. ;
480 newt3 = dx1 *sqrt(3./2);
481 (*cell)[offSpring + it].t0 = (*cell)[headId].t0;
482 (*cell)[offSpring + it].t3 = (*cell)[headId].t3;
483 (*cell)[offSpring + it].t0 += newt0 * ctheta + stheta * newt3;
484 (*cell)[offSpring + it].t3 += newt0 * stheta - ctheta * newt3;
485 LALInitHexagonalBank(status->statusPtr, cell, offSpring+it,
486 moments, paramsIn, gridParam, cellEvolution, cellList);
487 break;
488 case 5:
489 newt0 = dx0/2. ;
490 newt3 = dx1 *sqrt(3./2);
491 (*cell)[offSpring + it].t0 = (*cell)[headId].t0;
492 (*cell)[offSpring + it].t3 = (*cell)[headId].t3;
493 (*cell)[offSpring + it].t0 += newt0 * ctheta + stheta * newt3;
494 (*cell)[offSpring + it].t3 += newt0 * stheta - ctheta * newt3;
495 LALInitHexagonalBank(status->statusPtr, cell, offSpring+it,
496 moments, paramsIn, gridParam, cellEvolution, cellList);
497 break;
498 }
499
500 /* Now, tricky part, if a child has been creating, he must have a
501 * connection with its parents and vice-versa. */
502 if ((*cell)[offSpring + it].child[(i+3)%6] == -1)
503 {
504 (*cell)[offSpring + it].child[(i+3)%6] = (*cell)[headId].ID;
505 (*cell)[headId].child[i] = offSpring+it;
506 }
507 /* a new cell index */
508 it += 1;
509 }
510 }
511
512 cellEvolution->nTemplate +=it;
513
514
515 /* Here, the parent has its 6 children set; he become sterile. */
516 (*cell)[headId].status = Sterile;
517 (cellEvolution->fertile) = cellEvolution->fertile-1;
518 LALListDelete(cellList, headId);
519
520 /* what shall we do with that parent. Is he valid ? inside the space,
521 * outside since eta > 0.25 but close to the boundary .... */
522 {
523 if ((*cell)[headId].RectPosition[0] == Above && (*cell)[headId].in == 1)
524 {
525 (*cell)[headId].RectPosition[0]=Out;
526 }
527 }
528
529 /* propagate connections to the brothers to avoid redundancies */
530 for (i=0; i<6; i++)
531 {
532 /* for each child*/
533 id1 = (*cell)[headId].child[i%6];
534 id2 = (*cell)[headId].child[(i+1)%6];
535 (*cell)[id1].child[(i+2)%6] = (*cell)[id2].ID;
536 (*cell)[id2].child[(i+4+1)%6] = (*cell)[id1].ID;
537 }
538
539 /* enfin trouver position[0] (In/out)? of the children. */
540 for (i=0; i<6; i++)
541 {/* for each child find position[0]*/
542 id1 = (*cell)[headId].child[i%6];
543
544 if ((*cell)[id1].status == Fertile)
545 {
546 LALSPAValidPosition(status->statusPtr, cell, id1,
547 moments, cellEvolution, cellList);
549
550 if ((*cell)[id1].position != In )
551 {
552 if ((*cell)[id1].status == Fertile)
553 {
554 (*cell)[id1].status= Sterile;
555 cellEvolution->fertile=cellEvolution->fertile-1;
556 LALListDelete(cellList, id1);
557 }
558 }
559 }
560 }
561
563 RETURN ( status );
564}
565
566
567
568void
571 InspiralCell **cell,
572 INT4 id,
573 InspiralMomentsEtc *moments,
574 InspiralTemplate *paramsIn,
575 HexaGridParam *gridParam,
576 CellEvolution *cellEvolution,
577 CellList **cellList)
578{
579 INT4 i;
580 INT4 valid;
581
584
585 /* a new cell is created; by default it can create new children,
586 therefore it is fertile */
587 cellEvolution->fertile = cellEvolution->fertile + 1;;
588 (*cell)[id].status = Fertile;
589 LALListAppend(cellList, id);
590
591
592 /* all of whom are unset and do not have any id set yet*/
593 for (i = 0; i < 6; i++)
594 {
595 (*cell)[id].child[i] = -1;
596 }
597
598 /* filled some values related to the space */
599 (*cell)[id].ID = id;
600 (*cell)[id].position = In;
601 (*cell)[id].metric.space = gridParam->space;
602
603
604 /* before any further computation, check that t0, t3 are positive.*/
605 if ((*cell)[id].t0 > 0 && (*cell)[id].t3 > 0)
606 {
607 /* Get the metric at the position of the cell */
608 paramsIn->t0 = (*cell)[id].t0;
609 paramsIn->t3 = (*cell)[id].t3;
610
612 &((*cell)[id].metric),
613 paramsIn,
614 moments);
616
617 /* let us store the dx0 and dx3 at that point. */
618 (*cell)[id].dx0 = sqrt(2.L * (1.L - gridParam->mm)/(*cell)[id].metric.g00 );
619 (*cell)[id].dx1 = sqrt(2.L * (1.L - gridParam->mm)/(*cell)[id].metric.g11 );
620
621 LALFindPosition(status->statusPtr, (*cell)[id].dx0, (*cell)[id].dx1,
622 &((*cell)[id].RectPosition[0]), paramsIn, gridParam);
624
625 /* if outside, this is a sterile cell which can not propagate */
626 if ((*cell)[id].RectPosition[0] == Out)
627 {
628 (*cell)[id].position = Out;
629 for (i = 0; i < 5; i++)
630 {
631 (*cell)[id].RectPosition[i] = Out;
632 }
633 (*cell)[id].status = Sterile;
634 (cellEvolution->fertile)=cellEvolution->fertile-1;
635 LALListDelete(cellList, id);
636
638 RETURN(status);
639 }
640 else
641 {
642 valid = 1;
643 GetPositionRectangle(status->statusPtr, &(*cell), id, paramsIn ,
644 gridParam, cellEvolution, &(*cellList), &valid);
645 }
646 }
647 else
648 {/* if t0 or t3 < 0 , this is not a valid cell*/
649 valid = 0;
650 }
651
652 /* If this is not a valid template, we remove it from the bank*/
653 if (valid == 0)
654 {
655 for (i=0; i<5; i++)
656 {
657 (*cell)[id].RectPosition[i] = Out;
658 }
659 (*cell)[id].position = Out;
660 (*cell)[id].status = Sterile;
661 (cellEvolution->fertile) =cellEvolution->fertile-1;
662 LALListDelete(cellList, id);
663 }
664
665
666
667
668#if 1
669 if (gridParam->gridSpacing == HybridHexagonal)
670 {
671 INT4 below=0, above=0;
672 for (i=1; i<=4; i++){
673 if ( (*cell)[id].RectPosition[i] == Below) below++;
674 if ( (*cell)[id].RectPosition[i] == Above) above++;
675 }
676 if (below==2 && above == 2){
677 (*cell)[id].position = Edge;
678 (cellEvolution->fertile)=cellEvolution->fertile-1;
679 LALListDelete(cellList, id);
680
681 }
682
683
684 }
685#endif
686
687
688
690 RETURN(status);
691}
692
693
694
695/* Get the position of the rectangle corners which are inscribe within the ambiguity
696 * function. Are they within the parameter space or not ?*/
697void
700 InspiralCell **cell,
701 INT4 id,
703 HexaGridParam *gridParam,
704 CellEvolution UNUSED *cellEvolution,
705 CellList UNUSED **cellList,
706 INT4 *valid)
707{
708 RectangleIn RectIn;
709 RectangleOut RectOut;
710 InspiralTemplate paramsIn;
711
714
715 /* let us investigate this particular template : */
716 RectIn.x0 = params->t0;
717 RectIn.y0 = params->t3;
718 RectIn.dx = (*cell)[id].dx0 ;
719 RectIn.dy = (*cell)[id].dx1 ;
720 RectIn.theta = (*cell)[id].metric.theta;
721
722 /* what is the rectangle ? */
723 LALRectangleVertices(status->statusPtr, &RectOut, &RectIn);
725
726 /* for each corner, let us decide where it lies in the parameter space */
727 paramsIn = *params;
728 paramsIn.t0 = RectOut.x1;
729 paramsIn.t3 = RectOut.y1;
730
731 if (RectOut.x1<0 || RectOut.y1<0
732 || RectOut.x2<0 || RectOut.y2<0
733 || RectOut.x3<0 || RectOut.y3<0
734 || RectOut.x4<0 || RectOut.y4<0)
735 {
736 *valid = 0;
738 RETURN(status);
739 }
740
741 if (RectOut.x1>0 && RectOut.y1>0)
742 {
743 LALFindPosition(status->statusPtr,(*cell)[id].dx0, (*cell)[id].dx1,
744 &((*cell)[id].RectPosition[1]),
745 &paramsIn,
746 gridParam);
748 }
749
750 paramsIn.t0 = RectOut.x2;
751 paramsIn.t3 = RectOut.y2;
752 if (RectOut.x2>0 && RectOut.y2>0){
753 LALFindPosition(status->statusPtr, (*cell)[id].dx0, (*cell)[id].dx1,
754 &((*cell)[id].RectPosition[2]), &paramsIn, gridParam);
756
757 }
758
759 paramsIn.t0 = RectOut.x3;
760 paramsIn.t3 = RectOut.y3;
761 if (RectOut.x3>0 && RectOut.y3>0)
762 {
763 LALFindPosition(status->statusPtr, (*cell)[id].dx0, (*cell)[id].dx1,
764 &((*cell)[id].RectPosition[3]), &paramsIn, gridParam);
766 }
767
768 paramsIn.t0 = RectOut.x4;
769 paramsIn.t3 = RectOut.y4;
770 if (RectOut.x4>0 && RectOut.y4>0)
771 {
772 LALFindPosition(status->statusPtr, (*cell)[id].dx0, (*cell)[id].dx1,
773 &((*cell)[id].RectPosition[4]), &paramsIn, gridParam);
775 }
776
778 RETURN ( status );
779}
780
781
782
783
784
785
786
787
788void
790 InspiralCell **cell,
791 INT4 id1,
792 InspiralMomentsEtc UNUSED *moments,
793 CellEvolution *cellEvolution,
794 CellList **cellList
795 )
796{
797 INT4 below = 0, in = 0, out = 0, above = 0;
798
801
802
803 switch ((*cell)[id1].RectPosition[1]){
804 case In: in +=1; break;
805 case Below: below +=1; break;
806 case Above: above +=1; break;
807 case Out: out +=1; break;
808 case Edge: break;
809 }
810 switch ((*cell)[id1].RectPosition[2]){
811 case In: in +=1; break;
812 case Below: below +=1; break;
813 case Above: above +=1; break;
814 case Out: out +=1; break;
815 case Edge: break;
816 }
817 switch ((*cell)[id1].RectPosition[3]){
818 case In: in +=1; break;
819 case Below: below +=1; break;
820 case Above: above +=1; break;
821 case Out: out +=1; break;
822 case Edge: break;
823 }
824 switch ((*cell)[id1].RectPosition[4]){
825 case In: in +=1; break;
826 case Below: below +=1; break;
827 case Above: above +=1; break;
828 case Out: out +=1; break;
829 case Edge: break;
830 }
831 switch ((*cell)[id1].RectPosition[0]){
832 case In: in +=1; break;
833 case Below: below +=1; break;
834 case Above: above +=1; break;
835 case Out: out +=1; break;
836 case Edge: break;
837 }
838
839 (*cell)[id1].in = in;
840
841 if ((*cell)[id1].RectPosition[0]==In)
842 {
843 (*cell)[id1].position = In;
844 if ((*cell)[id1].status == Sterile)
845 {
846 (*cell)[id1].status = Fertile;
847 (cellEvolution->fertile)=cellEvolution->fertile+1;;
848 LALListAppend(cellList, id1);
849 }
851 RETURN(status);
852 }
853
854 if ( above == 5){
855 (*cell)[id1].position = Out;
856 if ((*cell)[id1].status == Fertile)
857 {
858 (*cell)[id1].status = Sterile;
859 (cellEvolution->fertile)=cellEvolution->fertile-1;
860 LALListDelete(cellList, id1);
861
862 }
863 }
864 else if ( below == 5){
865 (*cell)[id1].position = Out;
866 if ((*cell)[id1].status == Fertile)
867 {
868 (*cell)[id1].status = Sterile;
869 (cellEvolution->fertile)=cellEvolution->fertile-1;
870 LALListDelete(cellList, id1);
871
872 }
873 }
874 else if ( out == 5){
875 (*cell)[id1].position = Out;
876 if ((*cell)[id1].status == Fertile)
877 {
878 (*cell)[id1].status = Sterile;
879 (cellEvolution->fertile)=cellEvolution->fertile-1;
880 LALListDelete(cellList, id1);
881
882 }
883 }
884 else if (in >= 1){
885 (*cell)[id1].position = In;
886 if ((*cell)[id1].status == Sterile)
887 {
888 (*cell)[id1].status = Fertile;
889 (cellEvolution->fertile)=cellEvolution->fertile+1;
890 LALListAppend(cellList, id1);
891 }
892
893 }
894 else if (above+below >= 5){
895 if(out==1){
896 (*cell)[id1].position = Out;
897 if ((*cell)[id1].status == Fertile)
898 {
899 (*cell)[id1].status = Sterile;
900 (cellEvolution->fertile)=cellEvolution->fertile-1;
901 LALListDelete(cellList, id1);
902
903 }
904 }
905 else
906 {
907 (*cell)[id1].position = In;
908 if ((*cell)[id1].status == Sterile)
909 {
910 (*cell)[id1].status = Fertile;
911 (cellEvolution->fertile)=cellEvolution->fertile-1;
912 LALListDelete(cellList, id1);
913
914
915 }
916 }
917 }
918 else{
919 (*cell)[id1].position = Out;
920 if ((*cell)[id1].status == Fertile)
921 {
922 (*cell)[id1].status = Sterile;
923 (cellEvolution->fertile)=cellEvolution->fertile-1;
924 LALListDelete(cellList, id1);
925
926 }
927 }
928
930 RETURN(status);
931}
932
933
934void
936 REAL4 dx0,
937 REAL4 dx1,
938 Position *position,
939 InspiralTemplate *paramsIn,
940 HexaGridParam *gridParam
941)
942{
943 REAL8 mint3;
944 REAL4 eta;
945 REAL4 totalMass, oneby4, tiny, piFl, A0, A3;
946
949
950 oneby4 = 1./4.;
951 tiny = 1.e-10;
952 piFl = LAL_PI * paramsIn->fLower;
953 A0 = 5. / pow(piFl, 8./3.) / 256.;
954 A3 = LAL_PI / pow(piFl, 5./3.)/8.;
955
956 ASSERT(paramsIn->t0 > 0., status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
957 ASSERT(paramsIn->t3 > 0., status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
958
959 /* given t0, t3 we get the totalMass and eta.
960 We do not need to call ParameterCalc again and again here. */
961 totalMass = A0 * paramsIn->t3/(A3 * paramsIn->t0);
962 eta = A0/(paramsIn->t0 * pow(totalMass, (5./3.)));
963
964 /* be sure eta is inside the space if it is suppose to be */
965 if (eta > oneby4) {
966 eta-=tiny;
967 }
968
969 /* let us fill the param strucutre now : eta, Mass, mass1, mass2*/
970 paramsIn->eta = eta;
971 totalMass = paramsIn->totalMass = totalMass/LAL_MTSUN_SI;
972 if (eta <= oneby4) {
973 paramsIn->mass1 = 0.5*totalMass * ( 1.L + sqrt(1.L - 4.L*eta));
974 paramsIn->mass2 = 0.5*totalMass * ( 1.L - sqrt(1.L - 4.L*eta));
975 }
976
977 /* does t3 positive*/
978 if ((paramsIn->t3-dx1)<0)
979 {
980 mint3 = 0;
981 }
982 else
983 {
984 mint3 = paramsIn->t3-dx1;
985 }
986
987 if ( (paramsIn->t0 <gridParam->x0Min - dx0)
988 ||(paramsIn->t0 >gridParam->x0Max + dx0)
989 || (paramsIn->t3 <= mint3))
990 {
991 *position = Out;
993 RETURN(status);
994 }
995
996 switch ( gridParam->massRange )
997 {
999 if (
1000 paramsIn->mass1 >= gridParam->mMin &&
1001 paramsIn->mass2 >= gridParam->mMin &&
1002 paramsIn->mass1 <= gridParam->mMax &&
1003 paramsIn->mass2 <= gridParam->mMax &&
1004 paramsIn->eta <= 0.25 &&
1005 paramsIn->eta >= gridParam->etaMin
1006 )
1007 {
1008 *position = In;
1009 }
1010 else
1011 if (paramsIn->eta > .25){
1012 *position = Below;
1013 }
1014 else{
1015 *position = Above;
1016 }
1017 break;
1018
1020 if (
1021 paramsIn->mass1 >= gridParam->mMin &&
1022 paramsIn->mass2 >= gridParam->mMin &&
1023 paramsIn->totalMass <= gridParam->MMax &&
1024 paramsIn->eta <= 0.25 &&
1025 paramsIn->eta >= gridParam->etaMin
1026 )
1027 {
1028 *position = In;
1029 }
1030 else
1031 if (paramsIn->eta > .25){
1032 *position = Below;
1033 }
1034 else{
1035 *position = Above;
1036 }
1037 break;
1038
1040 if (
1041 paramsIn->mass1 >= gridParam->mMin &&
1042 paramsIn->mass2 >= gridParam->mMin &&
1043 paramsIn->totalMass <= gridParam->MMax &&
1044 paramsIn->totalMass >= gridParam->MMin &&
1045 paramsIn->eta <= 0.25 &&
1046 paramsIn->eta >= gridParam->etaMin
1047 )
1048 {
1049 *position = In;
1050 }
1051 else if (paramsIn->eta > .25 ){
1052 *position = Below;
1053 }
1054 else{
1055 *position = Above;
1056 }
1057
1058 /* Now cut out unnecessary templates */
1059 if ( paramsIn->totalMass < gridParam->MMin )
1060 {
1061 REAL4 totalMass2 = A0 * (paramsIn->t3 - dx1)/(A3 * paramsIn->t0);
1062 totalMass2 = totalMass2 / LAL_MTSUN_SI;
1063 totalMass = A0 * paramsIn->t3/(A3 * (paramsIn->t0 - dx0));
1064 totalMass = totalMass / LAL_MTSUN_SI;
1065
1066 if ( totalMass < gridParam->MMin && totalMass2 < gridParam->MMin )
1067 {
1068 *position = Out;
1069 }
1070 }
1071 break;
1072
1073 default:
1074 ABORT(status, 999, "Invalid choice for enum InspiralBankMassRange");
1075 break;
1076 }
1077
1079 RETURN(status);
1080}
1081
1082
1083/* This function corresponds to the eta=1/4 line? */
1086 REAL4 *result,
1087 REAL4 t3,
1088 void *param)
1089{
1090 REAL4 ct, b;
1091 PRIN *prin;
1092
1095
1096 prin = (PRIN *)param;
1097 ct = prin->ct;
1098 b = prin->b;
1099
1100 *result = ct*pow(t3,5./2.) - t3 + b;
1101
1103 RETURN(status);
1104}
void LALInspiralParameterCalc(LALStatus *status, InspiralTemplate *params)
void LALSPAValidPosition(LALStatus *status, InspiralCell **cell, INT4 id1, InspiralMomentsEtc UNUSED *moments, CellEvolution *cellEvolution, CellList **cellList)
void GetPositionRectangle(LALStatus *status, InspiralCell **cell, INT4 id, InspiralTemplate *params, HexaGridParam *gridParam, CellEvolution UNUSED *cellEvolution, CellList UNUSED **cellList, INT4 *valid)
#define LALRealloc(p, n)
#define LALCalloc(m, n)
#define LALMalloc(n)
#define LALFree(p)
#define tiny
#define ABORT(statusptr, code, mesg)
#define CHECKSTATUSPTR(statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
double i
double e
double theta
void LALSBisectionFindRoot(LALStatus *status, REAL4 *root, SFindRootIn *input, void *params)
#define LAL_PI
#define LAL_MTSUN_SI
double REAL8
int32_t INT4
float REAL4
#define LALINSPIRALH_ESIZE
Invalid input range.
Definition: LALInspiral.h:59
@ t03
chirptimes and , and
Definition: LALInspiral.h:185
@ m1Andm2
component masses
Definition: LALInspiral.h:179
void LALInitHexagonalBank(LALStatus *status, InspiralCell **cell, INT4 id, InspiralMomentsEtc *moments, InspiralTemplate *paramsIn, HexaGridParam *gridParam, CellEvolution *cellEvolution, CellList **cellList)
UINT4 LALListLength(CellList *head)
#define LALINSPIRALBANKH_EHEXAINIT
Empty bank.
void LALRectangleVertices(LALStatus *status, RectangleOut *out, RectangleIn *in)
Function to find the vertices of a rectangle given its centre, half side-lengths and orientation angl...
void LALInspiralSetParams(LALStatus *status, InspiralTemplate *tempPars, InspiralCoarseBankIn coarseIn)
A routine that fills an InspiralTemplate structure based on the values in the InspiralCoarseBankIn st...
void LALInspiralSetSearchLimits(LALStatus *status, InspiralBankParams *bankParams, InspiralCoarseBankIn coarseIn)
Function which calculates the minimum and maximum values of and .
void LALInspiralCreatePNCoarseBankHexa(LALStatus *status, InspiralTemplateList **list, INT4 *nlist, InspiralCoarseBankIn coarseIn)
void LALListAppend(CellList **headRef, INT4 id)
Position
This enum can take the following values In, Out, Below, Edge, Above and is used only by the Hexagonal...
void LALPopulateCell(LALStatus *status, InspiralMomentsEtc *moments, InspiralCell **cell, INT4 headId, InspiralTemplate *paramsIn, HexaGridParam *gridParam, CellEvolution *cellEvolution, CellList **cellList)
void LALFindPosition(LALStatus *status, REAL4 dx0, REAL4 dx1, Position *position, InspiralTemplate *paramsIn, HexaGridParam *gridParam)
void LALGetInspiralMoments(LALStatus *status, InspiralMomentsEtc *moments, REAL8FrequencySeries *psd, InspiralTemplate *params)
void LALListDelete(CellList **headRef, INT4 id)
void LALSPAF(LALStatus *status, REAL4 *result, REAL4 t3, void *param)
#define LALINSPIRALBANKH_ESIZE
Invalid input range.
#define LALINSPIRALBANKH_EMEM
Memory allocation failure.
void LALInspiralComputeMetric(LALStatus *status, InspiralMetric *metric, InspiralTemplate *params, InspiralMomentsEtc *moments)
@ MinMaxComponentTotalMass
@ MinMaxComponentMass
@ MinComponentMassMaxTotalMass
@ HybridHexagonal
UNDOCUMENTED.
@ Edge
UNDOCUMENTED.
@ Above
UNDOCUMENTED.
@ Out
UNDOCUMENTED.
@ In
UNDOCUMENTED.
@ Below
UNDOCUMENTED.
@ Sterile
@ Fertile
static const INT4 a
double t0
This is a structure needed in the inner workings of the LALInspiralHexagonalBank code.
This is a structure needed in the inner workings of the LALInspiralHexagonalBank code.
struct tagCellList * next
This is a structure needed in the inner workings of the LALInspiralHexagonalBank code.
InspiralBankMassRange massRange
GridSpacing gridSpacing
CoordinateSpace space
This is a structure needed in the inner workings of the LALInspiralCreateCoarseBank code.
REAL8 x1Max
maximum value of the second coordinate as defined by the search region
REAL8 x1Min
minimum value of the second coordinate as defined by the search region
REAL8 x0Min
minimum value of the first coordinate as defined by the search region
REAL8 x0Max
maximum value of the first coordinate as defined by the search region
This is a structure needed in the inner workings of the LALInspiralHexagonalBank code.
Position position
InspiralMetric metric
Input for choosing a template bank.
REAL8 mMin
minimum mass of components to search for
REAL8 mMax
maximum mass of components to search for
InspiralBankMassRange massRange
enum that determines whether templates should be chosen using fixed ranges for component masses or to...
GridSpacing gridSpacing
Type of gridspacing required.
REAL8FrequencySeries shf
Frequency series containing the PSD.
REAL8 MMax
alternatively, maximum total mass of binary to search for
REAL8 etamin
minimum value of eta in our search
REAL8 fLower
Lower frequency cutoff.
REAL8 mmCoarse
Coarse grid minimal match.
CoordinateSpace space
enum that decides whether to use or in constructing the template bank
REAL8 MMin
UNDOCUMENTED.
Parameter structure that holds the moments of the PSD and other useful constants required in the comp...
The inspiral waveform parameter structure containing information about the waveform to be generated.
Definition: LALInspiral.h:205
INT4 ieta
parameter that tells whether the symmetric mass ratio should be set to zero in the PN expansions of ...
Definition: LALInspiral.h:226
REAL8 eta
symmetric mass ratio (input/output)
Definition: LALInspiral.h:291
REAL8 totalMass
total mass of the binary in solar mass (input/output)
Definition: LALInspiral.h:292
REAL8 mass1
Mass of the primary in solar mass (input/output)
Definition: LALInspiral.h:211
REAL8 t3
1.5 post-Newtonian chirp time in seconds (input/output)
Definition: LALInspiral.h:296
REAL8 t0
Newtonain chirp time in seconds (input/output)
Definition: LALInspiral.h:294
REAL8 mass2
Mass of the secondary in solar mass (mass1 need not be larger than mass2 (input/output)
Definition: LALInspiral.h:212
InputMasses massChoice
The pair of (mass) parameters given (see structure defining this member for more details) (input)
Definition: LALInspiral.h:323
REAL8 fLower
lower frequency cutoff of the detector in Hz (input)
Definition: LALInspiral.h:217
A grid of inspiral templates (ie a template list).
UNDOCUMENTED.
REAL4 b
REAL4 ct
Input structure to function LALRectangleVertices()
Output structure to function LALRectangleVertices().
void(* function)(LALStatus *s, REAL4 *y, REAL4 x, void *p)