GenerateInspRing.c

Go to the documentation of this file.
00001 /* *  Copyright (C) 2007 Bernd Machenschalk, Stephen Fairhurst
00002 *
00003 *  This program is free software; you can redistribute it and/or modify
00004 *  it under the terms of the GNU General Public License as published by
00005 *  the Free Software Foundation; either version 2 of the License, or
00006 *  (at your option) any later version.
00007 *
00008 *  This program is distributed in the hope that it will be useful,
00009 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 *  GNU General Public License for more details.
00012 *
00013 *  You should have received a copy of the GNU General Public License
00014 *  along with with program; see the file COPYING. If not, write to the
00015 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00016 *  MA  02111-1307  USA
00017 */
00018 
00019 /** \file GenerateInspRing.c
00020  *  \ingroup GenerateInspRing
00021  *  \author S.Fairhurst
00022  * 
00023  *  \brief Functions for adding a (realistic?) merger ringdown to the end of
00024  *  and inspiral waveform
00025  *
00026  * $Id: GenerateInspRing.c,v 1.18 2008/01/31 18:41:18 sfairhur Exp $ 
00027  *
00028  */
00029 
00030 #include <stdlib.h>
00031 #include <math.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <lal/Date.h>
00036 #include <lal/DetResponse.h>
00037 #include <lal/LALStdlib.h>
00038 #include <lal/LALConstants.h>
00039 #include <lal/AVFactories.h>
00040 #include <lal/SeqFactories.h>
00041 #include <lal/LIGOMetadataTables.h>
00042 #include <lal/LIGOMetadataUtils.h>
00043 #include <lal/Units.h>
00044 #include <lal/SimulateCoherentGW.h>
00045 #include <lal/GenerateRing.h>
00046 #include <lal/Ring.h>
00047 #include <lal/TimeDelay.h>
00048 #include <lal/TimeSeries.h>
00049 #include <lal/GenerateInspRing.h>
00050 
00051 NRCSID (GENERATEINSPRINGC,"$Id: GenerateInspRing.c,v 1.18 2008/01/31 18:41:18 sfairhur Exp $");
00052 
00053 static SimRingdownTable*
00054 XLALDeriveRingdownParameters(
00055     SimRingdownTable    *ringInj      
00056     );
00057 
00058 /** Takes an inspiral waveform, and a simInspiralTable and generates a ringdown
00059  * at an appropriate frequency and quality */
00060 CoherentGW *
00061 XLALGenerateInspRing(
00062     CoherentGW          *waveform,     /**< the inspiral waveform */
00063     SimInspiralTable    *inspiralInj,  /**< details of the inspiral */
00064     SimRingdownTable    *ringInj,      /**< ringdown details to be populated */
00065     int                  injectSignalType /**< type of injection */
00066     )
00067 {
00068   static const char *func = "XLALGenerateInspRing";
00069   
00070   REAL4 *a, *f; /* pointers to generated amplitude and frequency data */
00071   REAL4 *shift = NULL; /* pointers to generated shift (polarization) data */
00072   REAL8 *phi;   /* pointer to generated phase data */
00073 
00074   /* length of the waveform */
00075   INT4 inputLength;
00076   INT4 outputLength;
00077   INT4 mergerLength;
00078   INT4 ringLength;
00079   INT4 endMerger = 0;
00080   INT4 condt;
00081   
00082   /* waveform parameters */
00083   REAL8 phase;
00084   REAL8 mergerPhase;
00085   REAL8 phi0;
00086   REAL4 dt; 
00087   REAL4 ampPlus;
00088   REAL4 ampPlusDot;
00089   REAL4 a2Plus;
00090   REAL4 ampCross;
00091   REAL4 ampCrossDot;
00092   REAL4 a2Cross;
00093   REAL4 freq;
00094   REAL4 freqDot;
00095   REAL4 freq0;
00096   REAL4 freqDot0;
00097   REAL4 polarization;
00098   REAL4 polDot;
00099   REAL4 dampFac;
00100   REAL4 phaseFac;
00101   REAL4 A, lambda;
00102   REAL4 tToRing;
00103   REAL4 tRing;
00104   REAL4 amp;
00105   INT4 n, N;
00106 
00107   /* ringdown details */
00108   REAL4                 mTot = 0;
00109   REAL4                 orbAngMom, totalAngMom;
00110   REAL4                 Jx, Jy, Jz;
00111   
00112   REAL4                 splus, scross, cosiota, cosiotaA, cosiotaB;
00113   
00114   /*
00115    *
00116    * Work out where the inspiral ended
00117    *
00118    */
00119 
00120   /* check that the inspiral waveform exists */
00121   if ( !waveform || !(waveform->a->data) || !(waveform->f->data) ||
00122       !(waveform->phi->data) )
00123   {
00124     XLALPrintError("Invalid waveform passed as input to %s\n", func);
00125     XLAL_ERROR_NULL(func,XLAL_EIO);
00126   }
00127 
00128   if ( (waveform->a->data->length < 2) )
00129   {
00130     XLALPrintError(
00131         "Length of waveform input to %s must be at least 2 points\n", func);
00132     XLAL_ERROR_NULL(func,XLAL_EIO);
00133   }
00134 
00135   if ( !inspiralInj )
00136   {
00137     XLALPrintError("No sim inspiral table passed as input to %s\n", func);
00138     XLAL_ERROR_NULL(func,XLAL_EIO);
00139   }
00140 
00141   /* read in the number of points already present */
00142   inputLength = waveform->a->data->length;
00143 
00144   /* record the final frequency, amplitude and phase */
00145   dt = waveform->f->deltaT;
00146 
00147   ampPlus = waveform->a->data->data[2*inputLength - 2];
00148   ampPlusDot = ampPlus - waveform->a->data->data[2*inputLength - 4];
00149 
00150   ampCross = waveform->a->data->data[2*inputLength - 1];
00151   ampCrossDot = ampCross - waveform->a->data->data[2*inputLength - 3];
00152 
00153   freq0 = waveform->f->data->data[inputLength - 1];
00154   freqDot0 = freq0 - waveform->f->data->data[inputLength - 2];
00155   freqDot0 /= dt;
00156 
00157   phase = waveform->phi->data->data[inputLength - 1];
00158 
00159 
00160   if ( waveform->shift )
00161   {
00162     polarization = waveform->shift->data->data[inputLength - 1];
00163     polDot = polarization - waveform->shift->data->data[inputLength - 2];
00164   }
00165 
00166   XLALPrintInfo(
00167       "Final inspiral frequency = %.2f Hz, fdot = %.2e Hz/s\n"
00168       "\n", freq0, freqDot0);
00169 
00170   /*
00171    *
00172    * Work out where we want the ringdown to start
00173    *
00174    */
00175 
00176 
00177 
00178   /* estimate the final angular momentum */
00179   orbAngMom = 4 * inspiralInj->eta * 0.7;
00180   mTot = inspiralInj->mass1 + inspiralInj->mass2;
00181 
00182   Jx = orbAngMom * sin(inspiralInj->inclination) + 
00183     (inspiralInj->spin1x * inspiralInj->mass1 * inspiralInj->mass1 + 
00184      inspiralInj->spin2x * inspiralInj->mass2 * inspiralInj->mass2) / 
00185     (mTot * mTot) ;
00186   Jy = (inspiralInj->spin1y * inspiralInj->mass1 * inspiralInj->mass1 +
00187       inspiralInj->spin2y * inspiralInj->mass2 * inspiralInj->mass2) /
00188     (mTot * mTot) ; 
00189   Jz = orbAngMom * cos(inspiralInj->inclination) + 
00190     (inspiralInj->spin1z * inspiralInj->mass1 * inspiralInj->mass1 + 
00191      inspiralInj->spin2z * inspiralInj->mass2 * inspiralInj->mass2) / 
00192     (mTot * mTot);
00193   totalAngMom = pow(Jx * Jx + Jy * Jy + Jz * Jz, 0.5);
00194 
00195   XLALPrintInfo( "Approximate orbital ang mom = %.2f\n", orbAngMom);
00196   XLALPrintInfo( "Approximate total angular momentum of inspiral:\n"
00197       "Jx = %.2f, Jy = %.2f, Jz = %.2f\n", Jx, Jy, Jz);
00198   XLALPrintInfo( "Estimated Final Spin = %.2f\n", totalAngMom );
00199 
00200   /* estimate the final mass */
00201   XLALPrintInfo( "Total inspiral mass = %.2f\n", mTot );
00202   mTot *= (1 - 0.01 * (1.0 + 6.0 * totalAngMom * totalAngMom ) );
00203   ringInj->mass = mTot;
00204   XLALPrintInfo( "Estimated Final Mass = %.2f\n", ringInj->mass );
00205 
00206   /* populate the ring params */
00207   ringInj->spin = totalAngMom < 0.99 ? totalAngMom : 0.95;
00208 
00209   ringInj->frequency = pow( LAL_C_SI, 3) / LAL_G_SI / LAL_MSUN_SI / 2.0 / 
00210     LAL_PI * ( 1.0 - 0.63 * pow( ( 1.0 - ringInj->spin ), 0.3 ) ) / 
00211     ringInj->mass;
00212   ringInj->quality = 2.0 * pow( ( 1.0 - ringInj->spin ), -0.45 );
00213 
00214   XLALPrintInfo( 
00215       "Estimated Ringdown Frequency = %.2f Hz, and Quality = %.2f\n"
00216       "\n", ringInj->frequency, ringInj->quality );
00217 
00218   ringInj->longitude    = inspiralInj->longitude;
00219   ringInj->latitude     = inspiralInj->latitude;
00220   ringInj->distance     = inspiralInj->distance;
00221 
00222   XLALPrintInfo(
00223       "Ringdown longitude = %.2f, latitude = %.2f, distance = %.2f\n",
00224       ringInj->longitude, ringInj->latitude, ringInj->distance );
00225 
00226 
00227   /*
00228    *
00229    * Work out the length of the full signal
00230    *
00231    */
00232 
00233   /* We use a very simple model to extend the frequency of the waveform.
00234    * This is done in two parts:
00235    *
00236    * 1) Continue the frequency by assuming that fdot is proportional f^(11/3)
00237    *
00238    *    using this, we obtain the frequency and phase at any later time 
00239    *    given f, fdot at t=0 as:
00240    *
00241    *    f(t) = f(0) * ( 1 - (8 fdot(0) t / 3 f(0) ) )^(-3/8)
00242    *
00243    *    phi(t) = phi0 - (2 pi) * 3/5 * f(0)^2 / fdot(0) *
00244    *                     (1 - (8 fdot(0) t / 3 f(0) ) )^(5/8)
00245    *
00246    *    where phi0 = phi(0) + ( 2 pi ) * ( 3 f(0)^2 / 5 fdot(0) )
00247    *
00248    * 
00249    * 2) At the point before the ring frequency would be exceeded, 
00250    *    exponentially approach the ring frequency.
00251    *    -- The exponential decay is determined by matching the derivative
00252    */
00253 
00254   /* calculate the number of points to reach 0.9 * ringdown frequency */
00255   tToRing = 3 * freq0 / ( 8 * freqDot0 ) * 
00256     (1 - pow( freq0 / (0.9 * ringInj->frequency), 8.0/3.0) );
00257   mergerLength = ceil( tToRing / dt ) - 1;
00258   phi0 = phase + LAL_TWOPI * 3 * freq0 * freq0 / (5 * freqDot0);
00259 
00260   mergerPhase = phi0 - phase
00261     - ( LAL_TWOPI) * (3.0 * freq0 * freq0 ) / ( 5.0 * freqDot0 ) * 
00262     pow( 1 - ( 8.0 * freqDot0 * tToRing) / ( 3.0 * freq0 ) , 5.0/8.0 );
00263 
00264 
00265   XLALPrintInfo( "Adding by hand a merger and ringdown\n");
00266   XLALPrintInfo( "Time to reach 0.9 of ringdown frequency = %.4f seconds,\n"
00267       "%d data points, %.2f radians in GW phase\n" 
00268       "We then add the same length to asymptote to ringdown values\n",
00269       tToRing, mergerLength, mergerPhase);
00270 
00271   if ( mergerPhase > 2 * LAL_TWOPI )
00272   {
00273     XLALPrintError("Failed to add a decent merger and ringdown\n"
00274         "The merger had a length of %.2f radians in GW phase (only allow 4pi)\n"
00275         "Returning null from %s\n",
00276         mergerPhase, func);
00277     XLALFree( waveform->a );
00278     XLALFree( waveform->phi );
00279     XLALFree( waveform->f );
00280     XLALFree( waveform->shift );
00281     XLAL_ERROR_NULL(func,XLAL_EFAILED);
00282   }
00283 
00284 
00285   /* calculate number of additional points necessary to damp by exp(12). */
00286   phaseFac = LAL_TWOPI * ringInj->frequency * dt;
00287   dampFac = exp( - phaseFac / (2 * ringInj->quality));
00288 
00289   ringLength = ceil((24 * ringInj->quality)/( phaseFac));  
00290   tRing = ringLength * dt;
00291 
00292   XLALPrintInfo( "Time to damp the ringdown by exp(12) = %.4f seconds,\n"
00293       "%d data points, %.2f radians in GW phase\n"
00294       "\n", tRing, ringLength, ringLength * phaseFac);
00295 
00296   /* Total extra length is merger length + ringdown length + some length over
00297    * which we smooth the merger to the ring */
00298 
00299   outputLength = inputLength + 2 * mergerLength - 1 + ringLength;
00300 
00301 
00302 
00303 
00304   /* 
00305    *
00306    * extend the data structures
00307    *
00308    */
00309 
00310   waveform->a->data->length = outputLength;
00311   waveform->a->data->data = (REAL4 *) XLALRealloc( ( waveform->a->data->data ), 
00312       2*outputLength*sizeof(REAL4) );  
00313   if ( !waveform->a->data->data )
00314   {
00315     XLALFree( waveform->a);
00316     XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00317   }
00318 
00319   memset(waveform->a->data->data + 2 * inputLength, 0, 
00320       2 * (outputLength - inputLength) * sizeof(REAL4) );
00321   XLALResizeREAL8TimeSeries( waveform->phi, 0, outputLength);
00322   if ( !waveform->phi->data )
00323   {
00324     XLALFree( waveform->a);
00325     XLALFree( waveform->phi);
00326     XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00327   }
00328 
00329   XLALResizeREAL4TimeSeries( waveform->f, 0, outputLength);
00330   if ( !waveform->f->data->data )
00331   {
00332     XLALFree( waveform->a );
00333     XLALFree( waveform->phi );
00334     XLALFree( waveform->f );
00335     XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00336   }
00337 
00338   if ( waveform->shift )
00339   {
00340     XLALResizeREAL4TimeSeries( waveform->shift, 0, outputLength);
00341     if ( !waveform->f->data->data )
00342     {
00343       XLALFree( waveform->a );
00344       XLALFree( waveform->phi );
00345       XLALFree( waveform->f );
00346       XLALFree( waveform->shift );
00347       XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00348     }
00349   }
00350 
00351   a = &(waveform->a->data->data[2*inputLength]);
00352   phi = &(waveform->phi->data->data[inputLength]);
00353   f = &(waveform->f->data->data[inputLength]);
00354 
00355   if ( waveform->shift )
00356   {
00357     shift = &(waveform->shift->data->data[inputLength]);
00358   }
00359 
00360   /*
00361    *
00362    * generate frequency, phase and shift (if needed) for merger and ringdown
00363    *
00364    */
00365 
00366   freq = freq0;
00367 
00368   /* run frequency close to ring frequency */
00369   for ( n = 1; n < mergerLength + 1; n++ )
00370   {
00371     REAL4 factor = 1 - (8.0 * freqDot0 * n * dt) / (3.0 * freq0 );
00372     freq = *(f++) = freq0 * pow( factor , -3.0/8.0 );
00373     phase = *(phi++) = phi0 - 
00374       LAL_TWOPI * 3.0 * freq0 * freq0 / (5.0 * freqDot0) * 
00375       pow( factor , 5.0/8.0);
00376     if ( shift )
00377     {
00378       polarization = *(shift++) = polarization + polDot;
00379     }
00380   }
00381 
00382   /* populate ringdown phase */
00383   ringInj->phase = phase;
00384   
00385   /* converge to ring frequency and constant polarization */
00386   /* fit to freq = f_ring - A * exp( - lambda * t )
00387    * then A = f_ring - freq
00388    *      A * lambda = freqDot
00389    */
00390   freqDot = (freq - *(f - 2)) / dt;
00391   A = ringInj->frequency - freq;
00392   lambda = freqDot / A;
00393 
00394   XLALPrintInfo(
00395       "Starting to asymptote to ringdown\n"
00396       "Final 'merger' frequency = %.2f Hz, fdot = %.2e Hz/s\n", 
00397       freq, freqDot); 
00398   XLALPrintInfo(
00399       "Frequency evolution fitted to freq = f_ring - A exp(-lambda t)\n"
00400       "A = %.2f, lambda = %.2e\n"
00401       "\n", A, lambda); 
00402 
00403   condt = 0;
00404   for ( n = 1; n < mergerLength + ringLength; n++ )
00405   {
00406     phase = *(phi++) = phase + LAL_TWOPI * freq * dt;
00407     freq = *(f++) = ringInj->frequency - A * exp( - n * dt * lambda );
00408     if ( freq == ringInj->frequency & condt == 0)
00409     {
00410       endMerger = n - 1.0;
00411       condt = 1.0;
00412     }
00413     if ( shift )
00414     {
00415       polDot *= exp( - lambda * dt);
00416       polarization = *(shift++) = polarization + polDot;
00417     }
00418   }
00419 
00420   /* ringdown start time */
00421   {
00422     REAL8 tRing;
00423     tRing = XLALGPSGetREAL8(&(inspiralInj->geocent_end_time));
00424     tRing += ( mergerLength + endMerger + 1.0) * dt;
00425     XLALGPSSetREAL8( &(ringInj->geocent_start_time), tRing );
00426   }
00427   XLALPrintInfo(
00428       "Ringdown start time = %d.%d\n", ringInj->geocent_start_time.gpsSeconds,
00429       ringInj->geocent_start_time.gpsNanoSeconds);
00430 
00431   /* ringdown polarization */
00432   ringInj->polarization = polarization;
00433     
00434 
00435   /*
00436    *
00437    * set amplitude for merger and ringdown
00438    *
00439    */
00440 
00441   /* From end of inspiral to start of ringdown, we fit the amplitudes with
00442    * a quadratic.  The three pieces of data we need to fit are:
00443    * 1) The initial amplitude 
00444    * 2) The initial amplitude derivative
00445    * 3) The ringdown amplitude derivative / amplitude =  1 - dampFac
00446    *
00447    * so, if A(n) = a_0 + a_1 * n + a_2 * n^2,
00448    * 
00449    * a_0 = amp
00450    * a_1 = ampDot
00451    * 
00452    *     a_1 + 2 * N * a_2
00453    * -------------------------- = (dampFac - 1)
00454    * a_0 + N * a_1  + N^2 * a_2
00455    *
00456    *       (dampFac - 1) (a_0 + N * a_1) - a_1
00457    * a_2 = ----------------------------
00458    *       (1 - dampFac) * N^2 + 2 * N 
00459    */
00460 
00461   /* the number of points */
00462   N = 2 * mergerLength;
00463 
00464   a2Plus = ((dampFac - 1) * ( ampPlus + N * ampPlusDot ) - ampPlusDot) /
00465     ( 2*N - N*N*(dampFac - 1) );
00466   a2Cross = ((dampFac - 1) * ( ampCross + N * ampCrossDot ) - ampCrossDot) /
00467     ( 2*N - N*N*(dampFac - 1) );
00468 
00469   XLALPrintInfo( "Fitting amplitude evolution to a quadratic\n"
00470       "A = a_0 + a_1 * t + a_2 * t^2\n"
00471       "For plus polarization, a_0 = %.2e, a_1 = %.2e, a_2 = %.2e\n"
00472       "For cross polarization, a_0 = %.2e, a_1 = %.2e, a_2 = %.2e\n"
00473       "\n", ampPlus, ampPlusDot / dt, a2Plus / (dt * dt),
00474       ampCross, ampCrossDot / dt, a2Cross / (dt * dt) );
00475 
00476   /* quadratic part */
00477   for ( n = 1; n < N; n++ )
00478   {
00479     *(a++) = ampPlus + ampPlusDot * n + a2Plus * n * n;
00480     *(a++) = ampCross + ampCrossDot * n + a2Cross * n * n;
00481   }
00482 
00483   /* set the final amplitudes */
00484   ampPlus = *(a - 2);
00485   ampCross = *(a - 1);
00486 
00487   for ( n = 0; n < ringLength; n++ )
00488   {
00489     ampPlus = *(a++) = ampPlus * dampFac;
00490     ampCross = *(a++) = ampCross * dampFac;
00491   }
00492  
00493   /* h0 */
00494   n = 2.0*(inputLength + mergerLength + endMerger );
00495   ampPlus = waveform->a->data->data[n];
00496   n = 2.0*(inputLength + mergerLength + endMerger ) + 1.0;
00497   ampCross = waveform->a->data->data[n];
00498   
00499   cosiotaA = ampPlus / ampCross * 
00500     (1.0 + sqrt(1-ampCross*ampCross/ampPlus/ampPlus));
00501   cosiotaB = ampPlus / ampCross * 
00502     (1.0 - sqrt(1-ampCross*ampCross/ampPlus/ampPlus));
00503 
00504   if ( cosiotaA > -1.0 && cosiotaA < 1.0)
00505     cosiota = cosiotaA;
00506   else if ( cosiotaB > -1.0 && cosiotaB < 1.0)
00507     cosiota = cosiotaB;
00508   else
00509   {
00510     XLALPrintError("inclination angle out of range\n");
00511     XLALFree( waveform->a );
00512     XLALFree( waveform->phi );
00513     XLALFree( waveform->f );
00514     XLALFree( waveform->shift );
00515     XLAL_ERROR_NULL(func,XLAL_EFAILED);
00516   }
00517  
00518   /* ringdown inclination and amplitude */ 
00519   ringInj->inclination = acos( cosiota );
00520   amp =  ampPlus / ( 1.0 + cosiota * cosiota );
00521   ringInj->amplitude = sqrt( amp*amp);
00522   
00523   /* zero out inspiral and merger if we only want to inject a ringdown*/
00524   if ( injectSignalType ==  imr_ring_inject || 
00525       strstr(inspiralInj->waveform, "KludgeRingOnly") )
00526   {
00527     for ( n = 0; n < 2.0*(inputLength + mergerLength + endMerger ); n++ )
00528     {
00529       waveform->a->data->data[n]= 0;
00530     }
00531   }
00532   ringInj = XLALDeriveRingdownParameters(ringInj);
00533 
00534   return( waveform );
00535 }
00536   
00537 static SimRingdownTable*
00538 XLALDeriveRingdownParameters(
00539     SimRingdownTable    *ringInj      /**< ringdown details to be populated */
00540     )
00541 {
00542   static const char *func = "XLALDeriveRingdownParameters";
00543   REAL4 cosiota;
00544   double splus, scross, fplus, fcross;
00545   double tDelay, tStart;
00546   
00547   LALDetector lho = lalCachedDetectors[LALDetectorIndexLHODIFF];
00548   LALDetector llo = lalCachedDetectors[LALDetectorIndexLLODIFF];
00549 
00550   /* Calculate the Ringdown parameters */
00551   XLALPrintInfo( "Calculating (approximate) parameters for the ringdown\n" );
00552 
00553   /* waveform */
00554   memcpy( ringInj->waveform, "Ringdown", 
00555       LIGOMETA_WAVEFORM_MAX * sizeof(CHAR));
00556   LALSnprintf( ringInj->coordinates, LIGOMETA_COORDINATES_MAX * sizeof(CHAR), 
00557       "EQUATORIAL");
00558 
00559   /* calculate hrss */
00560   ringInj->hrss = ringInj->amplitude * sqrt( 2 / LAL_PI / ringInj->frequency ) *
00561     pow( ( 2.0 * pow( ringInj->quality, 3.0 ) + ringInj->quality ) /
00562         ( 1.0 + 4.0 * pow ( ringInj->quality, 2 ) ) , 0.5);
00563 
00564   XLALPrintInfo( "Ringdown h_rss = %.2g\n", ringInj->hrss);
00565 
00566   /* and epsilon */
00567   ringInj->epsilon = XLALBlackHoleRingEpsilon( ringInj->frequency,
00568       ringInj->quality, ringInj->distance, ringInj->amplitude );
00569   XLALPrintInfo( "Ringdown epsilon = %.2g\n", ringInj->epsilon);
00570 
00571   /* calculate start time at sites */
00572   tStart =  XLALGPSGetREAL8(&(ringInj->geocent_start_time) );
00573   ringInj->start_time_gmst = XLALGreenwichSiderealTime( 
00574       &(ringInj->geocent_start_time), 0.0 );
00575  
00576   /* lho */
00577   tDelay = XLALTimeDelayFromEarthCenter( lho.location, ringInj->longitude,
00578       ringInj->latitude, &(ringInj->geocent_start_time) );
00579   XLALGPSSetREAL8( &(ringInj->h_start_time), tDelay + tStart );
00580   /* llo */
00581   tDelay = XLALTimeDelayFromEarthCenter( llo.location, ringInj->longitude,
00582       ringInj->latitude, &(ringInj->geocent_start_time) );
00583   XLALGPSSetREAL8( &(ringInj->l_start_time), tDelay + tStart );
00584 
00585   XLALPrintInfo( "Site start times:\n"
00586       "LHO: %d.%d GPS seconds\n"
00587       "LLO: %d.%d GPS seconds\n",
00588       ringInj->h_start_time.gpsSeconds, ringInj->h_start_time.gpsNanoSeconds,
00589       ringInj->l_start_time.gpsSeconds, ringInj->l_start_time.gpsNanoSeconds);
00590 
00591   /* compute effective distance and hrss for sites */
00592   cosiota = cos(ringInj->inclination);
00593   splus = -( 1.0 + cosiota * cosiota );
00594   scross = -2.0 * cosiota;
00595   /* LHO */
00596   XLALComputeDetAMResponse(&fplus, &fcross, lho.response, ringInj->latitude, 
00597       ringInj->longitude, ringInj->polarization, ringInj->start_time_gmst);
00598   ringInj->eff_dist_h = 2.0 * ringInj->distance;
00599   ringInj->eff_dist_h /= sqrt( splus*splus*fplus*fplus +
00600       scross*scross*fcross*fcross );
00601   ringInj->hrss_h = ringInj->amplitude * pow ( (
00602         (2*pow(ringInj->quality,3)+ringInj->quality ) * 
00603         splus*splus*fplus*fplus +
00604         2*pow(ringInj->quality,2) * splus*scross*fplus*fcross +
00605         2*pow(ringInj->quality,3) * scross*scross*fcross*fcross )
00606       /  2.0 / LAL_PI / ringInj->frequency / 
00607       ( 1.0 + 4.0 * pow ( ringInj->quality, 2 ) ) , 0.5 );
00608   XLALPrintInfo( "LHO response: F+ = %f, Fx = %f\n", fplus, fcross);
00609 
00610   /* compute hrss at LLO */
00611   /* LLO */
00612   XLALComputeDetAMResponse(&fplus, &fcross, llo.response, ringInj->longitude, 
00613       ringInj->latitude, ringInj->polarization, ringInj->start_time_gmst);
00614   ringInj->eff_dist_l = 2.0 * ringInj->distance;
00615   ringInj->eff_dist_l /= sqrt( splus*splus*fplus*fplus +
00616       scross*scross*fcross*fcross );
00617   ringInj->hrss_l = ringInj->amplitude * pow ( (
00618         (2*pow(ringInj->quality,3)+ringInj->quality ) * 
00619         splus*splus*fplus*fplus +
00620         2*pow(ringInj->quality,2) * splus*scross*fplus*fcross +
00621         2*pow(ringInj->quality,3) * scross*scross*fcross*fcross )
00622       /  2.0 / LAL_PI / ringInj->frequency / 
00623       ( 1.0 + 4.0 * pow ( ringInj->quality, 2 ) ) , 0.5 );
00624 
00625   XLALPrintInfo( "LLO response: F+ = %f, Fx = %f\n", fplus, fcross);
00626   XLALPrintInfo( "Site effective distances:\n"
00627       "LHO: %f Mpc\n"
00628       "LLO: %f Mpc\n",
00629       ringInj->eff_dist_h, ringInj->eff_dist_l);
00630 
00631   XLALPrintInfo( "Site h_rss:\n"
00632       "LHO: %g\n"
00633       "LLO: %g\n",
00634       ringInj->hrss_l, ringInj->hrss_l);
00635   return( ringInj );
00636 }
00637 

Generated on Sat Sep 6 03:06:59 2008 for LAL by  doxygen 1.5.2