00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 #include <math.h>
00101 #include <lal/AVFactories.h>
00102 #include <lal/FlatMesh.h>
00103 #include <lal/LALConfig.h>
00104 #include <lal/LALConstants.h>
00105 #include <lal/LALDatatypes.h>
00106 #include <lal/LALInspiralBank.h>
00107 #include <lal/LALMalloc.h>
00108 #include <lal/LALStatusMacros.h>
00109 #include <lal/LALStdlib.h>
00110 #include <lal/LIGOMetadataTables.h>
00111 #include <lal/MatrixUtils.h>
00112 #include <lal/SeqFactories.h>
00113
00114
00115 #define INSPIRALSPINBANKC_ENOTILES 5
00116 #define INSPIRALSPINBANKC_MSGENOTILES "No templates were generated"
00117
00118
00119 NRCSID(INSPIRALSPINBANKC, "$Id: InspiralSpinBank.c,v 1.26 2007/06/08 14:41:42 bema Exp $");
00120
00121
00122
00123 static void cleanup(LALStatus *,
00124 REAL4Array **,
00125 UINT4Vector **,
00126 REAL4Vector **,
00127 SnglInspiralTable *,
00128 SnglInspiralTable *,
00129 INT4 *
00130 );
00131
00132 static REAL4 calculateX(
00133 REAL4,
00134 REAL4,
00135 REAL4,
00136 REAL4,
00137 REAL4,
00138 REAL4,
00139 INT4,
00140 REAL4
00141 );
00142
00143 static REAL4 calculateY(
00144 REAL4,
00145 REAL4,
00146 REAL4,
00147 REAL4,
00148 REAL4,
00149 REAL4,
00150 INT4,
00151 REAL4
00152 );
00153
00154 static REAL4 calculateZ(
00155 REAL4,
00156 REAL4,
00157 REAL4
00158 );
00159
00160 static INT4 test(
00161 REAL4,
00162 REAL4,
00163 REAL4,
00164 REAL4,
00165 REAL4,
00166 REAL4,
00167 REAL4,
00168 REAL4
00169 );
00170
00171 static BOOLEAN inPsiRegion(
00172 REAL4,
00173 REAL4,
00174 REAL4,
00175 InspiralCoarseBankIn *,
00176 REAL4
00177 );
00178
00179
00180
00181
00182
00183 static void
00184 LALInspiralSpinBankMetric(
00185 LALStatus *status,
00186 REAL4Array *metric,
00187 InspiralMomentsEtc *moments,
00188 InspiralTemplate *inspiralTemplate,
00189 REAL4 *f0
00190 )
00191 {
00192 INT4 loop = 0;
00193 REAL8 J1 = 0.0;
00194 REAL8 J4 = 0.0;
00195 REAL8 J6 = 0.0;
00196 REAL8 J9 = 0.0;
00197 REAL8 J11 = 0.0;
00198 REAL8 J12 = 0.0;
00199 REAL8 J14 = 0.0;
00200 REAL8 J17 = 0.0;
00201
00202 INITSTATUS( status, "LALInspiralSpinBank", INSPIRALSPINBANKC );
00203 ATTATCHSTATUSPTR( status );
00204
00205 if (!metric){
00206 ABORT(status, LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL);
00207 }
00208 if (!moments){
00209 ABORT(status, LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL);
00210 }
00211
00212
00213
00214 for(loop = 1; loop <=17; loop++){
00215 moments->j[loop] *= pow((inspiralTemplate->fLower/(*f0)), ((7.0-(REAL4) loop)/3.0));
00216 }
00217
00218
00219 J1 = moments->j[1];
00220 J4 = moments->j[4];
00221 J6 = moments->j[6];
00222 J9 = moments->j[9];
00223 J11 = moments->j[11];
00224 J12 = moments->j[12];
00225 J14 = moments->j[14];
00226 J17 = moments->j[17];
00227
00228
00229
00230 metric->data[0] = (REAL4) 0.5*(J17-J12*J12-(J9-J4*J12)*(J9-J4*J12)/(J1-J4*J4));
00231 metric->data[1] = (REAL4) 0.5*(J14-J9*J12-(J6-J4*J9)*(J9-J4*J12)/(J1-J4*J4));
00232 metric->data[2] = (REAL4) 0;
00233 metric->data[3] = (REAL4) 0.5*(J14-J9*J12-(J6-J4*J9)*(J9-J4*J12)/(J1-J4*J4));
00234 metric->data[4] = (REAL4) 0.5*(J11-J9*J9-(J6-J4*J9)*(J6-J4*J9)/(J1-J4*J4));
00235
00236 metric->data[5] = (REAL4) 0.0;
00237 metric->data[6] = (REAL4) 0.0;
00238 metric->data[7] = (REAL4) 0.0;
00239 metric->data[8] = (REAL4) 0.5*(J11-J9*J9-(J6-J4*J9)*(J6-J4*J9)/(J1-J4*J4));
00240
00241
00242 if ( lalDebugLevel & LALINFO )
00243 {
00244 CHAR msg[256];
00245 LALSnprintf( msg, sizeof(msg) / sizeof(*msg), "metric components:\n"
00246 "psi0-psi0 %e\npsi0-psi3 %e psi3-psi3 %e\npsi0-beta %e "
00247 "psi3-beta %e beta-beta %e\n", metric->data[0] /
00248 pow(*f0,10./3), metric->data[3] / pow(*f0,7./3),
00249 metric->data[4] / pow(*f0,4./3), metric->data[6] /
00250 pow(*f0,7./3), metric->data[7] / pow(*f0,4./3),
00251 metric->data[8] / pow(*f0,4./3) );
00252 LALInfo( status, msg );
00253 LALSnprintf( msg, sizeof(msg) / sizeof(*msg), "f0 = %f j1=%f j4=%f "
00254 "j6=%f j9=%f j11=%f j12=%f j14=%f j17=%f", *f0, J1, J4,
00255 J6, J9, J11, J12, J14, J17 );
00256 LALInfo( status, msg );
00257 }
00258
00259 DETATCHSTATUSPTR( status );
00260 RETURN( status );
00261 }
00262
00263
00264
00265
00266 static void
00267 allocate(
00268 REAL4 x,
00269 REAL4 y,
00270 REAL4 z,
00271 REAL4 f0,
00272 SnglInspiralTable **tmplt,
00273 INT4 *ntiles,
00274 BOOLEAN havePsi )
00275 {
00276 REAL4 mass, eta, m1, m2;
00277
00278 *tmplt = (*tmplt)->next = (SnglInspiralTable *) LALCalloc( 1,
00279 sizeof(SnglInspiralTable) );
00280
00281 mass = -y/x / (16.0*LAL_PI*LAL_PI*f0);
00282 eta = 16.0457 * pow( -x*x/y/y/y/y/y, 0.3333333 );
00283 m1 = 0.5*mass* (1 + sqrt(1 - 4*eta));
00284 m2 = 0.5*mass* (1 - sqrt(1 - 4*eta));
00285
00286 if ( ! havePsi )
00287 {
00288 (*tmplt)->mass1 = m1;
00289 (*tmplt)->mass2 = m2;
00290 (*tmplt)->eta = eta;
00291 (*tmplt)->mchirp = pow(m1*m2,0.6)/pow(m1+m2,0.2);
00292 }
00293 (*tmplt)->psi0 = x*pow(f0,5./3);
00294 (*tmplt)->psi3 = y*pow(f0,2./3);
00295 (*tmplt)->beta = z*pow(f0,2./3);
00296 ++(*ntiles);
00297 }
00298
00299
00300
00301 void
00302 LALInspiralSpinBank(
00303 LALStatus *status,
00304 SnglInspiralTable **tiles,
00305 INT4 *ntiles,
00306 InspiralCoarseBankIn *coarseIn
00307 )
00308
00309 {
00310 SnglInspiralTable *tmplt = NULL;
00311 REAL4Array *metric = NULL;
00312 UINT4Vector *metricDimensions = NULL;
00313 REAL4Vector *eigenval = NULL;
00314 InspiralMomentsEtc moments;
00315 InspiralTemplate inspiralTemplate;
00316 REAL4 x, y, z;
00317 REAL4 x0, myy0, z0;
00318 REAL4 x1, myy1, z1;
00319 REAL4 xp, yp, zp;
00320 REAL4 xp0, yp0, zp0;
00321 REAL4 xp1, yp1, zp1;
00322 REAL4 dxp, dyp, dzp;
00323 REAL4 theta;
00324 REAL4 m1Min, m1Max;
00325 REAL4 m2Min, m2Max;
00326 REAL4 f0 = -1;
00327 INT2 bccFlag = 0;
00328 INT4 cnt = 0;
00329 REAL4 shf0 = 1;
00330 BOOLEAN havePsi;
00331
00332
00333 INITSTATUS( status, "LALInspiralSpinBank", INSPIRALSPINBANKC );
00334 ATTATCHSTATUSPTR( status );
00335
00336
00337 ASSERT( coarseIn, status, LALINSPIRALBANKH_ENULL,
00338 LALINSPIRALBANKH_MSGENULL );
00339
00340 ASSERT( coarseIn->mmCoarse > 0, status, LALINSPIRALBANKH_ECHOICE,
00341 LALINSPIRALBANKH_MSGECHOICE );
00342
00343 if( coarseIn->mMin > 0 )
00344 {
00345 ASSERT( coarseIn->MMax > 0, status, LALINSPIRALBANKH_ECHOICE,
00346 LALINSPIRALBANKH_MSGECHOICE );
00347 ASSERT( coarseIn->MMax > 2*coarseIn->mMin, status,
00348 LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE );
00349 havePsi = 0;
00350 }
00351
00352 else
00353 {
00354 ASSERT( coarseIn->psi0Min > 0, status, LALINSPIRALBANKH_ECHOICE,
00355 LALINSPIRALBANKH_MSGECHOICE );
00356 ASSERT( coarseIn->psi0Max > coarseIn->psi0Min, status,
00357 LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE );
00358 ASSERT( coarseIn->psi3Min < 0, status, LALINSPIRALBANKH_ECHOICE,
00359 LALINSPIRALBANKH_MSGECHOICE );
00360 ASSERT( coarseIn->psi3Max > coarseIn->psi3Min, status,
00361 LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE );
00362 ASSERT( coarseIn->betaMax > coarseIn->betaMin, status,
00363 LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE );
00364 havePsi = 1;
00365 }
00366
00367 ASSERT( coarseIn->shf.data, status, LALINSPIRALBANKH_ENULL,
00368 LALINSPIRALBANKH_MSGENULL );
00369 ASSERT( coarseIn->shf.data->data, status, LALINSPIRALBANKH_ENULL,
00370 LALINSPIRALBANKH_MSGENULL );
00371
00372
00373 LALU4CreateVector( status->statusPtr, &metricDimensions, (UINT4) 2 );
00374 BEGINFAIL(status)
00375 cleanup(status->statusPtr, &metric, &metricDimensions, &eigenval, *tiles, tmplt, ntiles);
00376 ENDFAIL(status);
00377 metricDimensions->data[0] = 3;
00378 metricDimensions->data[1] = 3;
00379 LALSCreateArray( status->statusPtr, &metric, metricDimensions );
00380 BEGINFAIL(status)
00381 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt, ntiles);
00382 ENDFAIL(status);
00383 eigenval = NULL;
00384 LALSCreateVector( status->statusPtr, &eigenval, 3 );
00385 BEGINFAIL(status)
00386 cleanup(status->statusPtr,&metric, &metricDimensions,&eigenval,*tiles,tmplt, ntiles);
00387 ENDFAIL(status);
00388
00389
00390 for( cnt = 0; cnt < (INT4) coarseIn->shf.data->length; cnt++ )
00391 {
00392 if( coarseIn->shf.data->data[cnt] > 0 && coarseIn->shf.data->data[cnt] <
00393 shf0 )
00394 {
00395 f0 = (REAL4) coarseIn->shf.deltaF * cnt;
00396 shf0 = coarseIn->shf.data->data[cnt];
00397 }
00398 }
00399
00400 inspiralTemplate.fLower = coarseIn->fLower;
00401 inspiralTemplate.fCutoff = coarseIn->fUpper;
00402 LALGetInspiralMoments( status->statusPtr, &moments, &(coarseIn->shf),
00403 &inspiralTemplate );
00404 BEGINFAIL(status)
00405 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
00406 ENDFAIL(status);
00407
00408
00409 LALInspiralSpinBankMetric(status->statusPtr, metric, &moments, &inspiralTemplate, &f0);
00410 BEGINFAIL(status)
00411 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt, ntiles);
00412 ENDFAIL(status);
00413
00414 LALSSymmetricEigenVectors( status->statusPtr, eigenval, metric );
00415 BEGINFAIL(status)
00416 cleanup(status->statusPtr,&metric, &metricDimensions,&eigenval,*tiles,tmplt, ntiles);
00417 ENDFAIL(status);
00418
00419
00420 *tiles = tmplt = (SnglInspiralTable *) LALCalloc( 1,
00421 sizeof( SnglInspiralTable ) );
00422 if ( *tiles == NULL )
00423 {
00424 cleanup( status->statusPtr, &metric, &metricDimensions, &eigenval,
00425 *tiles, tmplt, ntiles);
00426 ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00427 }
00428 *ntiles = 0;
00429
00430
00431 if( eigenval->data[0] <= 0 || eigenval->data[1] <=0 || eigenval->data[2]
00432 <= 0 )
00433 {
00434 ABORT(status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE);
00435 }
00436 dxp = 1.333333*sqrt(2*(1-coarseIn->mmCoarse)/eigenval->data[0]);
00437 dyp = 1.333333*sqrt(2*(1-coarseIn->mmCoarse)/eigenval->data[1]);
00438 dzp = 0.6666667*sqrt(2*(1-coarseIn->mmCoarse)/eigenval->data[2]);
00439 theta = atan2( -metric->data[3], -metric->data[0] );
00440 printf( "theta is %e\n", theta );
00441
00442
00443 if ( ! havePsi )
00444 {
00445
00446 m2Min = coarseIn->mMin*LAL_MTSUN_SI;
00447 m2Max = coarseIn->MMax*LAL_MTSUN_SI/2;
00448 m1Min = 2.0*m2Max;
00449 m1Max = 15.0*LAL_MTSUN_SI - m2Max;
00450
00451
00452 x0 = 0.9*(3.0/128) / (pow(LAL_PI*f0*(m1Max+m2Max),1.666667)
00453 *(m1Max*m2Max/pow(m1Max+m2Max,2)));
00454 myy0 = 1.1*(-.375*LAL_PI) / (pow(LAL_PI*f0*(m1Max+m2Min),0.6666667)*(m1Max*m2Min/pow(m1Max+m2Min,2)));
00455 z0 = 0;
00456 x1 = 1.1*(3.0/128) / (pow(LAL_PI*f0*(m1Min+m2Min),1.666667)*(m1Min*m2Min/pow(m1Min+m2Min,2)));
00457 myy1 = .9*(-.375*LAL_PI) / (pow(LAL_PI*f0*(m1Min+m2Max),0.6666667)*(m1Min*m2Max/pow(m1Min+m2Max,2)));
00458 z1 = 3.8* LAL_PI/29.961432 * (1+0.75*m2Max/m1Min) * (m1Max/m2Min) * pow(LAL_MTSUN_SI*100.0/(m1Min+m2Min), 0.6666667);
00459 }
00460
00461 else
00462 {
00463
00464 x0 = coarseIn->psi0Min / pow( f0, 5./3 );
00465 x1 = coarseIn->psi0Max / pow( f0, 5./3 );
00466 myy0 = coarseIn->psi3Min / pow( f0, 2./3 );
00467 myy1 = coarseIn->psi3Max / pow( f0, 2./3 );
00468 z0 = coarseIn->betaMin / pow( f0, 2./3 );
00469 z1 = coarseIn->betaMax / pow( f0, 2./3 );
00470 }
00471
00472
00473 xp0 = x0 + sin(theta)*sin(theta) * (x1 - x0);
00474 yp0 = myy0 - cos(theta)*sin(theta) * (x1 - x0);
00475 yp1 = sin(theta) * (x1 - x0) + cos(theta) * (myy1 - myy0);
00476 xp1 = sin(theta) * (myy1 - myy0) + cos(theta) * (x1 - x0);
00477 zp0 = z0;
00478 zp1 = z1;
00479
00480
00481 for (zp = 0; zp <= zp1; zp += dzp)
00482 {
00483 bccFlag++;
00484 for (yp = 0; yp<= yp1; yp += dyp)
00485 {
00486 for (xp = 0; xp <= xp1; xp += dxp)
00487 {
00488
00489
00490 x = calculateX(0, xp0, xp, dxp, yp, dyp, bccFlag, theta);
00491 y = calculateY(0, yp0, xp, dxp, yp, dyp, bccFlag, theta);
00492 z = calculateZ(0, zp, dzp);
00493 if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
00494 || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00495 {
00496 allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
00497 if( tmplt == NULL )
00498 {
00499 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
00500 ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00501 }
00502 }
00503
00504
00505 x = calculateX(-1, xp0, xp, dxp, yp, dyp, bccFlag, theta);
00506 if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
00507 || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00508 {
00509 x = calculateX(-0.5, xp0, xp, dxp, yp, dyp, bccFlag, theta);
00510 if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
00511 || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00512 {
00513 allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
00514 if( tmplt == NULL )
00515 {
00516 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
00517 ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00518 }
00519 }
00520 }
00521
00522
00523 x = calculateX(0, xp0, xp, dxp, yp, dyp, bccFlag, theta);
00524 y = calculateY(-1, yp0, xp, dxp, yp, dyp, bccFlag, theta);
00525 if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
00526 || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00527 {
00528 y = calculateY(-0.5, yp0, xp, dxp, yp, dyp, bccFlag, theta);
00529 if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
00530 || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00531 {
00532 allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
00533 if (!tmplt){
00534 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
00535 ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00536 }
00537 }
00538 }
00539
00540
00541 y = calculateY(0, yp0, xp, dxp, yp, dyp, (bccFlag+1), theta);
00542 z = calculateZ(-1, zp, dzp);
00543 if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
00544 || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00545 {
00546 z = calculateZ(-0.5, zp, dzp);
00547 if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
00548 || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00549 {
00550 allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
00551 if (!tmplt){
00552 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
00553 ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00554 }
00555 }
00556 }
00557
00558
00559 x = calculateX(1, xp0, xp, dxp, yp, dyp, bccFlag, theta);
00560 y = calculateY(0, yp0, xp, dxp, yp, dyp, (bccFlag+1), theta);
00561 z = calculateZ(0, zp, dzp);
00562 if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
00563 || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00564 {
00565 x = calculateX(0.5, xp0, xp, dxp, yp, dyp, bccFlag, theta);
00566 if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
00567 || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00568 {
00569 allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
00570 if (!tmplt){
00571 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
00572 ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00573 }
00574 }
00575 }
00576
00577
00578 x = calculateX(0, xp0, xp, dxp, yp, dyp, bccFlag, theta);
00579 y = calculateY(1, yp0, xp, dxp, yp, dyp, bccFlag, theta);
00580 if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
00581 || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00582 {
00583 y = calculateY(0.5, yp0, xp, dxp, yp, dyp, bccFlag, theta);
00584 if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
00585 || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00586 {
00587 allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
00588 if (!tmplt){
00589 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
00590 ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00591 }
00592 }
00593 }
00594
00595
00596 y = calculateY(0, yp0, xp, dxp, yp, dyp, (bccFlag+1), theta);
00597 z = calculateZ(1, zp, dzp);
00598 if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
00599 || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00600 {
00601 z = calculateZ(0.5, zp, dzp);
00602 if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
00603 || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
00604 {
00605 allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
00606 if (!tmplt){
00607 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
00608 ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
00609 }
00610 }
00611 }
00612 }
00613 }
00614 }
00615
00616
00617 tmplt = (*tiles)->next;
00618 LALFree( *tiles );
00619 *tiles = tmplt;
00620
00621
00622 if (*tiles == NULL)
00623 {
00624 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
00625 ABORT(status, INSPIRALSPINBANKC_ENOTILES, INSPIRALSPINBANKC_MSGENOTILES);
00626 }
00627
00628
00629 cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,NULL,NULL,&cnt);
00630 DETATCHSTATUSPTR( status );
00631 RETURN( status );
00632 }
00633
00634
00635
00636 static void cleanup(
00637 LALStatus *s,
00638 REAL4Array **m,
00639 UINT4Vector **md,
00640 REAL4Vector **e,
00641 SnglInspiralTable *f,
00642 SnglInspiralTable *t,
00643 INT4 *nt)
00644 {
00645 INITSTATUS( s, "LALInspiralSpinBank-cleanup", INSPIRALSPINBANKC );
00646 ATTATCHSTATUSPTR( s );
00647
00648 if (m){
00649 TRY(LALU4DestroyVector(s->statusPtr,md),s);
00650 }
00651 if (md){
00652 TRY(LALSDestroyVector(s->statusPtr, e),s);
00653 }
00654 if (e){
00655 TRY(LALSDestroyArray(s->statusPtr, m),s);
00656 }
00657 if (t && f)
00658 {
00659 t = f;
00660 while ((t->next) && (*nt > 0))
00661 {
00662 f = t;
00663 t = t->next;
00664 LALFree(f);
00665 --(*nt);
00666 }
00667 LALFree(t);
00668 --(*nt);
00669 }
00670 DETATCHSTATUSPTR( s );
00671 RETURN( s );
00672 }
00673
00674 static REAL4 calculateX(REAL4 n,
00675 REAL4 xp0,
00676 REAL4 xp,
00677 REAL4 dxp,
00678 REAL4 yp,
00679 REAL4 dyp,
00680 INT4 bccFlag,
00681 REAL4 theta)
00682 {
00683 return xp0 + (n*dxp + xp+dxp/2.0*(bccFlag%2))*cos(theta) -
00684 (yp+dyp/2.0*(bccFlag%2))*sin(theta);
00685 }
00686
00687 static REAL4 calculateY(REAL4 n,
00688 REAL4 yp0,
00689 REAL4 xp,
00690 REAL4 dxp,
00691 REAL4 yp,
00692 REAL4 dyp,
00693 INT4 bccFlag,
00694 REAL4 theta)
00695 {
00696 return (yp0 + (xp+dxp/2.0*((bccFlag)%2))*sin(theta) +
00697 (n*dyp + yp+dyp/2.0*((bccFlag)%2))*cos(theta));
00698 }
00699
00700 static REAL4 calculateZ(REAL4 n,
00701 REAL4 zp,
00702 REAL4 dzp)
00703 {
00704 return (zp + n*dzp);
00705 }
00706
00707
00708
00709 static INT4 test(REAL4 x,
00710 REAL4 y,
00711 REAL4 z,
00712 REAL4 m1Min,
00713 REAL4 m1Max,
00714 REAL4 m2Min,
00715 REAL4 m2Max,
00716 REAL4 f0){
00717
00718 REAL4 mass, eta, m1, m2, betaMax;
00719 mass = -y/x / (16.0*LAL_PI*LAL_PI*f0);
00720 if (mass < 0)
00721 return 0;
00722 eta = 16.0457 * pow( -x*x/y/y/y/y/y, 0.3333333 );
00723 if (eta > 0.25 || eta < 0)
00724 return 0;
00725 m1 = 0.5*mass* (1 + sqrt(1 - 4*eta));
00726 m2 = 0.5*mass* (1 - sqrt(1 - 4*eta));
00727 if (m1 > m1Max || m1 < m1Min || m2 > m2Max || m2 < m2Min)
00728 return 0;
00729 betaMax = 3.8*LAL_PI/29.961432 * (1+0.75*m2/m1)*(m1/m2) * pow((LAL_MTSUN_SI*100.0/mass),0.6666667);
00730 if (z > betaMax)
00731 return 0;
00732 return 1;
00733 }
00734
00735
00736
00737
00738
00739 static BOOLEAN inPsiRegion( REAL4 psi0,
00740 REAL4 psi3,
00741 REAL4 beta,
00742 InspiralCoarseBankIn *coarseIn,
00743 REAL4 f0 )
00744 {
00745 REAL4 fac1 = pow( f0, 5./3 );
00746 REAL4 fac2 = fac1 / f0;
00747
00748 if ( psi0 < coarseIn->psi0Min/fac1 )
00749 return 0;
00750 if ( psi0 > coarseIn->psi0Max/fac1 )
00751 return 0;
00752 if ( psi3 < coarseIn->psi3Min/fac2 )
00753 return 0;
00754 if ( psi3 > coarseIn->psi3Max/fac2 )
00755 return 0;
00756 if ( beta < coarseIn->betaMin/fac2 )
00757 return 0;
00758 if ( beta > coarseIn->betaMax/fac2 )
00759 return 0;
00760
00761 return 1;
00762 }