/** \see See \ref Eigen_c for documentation */ void LALDSymmetricEigenValues( LALStatus *stat, REAL8Vector *values, REAL8Array *matrix ) { REAL8Vector *offDiag = NULL; /* off-diagonal line of tri-diagonalized matrix */ INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Check dimension length. All other argument testing is done by the subroutines. */ ASSERT( values, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( values->length, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); /* Allocate an off-diagonal vector for the tri-diagonal matrix. */ TRY( LALDCreateVector( stat->statusPtr, &offDiag, values->length ), stat ); /* Call the subroutines. */ LALDSymmetricToTriDiagonal2( stat->statusPtr, values, matrix, offDiag ); BEGINFAIL( stat ) { TRY( LALDDestroyVector( stat->statusPtr, &offDiag ), stat ); } ENDFAIL( stat ); LALDTriDiagonalToDiagonal2( stat->statusPtr, values, matrix, offDiag ); BEGINFAIL( stat ) { TRY( LALDDestroyVector( stat->statusPtr, &offDiag ), stat ); } ENDFAIL( stat ); /* Clean up. */ TRY( LALDDestroyVector( stat->statusPtr, &offDiag ), stat ); DETATCHSTATUSPTR( stat ); RETURN( stat ); }
void getMetric( LALStatus *stat, REAL4 g[3], REAL4 x[2], void *params ) { PtoleMetricIn *patch = params; /* avoid pesky gcc warnings */ REAL8Vector *metric = NULL; /* for output of metric */ /* Set up shop. */ INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); TRY( LALDCreateVector( stat->statusPtr, &metric, 6 ), stat ); /* Translate input. */ patch->position.longitude = x[1]; patch->position.latitude = x[0]; /* Call the real metric function. */ LALPtoleMetric( stat->statusPtr, metric, patch ); BEGINFAIL( stat ) TRY( LALDDestroyVector( stat->statusPtr, &metric ), stat ); ENDFAIL( stat ); LALProjectMetric( stat->statusPtr, metric, 0 ); BEGINFAIL( stat ) TRY( LALDDestroyVector( stat->statusPtr, &metric ), stat ); ENDFAIL( stat ); /* Translate output. */ g[1] = metric->data[2]; g[0] = metric->data[5]; g[2] = metric->data[4]; /* Clean up and leave. */ TRY( LALDDestroyVector( stat->statusPtr, &metric ), stat ); DETATCHSTATUSPTR( stat ); RETURN( stat ); } /* getMetric() */
/** * \author Creighton, T. D. * * \brief Computes a continuous waveform with frequency drift and Doppler * modulation from a hyperbolic orbital trajectory. * * This function computes a quaiperiodic waveform using the spindown and * orbital parameters in <tt>*params</tt>, storing the result in * <tt>*output</tt>. * * In the <tt>*params</tt> structure, the routine uses all the "input" * fields specified in \ref GenerateSpinOrbitCW_h, and sets all of the * "output" fields. If <tt>params-\>f</tt>=\c NULL, no spindown * modulation is performed. If <tt>params-\>oneMinusEcc</tt>\f$\not<0\f$ (a * non-hyperbolic orbit), or if * <tt>params-\>rPeriNorm</tt>\f$\times\f$<tt>params-\>angularSpeed</tt>\f$\geq1\f$ * (faster-than-light speed at periapsis), an error is returned. * * In the <tt>*output</tt> structure, the field <tt>output-\>h</tt> is * ignored, but all other pointer fields must be set to \c NULL. The * function will create and allocate space for <tt>output-\>a</tt>, * <tt>output-\>f</tt>, and <tt>output-\>phi</tt> as necessary. The * <tt>output-\>shift</tt> field will remain set to \c NULL. * * ### Algorithm ### * * For hyperbolic orbits, we combine \eqref{eq_spinorbit-tr}, * \eqref{eq_spinorbit-t}, and \eqref{eq_spinorbit-upsilon} to get \f$t_r\f$ * directly as a function of \f$E\f$: * \f{eqnarray}{ * \label{eq_tr-e3} * t_r = t_p & + & \left(\frac{r_p \sin i}{c}\right)\sin\omega\\ * & + & \frac{1}{n} \left( -E + * \left[v_p(e-1)\cos\omega + e\right]\sinh E * - \left[v_p\sqrt{\frac{e-1}{e+1}}\sin\omega\right] * [\cosh E - 1]\right) \;, * \f} * where \f$v_p=r_p\dot{\upsilon}_p\sin i/c\f$ is a normalized velocity at * periapsis and \f$n=\dot{\upsilon}_p\sqrt{(1-e)^3/(1+e)}\f$ is a normalized * angular speed for the orbit (the hyperbolic analogue of the mean * angular speed for closed orbits). For simplicity we write this as: * \f{equation}{ * \label{eq_tr-e4} * t_r = T_p + \frac{1}{n}\left( E + A\sinh E + B[\cosh E - 1] \right) \;, * \f} * * \figure{inject_hanomaly,eps,0.23,Function to be inverted to find eccentric anomaly} * * where \f$T_p\f$ is the \e observed time of periapsis passage. Thus * the key numerical procedure in this routine is to invert the * expression \f$x=E+A\sinh E+B(\cosh E - 1)\f$ to get \f$E(x)\f$. This function * is sketched to the right (solid line), along with an approximation * used for making an initial guess (dotted line), as described later. * * We note that \f$A^2-B^2<1\f$, although it approaches 1 when * \f$e\rightarrow1\f$, or when \f$v_p\rightarrow1\f$ and either \f$e=0\f$ or * \f$\omega=\pi\f$. Except in this limit, Newton-Raphson methods will * converge rapidly for any initial guess. In this limit, though, the * slope \f$dx/dE\f$ approaches zero at \f$E=0\f$, and an initial guess or * iteration landing near this point will send the next iteration off to * unacceptably large or small values. A hybrid root-finding strategy is * used to deal with this, and with the exponential behaviour of \f$x\f$ at * large \f$E\f$. * * First, we compute \f$x=x_{\pm1}\f$ at \f$E=\pm1\f$. If the desired \f$x\f$ lies * in this range, we use a straightforward Newton-Raphson root finder, * with the constraint that all guesses of \f$E\f$ are restricted to the * domain \f$[-1,1]\f$. This guarantees that the scheme will eventually find * itself on a uniformly-convergent trajectory. * * Second, for \f$E\f$ outside of this range, \f$x\f$ is dominated by the * exponential terms: \f$x\approx\frac{1}{2}(A+B)\exp(E)\f$ for \f$E\gg1\f$, and * \f$x\approx-\frac{1}{2}(A-B)\exp(-E)\f$ for \f$E\ll-1\f$. We therefore do an * \e approximate Newton-Raphson iteration on the function \f$\ln|x|\f$, * where the approximation is that we take \f$d\ln|x|/d|E|\approx1\f$. This * involves computing an extra logarithm inside the loop, but gives very * rapid convergence to high precision, since \f$\ln|x|\f$ is very nearly * linear in these regions. * * At the start of the algorithm, we use an initial guess of * \f$E=-\ln[-2(x-x_{-1})/(A-B)-\exp(1)]\f$ for \f$x<x_{-1}\f$, \f$E=x/x_{-1}\f$ for * \f$x_{-1}\leq x\leq0\f$, \f$E=x/x_{+1}\f$ for \f$0\leq x\leq x_{+1}\f$, or * \f$E=\ln[2(x-x_{+1})/(A+B)-\exp(1)]\f$ for \f$x>x_{+1}\f$. We refine this * guess until we get agreement to within 0.01 parts in part in * \f$N_\mathrm{cyc}\f$ (where \f$N_\mathrm{cyc}\f$ is the larger of the number * of wave cycles in a time \f$2\pi/n\f$, or the number of wave cycles in the * entire waveform being generated), or one part in \f$10^{15}\f$ (an order * of magnitude off the best precision possible with \c REAL8 * numbers). The latter case indicates that \c REAL8 precision may * fail to give accurate phasing, and one should consider modeling the * orbit as a set of Taylor frequency coefficients \'{a} la * <tt>LALGenerateTaylorCW()</tt>. On subsequent timesteps, we use the * previous timestep as an initial guess, which is good so long as the * timesteps are much smaller than \f$1/n\f$. * * Once a value of \f$E\f$ is found for a given timestep in the output * series, we compute the system time \f$t\f$ via \eqref{eq_spinorbit-t}, * and use it to determine the wave phase and (non-Doppler-shifted) * frequency via \eqref{eq_taylorcw-freq} * and \eqref{eq_taylorcw-phi}. The Doppler shift on the frequency is * then computed using \eqref{eq_spinorbit-upsilon} * and \eqref{eq_orbit-rdot}. We use \f$\upsilon\f$ as an intermediate in * the Doppler shift calculations, since expressing \f$\dot{R}\f$ directly in * terms of \f$E\f$ results in expression of the form \f$(e-1)/(e\cosh E-1)\f$, * which are difficult to simplify and face precision losses when * \f$E\sim0\f$ and \f$e\rightarrow1\f$. By contrast, solving for \f$\upsilon\f$ is * numerically stable provided that the system <tt>atan2()</tt> function is * well-designed. * * This routine does not account for relativistic timing variations, and * issues warnings or errors based on the criterea of * \eqref{eq_relativistic-orbit} in \ref LALGenerateEllipticSpinOrbitCW(). */ void LALGenerateHyperbolicSpinOrbitCW( LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params ) { UINT4 n, i; /* number of and index over samples */ UINT4 nSpin = 0, j; /* number of and index over spindown terms */ REAL8 t, dt, tPow; /* time, interval, and t raised to a power */ REAL8 phi0, f0, twopif0; /* initial phase, frequency, and 2*pi*f0 */ REAL8 f, fPrev; /* current and previous values of frequency */ REAL4 df = 0.0; /* maximum difference between f and fPrev */ REAL8 phi; /* current value of phase */ REAL8 vDotAvg; /* nomalized orbital angular speed */ REAL8 vp; /* projected speed at periapsis */ REAL8 upsilon, argument; /* true anomaly, and argument of periapsis */ REAL8 eCosOmega; /* eccentricity * cosine of argument */ REAL8 tPeriObs; /* time of observed periapsis */ REAL8 spinOff; /* spin epoch - orbit epoch */ REAL8 x; /* observed ``mean anomaly'' */ REAL8 xPlus, xMinus; /* limits where exponentials dominate */ REAL8 dx, dxMax; /* current and target errors in x */ REAL8 a, b; /* constants in equation for x */ REAL8 ecc; /* orbital eccentricity */ REAL8 eccMinusOne, eccPlusOne; /* ecc - 1 and ecc + 1 */ REAL8 e; /* hyperbolic anomaly */ REAL8 sinhe, coshe; /* sinh of e, and cosh of e minus 1 */ REAL8 *fSpin = NULL; /* pointer to Taylor coefficients */ REAL4 *fData; /* pointer to frequency data */ REAL8 *phiData; /* pointer to phase data */ INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Make sure parameter and output structures exist. */ ASSERT( params, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); ASSERT( output, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); /* Make sure output fields don't exist. */ ASSERT( !( output->a ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->f ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->phi ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->shift ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); /* If Taylor coeficients are specified, make sure they exist. */ if ( params->f ) { ASSERT( params->f->data, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); nSpin = params->f->length; fSpin = params->f->data; } /* Set up some constants (to avoid repeated calculation or dereferencing), and make sure they have acceptable values. */ eccMinusOne = -params->oneMinusEcc; ecc = 1.0 + eccMinusOne; eccPlusOne = 2.0 + eccMinusOne; if ( eccMinusOne <= 0.0 ) { ABORT( stat, GENERATESPINORBITCWH_EECC, GENERATESPINORBITCWH_MSGEECC ); } vp = params->rPeriNorm*params->angularSpeed; vDotAvg = params->angularSpeed *sqrt( eccMinusOne*eccMinusOne*eccMinusOne/eccPlusOne ); n = params->length; dt = params->deltaT; f0 = fPrev = params->f0; if ( vp >= 1.0 ) { ABORT( stat, GENERATESPINORBITCWH_EFTL, GENERATESPINORBITCWH_MSGEFTL ); } if ( vp <= 0.0 || dt <= 0.0 || f0 <= 0.0 || vDotAvg <= 0.0 || n == 0 ) { ABORT( stat, GENERATESPINORBITCWH_ESGN, GENERATESPINORBITCWH_MSGESGN ); } /* Set up some other constants. */ twopif0 = f0*LAL_TWOPI; phi0 = params->phi0; argument = params->omega; a = vp*eccMinusOne*cos( argument ) + ecc; b = -vp*sqrt( eccMinusOne/eccPlusOne )*sin( argument ); eCosOmega = ecc*cos( argument ); if ( n*dt*vDotAvg > LAL_TWOPI ) dxMax = 0.01/( f0*n*dt ); else dxMax = 0.01/( f0*LAL_TWOPI/vDotAvg ); if ( dxMax < 1.0e-15 ) { dxMax = 1.0e-15; #ifndef NDEBUG LALWarning( stat, "REAL8 arithmetic may not have sufficient" " precision for this orbit" ); #endif } #ifndef NDEBUG if ( lalDebugLevel & LALWARNING ) { REAL8 tau = n*dt; if ( tau > LAL_TWOPI/vDotAvg ) tau = LAL_TWOPI/vDotAvg; if ( f0*tau*vp*vp*ecc/eccPlusOne > 0.25 ) LALWarning( stat, "Orbit may have significant relativistic" " effects that are not included" ); } #endif /* Compute offset between time series epoch and observed periapsis, and betweem true periapsis and spindown reference epoch. */ tPeriObs = (REAL8)( params->orbitEpoch.gpsSeconds - params->epoch.gpsSeconds ); tPeriObs += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->epoch.gpsNanoSeconds ); tPeriObs += params->rPeriNorm*sin( params->omega ); spinOff = (REAL8)( params->orbitEpoch.gpsSeconds - params->spinEpoch.gpsSeconds ); spinOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->spinEpoch.gpsNanoSeconds ); /* Determine bounds of hybrid root-finding algorithm, and initial guess for e. */ xMinus = 1.0 + a*sinh( -1.0 ) + b*cosh( -1.0 ) - b; xPlus = -1.0 + a*sinh( 1.0 ) + b*cosh( 1.0 ) - b; x = -vDotAvg*tPeriObs; if ( x < xMinus ) e = -log( -2.0*( x - xMinus )/( a - b ) - exp( 1.0 ) ); else if ( x <= 0 ) e = x/xMinus; else if ( x <= xPlus ) e = x/xPlus; else e = log( 2.0*( x - xPlus )/( a + b ) - exp( 1.0 ) ); sinhe = sinh( e ); coshe = cosh( e ) - 1.0; /* Allocate output structures. */ if ( ( output->a = (REAL4TimeVectorSeries *) LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) { ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->a, 0, sizeof(REAL4TimeVectorSeries) ); if ( ( output->f = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->f, 0, sizeof(REAL4TimeSeries) ); if ( ( output->phi = (REAL8TimeSeries *) LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->phi, 0, sizeof(REAL8TimeSeries) ); /* Set output structure metadata fields. */ output->position = params->position; output->psi = params->psi; output->a->epoch = output->f->epoch = output->phi->epoch = params->epoch; output->a->deltaT = n*params->deltaT; output->f->deltaT = output->phi->deltaT = params->deltaT; output->a->sampleUnits = lalStrainUnit; output->f->sampleUnits = lalHertzUnit; output->phi->sampleUnits = lalDimensionlessUnit; snprintf( output->a->name, LALNameLength, "CW amplitudes" ); snprintf( output->f->name, LALNameLength, "CW frequency" ); snprintf( output->phi->name, LALNameLength, "CW phase" ); /* Allocate phase and frequency arrays. */ LALSCreateVector( stat->statusPtr, &( output->f->data ), n ); BEGINFAIL( stat ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); LALDCreateVector( stat->statusPtr, &( output->phi->data ), n ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); /* Allocate and fill amplitude array. */ { CreateVectorSequenceIn in; /* input to create output->a */ in.length = 2; in.vectorLength = 2; LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); output->a->data->data[0] = output->a->data->data[2] = params->aPlus; output->a->data->data[1] = output->a->data->data[3] = params->aCross; } /* Fill frequency and phase arrays. */ fData = output->f->data->data; phiData = output->phi->data->data; for ( i = 0; i < n; i++ ) { x = vDotAvg*( i*dt - tPeriObs ); /* Use approximate Newton-Raphson method on ln|x| if |x| > 1. */ if ( x < xMinus ) { x = log( -x ); while ( fabs( dx = log( e - a*sinhe - b*coshe ) - x ) > dxMax ) { e += dx; sinhe = sinh( e ); coshe = cosh( e ) - 1.0; } } else if ( x > xPlus ) { x = log( x ); while ( fabs( dx = log( -e + a*sinhe + b*coshe ) - x ) > dxMax ) { e -= dx; sinhe = sinh( e ); coshe = cosh( e ) - 1.0; } } /* Use ordinary Newton-Raphson method on x if |x| <= 1. */ else { while ( fabs( dx = -e + a*sinhe + b*coshe - x ) > dxMax ) { e -= dx/( -1.0 + a*coshe + a + b*sinhe ); if ( e < -1.0 ) e = -1.0; else if ( e > 1.0 ) e = 1.0; sinhe = sinh( e ); coshe = cosh( e ) - 1.0; } } /* Compute source emission time, phase, and frequency. */ phi = t = tPow = ( ecc*sinhe - e )/vDotAvg + spinOff; f = 1.0; for ( j = 0; j < nSpin; j++ ) { f += fSpin[j]*tPow; phi += fSpin[j]*( tPow*=t )/( j + 2.0 ); } /* Appy frequency Doppler shift. */ upsilon = 2.0*atan2( sqrt( eccPlusOne*coshe ), sqrt( eccMinusOne*( coshe + 2.0 ) ) ); f *= f0 / ( 1.0 + vp*( cos( argument + upsilon ) + eCosOmega ) /eccPlusOne ); phi *= twopif0; if ( fabs( f - fPrev ) > df ) df = fabs( f - fPrev ); *(fData++) = fPrev = f; *(phiData++) = phi + phi0; } /* Set output field and return. */ params->dfdt = df*dt; DETATCHSTATUSPTR( stat ); RETURN( stat ); }
/** * \author Jones D. I., Owen, B. J., and Whitbeck, D. M. * \date 2001-2005 * \brief Computes metric components for a pulsar search in the ``Ptolemaic'' * approximation; both the Earth's spin and orbit are included. * * ### Description ### * * This function computes metric components in a way that yields results * very similar to those of LALCoherentMetric() called with the * output of LALTBaryPtolemaic(). The CPU demand, however, is less, * and the metric components can be expressed analytically, lending * themselves to better understanding of the behavior of the parameter * space. For short durations (less than about 70000 seconds or 20 hours) a * Taylor series expansion is used to improve the accuracy with which several * terms are computed. * * ### Algorithm ### * * For speed and checking reasons, a minimum of numerical computation is * involved. The metric components can be expressed analytically (though not * tidily) in terms of trig functions and are much too large to be worth * writing down here. More comprehensive documentation on the derivation of * the metric components can be found in the pulgroup CVS archive as * docs/S2/FDS/Isolated/ptolemetric.tex. Jones, Owen, and Whitbeck will write * up the calculation and some tests as a journal article. * * The function LALGetEarthTimes() is used to calculate the spin and * rotational phase of the Earth at the beginning of the observation. * * On output, the \a metric->data is arranged with the same indexing * scheme as in LALCoherentMetric(). The order of the parameters is * \f$(f_0, \alpha, \delta)\f$. * * ### Notes ### * * The analytic metric components were derived separately by Jones and * Whitbeck (and partly by Owen) and found to agree. Also, the output of this * function has been compared against that of the function combination * (CoherentMetric + TDBaryPtolemaic), which is a numerical implementation of * the Ptolemaic approximation, and found to agree up to the fourth * significant figure or better. Even using DTEphemeris.c for the true * Earth's orbit only causes errors in the metric components of order 10\%, * with (so far) no noticeable effect on the sky coverage. * * At present, only one spindown parameter can be included with the sky * location. The code contains (commented out) expressions for * spindown-spindown metric components for an arbitrary number of spindowns, * but the (commented out) spindown-sky components neglect orbital motion. * * A separate routine, XLALSpindownMetric(), has been added to compute the * metric for multiple spindowns but for fixed sky position, suitable for * e.g. directed searches. */ void LALPtoleMetric( LALStatus *status, REAL8Vector *metric, PtoleMetricIn *input ) { INT2 j; /* Loop counters */ /*REAL8 temp1, temp2, temp3, temp4; dummy variables */ REAL8 R_o, R_s; /* Amplitude of daily/yearly modulation, s */ REAL8 lat, lon; /* latitude and longitude of detector site */ REAL8 omega_s, omega_o; /* Ang freq of daily/yearly modulation, rad/s */ REAL8 phi_o_i; /* Phase of Earth's orbit at begining (epoch) */ REAL8 phi_o_f; /* Phase of Earth's orbit at end (epoch+duration) */ REAL8 phi_s_i; /* Phase of Earth's spin at beginning (epoch) */ REAL8 phi_s_f; /* Phase of Earth's spin at end (epoch+duration) */ REAL8 cos_l, sin_l, sin_2l; /* Trig fns for detector lattitude */ REAL8 cos_i, sin_i; /* Trig fns for inclination of Earth's spin */ REAL8 cos_a, sin_a, sin_2a; /* Trig fns for source RA */ REAL8 cos_d, sin_d, sin_2d; /* Trig fns for source declination */ REAL8 A[22]; /* Array of intermediate quantities */ REAL8 B[10]; /* Array of intermediate quantities */ REAL8 Is[5]; /* Array of integrals needed for spindown.*/ UINT2 dim; /* Dimension of parameter space */ PulsarTimesParamStruc zero_phases; /* Needed to calculate phases of spin*/ /* and orbit at t_gps =0 */ REAL8Vector *big_metric; /* 10-dim metric in (phi,f,a,d,f1) for internal use */ REAL8 T; /* Duration of observation */ REAL8 f; /* Frequency */ /* Some useful short-hand notations involving the orbital phase: */ REAL8 D_p_o; REAL8 sin_p_o; REAL8 cos_p_o; REAL8 D_sin_p_o; REAL8 D_cos_p_o; REAL8 D_sin_2p_o; REAL8 D_cos_2p_o; /* Some useful short-hand notations involving the spin phase: */ REAL8 D_p_s; REAL8 sin_p_s; REAL8 cos_p_s; REAL8 D_sin_p_s; REAL8 D_cos_p_s; REAL8 D_sin_2p_s; REAL8 D_cos_2p_s; /* Some useful short-hand notations involving spin and orbital phases: */ REAL8 D_sin_p_o_plus_s; REAL8 D_sin_p_o_minus_s; REAL8 D_cos_p_o_plus_s; REAL8 D_cos_p_o_minus_s; /* Quantities related to the short-time Tatlor expansions : */ REAL8 D_p_o_crit; /* The orbital phase BELOW which series used. */ REAL8 sum1, sum2, sum3; REAL8 next1, next2, next3; INT2 j_max; /* Number of terms in series */ INITSTATUS(status); /* Check for valid input structure. */ ASSERT( input != NULL, status, PTOLEMETRICH_ENULL, PTOLEMETRICH_MSGENULL ); /* Check for valid sky position. */ ASSERT( input->position.system == COORDINATESYSTEM_EQUATORIAL, status, PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM ); ASSERT( input->position.longitude >= 0, status, PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM ); ASSERT( input->position.longitude <= LAL_TWOPI, status, PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM ); ASSERT( abs(input->position.latitude) <= LAL_PI_2, status, PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM ); /* Check for valid maximum frequency. */ ASSERT( input->maxFreq > MIN_MAXFREQ, status, PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM ); /* Check for valid detector location. */ ASSERT( abs(input->site->frDetector.vertexLatitudeRadians) <= LAL_PI_2, status, PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM ); ASSERT( abs(input->site->frDetector.vertexLongitudeRadians) <= LAL_PI, status, PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM ); if( input->spindown ) dim = 2+input->spindown->length; else dim = 2; ASSERT( metric != NULL, status, PTOLEMETRICH_ENULL, PTOLEMETRICH_MSGENULL ); ASSERT( metric->data != NULL, status, PTOLEMETRICH_ENULL, PTOLEMETRICH_MSGENULL ); ASSERT( metric->length == (UINT4)(dim+1)*(dim+2)/2, status, PTOLEMETRICH_EDIM, PTOLEMETRICH_MSGEDIM ); /* A bigger metric that includes phase for internal use only: */ /* Apart from normalization, this is just the information matrix. */ big_metric = NULL; LALDCreateVector( status, &big_metric, (dim+2)*(dim+3)/2); /* Detector location: */ lat = input->site->frDetector.vertexLatitudeRadians; lon = input->site->frDetector.vertexLongitudeRadians; cos_l = cos(lat); sin_l = sin(lat); sin_2l = sin(2*lat); /* Inclination of Earth's spin-axis to ecliptic */ sin_i = sin(LAL_IEARTH); cos_i = cos(LAL_IEARTH); /* Radii of circular motions in seconds: */ R_s = LAL_REARTH_SI / LAL_C_SI; R_o = LAL_AU_SI / LAL_C_SI; /* To switch off orbital motion uncomment this: */ /* R_o = 0.0; */ /* To switch off spin motion uncomment this: */ /* R_s = 0.0; */ /* Angular velocities: */ omega_s = LAL_TWOPI / LAL_DAYSID_SI; omega_o = LAL_TWOPI / LAL_YRSID_SI; /* Duration of observation */ T = input->duration; /* Frequency: */ f = input->maxFreq; /* Source RA: */ sin_a = sin(input->position.longitude); cos_a = cos(input->position.longitude); sin_2a = sin(2*(input->position.longitude)); /* Source declination: */ sin_d = sin(input->position.latitude); cos_d = cos(input->position.latitude); sin_2d = sin(2*(input->position.latitude)); /* Calculation of phases of spin and orbit at start: */ zero_phases.epoch.gpsSeconds = input->epoch.gpsSeconds; zero_phases.epoch.gpsNanoSeconds = input->epoch.gpsNanoSeconds; LALGetEarthTimes( status, &zero_phases); phi_o_i = -zero_phases.tAutumn/LAL_YRSID_SI*LAL_TWOPI; phi_s_i = -zero_phases.tMidnight/LAL_DAYSID_SI*LAL_TWOPI + lon; /* Quantities involving the orbital phase: */ phi_o_f = phi_o_i + omega_o*T; D_p_o = omega_o*T; sin_p_o = sin(phi_o_f); cos_p_o = cos(phi_o_f); D_sin_p_o = (sin(phi_o_f) - sin(phi_o_i))/D_p_o; D_cos_p_o = (cos(phi_o_f) - cos(phi_o_i))/D_p_o; D_sin_2p_o = (sin(2*phi_o_f) - sin(2*phi_o_i))/2.0/D_p_o; D_cos_2p_o = (cos(2*phi_o_f) - cos(2*phi_o_i))/2.0/D_p_o; /* Quantities involving the spin phase: */ phi_s_f = phi_s_i + omega_s*T; D_p_s = omega_s*T; sin_p_s = sin(phi_s_f); cos_p_s = cos(phi_s_f); D_sin_p_s = (sin(phi_s_f) - sin(phi_s_i))/D_p_s; D_cos_p_s = (cos(phi_s_f) - cos(phi_s_i))/D_p_s; D_sin_2p_s = (sin(2*phi_s_f) - sin(2*phi_s_i))/2.0/D_p_s; D_cos_2p_s = (cos(2*phi_s_f) - cos(2*phi_s_i))/2.0/D_p_s; /* Some mixed quantities: */ D_sin_p_o_plus_s = (sin(phi_o_f+phi_s_f) - sin(phi_o_i+phi_s_i))/(D_p_o + D_p_s); D_sin_p_o_minus_s = (sin(phi_o_f-phi_s_f) - sin(phi_o_i-phi_s_i))/(D_p_o - D_p_s); D_cos_p_o_plus_s = (cos(phi_o_f+phi_s_f) - cos(phi_o_i+phi_s_i))/(D_p_o + D_p_s); D_cos_p_o_minus_s = (cos(phi_o_f-phi_s_f) - cos(phi_o_i-phi_s_i))/(D_p_o - D_p_s); /***************************************************************/ /* Small D_p_o overwrite: */ /***************************************************************/ j_max = 7; D_p_o_crit = 1.4e-2; /* This corresponds to about 70000 seconds */ sum1 = next1 = D_p_o/2.0; sum2 = next2 = D_p_o/3.0/2.0; sum3 = next3 = D_p_o; for(j=1; j<=j_max; j++) { next1 *= -pow(D_p_o,2.0)/(2.0*j+1.0)/(2.0*j+2.0); sum1 += next1; next2 *= -pow(D_p_o,2.0)/(2.0*j+2.0)/(2.0*j+3.0); sum2 += next2; next3 *= -pow(2.0*D_p_o,2.0)/(2.0*j+1.0)/(2.0*j+2.0); sum3 += next3; } if(D_p_o < D_p_o_crit) { D_sin_p_o = sin(phi_o_f)*sum1 + cos(phi_o_f)*sin(D_p_o)/D_p_o; D_cos_p_o = cos(phi_o_f)*sum1 - sin(phi_o_f)*sin(D_p_o)/D_p_o; D_sin_2p_o = sin(2.0*phi_o_f)*sum3 + cos(2.0*phi_o_f)*sin(2.0*D_p_o)/2.0/D_p_o; D_cos_2p_o = cos(2.0*phi_o_f)*sum3 - sin(2.0*phi_o_f)*sin(2.0*D_p_o)/2.0/D_p_o; } /****************************************************************/ /* The A[i] quantities: */ A[1] = R_o*D_sin_p_o + R_s*cos_l*D_sin_p_s; A[2] = R_o*cos_i*D_cos_p_o + R_s*cos_l*D_cos_p_s; A[3] = -R_o*sin_i*D_cos_p_o + R_s*sin_l; A[4] = R_o*(sin_p_o/D_p_o + D_cos_p_o/D_p_o); A[5] = R_s*(sin_p_s/D_p_s + D_cos_p_s/D_p_s); A[6] = R_o*(-cos_p_o/D_p_o + D_sin_p_o/D_p_o); /* Special overwrite for A4 and A6: *********************/ if(D_p_o < D_p_o_crit) { A[4] = R_o*(cos(phi_o_f)*sum1/D_p_o + sin(phi_o_f)*sum2); A[6] = R_o*(sin(phi_o_f)*sum1/D_p_o - cos(phi_o_f)*sum2); } /***********************************************************/ A[7] = R_s*(-cos_p_s/D_p_s + D_sin_p_s/D_p_s); A[8] = R_o*R_o*(1 + D_sin_2p_o); A[9] = R_o*R_s*(D_sin_p_o_minus_s + D_sin_p_o_plus_s); A[10] = R_s*R_s*(1 + D_sin_2p_s); A[11] = R_o*R_o*D_cos_2p_o; A[12] = R_o*R_s*(-D_cos_p_o_minus_s + D_cos_p_o_plus_s); A[13] = R_o*R_s*(D_cos_p_o_minus_s + D_cos_p_o_plus_s); A[14] = R_s*R_s*D_cos_2p_s; A[15] = R_o*R_o*(1 - D_sin_2p_o); A[16] = R_o*R_s*(D_sin_p_o_minus_s - D_sin_p_o_plus_s); A[17] = R_s*R_s*(1 - D_sin_2p_s); A[18] = R_o*R_s*D_sin_p_o; A[19] = R_s*R_s*D_sin_p_s; A[20] = R_o*R_s*D_cos_p_o; A[21] = R_s*R_s*D_cos_p_s; /* The B[i] quantities: */ B[1] = A[4] + A[5]*cos_l; B[2] = A[6]*cos_i + A[7]*cos_l; B[3] = A[6]*sin_i + R_s*sin_l/2; B[4] = A[8] + 2*A[9]*cos_l + A[10]*cos_l*cos_l; B[5] = A[11]*cos_i + A[12]*cos_l + A[13]*cos_i*cos_l + A[14]*cos_l*cos_l; B[6] = A[15]*cos_i*cos_i +2*A[16]*cos_i*cos_l + A[17]*cos_l*cos_l; B[7] = -A[11]*sin_i + 2*A[18]*sin_l - A[13]*sin_i*cos_l + A[19]*sin_2l; B[8] = A[15]*sin_i*cos_i - 2*A[20]*cos_i*sin_l + A[16]*sin_i*cos_l - A[21]*sin_2l; B[9] = A[15]*sin_i*sin_i - 4*A[20]*sin_i*sin_l + 2*R_s*R_s*sin_l*sin_l; /* The spindown integrals. */ /* orbital t^2 cos */ Is[1] = (2*sin(phi_o_i) + 2*omega_o*T*cos_p_o + (-2 + pow(omega_o*T,2))*sin_p_o)/pow(omega_o*T,3); /* spin t^2 cos */ Is[2] = (2*sin(phi_s_i) + 2*omega_s*T*cos_p_s + (-2 + pow(omega_s*T,2))*sin_p_s)/pow(omega_s*T,3); /* orbital t^2 sin */ Is[3] = (-2*cos(phi_o_i) + 2*omega_o*T*sin_p_o - (-2 + pow(omega_o*T,2))*cos_p_o)/pow(omega_o*T,3); /*spin t^2 sin */ Is[4] = (-2*cos(phi_s_i) + 2*omega_s*T*sin_p_s - (-2 + pow(omega_s*T,2))*cos_p_s)/pow(omega_s*T,3); /* The 4-dim metric components: */ /* g_pp = */ big_metric->data[0] = 1; /* g_pf = */ big_metric->data[1] = LAL_PI*T; /* g_pa = */ big_metric->data[3] = -LAL_TWOPI*f*cos_d*(A[1]*sin_a + A[2]*cos_a); /* g_pd = */ big_metric->data[6] = LAL_TWOPI*f*(-A[1]*sin_d*cos_a + A[2]*sin_d*sin_a + A[3]*cos_d); /* g_ff = */ big_metric->data[2] = pow(LAL_TWOPI*T, 2)/3; /* g_fa = */ big_metric->data[4] = pow(LAL_TWOPI,2)*f*cos_d*T*(-B[1]*sin_a + B[2]*cos_a); /* g_fd = */ big_metric->data[7] = pow(LAL_TWOPI,2)*f*T*(-B[1]*sin_d*cos_a - B[2]*sin_d*sin_a + B[3]*cos_d); /* g_aa = */ big_metric->data[5] = 2*pow(LAL_PI*f*cos_d,2) * (B[4]*sin_a*sin_a + B[5]*sin_2a + B[6]*cos_a*cos_a); /* g_ad = */ big_metric->data[8] = 2*pow(LAL_PI*f,2)*cos_d*(B[4]*sin_a*cos_a*sin_d - B[5]*sin_a*sin_a*sin_d -B[7]*sin_a*cos_d + B[5]*cos_a*cos_a*sin_d - B[6]*sin_a*cos_a*sin_d +B[8]*cos_a*cos_d); /* g_dd = */ big_metric->data[9] = 2*pow(LAL_PI*f,2)*(B[4]*pow(cos_a*sin_d,2) + B[6]*pow(sin_a*sin_d,2) +B[9]*pow(cos_d,2) - B[5]*sin_2a*pow(sin_d,2) - B[8]*sin_a*sin_2d -B[7]*cos_a*sin_2d); /*The spindown components*/ if(dim==3) { /* g_p1 = */ big_metric->data[10] = T*LAL_PI*f*T/3; /* g_f1= */ big_metric->data[11]= T*pow(LAL_PI*T,2)*f/2; /* g_a1 = */ big_metric->data[12] = T*2*pow(LAL_PI*f,2)*T*(-cos_d*sin_a*(R_o*Is[1] + R_s*cos_l*Is[2])+ cos_d*cos_a*(R_o*cos_i*Is[3] + R_s*cos_l*Is[4])); /* g_d1 = */ big_metric->data[13] = T*2*pow(LAL_PI*f,2)*T*(-sin_d*cos_a*(R_o*Is[1] + R_s*cos_l*Is[2])- sin_d*sin_a*(R_o*cos_i*Is[3] + R_s*cos_l*Is[4]) + cos_d*(R_o*sin_i*Is[3] + R_s*sin_l/3)); /* g_11 = */ big_metric->data[14] = T*T*pow(LAL_PI*f*T,2)/5; } /**********************************************************/ /* Spin-down stuff not consistent with rest of code - don't uncomment! */ /* Spindown-spindown metric components, before projection if( input->spindown ) for (j=1; j<=dim-2; j++) for (k=1; k<=j; k++) metric->data[(k+2)+(j+2)*(j+3)/2] = pow(LAL_TWOPI*input->maxFreq *input->duration,2)/(j+2)/(k+2)/(j+k+3); Spindown-angle metric components, before projection if( input->spindown ) for (j=1; j<=(INT4)input->spindown->length; j++) { Spindown-RA: 1+(j+2)*(j+3)/2 metric->data[1+(j+2)*(j+3)/2] = 0; temp1=0; temp2=0; for (k=j+1; k>=0; k--) { metric->data[1+(j+2)*(j+3)/2] += pow(-1,(k+1)/2)*factrl(j+1) /factrl(j+1-k)/pow(D_p_s,k)*((k%2)?sin_p_s:cos_p_s); metric->data[1+(j+2)*(j+3)/2] += pow(-1,j/2)/pow(D_p_s,j+1)*factrl(j+1) *((j%2)?cos(phi_s_i):sin(phi_s_i)); metric->data[1+(j+2)*(j+3)/2] -= (cos_p_s-cos(phi_s_i))/(j+2); metric->data[1+(j+2)*(j+3)/2] *= -pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_l *cos_d/omega_s/(j+1); temp1+=pow(-1,(k+1)/2)*factrl(j+1) /factrl(j+1-k)/pow(D_p_s,k)*((k%2)?sin_p_s:cos_p_s); temp2+=pow(-1,(k+1)/2)*factrl(j+1) /factrl(j+1-k)/pow(D_p_o,k)*((k%2)?sin_p_o:cos_p_o); } temp1+=pow(-1,j/2)/pow(D_p_s,j+1)*factrl(j+1) *((j%2)?cos(phi_s_i):sin(phi_s_i)); temp2+=pow(-1,j/2)/pow(D_p_o,j+1)*factrl(j+1) *((j%2)?cos(phi_o_i):sin(phi_o_i)); temp1-=(cos_p_s-cos(phi_s_i))/(j+2); temp2-=(cos_p_o-cos(phi_o_i))/(j+2); temp1*=-pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_l *cos_d/omega_s/(j+1); temp2*=-pow(LAL_TWOPI*input->maxFreq,2)*R_o*cos_i *cos_d/omega_o/(j+1); metric->data[1+(j+2)*(j+3)/2]+=temp1+temp2; Spindown-dec: 2+(j+2)*(j+3)/2 metric->data[2+(j+2)*(j+3)/2] = 0; temp3=0; temp4=0; for (k=j+1; k>=0; k--) { metric->data[2+(j+2)*(j+3)/2] -= pow(-1,k/2)*factrl(j+1)/factrl(j+1-k) /pow(D_p_s,k)*((k%2)?cos_p_s:sin_p_s); metric->data[2+(j+2)*(j+3)/2] += pow(-1,(j+1)/2)/pow(D_p_s,j+1) *factrl(j+1)*((j%2)?sin(phi_s_i):cos(phi_s_i)); metric->data[2+(j+2)*(j+3)/2] += (sin_p_s-sin(phi_s_i))/(j+2); metric->data[2+(j+2)*(j+3)/2] *= pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_l *sin_d/omega_s/(j+1); } for( j... ) temp3-=pow(-1,k/2)*factrl(j+1)/factrl(j+1-k) /pow(D_p_s,k)*((k%2)?cos_p_s:sin_p_s); temp4-=pow(-1,k/2)*factrl(j+1)/factrl(j+1-k) /pow(D_p_o,k)*((k%2)?cos_p_o:sin_p_o); } temp3+=pow(-1,(j+1)/2)/pow(D_p_s,j+1) *factrl(j+1)*((j%2)?sin(phi_s_i):cos(phi_s_i)); temp4+=pow(-1,(j+1)/2)/pow(D_p_o,j+1) *factrl(j+1)*((j%2)?sin(phi_o_i):cos(phi_o_i)); temp3+=(sin_p_s-sin(phi_s_i))/(j+2); temp4+=(sin_p_o-sin(phi_o_i))/(j+2); temp3*=pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_l *sin_d/omega_s/(j+1); temp4*=pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_i *sin_d/omega_o/(j+1); metric->data[2+(j+2)*(j+3)/2]=temp3+temp4; } f0-spindown : 0+(j+2)*(j+3)/2 if( input->spindown ) for (j=1; j<=dim-2; j++) metric->data[(j+2)*(j+3)/2] = 2*pow(LAL_PI,2)*input->maxFreq *pow(input->duration,2)/(j+2)/(j+3);*/ /*************************************************************/ /* Project down to 4-dim metric: */ /*f-f component */ metric->data[0] = big_metric->data[2] - big_metric->data[1]*big_metric->data[1]/big_metric->data[0]; /*f-a component */ metric->data[1] = big_metric->data[4] - big_metric->data[1]*big_metric->data[3]/big_metric->data[0]; /*a-a component */ metric->data[2] = big_metric->data[5] - big_metric->data[3]*big_metric->data[3]/big_metric->data[0]; /*f-d component */ metric->data[3] = big_metric->data[7] - big_metric->data[6]*big_metric->data[1]/big_metric->data[0]; /*a-d component */ metric->data[4] = big_metric->data[8] - big_metric->data[6]*big_metric->data[3]/big_metric->data[0]; /*d-d component */ metric->data[5] = big_metric->data[9] - big_metric->data[6]*big_metric->data[6]/big_metric->data[0]; if(dim==3) { /*f-f1 component */ metric->data[6] = big_metric->data[11] - big_metric->data[1]*big_metric->data[10]/big_metric->data[0]; /*a-f1 component */ metric->data[7] = big_metric->data[12] - big_metric->data[3]*big_metric->data[10]/big_metric->data[0]; /*d-f1 component */ metric->data[8] = big_metric->data[13] - big_metric->data[6]*big_metric->data[10]/big_metric->data[0]; /* f1-f1 component */ metric->data[9] = big_metric->data[14] - big_metric->data[10]*big_metric->data[10]/big_metric->data[0]; } LALDDestroyVector( status, &big_metric ); /* All done */ RETURN( status ); } /* LALPtoleMetric() */
int main (int argc, char *argv[]) { enum {ArraySize = 10}; static LALStatus status; static REAL4Vector *x; static REAL4Vector *y; static REAL8Vector *xx; static REAL8Vector *yy; SInterpolateOut sintout; SInterpolatePar sintpar; DInterpolateOut dintout; DInterpolatePar dintpar; int i; ParseOptions (argc, argv); LALSCreateVector (&status, &x, ArraySize); TestStatus (&status, CODES(0), 1); LALSCreateVector (&status, &y, ArraySize); TestStatus (&status, CODES(0), 1); LALDCreateVector (&status, &xx, ArraySize); TestStatus (&status, CODES(0), 1); LALDCreateVector (&status, &yy, ArraySize); TestStatus (&status, CODES(0), 1); if ( verbose ) printf ("Initial data:\n"); if ( verbose ) printf ("y = P(x) = 7 - 8x + 2x^2 + 2x^3 - x^4\n"); if ( verbose ) printf ("-----------------\n"); if ( verbose ) printf ("x\ty\n"); if ( verbose ) printf ("=================\n"); for (i = 0; i < ArraySize; ++i) { REAL4 xi = x->data[i] = xx->data[i] = i*i; y->data[i] = yy->data[i] = 7 + xi*(-8 + xi*(2 + xi*(2 - xi))); if ( verbose ) printf ("%.0f\t%.0f\n", x->data[i], y->data[i]); } if ( verbose ) printf ("-----------------\n"); if ( verbose ) printf ("\nInterpolate to x = 0.3:\n"); if ( verbose ) printf ("---------------------------------\n"); if ( verbose ) printf ("order\ty\t\tdy\n"); if ( verbose ) printf ("=================================\n"); sintpar.x = x->data; sintpar.y = y->data; dintpar.x = xx->data; dintpar.y = yy->data; for (i = 2; i < ArraySize; ++i) { sintpar.n = i; dintpar.n = i; LALSPolynomialInterpolation (&status, &sintout, 0.3, &sintpar); TestStatus (&status, CODES(0), 1); LALDPolynomialInterpolation (&status, &dintout, 0.3, &dintpar); TestStatus (&status, CODES(0), 1); if ( verbose ) printf ("%d\t%f\t%f\t%f\t%f\n", i - 1, sintout.y, sintout.dy, dintout.y, dintout.dy); } if ( verbose ) printf ("---------------------------------\n"); if ( verbose ) printf ("\nExtrapolate to x = -0.3:\n"); if ( verbose ) printf ("---------------------------------\n"); if ( verbose ) printf ("order\ty\t\tdy\n"); if ( verbose ) printf ("=================================\n"); sintpar.x = x->data; sintpar.y = y->data; dintpar.x = xx->data; dintpar.y = yy->data; for (i = 2; i < ArraySize; ++i) { sintpar.n = i; dintpar.n = i; LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar); TestStatus (&status, CODES(0), 1); LALDPolynomialInterpolation (&status, &dintout, -0.3, &dintpar); TestStatus (&status, CODES(0), 1); if ( verbose ) printf ("%d\t%f\t%f\t%f\t%f\n", i - 1, sintout.y, sintout.dy, dintout.y, dintout.dy); } if ( verbose ) printf ("---------------------------------\n"); LALSDestroyVector (&status, &x); TestStatus (&status, CODES(0), 1); LALSDestroyVector (&status, &y); TestStatus (&status, CODES(0), 1); LALDDestroyVector (&status, &xx); TestStatus (&status, CODES(0), 1); LALDDestroyVector (&status, &yy); TestStatus (&status, CODES(0), 1); LALCheckMemoryLeaks (); LALSCreateVector (&status, &x, ArraySize); TestStatus (&status, CODES(0), 1); LALSCreateVector (&status, &y, ArraySize); TestStatus (&status, CODES(0), 1); LALDCreateVector (&status, &xx, ArraySize); TestStatus (&status, CODES(0), 1); LALDCreateVector (&status, &yy, ArraySize); TestStatus (&status, CODES(0), 1); #ifndef LAL_NDEBUG if ( ! lalNoDebug ) { if ( verbose ) printf ("\nCheck error conditions:\n"); if ( verbose ) printf ("\nNull pointer:\r"); LALSPolynomialInterpolation (&status, NULL, -0.3, &sintpar); TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1); LALDPolynomialInterpolation (&status, NULL, -0.3, &dintpar); TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1); if ( verbose ) printf ("Null pointer check passed.\n"); if ( verbose ) printf ("\nNull pointer:\r"); LALSPolynomialInterpolation (&status, &sintout, -0.3, NULL); TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1); LALDPolynomialInterpolation (&status, &dintout, -0.3, NULL); TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1); if ( verbose ) printf ("Null pointer check passed.\n"); sintpar.x = NULL; dintpar.x = NULL; if ( verbose ) printf ("\nNull pointer:\r"); LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar); TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1); LALDPolynomialInterpolation (&status, &dintout, -0.3, &dintpar); TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1); if ( verbose ) printf ("Null pointer check passed.\n"); sintpar.x = x->data; sintpar.y = NULL; dintpar.x = xx->data; dintpar.y = NULL; if ( verbose ) printf ("\nNull pointer:\r"); LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar); TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1); LALDPolynomialInterpolation (&status, &dintout, -0.3, &dintpar); TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1); if ( verbose ) printf ("Null pointer check passed.\n"); sintpar.y = y->data; sintpar.n = 1; dintpar.y = yy->data; dintpar.n = 1; if ( verbose ) printf ("\nInvalid size:\r"); LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar); TestStatus (&status, CODES(INTERPOLATEH_ESIZE), 1); dintout.dy = XLALREAL8PolynomialInterpolation (&(dintout.y), -0.3, dintpar.y, dintpar.x, dintpar.n); if (xlalErrno == XLAL_ESIZE) xlalErrno = 0; else abort(); if ( verbose ) printf ("Invalid size check passed.\n"); x->data[1] = x->data[0] = 2; xx->data[1] = xx->data[0] = 2; sintpar.n = 3; dintpar.n = 3; if ( verbose ) printf ("\nZero divide:\r"); LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar); TestStatus (&status, CODES(INTERPOLATEH_EZERO), 1); dintout.dy = XLALREAL8PolynomialInterpolation (&(dintout.y), -0.3, dintpar.y, dintpar.x, dintpar.n); if (xlalErrno == XLAL_EFPDIV0) xlalErrno = 0; else abort(); if ( verbose ) printf ("Zero divide check passed.\n"); } #endif LALSDestroyVector (&status, &x); TestStatus (&status, CODES(0), 1); LALSDestroyVector (&status, &y); TestStatus (&status, CODES(0), 1); LALDDestroyVector (&status, &xx); TestStatus (&status, CODES(0), 1); LALDDestroyVector (&status, &yy); TestStatus (&status, CODES(0), 1); return 0; }
/** * \brief Provides an interface between code build from \ref lalinspiral_findchirp and * various simulation packages for injecting chirps into data. * \author Brown, D. A. and Creighton, T. D * * Injects the signals described * in the linked list of \c SimInspiralTable structures \c events * into the data \c chan. The response function \c resp should * contain the response function to use when injecting the signals into the data. */ void LALFindChirpInjectIMR ( LALStatus *status, REAL4TimeSeries *chan, SimInspiralTable *events, SimRingdownTable *ringdownevents, COMPLEX8FrequencySeries *resp, INT4 injectSignalType ) { UINT4 k; DetectorResponse detector; SimInspiralTable *thisEvent = NULL; SimRingdownTable *thisRingdownEvent = NULL; PPNParamStruc ppnParams; CoherentGW waveform, *wfm; INT8 waveformStartTime; REAL4TimeSeries signalvec; COMPLEX8Vector *unity = NULL; CHAR warnMsg[512]; #if 0 UINT4 n; UINT4 i; #endif INITSTATUS(status); ATTATCHSTATUSPTR( status ); ASSERT( chan, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( chan->data, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( chan->data->data, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( events, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( resp, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( resp->data, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( resp->data->data, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); /* * * set up structures and parameters needed * */ /* fixed waveform injection parameters */ memset( &ppnParams, 0, sizeof(PPNParamStruc) ); ppnParams.deltaT = chan->deltaT; ppnParams.lengthIn = 0; ppnParams.ppn = NULL; /* * * compute the transfer function from the given response function * */ /* allocate memory and copy the parameters describing the freq series */ memset( &detector, 0, sizeof( DetectorResponse ) ); detector.transfer = (COMPLEX8FrequencySeries *) LALCalloc( 1, sizeof(COMPLEX8FrequencySeries) ); if ( ! detector.transfer ) { ABORT( status, FINDCHIRPH_EALOC, FINDCHIRPH_MSGEALOC ); } memcpy( &(detector.transfer->epoch), &(resp->epoch), sizeof(LIGOTimeGPS) ); detector.transfer->f0 = resp->f0; detector.transfer->deltaF = resp->deltaF; detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) ); /* set the detector site */ switch ( chan->name[0] ) { case 'H': *(detector.site) = lalCachedDetectors[LALDetectorIndexLHODIFF]; LALWarning( status, "computing waveform for Hanford." ); break; case 'L': *(detector.site) = lalCachedDetectors[LALDetectorIndexLLODIFF]; LALWarning( status, "computing waveform for Livingston." ); break; case 'G': *(detector.site) = lalCachedDetectors[LALDetectorIndexGEO600DIFF]; LALWarning( status, "computing waveform for GEO600." ); break; case 'T': *(detector.site) = lalCachedDetectors[LALDetectorIndexTAMA300DIFF]; LALWarning( status, "computing waveform for TAMA300." ); break; case 'V': *(detector.site) = lalCachedDetectors[LALDetectorIndexVIRGODIFF]; LALWarning( status, "computing waveform for Virgo." ); break; default: LALFree( detector.site ); detector.site = NULL; LALWarning( status, "Unknown detector site, computing plus mode " "waveform with no time delay" ); break; } /* set up units for the transfer function */ if (XLALUnitDivide( &(detector.transfer->sampleUnits), &lalADCCountUnit, &lalStrainUnit ) == NULL) { ABORTXLAL(status); } /* invert the response function to get the transfer function */ LALCCreateVector( status->statusPtr, &( detector.transfer->data ), resp->data->length ); CHECKSTATUSPTR( status ); LALCCreateVector( status->statusPtr, &unity, resp->data->length ); CHECKSTATUSPTR( status ); for ( k = 0; k < resp->data->length; ++k ) { unity->data[k] = 1.0; } LALCCVectorDivide( status->statusPtr, detector.transfer->data, unity, resp->data ); CHECKSTATUSPTR( status ); LALCDestroyVector( status->statusPtr, &unity ); CHECKSTATUSPTR( status ); thisRingdownEvent = ringdownevents; /* * * loop over the signals and inject them into the time series * */ for ( thisEvent = events; thisEvent; thisEvent = thisEvent->next) { /* * * generate waveform and inject it into the data * */ /* clear the waveform structure */ memset( &waveform, 0, sizeof(CoherentGW) ); LALGenerateInspiral(status->statusPtr, &waveform, thisEvent, &ppnParams); CHECKSTATUSPTR( status ); /* add the ringdown */ wfm = XLALGenerateInspRing( &waveform, thisEvent, thisRingdownEvent, injectSignalType ); if ( !wfm ) { fprintf( stderr, "Failed to generate the waveform \n" ); if (xlalErrno == XLAL_EFAILED) { fprintf( stderr, "Too much merger\n"); XLALDestroyREAL4TimeSeries( chan ); xlalErrno = XLAL_SUCCESS; return; } else exit ( 1 ); } waveform = *wfm; LALInfo( status, ppnParams.termDescription ); if ( thisEvent->geocent_end_time.gpsSeconds ) { /* get the gps start time of the signal to inject */ waveformStartTime = XLALGPSToINT8NS( &(thisEvent->geocent_end_time) ); waveformStartTime -= (INT8) ( 1000000000.0 * ppnParams.tc ); } else { LALInfo( status, "Waveform start time is zero: injecting waveform " "into center of data segment" ); /* center the waveform in the data segment */ waveformStartTime = XLALGPSToINT8NS( &(chan->epoch) ); waveformStartTime += (INT8) ( 1000000000.0 * ((REAL8) (chan->data->length - ppnParams.length) / 2.0) * chan->deltaT ); } snprintf( warnMsg, sizeof(warnMsg)/sizeof(*warnMsg), "Injected waveform timing:\n" "thisEvent->geocent_end_time.gpsSeconds = %d\n" "thisEvent->geocent_end_time.gpsNanoSeconds = %d\n" "ppnParams.tc = %e\n" "waveformStartTime = %" LAL_INT8_FORMAT "\n", thisEvent->geocent_end_time.gpsSeconds, thisEvent->geocent_end_time.gpsNanoSeconds, ppnParams.tc, waveformStartTime ); LALInfo( status, warnMsg ); /* clear the signal structure */ memset( &signalvec, 0, sizeof(REAL4TimeSeries) ); /* set the start times for injection */ XLALINT8NSToGPS( &(waveform.a->epoch), waveformStartTime ); memcpy( &(waveform.f->epoch), &(waveform.a->epoch), sizeof(LIGOTimeGPS) ); memcpy( &(waveform.phi->epoch), &(waveform.a->epoch), sizeof(LIGOTimeGPS) ); /* set the start time of the signal vector to the start time of the chan */ signalvec.epoch = chan->epoch; /* set the parameters for the signal time series */ signalvec.deltaT = chan->deltaT; if ( ( signalvec.f0 = chan->f0 ) != 0 ) { ABORT( status, FINDCHIRPH_EHETR, FINDCHIRPH_MSGEHETR ); } signalvec.sampleUnits = lalADCCountUnit; /* simulate the detectors response to the inspiral */ LALSCreateVector( status->statusPtr, &(signalvec.data), chan->data->length ); CHECKSTATUSPTR( status ); LALSimulateCoherentGW( status->statusPtr, &signalvec, &waveform, &detector ); CHECKSTATUSPTR( status ); /* *****************************************************************************/ #if 0 FILE *fp; char fname[512]; UINT4 jj, kplus, kcross; snprintf( fname, sizeof(fname) / sizeof(*fname), "waveform-%d-%d-%s.txt", thisEvent->geocent_end_time.gpsSeconds, thisEvent->geocent_end_time.gpsNanoSeconds, thisEvent->waveform ); fp = fopen( fname, "w" ); for( jj = 0, kplus = 0, kcross = 1; jj < waveform.phi->data->length; ++jj, kplus += 2, kcross +=2 ) { fprintf(fp, "%d %e %e %le %e\n", jj, waveform.a->data->data[kplus], waveform.a->data->data[kcross], waveform.phi->data->data[jj], waveform.f->data->data[jj]); } fclose( fp ); #endif /* ********************************************************************************/ #if 0 FILE *fp; char fname[512]; UINT4 jj; snprintf( fname, sizeof(fname) / sizeof(*fname), "waveform-%d-%d-%s.txt", thisEvent->geocent_end_time.gpsSeconds, thisEvent->geocent_end_time.gpsNanoSeconds, thisEvent->waveform ); fp = fopen( fname, "w" ); for( jj = 0; jj < signalvec.data->length; ++jj ) { fprintf(fp, "%d %e %e \n", jj, signalvec.data->data[jj]); } fclose( fp ); #endif /* ********************************************************************************/ /* inject the signal into the data channel */ LALSSInjectTimeSeries( status->statusPtr, chan, &signalvec ); CHECKSTATUSPTR( status ); /* allocate and go to next SimRingdownTable */ if( thisEvent->next ) thisRingdownEvent = thisRingdownEvent->next = (SimRingdownTable *) calloc( 1, sizeof(SimRingdownTable) ); else thisRingdownEvent->next = NULL; /* destroy the signal */ LALSDestroyVector( status->statusPtr, &(signalvec.data) ); CHECKSTATUSPTR( status ); LALSDestroyVectorSequence( status->statusPtr, &(waveform.a->data) ); CHECKSTATUSPTR( status ); LALSDestroyVector( status->statusPtr, &(waveform.f->data) ); CHECKSTATUSPTR( status ); LALDDestroyVector( status->statusPtr, &(waveform.phi->data) ); CHECKSTATUSPTR( status ); if ( waveform.shift ) { LALSDestroyVector( status->statusPtr, &(waveform.shift->data) ); CHECKSTATUSPTR( status ); } LALFree( waveform.a ); LALFree( waveform.f ); LALFree( waveform.phi ); if ( waveform.shift ) { LALFree( waveform.shift ); } } LALCDestroyVector( status->statusPtr, &( detector.transfer->data ) ); CHECKSTATUSPTR( status ); if ( detector.site ) LALFree( detector.site ); LALFree( detector.transfer ); DETATCHSTATUSPTR( status ); RETURN( status ); }
/** * \author Creighton, T. D. * * \brief Computes a continuous waveform with frequency drift and Doppler * modulation from a parabolic orbital trajectory. * * This function computes a quaiperiodic waveform using the spindown and * orbital parameters in <tt>*params</tt>, storing the result in * <tt>*output</tt>. * * In the <tt>*params</tt> structure, the routine uses all the "input" * fields specified in \ref GenerateSpinOrbitCW_h, and sets all of the * "output" fields. If <tt>params-\>f</tt>=\c NULL, no spindown * modulation is performed. If <tt>params-\>oneMinusEcc</tt>\f$\neq0\f$, or if * <tt>params-\>rPeriNorm</tt>\f$\times\f$<tt>params-\>angularSpeed</tt>\f$\geq1\f$ * (faster-than-light speed at periapsis), an error is returned. * * In the <tt>*output</tt> structure, the field <tt>output-\>h</tt> is * ignored, but all other pointer fields must be set to \c NULL. The * function will create and allocate space for <tt>output-\>a</tt>, * <tt>output-\>f</tt>, and <tt>output-\>phi</tt> as necessary. The * <tt>output-\>shift</tt> field will remain set to \c NULL. * * ### Algorithm ### * * For parabolic orbits, we combine \eqref{eq_spinorbit-tr}, * \eqref{eq_spinorbit-t}, and \eqref{eq_spinorbit-upsilon} to get \f$t_r\f$ * directly as a function of \f$E\f$: * \f{equation}{ * \label{eq_cubic-e} * t_r = t_p + \frac{r_p\sin i}{c} \left[ \cos\omega + * \left(\frac{1}{v_p} + \cos\omega\right)E - * \frac{\sin\omega}{4}E^2 + \frac{1}{12v_p}E^3\right] \;, * \f} * where \f$v_p=r_p\dot{\upsilon}_p\sin i/c\f$ is a normalized velocity at * periapsis. Following the prescription for the general analytic * solution to the real cubic equation, we substitute * \f$E=x+3v_p\sin\omega\f$ to obtain: * \f{equation}{ * \label{eq_cubic-x} * x^3 + px = q \;, * \f} * where: * \f{eqnarray}{ * \label{eq_cubic-p} * p & = & 12 + 12v_p\cos\omega - 3v_p^2\sin^2\omega \;, \\ * \label{eq_cubic-q} * q & = & 12v_p^2\sin\omega\cos\omega - 24v_p\sin\omega + * 2v_p^3\sin^3\omega + 12\dot{\upsilon}_p(t_r-t_p) \;. * \f} * We note that \f$p>0\f$ is guaranteed as long as \f$v_p<1\f$, so the right-hand * side of \eqref{eq_cubic-x} is monotonic in \f$x\f$ and has exactly one * root. However, \f$p\rightarrow0\f$ in the limit \f$v_p\rightarrow1\f$ and * \f$\omega=\pi\f$. This may cause some loss of precision in subsequent * calculations. But \f$v_p\sim1\f$ means that our solution will be * inaccurate anyway because we ignore significant relativistic effects. * * Since \f$p>0\f$, we can substitute \f$x=y\sqrt{3/4p}\f$ to obtain: * \f{equation}{ * 4y^3 + 3y = \frac{q}{2}\left(\frac{3}{p}\right)^{3/2} \equiv C \;. * \f} * Using the triple-angle hyperbolic identity * \f$\sinh(3\theta)=4\sinh^3\theta+3\sinh\theta\f$, we have * \f$y=\sinh\left(\frac{1}{3}\sinh^{-1}C\right)\f$. The solution to the * original cubic equation is then: * \f{equation}{ * E = 3v_p\sin\omega + 2\sqrt{\frac{p}{3}} * \sinh\left(\frac{1}{3}\sinh^{-1}C\right) \;. * \f} * To ease the calculation of \f$E\f$, we precompute the constant part * \f$E_0=3v_p\sin\omega\f$ and the coefficient \f$\Delta E=2\sqrt{p/3}\f$. * Similarly for \f$C\f$, we precompute a constant piece \f$C_0\f$ evaluated at * the epoch of the output time series, and a stepsize coefficient * \f$\Delta C=6(p/3)^{3/2}\dot{\upsilon}_p\Delta t\f$, where \f$\Delta t\f$ is * the step size in the (output) time series in \f$t_r\f$. Thus at any * timestep \f$i\f$, we obtain \f$C\f$ and hence \f$E\f$ via: * \f{eqnarray}{ * C & = & C_0 + i\Delta C \;,\\ * E & = & E_0 + \Delta E\times\left\{\begin{array}{l@{\qquad}c} * \sinh\left[\frac{1}{3}\ln\left( * C + \sqrt{C^2+1} \right) \right]\;, & C\geq0 \;,\\ \\ * \sinh\left[-\frac{1}{3}\ln\left( * -C + \sqrt{C^2+1} \right) \right]\;, & C\leq0 \;,\\ * \end{array}\right. * \f} * where we have explicitly written \f$\sinh^{-1}\f$ in terms of functions in * \c math.h. Once \f$E\f$ is found, we can compute * \f$t=E(12+E^2)/(12\dot{\upsilon}_p)\f$ (where again \f$1/12\dot{\upsilon}_p\f$ * can be precomputed), and hence \f$f\f$ and \f$\phi\f$ via * \eqref{eq_taylorcw-freq} and \eqref{eq_taylorcw-phi}. The * frequency \f$f\f$ must then be divided by the Doppler factor: * \f[ * 1 + \frac{\dot{R}}{c} = 1 + \frac{v_p}{4+E^2}\left( * 4\cos\omega - 2E\sin\omega \right) * \f] * (where once again \f$4\cos\omega\f$ and \f$2\sin\omega\f$ can be precomputed). * * This routine does not account for relativistic timing variations, and * issues warnings or errors based on the criterea of * \eqref{eq_relativistic-orbit} in GenerateEllipticSpinOrbitCW(). * The routine will also warn if * it seems likely that \c REAL8 precision may not be sufficient to * track the orbit accurately. We estimate that numerical errors could * cause the number of computed wave cycles to vary by * \f[ * \Delta N \lesssim f_0 T\epsilon\left[ * \sim6+\ln\left(|C|+\sqrt{|C|^2+1}\right)\right] \;, * \f] * where \f$|C|\f$ is the maximum magnitude of the variable \f$C\f$ over the * course of the computation, \f$f_0T\f$ is the approximate total number of * wave cycles over the computation, and \f$\epsilon\approx2\times10^{-16}\f$ * is the fractional precision of \c REAL8 arithmetic. If this * estimate exceeds 0.01 cycles, a warning is issued. */ void LALGenerateParabolicSpinOrbitCW( LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params ) { UINT4 n, i; /* number of and index over samples */ UINT4 nSpin = 0, j; /* number of and index over spindown terms */ REAL8 t, dt, tPow; /* time, interval, and t raised to a power */ REAL8 phi0, f0, twopif0; /* initial phase, frequency, and 2*pi*f0 */ REAL8 f, fPrev; /* current and previous values of frequency */ REAL4 df = 0.0; /* maximum difference between f and fPrev */ REAL8 phi; /* current value of phase */ REAL8 vp; /* projected speed at periapsis */ REAL8 argument; /* argument of periapsis */ REAL8 fourCosOmega; /* four times the cosine of argument */ REAL8 twoSinOmega; /* two times the sine of argument */ REAL8 vpCosOmega; /* vp times cosine of argument */ REAL8 vpSinOmega; /* vp times sine of argument */ REAL8 vpSinOmega2; /* vpSinOmega squared */ REAL8 vDot6; /* 6 times angular speed at periapsis */ REAL8 oneBy12vDot; /* one over (12 times angular speed) */ REAL8 pBy3; /* constant sqrt(p/3) in cubic equation */ REAL8 p32; /* constant (p/3)^1.5 in cubic equation */ REAL8 c, c0, dc; /* C variable, offset, and step increment */ REAL8 e, e2, e0; /* E variable, E^2, and constant piece of E */ REAL8 de; /* coefficient of sinh() piece of E */ REAL8 tpOff; /* orbit epoch - time series epoch (s) */ REAL8 spinOff; /* spin epoch - orbit epoch (s) */ REAL8 *fSpin = NULL; /* pointer to Taylor coefficients */ REAL4 *fData; /* pointer to frequency data */ REAL8 *phiData; /* pointer to phase data */ INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Make sure parameter and output structures exist. */ ASSERT( params, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); ASSERT( output, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); /* Make sure output fields don't exist. */ ASSERT( !( output->a ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->f ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->phi ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->shift ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); /* If Taylor coeficients are specified, make sure they exist. */ if ( params->f ) { ASSERT( params->f->data, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); nSpin = params->f->length; fSpin = params->f->data; } /* Set up some constants (to avoid repeated calculation or dereferencing), and make sure they have acceptable values. */ vp = params->rPeriNorm*params->angularSpeed; vDot6 = 6.0*params->angularSpeed; n = params->length; dt = params->deltaT; f0 = fPrev = params->f0; if ( params->oneMinusEcc != 0.0 ) { ABORT( stat, GENERATESPINORBITCWH_EECC, GENERATESPINORBITCWH_MSGEECC ); } if ( vp >= 1.0 ) { ABORT( stat, GENERATESPINORBITCWH_EFTL, GENERATESPINORBITCWH_MSGEFTL ); } if ( vp <= 0.0 || dt <= 0.0 || f0 <= 0.0 || vDot6 <= 0.0 || n == 0 ) { ABORT( stat, GENERATESPINORBITCWH_ESGN, GENERATESPINORBITCWH_MSGESGN ); } #ifndef NDEBUG if ( lalDebugLevel & LALWARNING ) { if ( f0*n*dt*vp*vp > 0.5 ) LALWarning( stat, "Orbit may have significant relativistic" " effects that are not included" ); } #endif /* Compute offset between time series epoch and periapsis, and betweem periapsis and spindown reference epoch. */ tpOff = (REAL8)( params->orbitEpoch.gpsSeconds - params->epoch.gpsSeconds ); tpOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->epoch.gpsNanoSeconds ); spinOff = (REAL8)( params->orbitEpoch.gpsSeconds - params->spinEpoch.gpsSeconds ); spinOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->spinEpoch.gpsNanoSeconds ); /* Set up some other constants. */ twopif0 = f0*LAL_TWOPI; phi0 = params->phi0; argument = params->omega; oneBy12vDot = 0.5/vDot6; fourCosOmega = 4.0*cos( argument ); twoSinOmega = 2.0*sin( argument ); vpCosOmega = 0.25*vp*fourCosOmega; vpSinOmega = 0.5*vp*twoSinOmega; vpSinOmega2 = vpSinOmega*vpSinOmega; pBy3 = sqrt( 4.0*( 1.0 + vpCosOmega ) - vpSinOmega2 ); p32 = 1.0/( pBy3*pBy3*pBy3 ); c0 = p32*( vpSinOmega*( 6.0*vpCosOmega - 12.0 + vpSinOmega2 ) - tpOff*vDot6 ); dc = p32*vDot6*dt; e0 = 3.0*vpSinOmega; de = 2.0*pBy3; /* Check whether REAL8 precision is good enough. */ #ifndef NDEBUG if ( lalDebugLevel & LALWARNING ) { REAL8 x = fabs( c0 + n*dc ); /* a temporary computation variable */ if ( x < fabs( c0 ) ) x = fabs( c0 ); x = 6.0 + log( x + sqrt( x*x + 1.0 ) ); if ( LAL_REAL8_EPS*f0*dt*n*x > 0.01 ) LALWarning( stat, "REAL8 arithmetic may not have sufficient" " precision for this orbit" ); } #endif /* Allocate output structures. */ if ( ( output->a = (REAL4TimeVectorSeries *) LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) { ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->a, 0, sizeof(REAL4TimeVectorSeries) ); if ( ( output->f = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->f, 0, sizeof(REAL4TimeSeries) ); if ( ( output->phi = (REAL8TimeSeries *) LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->phi, 0, sizeof(REAL8TimeSeries) ); /* Set output structure metadata fields. */ output->position = params->position; output->psi = params->psi; output->a->epoch = output->f->epoch = output->phi->epoch = params->epoch; output->a->deltaT = n*params->deltaT; output->f->deltaT = output->phi->deltaT = params->deltaT; output->a->sampleUnits = lalStrainUnit; output->f->sampleUnits = lalHertzUnit; output->phi->sampleUnits = lalDimensionlessUnit; snprintf( output->a->name, LALNameLength, "CW amplitudes" ); snprintf( output->f->name, LALNameLength, "CW frequency" ); snprintf( output->phi->name, LALNameLength, "CW phase" ); /* Allocate phase and frequency arrays. */ LALSCreateVector( stat->statusPtr, &( output->f->data ), n ); BEGINFAIL( stat ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); LALDCreateVector( stat->statusPtr, &( output->phi->data ), n ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); /* Allocate and fill amplitude array. */ { CreateVectorSequenceIn in; /* input to create output->a */ in.length = 2; in.vectorLength = 2; LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); output->a->data->data[0] = output->a->data->data[2] = params->aPlus; output->a->data->data[1] = output->a->data->data[3] = params->aCross; } /* Fill frequency and phase arrays. */ fData = output->f->data->data; phiData = output->phi->data->data; for ( i = 0; i < n; i++ ) { /* Compute emission time. */ c = c0 + dc*i; if ( c > 0 ) e = e0 + de*sinh( log( c + sqrt( c*c + 1.0 ) )/3.0 ); else e = e0 + de*sinh( -log( -c + sqrt( c*c + 1.0 ) )/3.0 ); e2 = e*e; phi = t = tPow = oneBy12vDot*e*( 12.0 + e2 ); /* Compute source emission phase and frequency. */ f = 1.0; for ( j = 0; j < nSpin; j++ ) { f += fSpin[j]*tPow; phi += fSpin[j]*( tPow*=t )/( j + 2.0 ); } /* Appy frequency Doppler shift. */ f *= f0 / ( 1.0 + vp*( fourCosOmega - e*twoSinOmega ) /( 4.0 + e2 ) ); phi *= twopif0; if ( fabs( f - fPrev ) > df ) df = fabs( f - fPrev ); *(fData++) = fPrev = f; *(phiData++) = phi + phi0; } /* Set output field and return. */ params->dfdt = df*dt; DETATCHSTATUSPTR( stat ); RETURN( stat ); }
void LALCoarseFitToPulsar ( LALStatus *status, CoarseFitOutput *output, CoarseFitInput *input, CoarseFitParams *params ) { /******* DECLARE VARIABLES ************/ UINT4 n,i; /* integer indices */ REAL8 psi; REAL8 h0/*,h*/; REAL8 cosIota; REAL8 phase; REAL8 chiSquare; LALDetector detector; LALSource pulsar; LALDetAndSource detAndSource; LALDetAMResponse computedResponse; REAL4Vector *Fp, *Fc; /* pointers to amplitude responses of the detector */ REAL8Vector *var; REAL8 cos2phase,sin2phase; COMPLEX16 Xp, Xc; REAL8 Y, cosIota2; COMPLEX16 A,B; REAL8 sumAA, sumBB, sumAB; REAL8 h0BestFit=0,phaseBestFit=0, psiBestFit=0, cosIotaBestFit=0; REAL8 minChiSquare; COMPLEX16 eh0; REAL8 oldMinEh0, oldMaxEh0, weh0; UINT4 iH0, iCosIota, iPhase, iPsi, arg; INITSTATUS(status); ATTATCHSTATUSPTR(status); /******* CHECK VALIDITY OF ARGUMENTS ************/ ASSERT(output != (CoarseFitOutput *)NULL, status, FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT); ASSERT(params != (CoarseFitParams *)NULL, status, FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS); ASSERT(input != (CoarseFitInput *)NULL, status, FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT); ASSERT(input->B->length == input->var->length, status, FITTOPULSARH_EVECSIZE , FITTOPULSARH_MSGEVECSIZE ); /******* EXTRACT INPUTS AND PARAMETERS ************/ n = input->B->length; for (i = 0; i < n; i++) ASSERT(creal(input->var->data[i]) > 0.0 && cimag(input->var->data[i]) > 0.0, status, FITTOPULSARH_EVAR, FITTOPULSARH_MSGEVAR); detector = params->detector; detAndSource.pDetector = &detector; pulsar = params->pulsarSrc; /******* ALLOCATE MEMORY TO VECTORS **************/ Fp = NULL; LALSCreateVector(status->statusPtr, &Fp, n); Fp->length = n; Fc = NULL; LALSCreateVector(status->statusPtr, &Fc, n); Fc->length = n; var = NULL; LALDCreateVector(status->statusPtr, &var, n); var->length = n; /******* INITIALIZE VARIABLES *******************/ minChiSquare = INICHISQU; oldMaxEh0 = INIMAXEH; oldMinEh0 = INIMINEH; for (i=0;i<n;i++) { var->data[i] = creal(input->var->data[i]) + cimag(input->var->data[i]); } /******* DO ANALYSIS ************/ for (iPsi = 0; iPsi < params->meshPsi[2]; iPsi++) { psi = params->meshPsi[0] + iPsi*params->meshPsi[1]; pulsar.orientation = psi; detAndSource.pSource = &pulsar; /* create vectors containing amplitude response of detector for specified times */ for (i=0;i<n;i++) { LALComputeDetAMResponse(status->statusPtr, &computedResponse,&detAndSource, &input->t[i]); Fp->data[i] = (REAL8)computedResponse.plus; Fc->data[i] = (REAL8)computedResponse.cross; } for (iPhase = 0; iPhase < params->meshPhase[2]; iPhase++) { phase = params->meshPhase[0] + iPhase*params->meshPhase[1]; cos2phase = cos(2.0*phase); sin2phase = sin(2.0*phase); for (iCosIota = 0; iCosIota < params->meshCosIota[2]; iCosIota++) { cosIota = params->meshCosIota[0] + iCosIota*params->meshCosIota[1]; cosIota2 = 1.0 + cosIota*cosIota; Xp = crect( cosIota2 * cos2phase, cosIota2 * sin2phase ); Y = 2.0*cosIota; Xc = crect( Y*sin2phase, -Y*cos2phase ); sumAB = 0.0; sumAA = 0.0; sumBB = 0.0; eh0 = 0.0; for (i = 0; i < n; i++) { B = input->B->data[i]; A = crect( Fp->data[i]*creal(Xp) + Fc->data[i]*creal(Xc), Fp->data[i]*cimag(Xp) + Fc->data[i]*cimag(Xc) ); sumBB += (creal(B)*creal(B) + cimag(B)*cimag(B)) / var->data[i]; sumAA += (creal(A)*creal(A) + cimag(A)*cimag(A)) / var->data[i]; sumAB += (creal(B)*creal(A) + cimag(B)*cimag(A)) / var->data[i]; /**** calculate error on h0 **********/ eh0 += crect( (Fp->data[i]*cosIota2*cos2phase + 2.0*Fc->data[i]*cosIota*sin2phase) * (Fp->data[i]*cosIota2*cos2phase + 2.0*Fc->data[i]*cosIota*sin2phase) / creal(input->var->data[i]), (Fp->data[i]*cosIota2*sin2phase - 2.0*Fc->data[i]*cosIota*cos2phase) * (Fp->data[i]*cosIota2*sin2phase - 2.0*Fc->data[i]*cosIota*cos2phase) / cimag(input->var->data[i]) ); } for (iH0 = 0; iH0 < params->meshH0[2]; iH0++) { h0 = params->meshH0[0] + iH0*params->meshH0[1]; chiSquare = sumBB - 2.0*h0*sumAB + h0*h0*sumAA; if (chiSquare<minChiSquare) { minChiSquare = chiSquare; h0BestFit = h0; cosIotaBestFit = cosIota; psiBestFit = psi; phaseBestFit = phase; output->eh0[0] = 1.0 /sqrt(sqrt(creal(eh0)*creal(eh0) + cimag(eh0)*cimag(eh0))); } weh0 = 1.0 /sqrt(sqrt(creal(eh0)*creal(eh0) + cimag(eh0)*cimag(eh0))); if (weh0>oldMaxEh0) { output->eh0[2] = weh0; oldMaxEh0 = weh0; } if (weh0<oldMinEh0) { output->eh0[1] = weh0; oldMinEh0 = weh0; } arg = iH0 + params->meshH0[2]*(iCosIota + params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi)); output->mChiSquare->data[arg] = chiSquare; } } } } /******* CONSTRUCT OUTPUT ************/ output->h0 = h0BestFit; output->cosIota = cosIotaBestFit; output->phase = phaseBestFit; output->psi = psiBestFit; output->chiSquare = minChiSquare; ASSERT(minChiSquare < INICHISQU, status, FITTOPULSARH_EMAXCHI , FITTOPULSARH_MSGEMAXCHI); LALSDestroyVector(status->statusPtr, &Fp); LALSDestroyVector(status->statusPtr, &Fc); LALDDestroyVector(status->statusPtr, &var); DETATCHSTATUSPTR(status); RETURN(status); }
void FUNC ( LALStatus* status, STYPE *series, const CHAR *filename ) { REAL8Vector *f=NULL; REAL8 *fPtr; REAL8 *fStopPtr; union { TYPE value; BASETYPE array[sizeof(TYPE)/sizeof(BASETYPE)]; } data; TYPE *outputPtr; FILE *fp; CHAR line[MaxLineLength]; /*holds data from each line*/ LALUnit tempUnit; CHARVector *string=NULL; /* need to declare error section here */ INITSTATUS(status); ATTATCHSTATUSPTR(status); ASSERT( filename != NULL, status, READFTSERIESH_EFILENOTFOUND, READFTSERIESH_MSGEFILENOTFOUND ); /* if (filename == NULL) return; */ fp = LALFopen( filename, "r" ); if (fp == NULL) { ABORT( status, READFTSERIESH_EFILENOTFOUND, READFTSERIESH_MSGEFILENOTFOUND ); } /* limited to line of data not exceeding MaxLineLength chars*/ if (fgets(line,sizeof(line),fp) == NULL) { ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } if (line[0] != '#' || line[1] != ' ') { ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } if (snprintf( series->name, sizeof( series->name ), "%s", line + 2) < 0) { ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } /* Change trailing linefeed to '\0' */ if ( changeCharToNull(series->name, '\n', series->name + LALNameLength) ) { ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } if (fgets(line,sizeof(line),fp) == NULL) { ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } if (line[0] != '#' || line[1] != ' ') { ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } if (line[2] == '\n') { series->epoch.gpsSeconds = 0; series->epoch.gpsNanoSeconds = 0; } else if ( sscanf( line, "# Epoch is %d seconds, %d nanoseconds\n", &(series->epoch.gpsSeconds), &(series->epoch.gpsNanoSeconds) ) != 2 ) { ABORT( status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE ); } TRY( LALCHARCreateVector(status->statusPtr, &string, MaxLineLength), status ); if (fgets(line,sizeof(line),fp) == NULL) { TRY( LALCHARDestroyVector( status->statusPtr, &string ), status ); ABORT( status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE ); } if (!strcmp(line,"# Units are ()\n")) { series->sampleUnits = lalDimensionlessUnit; } else { if ( sscanf( line, "# Units are (%[^)]", string->data ) != 1 ) { TRY( LALCHARDestroyVector( status->statusPtr, &string ), status ); ABORT( status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE ); } if ( XLALParseUnitString(&tempUnit, string->data) == NULL ) { TRY( LALCHARDestroyVector( status->statusPtr, &string ), status ); ABORT( status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE ); } series->sampleUnits = tempUnit; } TRY( LALCHARDestroyVector( status->statusPtr, &string ), status ); TRY( LALDCreateVector(status->statusPtr, &f, series->data->length), status ); fPtr = &(f->data[0]); fStopPtr = fPtr + f->length; outputPtr = &(series->data->data[0]); if(fgets(line,sizeof(line),fp) == NULL) { TRY( LALDDestroyVector( status->statusPtr, &f ), status ); ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } while(fgets(line,sizeof(line),fp)!=NULL) { /*change arg so we dereference pointer */ if ( sscanf(line, FMT, fPtr, ARG) != 1 + NARGS ) { TRY( LALDDestroyVector( status->statusPtr, &f ), status ); ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } *(outputPtr) = data.value; fPtr++; outputPtr++; if (fPtr > fStopPtr) { TRY( LALDDestroyVector( status->statusPtr, &f ), status ); ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } } if (fPtr != fStopPtr) { TRY( LALDDestroyVector( status->statusPtr, &f ), status ); ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE); } (series->deltaF) = ( f->data[1] - f->data[0] ); (series->f0) = f->data[0]; TRY( LALDDestroyVector( status->statusPtr, &f ), status ); DETATCHSTATUSPTR(status); RETURN(status); }
int main(int argc, char **argv) { /* top-level status structure */ static LALStatus status; /* Structure specifying the nature of the bank needed */ static InspiralCoarseBankIn coarseIn; /* Template bank lists */ static InspiralTemplateList *list1, *list2; /* Number of templates in list1 and list2 */ INT4 nlist1=0; void (*noisemodel)(LALStatus*,REAL8*,REAL8) = LALLIGOIPsd; INT4 j, numPSDpts=16384/2; FILE *fpr; UserParams userParams; INT4 i=1; double scaling = sqrt(2.); /* initiliase userParams.calque */ userParams.calque = TaylorT1; while(i < argc) { if (strcmp(argv[i], "--help") == 0) { fprintf(stderr, "--template [TaylorT1, TaylorT3, EOB, ...]\n--grid-spacing [Hexagonal, SquareNotOriented, ...]\n`--noise-model [LIGO, VIRGO...]\n"); exit(0); } else if ( strcmp(argv[i], "--noise-model") == 0 ) { if ( strcmp(argv[++i], "VIRGO") ==0) { (noisemodel) = &LALVIRGOPsd; } else if ( strcmp(argv[i], "LIGOI") ==0){ (noisemodel) = &LALLIGOIPsd; } else if ( strcmp(argv[i], "LIGOA") ==0){ (noisemodel) = &LALAdvLIGOPsd; } else if ( strcmp(argv[i], "EGO") ==0){ (noisemodel) = &LALEGOPsd; } } else if ( strcmp(argv[i], "--template") == 0 ) { if ( strcmp(argv[++i], "TaylorT1") ==0) { userParams.calque = TaylorT1; } else if ( strcmp(argv[i], "TaylorT2") ==0) { userParams.calque = TaylorT2; } else if ( strcmp(argv[i], "TaylorT3") ==0) { userParams.calque = TaylorT3; } else if ( strcmp(argv[i], "TaylorF1") ==0) { userParams.calque = TaylorF1; } else if ( strcmp(argv[i], "TaylorF2") ==0) { userParams.calque = TaylorF2; } else if ( strcmp(argv[i], "PadeT1") ==0) { userParams.calque = PadeT1; } else if ( strcmp(argv[i], "PadeF1") ==0) { userParams.calque = PadeF1; } else if ( strcmp(argv[i], "EOB") ==0) { userParams.calque = EOB; } else if ( strcmp(argv[i], "BCV") ==0) { userParams.calque = BCV; } else if ( strcmp(argv[i], "SpinTaylorT3") ==0) { userParams.calque = SpinTaylorT3; } } /*end of --template if*/ else if ( strcmp(argv[i], "--grid-spacing") == 0 ) { i++; if (strcmp(argv[i], "Square") == 0) coarseIn.gridSpacing = Square; else if (strcmp(argv[i], "Hexagonal") == 0) coarseIn.gridSpacing = Hexagonal; else if (strcmp(argv[i], "HybridHexagonal") == 0) coarseIn.gridSpacing = HybridHexagonal; else if (strcmp(argv[i], "SquareNotOriented") == 0) coarseIn.gridSpacing = SquareNotOriented; else if (strcmp(argv[i], "HexagonalNotOriented") == 0) coarseIn.gridSpacing = HexagonalNotOriented; else {fprintf(stderr, "grid-spacing is either square or hexagonal\n"); exit(0);} } i++; } coarseIn.LowGM = -2; coarseIn.HighGM = 6; coarseIn.fLower = 40.L; coarseIn.fUpper = 2047L; coarseIn.tSampling = 4096.L; coarseIn.order = LAL_PNORDER_TWO; coarseIn.space = Tau0Tau3; coarseIn.mmCoarse = 0.98; coarseIn.mmFine = 0.98; coarseIn.iflso = 0.0L; coarseIn.mMin = 3; coarseIn.mMax = 30.0; coarseIn.MMax = coarseIn.mMax * 2.; coarseIn.massRange = MinMaxComponentMass; /* coarseIn.massRange = MinComponentMassMaxTotalMass;*/ /* minimum value of eta */ coarseIn.etamin = coarseIn.mMin * ( coarseIn.MMax - coarseIn.mMin) / pow(coarseIn.MMax,2.); coarseIn.psi0Min = 1.e0; coarseIn.psi0Max = 2.5e4; coarseIn.psi3Min = -1e4; coarseIn.psi3Max = -10; coarseIn.alpha = 0.L; coarseIn.numFcutTemplates = 4; memset( &(coarseIn.shf), 0, sizeof(REAL8FrequencySeries) ); coarseIn.shf.f0 = 0; LALDCreateVector( &status, &(coarseIn.shf.data), numPSDpts ); coarseIn.shf.deltaF = coarseIn.tSampling / (2.*(REAL8) coarseIn.shf.data->length + 1.L); LALNoiseSpectralDensity (&status, coarseIn.shf.data, noisemodel, coarseIn.shf.deltaF ); if (userParams.calque == BCV) { coarseIn.approximant = BCV; coarseIn.space = Psi0Psi3; } else { coarseIn.approximant = TaylorT3; coarseIn.space = Tau0Tau3; } LALInspiralCreateCoarseBank(&status, &list1, &nlist1, coarseIn); fprintf(stderr, "save %d template in results in SpaceCovering.out\n", nlist1); fflush(stdout); fflush(stderr); fpr = fopen("SpaceCovering.out", "w"); for (j=0; j<nlist1; j++) { switch(userParams.calque){ case TaylorT1: case TaylorT2: case TaylorT3: case EOB: fprintf(fpr, "%e %e %e %e %e %e %e\n", list1[j].params.t0, list1[j].params.t3, list1[j].metric.g00, list1[j].metric.g11, 2*sqrt((1-coarseIn.mmCoarse)/list1[j].metric.g00), 2*sqrt((1-coarseIn.mmCoarse)/list1[j].metric.g11), list1[j].metric.theta*180/LAL_PI); break; case BCV: fprintf(fpr, "%e %e %e %e %e %e %e\n", list1[j].params.psi0, list1[j].params.psi3, list1[j].metric.g00, list1[j].metric.g11, 2*sqrt((1-coarseIn.mmCoarse)/list1[j].metric.g00), 2*sqrt((1-coarseIn.mmCoarse)/list1[j].metric.g11), list1[j].metric.theta); break; } } fprintf(fpr, "&\n"); { INT4 k; UINT4 valid; static RectangleIn RectIn; static RectangleOut RectOut; static HexagonOut HexaOut; /* Print out the template parameters */ for (k=0; k<nlist1; j=k++) { RectIn.dx = sqrt(2.0 * (1. - coarseIn.mmCoarse)/list1[k].metric.g00 ); RectIn.dy = sqrt(2.0 * (1. - coarseIn.mmCoarse)/list1[k].metric.g11 ); RectIn.theta = list1[j].metric.theta ; if (userParams.calque == BCV) { RectIn.x0 = (REAL8) list1[k].params.psi0; RectIn.y0 = (REAL8) list1[k].params.psi3; } else { RectIn.x0 = (REAL8) list1[k].params.t0; RectIn.y0 = (REAL8) list1[k].params.t3; } /* * LALInspiralValidParams(&status, &valid, bankParams, coarseIn); * */ valid = 1; if (valid) { if (coarseIn.gridSpacing == SquareNotOriented) { LALRectangleVertices(&status, &RectOut, &RectIn); fprintf(fpr, "%e %e\n%e %e\n%e %e\n%e %e\n%e %e\n", RectOut.x1, RectOut.y1, RectOut.x2, RectOut.y2, RectOut.x3, RectOut.y3, RectOut.x4, RectOut.y4, RectOut.x5, RectOut.y5); fprintf(fpr, "&\n"); } else if (coarseIn.gridSpacing == Hexagonal || coarseIn.gridSpacing == HybridHexagonal) { RectIn.dx = sqrt(3.0 * (1. - coarseIn.mmCoarse)/list1[k].metric.g00 ); RectIn.dy = sqrt(3.0 * (1. - coarseIn.mmCoarse)/list1[k].metric.g11 ); /*RectIn.theta = list1[j].metric.theta + LAL_PI/6;*/ LALHexagonVertices(&status, &HexaOut, &RectIn); fprintf(fpr, "%e %e\n%e %e\n%e %e\n%e %e\n%e %e\n%e %e\n%e %e\n", HexaOut.x1, HexaOut.y1, HexaOut.x2, HexaOut.y2, HexaOut.x3, HexaOut.y3, HexaOut.x4, HexaOut.y4, HexaOut.x5, HexaOut.y5, HexaOut.x6, HexaOut.y6, HexaOut.x7, HexaOut.y7); fprintf(fpr, "&\n"); } } /*plots the ellipses*/ { int Nth =100; double th; double x,y,phi,a,b, theta; for (theta=0; theta<2*3.14; theta+=2*3.14/(double)Nth) { a = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/list1[j].metric.g00 ); b = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/list1[j].metric.g11 ); x = a * cos(theta)/scaling; y = b * sin(theta)/scaling; phi=list1[j].metric.theta ; /* phi *=1.1;*/ if (userParams.calque == BCV) { th = x*cos(phi)-y*sin(phi)+list1[j].params.psi0; y = x*sin(phi)+y*cos(phi)+list1[j].params.psi3; } else { th = x*cos(phi)-y*sin(phi)+list1[j].params.t0; y = x*sin(phi)+y*cos(phi)+list1[j].params.t3; } x = th; fprintf(fpr, "%f %f\n", x, y); } theta = 0; a = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/list1[j].metric.g00 ); b = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/list1[j].metric.g11 ); x = a * cos(theta) /scaling; y = b * sin(theta)/scaling; phi=list1[j].metric.theta ; if (userParams.calque == BCV) { th = x*cos(phi)-y*sin(phi)+list1[j].params.psi0; y = x*sin(phi)+y*cos(phi)+list1[j].params.psi3; } else { th = x*cos(phi)-y*sin(phi)+list1[j].params.t0; y = x*sin(phi)+y*cos(phi)+list1[j].params.t3; } x = th; fprintf(fpr, "%f %f\n", x, y); fprintf(fpr, "&\n"); } } } LALInspiralCreateBoundarySpace(coarseIn); fclose(fpr); /* Free the list, and exit. */ if (list1 != NULL) LALFree (list1); if (list2 != NULL) LALFree (list2); LALDDestroyVector( &status, &(coarseIn.shf.data) ); LALCheckMemoryLeaks(); return(0); }
void LALCoarseFitToPulsar ( LALStatus *status, CoarseFitOutput *output, CoarseFitInput *input, CoarseFitParams *params ) { /******* DECLARE VARIABLES ************/ UINT4 n,i,j; /* integer indices */ REAL8 psi; REAL8 h0; REAL8 cosIota; REAL8 phase; REAL8 chiSquare; LALDetector detector; LALSource pulsar; LALDetAndSource detAndSource; LALDetAMResponse computedResponse; REAL4Vector *Fp, *Fc; /* pointers to amplitude responses of the detector */ REAL8Vector *var; REAL8 cos2phase,sin2phase; COMPLEX16 Xp, Xc; REAL8 Y, cosIota2; COMPLEX16 A,B; REAL8 sumAA, sumBB, sumAB; REAL8 h0BestFit=0,phaseBestFit=0, psiBestFit=0, cosIotaBestFit=0; REAL8 minChiSquare; UINT4 iH0, iCosIota, iPhase, iPsi, arg; LALGPSandAcc pGPSandAcc; INITSTATUS(status); ATTATCHSTATUSPTR(status); /******* CHECK VALIDITY OF ARGUMENTS ************/ ASSERT(output != (CoarseFitOutput *)NULL, status, FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT); ASSERT(params != (CoarseFitParams *)NULL, status, FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS); ASSERT(input != (CoarseFitInput *)NULL, status, FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT); ASSERT(input->B->length == input->var->length, status, FITTOPULSARH_EVECSIZE , FITTOPULSARH_MSGEVECSIZE ); /******* EXTRACT INPUTS AND PARAMETERS ************/ n = input->B->length; for (i = 0; i < n; i++) ASSERT(input->var->data[i].re > 0.0 && input->var->data[i].im > 0.0, status, FITTOPULSARH_EVAR, FITTOPULSARH_MSGEVAR); detector = params->detector; detAndSource.pDetector = &detector; pulsar = params->pulsarSrc; /******* ALLOCATE MEMORY TO VECTORS **************/ Fp = NULL; LALSCreateVector(status->statusPtr, &Fp, n); Fp->length = n; Fc = NULL; LALSCreateVector(status->statusPtr, &Fc, n); Fc->length = n; var = NULL; LALDCreateVector(status->statusPtr, &var, n); var->length = n; /******* INITIALIZE VARIABLES *******************/ minChiSquare = INICHISQU; /******* DO ANALYSIS ************/ for (iPsi = 0; iPsi < params->meshPsi[2]; iPsi++) { fprintf(stderr,"%d out of %f iPsi\n", iPsi+1, params->meshPsi[2]); fflush(stderr); psi = params->meshPsi[0] + (REAL8)iPsi*params->meshPsi[1]; pulsar.orientation = psi; detAndSource.pSource = &pulsar; for (i=0;i<n;i++) { Fp->data[i] = 0.0; Fc->data[i] = 0.0; for(j=0;j<input->N;j++) { pGPSandAcc.gps.gpsNanoSeconds = input->t[i].gpsNanoSeconds; pGPSandAcc.gps.gpsSeconds = input->t[i].gpsSeconds + (double)j*60.0; pGPSandAcc.accuracy = 1.0; LALComputeDetAMResponse(status->statusPtr, &computedResponse,&detAndSource, &pGPSandAcc); Fp->data[i] += (REAL8)computedResponse.plus; Fc->data[i] += (REAL8)computedResponse.cross; } Fp->data[i] /= (double)input->N; Fc->data[i] /= (double)input->N; } for (iPhase = 0; iPhase < params->meshPhase[2]; iPhase++) { phase = params->meshPhase[0] + (REAL8)iPhase*params->meshPhase[1]; cos2phase = cos(2.0*phase); sin2phase = sin(2.0*phase); for (iCosIota = 0; iCosIota < params->meshCosIota[2]; iCosIota++) { cosIota = params->meshCosIota[0] + (REAL8)iCosIota*params->meshCosIota[1]; cosIota2 = 1.0 + cosIota*cosIota; Xp.re = 0.25*cosIota2 * cos2phase; Xp.im = 0.25*cosIota2 * sin2phase; Y = 0.5*cosIota; Xc.re = Y*sin2phase; Xc.im = -Y*cos2phase; sumAB = 0.0; sumAA = 0.0; sumBB = 0.0; for (i = 0; i < n; i++) { B.re = input->B->data[i].re; B.im = input->B->data[i].im; A.re = Fp->data[i]*Xp.re + Fc->data[i]*Xc.re; A.im = Fp->data[i]*Xp.im + Fc->data[i]*Xc.im; sumBB += B.re*B.re/input->var->data[i].re + B.im*B.im/input->var->data[i].im; sumAA += A.re*A.re/input->var->data[i].re + A.im*A.im/input->var->data[i].im; sumAB += B.re*A.re/input->var->data[i].re + B.im*A.im/input->var->data[i].im; } for (iH0 = 0; iH0 < params->meshH0[2]; iH0++) { h0 = params->meshH0[0] + (float)iH0*params->meshH0[1]; chiSquare = sumBB - 2.0*h0*sumAB + h0*h0*sumAA; if (chiSquare<minChiSquare) { minChiSquare = chiSquare; h0BestFit = h0; cosIotaBestFit = cosIota; psiBestFit = psi; phaseBestFit = phase; } arg = iH0 + params->meshH0[2]*(iCosIota + params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi)); output->mChiSquare->data[arg] = chiSquare; } } } } /******* CONSTRUCT OUTPUT ************/ output->h0 = h0BestFit; output->cosIota = cosIotaBestFit; output->phase = phaseBestFit; output->psi = psiBestFit; output->chiSquare = minChiSquare; ASSERT(minChiSquare < INICHISQU, status, FITTOPULSARH_EMAXCHI , FITTOPULSARH_MSGEMAXCHI); LALSDestroyVector(status->statusPtr, &Fp); LALSDestroyVector(status->statusPtr, &Fc); LALDDestroyVector(status->statusPtr, &var); DETATCHSTATUSPTR(status); RETURN(status); }
int main(int argc, char **argv) { /***** declare variables *****/ static LALStatus status; FILE *fp1, *fp2, *fp3, *fp4; FILE *fp_pdf1, *fp_pdf2, *fp_pdf3, *fp_pdf4; FILE *fp_pdf1Phase, *fp_pdf2Phase, *fp_pdf3Phase, *fp_pdf4Phase; FILE *fp_pdf1Psi, *fp_pdf2Psi, *fp_pdf3Psi, *fp_pdf4Psi; FILE *fp_pdf1CosIota, *fp_pdf2CosIota, *fp_pdf3CosIota, *fp_pdf4CosIota; FILE *fp_joint, *fp_jointPhase, *fp_jointPsi, *fp_jointCosIota; FILE *fpmesh, *psrfp; char infile1[256], infile2[256], infile3[256], infile4[256]; char outfile1[256], outfile2[256], outfile3[256], outfile4[256]; char outfile1Phase[256], outfile2Phase[256], outfile3Phase[256], outfile4Phase[256]; char outfile1Psi[256], outfile2Psi[256], outfile3Psi[256], outfile4Psi[256]; char outfile1CosIota[256], outfile2CosIota[256], outfile3CosIota[256], outfile4CosIota[256]; char outfile[256], outfilePhase[256],outfilePsi[256],outfileCosIota[256]; char psrinput[256], inmesh[256], txt[32], pulsar_name[64]; UINT4 iPsi, iPhase, iCosIota, iH0, arg, i; INT4 iRA=0, iDEC=0, if0=0, if1=0, if2=0,ifepoch=0, flag =0, irun; INT4 num_dect, iGEO = 0, iL1 = 0, iH1 = 0, iH2 = 0; REAL4 psr_ra, psr_dec; REAL8 RA, DEC, f0, f1, f2, val, t; REAL8 minChi, area, outL1, outH1, outH2, outGEO; COMPLEX16 B, var; LIGOTimeGPS fepoch, tgps1[MAXLENGTH],tgps2[MAXLENGTH],tgps3[MAXLENGTH], tgps4[MAXLENGTH]; FitInputStudentT input1, input2, input3, input4; CoarseFitInput input1_chi, input2_chi, input3_chi, input4_chi; CoarseFitParams params1, params2, params3, params4; CoarseFitOutput output1, output2, output3, output4; LALDetector detectorLHO,detectorLLO, detectorGEO; LALSource pulsar; PulsarPdfs prob1, prob2, prob3, prob4, prob; /* get command line arguments and print error if there is wrong number of arguments. if the variable condor is defined, then read in the first argument pulsar_name from stdin */ #ifndef CONDOR if (argc < 8 || argc > 11){ fprintf(stderr, "1. Name of pulsar (when not using condor)\n"); fprintf(stderr,"2. working directory\n"); fprintf(stderr, "3. flag=1 for Gaussian with explicit noise estimate provided\n flag=2 for noise analytically marginalised out of Gaussian\n"); fprintf(stderr, "4. name of mesh file in inputs directory\n"); fprintf(stderr, "5. irun - 2 for S2, 3 for S3\n"); fprintf(stderr, "6. num detectors (max 4)\n"); fprintf(stderr, "7-10. H1, H2, L1, and/or GEO\n"); fprintf(stderr,"There were argc= %d arguments:\n",argc -1); fflush(stderr); return 2; } sprintf(pulsar_name, "%s", argv[1]); #else // read pulsar name from stdin for condor scanf("%s", &pulsar_name[0]); fprintf(stderr, "pulsar name: %s\n",pulsar_name); #endif fprintf(stderr, "pulsarname=%s\n", pulsar_name); flag = atoi(argv[3]); irun = atoi(argv[5]); num_dect = atoi(argv[6]); if (num_dect >4) { fprintf(stderr, "Number of IFOs must be less than 5 (H1, H2, L1, and/or GEO)!\n"); return(1); } /* check which detectors we are being used for analysis*/ for (i=0;i<num_dect;i++) { if (!strcmp(argv[i+7],"GEO")) iGEO = 1; else if (!strcmp(argv[i+7],"L1")) iL1 = 1; else if (!strcmp(argv[i+7],"H1")) iH1 = 1; else if (!strcmp(argv[i+7],"H2")) iH2 = 1; else { fprintf(stderr, "what is %s? not GEO, L1, H1, or H2!\n",argv[i+7]); return(2); } } /************** BEGIN READING PULSAR PARAMETERS ******************/ /* read input file with pulsar information */ sprintf(psrinput,"%s/inputs/%s", argv[2],pulsar_name); psrfp=fopen(psrinput,"r"); while (2==fscanf(psrfp,"%s %lf", &txt[0], &val)) { if( !strcmp(txt,"ra") || !strcmp(txt,"RA")) { psr_ra = RA = val; iRA = 1; } else if( !strcmp(txt,"dec") || !strcmp(txt,"DEC")) { psr_dec = DEC = val; iDEC = 1; } else if( !strcmp(txt,"f0") || !strcmp(txt,"F0")) { f0 = val; if0 = 1; } else if( !strcmp(txt,"f1") || !strcmp(txt,"F1")) { f1 = val; if1 = 1; } else if( !strcmp(txt,"f2") || !strcmp(txt,"F2")) { f2 = val; if2 = 1; } else if( !strcmp(txt,"fepoch") || !strcmp(txt,"fepoch")) { fepoch.gpsSeconds = floor(val*1e-9); fepoch.gpsNanoSeconds = (INT8) val - fepoch.gpsSeconds*1e9; ifepoch = 1; } } if ((iRA+iDEC+ifepoch+if0+if1+if2) != 6) { fprintf(stderr, "pulsar input file missing info \nra\txxx\ndec\txxx\nf0\txxx\nf1\txxx\nf2\txxx\nfepoch\txxx\n"); return(3); } fclose(psrfp); /************** END READING PULSAR PARAMETERS ******************/ detectorLHO = lalCachedDetectors[LALDetectorIndexLHODIFF]; detectorLLO = lalCachedDetectors[LALDetectorIndexLLODIFF]; detectorGEO = lalCachedDetectors[LALDetectorIndexGEO600DIFF]; /* currently this code assumes that we are using 30 minute stretches of data this could be relaxed in the future */ input1.N = input2.N = input3.N = input4.N = 30; input1_chi.N = input2_chi.N = input3_chi.N = input4_chi.N = 30; /* set up strings pointing to the file that we want to read as input for the gaussian likelihood (flag=1) there is two extra columns in the input files corresponding to the variance of the real and imaginary Bk's. the Bk's used in the gausian likelihood (flag=1) are calculated every 30 minutes (average of 30 1-minute Bk). for the student-t likelihood (flag=2), the Bk's are from every 60 seconds */ if (flag == 1) { if (iL1) sprintf(infile1,"%s/dataL1/outfine.%s_L1.S%d_chi_30", argv[2],pulsar_name, irun); if (iH1) sprintf(infile2,"%s/dataH1/outfine.%s_H1.S%d_chi_30", argv[2], pulsar_name, irun); if (iH2) sprintf(infile3,"%s/dataH2/outfine.%s_H2.S%d_chi_30", argv[2], pulsar_name, irun); if (iGEO) sprintf(infile4, "%s/dataGEO/outfine.%s_GEO.S%d_chi_30", argv[2], pulsar_name, irun); } else if (flag == 2) { if (iL1) sprintf(infile1,"%s/dataL1/finehet_%s_L1", argv[2], pulsar_name); if (iH1) sprintf(infile2,"%s/dataH1/finehet_%s_H1", argv[2], pulsar_name); if (iH2) sprintf(infile3,"%s/dataH2/finehet_%s_H2", argv[2], pulsar_name); if (iGEO) sprintf(infile4,"%s/dataG1/finehet_%s_GEO", argv[2], pulsar_name); } else { fprintf(stderr, "flag should be 1 or 2\n"); return(2); } /* open output files */ if (iL1) fp1 = fopen(infile1, "r"); if (iH1) fp2 = fopen(infile2, "r"); if (iH2) fp3 = fopen(infile3, "r"); if (iGEO) fp4 = fopen(infile4, "r"); /* allocate memory for B_k and var */ if (flag ==1 && iL1 == 1) { input1_chi.B = NULL; LALZCreateVector( &status, &input1_chi.B, MAXLENGTH); TESTSTATUS(&status); input1_chi.var = NULL; LALZCreateVector( &status, &input1_chi.var, MAXLENGTH); TESTSTATUS(&status); } else if (flag == 2 && iL1 == 1) { input1.B = NULL; LALZCreateVector( &status, &input1.B, MAXLENGTH); TESTSTATUS(&status); } if (flag ==1 && iH1 == 1) { input2_chi.B = NULL; LALZCreateVector( &status, &input2_chi.B, MAXLENGTH); TESTSTATUS(&status); input2_chi.var = NULL; LALZCreateVector( &status, &input2_chi.var, MAXLENGTH); TESTSTATUS(&status); } else if (flag == 2 && iH1 == 1) { input2.B = NULL; LALZCreateVector( &status, &input2.B, MAXLENGTH); TESTSTATUS(&status); } if (flag ==1 && iH2 == 1) { input3_chi.B = NULL; LALZCreateVector( &status, &input3_chi.B, MAXLENGTH); TESTSTATUS(&status); input3_chi.var = NULL; LALZCreateVector( &status, &input3_chi.var, MAXLENGTH); TESTSTATUS(&status); } else if (flag == 2 && iH2 == 1) { input3.B = NULL; LALZCreateVector( &status, &input3.B, MAXLENGTH); TESTSTATUS(&status); } if (flag ==1 && iGEO == 1) { input4_chi.B = NULL; LALZCreateVector( &status, &input4_chi.B, MAXLENGTH); TESTSTATUS(&status); input4_chi.var = NULL; LALZCreateVector( &status, &input4_chi.var, MAXLENGTH); TESTSTATUS(&status); } else if (flag == 2 && iGEO == 1) { input4.B = NULL; LALZCreateVector( &status, &input4.B, MAXLENGTH); TESTSTATUS(&status); } params1.detector = detectorLLO; params2.detector = detectorLHO; params3.detector = detectorLHO; params4.detector = detectorGEO; /* set up RA, DEC, and coordinate system */ pulsar.equatorialCoords.longitude = psr_ra; pulsar.equatorialCoords.latitude = psr_dec; pulsar.equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; /* polarization angle will be redefined inside the fitting routine */ pulsar.orientation = 0.0; params1.pulsarSrc = params2.pulsarSrc = params3.pulsarSrc = params4.pulsarSrc= pulsar; /****************** BEGIN READ INPUT DATA (Bk's) ***************************/ /* read data from L1 */ if (iL1) { if (flag == 2) /* student-t */ { fscanf(fp1,"%lf\t%lf\t%lf",&t,&B.re, &B.im); i=0; while (!feof(fp1)) { if(fabs(B.re) > 1e-28 && fabs(B.im) > 1e-28){ tgps1[i].gpsSeconds = (INT4)floor(t); tgps1[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9)); input1.B->data[i].re = B.re; input1.B->data[i].im = B.im; i++; } fscanf(fp1,"%lf\t%lf\t%lf",&t,&B.re, &B.im); } input1.t = tgps1; input1.B->length = i; } else if (flag == 1) /* chisquare */ { fscanf(fp1,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im); i=0; while (!feof(fp1)) { tgps1[i].gpsSeconds = (INT4)floor(t); tgps1[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9)); input1_chi.B->data[i].re = B.re; input1_chi.B->data[i].im = B.im; input1_chi.var->data[i].re = var.re; input1_chi.var->data[i].im = var.im; fscanf(fp1,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im); i++; } input1_chi.t = tgps1; input1_chi.B->length = i; input1_chi.var->length = i; } fclose(fp1); } fprintf(stderr, "I've read in the L1 data.\n"); /* read data from H1 */ if (iH1) { if (flag == 2) /* student-t */ { fscanf(fp2,"%lf\t%lf\t%lf",&t,&B.re, &B.im); i=0; while (!feof(fp2)) { if(fabs(B.re) > 1e-28 && fabs(B.im) > 1e-28){ tgps2[i].gpsSeconds = (INT4)floor(t); tgps2[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9)); input2.B->data[i].re = B.re; input2.B->data[i].im = B.im; i++; } fscanf(fp2,"%lf\t%lf\t%lf",&t,&B.re, &B.im); } input2.t = tgps2; input2.B->length = i; } else if (flag == 1) /* chisquare */ { fscanf(fp2,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im); i=0; while (!feof(fp2)) { tgps2[i].gpsSeconds = (INT4)floor(t); tgps2[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9)); input2_chi.B->data[i].re = B.re; input2_chi.B->data[i].im = B.im; input2_chi.var->data[i].re = var.re; input2_chi.var->data[i].im = var.im; fscanf(fp2,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im); i++; } input2_chi.t = tgps2; input2_chi.B->length = i; input2_chi.var->length = i; } fclose(fp2); } fprintf(stderr, "I've read in the H1 data.\n"); /* read data from H2 */ if (iH2) { if (flag == 2) /* student-t */ { fscanf(fp3,"%lf\t%lf\t%lf",&t,&B.re, &B.im); i=0; while (!feof(fp3)) { if(fabs(B.re) > 1e-28 && fabs(B.im) > 1e-28){ tgps3[i].gpsSeconds = (INT4)floor(t); tgps3[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9)); input3.B->data[i].re = B.re; input3.B->data[i].im = B.im; i++; } fscanf(fp3,"%lf\t%lf\t%lf",&t,&B.re, &B.im); } input3.t = tgps3; input3.B->length = i; } else if (flag == 1) /* chisquare */ { fscanf(fp3,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im); i=0; while (!feof(fp3)) { tgps3[i].gpsSeconds = (INT4)floor(t); tgps3[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9)); input3_chi.B->data[i].re = B.re; input3_chi.B->data[i].im = B.im; input3_chi.var->data[i].re = var.re; input3_chi.var->data[i].im = var.im; fscanf(fp3,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im); i++; } input3_chi.t = tgps3; input3_chi.B->length = i; input3_chi.var->length = i; } fclose(fp3); } fprintf(stderr, "I've read in the H2 data.\n"); /* read data from GEO */ if (iGEO) { if (flag == 2) /* student-t */ { fscanf(fp4,"%lf\t%lf\t%lf",&t,&B.re, &B.im); i=0; while (!feof(fp4)) { if(fabs(B.re) > 1e-28 && fabs(B.im) > 1e-28){ tgps4[i].gpsSeconds = (INT4)floor(t); tgps4[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9)); input4.B->data[i].re = B.re; input4.B->data[i].im = B.im; i++; } fscanf(fp4,"%lf\t%lf\t%lf",&t,&B.re, &B.im); } input4.t = tgps4; input4.B->length = i; } else if (flag == 1) /* chisquare */ { fscanf(fp4,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im); i=0; while (!feof(fp4)) { tgps4[i].gpsSeconds = (INT4)floor(t); tgps4[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9)); input4_chi.B->data[i].re = B.re; input4_chi.B->data[i].im = B.im; input4_chi.var->data[i].re = var.re; input4_chi.var->data[i].im = var.im; fscanf(fp4,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im); i++; } input4_chi.t = tgps4; input4_chi.B->length = i; input4_chi.var->length = i; } fclose(fp4); } /****************** END READ INPUT DATA (Bk's) ***************************/ /******** read mesh input file *****************/ /* construct name of mesh file and open file */ sprintf(inmesh,"%s/inputs/%s", argv[2],argv[4]); fpmesh = fopen(inmesh,"r"); fscanf(fpmesh,"%s\t%lf\t%lf\t%lf",&txt[0],¶ms1.meshH0[0], ¶ms1.meshH0[1], ¶ms1.meshH0[2]); fprintf(stderr, "%s\t%e\t%e\t%f\t-> %e\n", txt, params1.meshH0[0], params1.meshH0[1], params1.meshH0[2],params1.meshH0[0]+params1.meshH0[1]*(params1.meshH0[2]-1.0)); params2.meshH0[0] = params3.meshH0[0] = params4.meshH0[0] = params1.meshH0[0]; params2.meshH0[1] = params3.meshH0[1] = params4.meshH0[1] = params1.meshH0[1]; params2.meshH0[2] = params3.meshH0[2] = params4.meshH0[2] = params1.meshH0[2]; fscanf(fpmesh,"%s\t%lf\t%lf\t%lf",&txt[0],¶ms1.meshCosIota[0], ¶ms1.meshCosIota[1], ¶ms1.meshCosIota[2]); fprintf(stderr, "%s\t%e\t%e\t%f\t-> %e\n", txt, params1.meshCosIota[0], params1.meshCosIota[1], params1.meshCosIota[2], params1.meshCosIota[0]+ params1.meshCosIota[1]*(params1.meshCosIota[2]-1.0)); params2.meshCosIota[0] = params3.meshCosIota[0] = params4.meshCosIota[0] = params1.meshCosIota[0]; params2.meshCosIota[1] = params3.meshCosIota[1] = params4.meshCosIota[1] = params1.meshCosIota[1]; params2.meshCosIota[2] = params3.meshCosIota[2] = params4.meshCosIota[2] = params1.meshCosIota[2]; fscanf(fpmesh,"%s\t%lf\t%lf\t%lf",&txt[0],¶ms1.meshPhase[0], ¶ms1.meshPhase[1], ¶ms1.meshPhase[2]); fprintf(stderr,"%s\t%e\t%e\t%f\t-> %e\n", txt, params1.meshPhase[0], params1.meshPhase[1], params1.meshPhase[2], params1.meshPhase[0]+params1.meshPhase[1]*(params1.meshPhase[2]-1.0)); params2.meshPhase[0] = params3.meshPhase[0] = params4.meshPhase[0] = params1.meshPhase[0]; params2.meshPhase[1] = params3.meshPhase[1] = params4.meshPhase[1] = params1.meshPhase[1]; params2.meshPhase[2] = params3.meshPhase[2] = params4.meshPhase[2] = params1.meshPhase[2]; fscanf(fpmesh,"%s\t%lf\t%lf\t%lf",&txt[0],¶ms1.meshPsi[0], ¶ms1.meshPsi[1], ¶ms1.meshPsi[2]); fprintf(stderr,"%s\t%e\t%e\t%f\t-> %e\n", txt, params1.meshPsi[0], params1.meshPsi[1], params1.meshPsi[2],params1.meshPsi[0]+params1.meshPsi[1]*(params1.meshPsi[2]-1.0)); params2.meshPsi[0] = params3.meshPsi[0] = params4.meshPsi[0] = params1.meshPsi[0]; params2.meshPsi[1] = params3.meshPsi[1] = params4.meshPsi[1] = params1.meshPsi[1]; params2.meshPsi[2] = params3.meshPsi[2] = params4.meshPsi[2] = params1.meshPsi[2]; fclose(fpmesh); /* allocate memory for 'chi square' matrix */ if (iL1) { output1.mChiSquare = NULL; LALDCreateVector( &status, &output1.mChiSquare,params1.meshH0[2]*params1.meshCosIota[2]*params1.meshPhase[2]*params1.meshPsi[2]); } if (iH1) { output2.mChiSquare = NULL; LALDCreateVector( &status, &output2.mChiSquare,params2.meshH0[2]*params2.meshCosIota[2]*params2.meshPhase[2]*params2.meshPsi[2]); } if (iH2) { output3.mChiSquare = NULL; LALDCreateVector( &status, &output3.mChiSquare,params3.meshH0[2]*params3.meshCosIota[2]*params3.meshPhase[2]*params3.meshPsi[2]); } if (iGEO) { output4.mChiSquare = NULL; LALDCreateVector( &status, &output4.mChiSquare,params4.meshH0[2]*params4.meshCosIota[2]*params4.meshPhase[2]*params4.meshPsi[2]); } /* allocate memory for pdfs */ if (iL1) { prob1.pdf = NULL; LALCreateVector(&status, &prob1.pdf, params1.meshH0[2]); prob1.cdf = NULL; LALCreateVector(&status, &prob1.cdf, params1.meshH0[2]); prob1.pdfPhase = NULL; LALCreateVector(&status, &prob1.pdfPhase, params1.meshPhase[2]); prob1.cdfPhase = NULL; LALCreateVector(&status, &prob1.cdfPhase, params1.meshPhase[2]); prob1.pdfPsi = NULL; LALCreateVector(&status, &prob1.pdfPsi, params1.meshPsi[2]); prob1.cdfPsi = NULL; LALCreateVector(&status, &prob1.cdfPsi, params1.meshPsi[2]); prob1.pdfCosIota = NULL; LALCreateVector(&status, &prob1.pdfCosIota, params1.meshCosIota[2]); prob1.cdfCosIota = NULL; LALCreateVector(&status, &prob1.cdfCosIota, params1.meshCosIota[2]); } if (iH1) { prob2.pdf = NULL; LALCreateVector(&status, &prob2.pdf, params2.meshH0[2]); prob2.cdf = NULL; LALCreateVector(&status, &prob2.cdf, params2.meshH0[2]); prob2.pdfPhase = NULL; LALCreateVector(&status, &prob2.pdfPhase, params2.meshPhase[2]); prob2.cdfPhase = NULL; LALCreateVector(&status, &prob2.cdfPhase, params2.meshPhase[2]); prob2.pdfPsi = NULL; LALCreateVector(&status, &prob2.pdfPsi, params2.meshPsi[2]); prob2.cdfPsi = NULL; LALCreateVector(&status, &prob2.cdfPsi, params2.meshPsi[2]); prob2.pdfCosIota = NULL; LALCreateVector(&status, &prob2.pdfCosIota, params2.meshCosIota[2]); prob2.cdfCosIota = NULL; LALCreateVector(&status, &prob2.cdfCosIota, params2.meshCosIota[2]); } if (iH2) { prob3.pdf = NULL; LALCreateVector(&status, &prob3.pdf, params3.meshH0[2]); prob3.cdf = NULL; LALCreateVector(&status, &prob3.cdf, params3.meshH0[2]); prob3.pdfPhase = NULL; LALCreateVector(&status, &prob3.pdfPhase, params3.meshPhase[2]); prob3.cdfPhase = NULL; LALCreateVector(&status, &prob3.cdfPhase, params3.meshPhase[2]); prob3.pdfPsi = NULL; LALCreateVector(&status, &prob3.pdfPsi, params3.meshPsi[2]); prob3.cdfPsi = NULL; LALCreateVector(&status, &prob3.cdfPsi, params3.meshPsi[2]); prob3.pdfCosIota = NULL; LALCreateVector(&status, &prob3.pdfCosIota, params3.meshCosIota[2]); prob3.cdfCosIota = NULL; LALCreateVector(&status, &prob3.cdfCosIota, params3.meshCosIota[2]); } if (iGEO) { prob4.pdf = NULL; LALCreateVector(&status, &prob4.pdf, params4.meshH0[2]); prob4.cdf = NULL; LALCreateVector(&status, &prob4.cdf, params4.meshH0[2]); prob4.pdfPhase = NULL; LALCreateVector(&status, &prob4.pdfPhase, params4.meshPhase[2]); prob4.cdfPhase = NULL; LALCreateVector(&status, &prob4.cdfPhase, params4.meshPhase[2]); prob4.pdfPsi = NULL; LALCreateVector(&status, &prob4.pdfPsi, params4.meshPsi[2]); prob4.cdfPsi = NULL; LALCreateVector(&status, &prob4.cdfPsi, params4.meshPsi[2]); prob4.pdfCosIota = NULL; LALCreateVector(&status, &prob4.pdfCosIota, params4.meshCosIota[2]); prob4.cdfCosIota = NULL; LALCreateVector(&status, &prob4.cdfCosIota, params4.meshCosIota[2]); } /* allocate memory for pdfs for joint analysis if there is data from more than one detector */ if (iH1 + iH2 + iL1 +iGEO > 1) { prob.pdf = NULL; LALCreateVector(&status, &prob.pdf, params1.meshH0[2]); prob.cdf = NULL; LALCreateVector(&status, &prob.cdf, params1.meshH0[2]); prob.pdfPhase = NULL; LALCreateVector(&status, &prob.pdfPhase, params1.meshPhase[2]); prob.cdfPhase = NULL; LALCreateVector(&status, &prob.cdfPhase, params1.meshPhase[2]); prob.pdfPsi = NULL; LALCreateVector(&status, &prob.pdfPsi, params1.meshPsi[2]); prob.cdfPsi = NULL; LALCreateVector(&status, &prob.cdfPsi, params1.meshPsi[2]); prob.pdfCosIota = NULL; LALCreateVector(&status, &prob.pdfCosIota, params1.meshCosIota[2]); prob.cdfCosIota = NULL; LALCreateVector(&status, &prob.cdfCosIota, params1.meshCosIota[2]); } minChi = 0.0; /* calculate chisquare for each IFO and then marginalize over nuissance parameters */ if (flag == 1) { if (iL1) { fprintf(stderr, "Entering LALCoarseFitToPulsar for L1\n"); LALCoarseFitToPulsar(&status,&output1, &input1_chi, ¶ms1); if(status.statusCode){ fprintf(stderr,"Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return 0;} minChi += output1.chiSquare; fprintf(stderr, "Entering LALPulsarMarginalize for L1\n"); LALPulsarMarginalize(&status, &prob1, &output1, ¶ms1);} if (iH1){ fprintf(stderr, "Entering LALCoarseFitToPulsar for H1\n"); LALCoarseFitToPulsar(&status,&output2, &input2_chi, ¶ms2); if(status.statusCode){ fprintf(stderr,"Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return 0;} minChi += output2.chiSquare; fprintf(stderr, "Entering LALPulsarMarginalize for H1\n"); LALPulsarMarginalize(&status, &prob2, &output2, ¶ms2);} if (iH2){ fprintf(stderr, "Entering LALCoarseFitToPulsar for H2\n"); LALCoarseFitToPulsar(&status,&output3, &input3_chi, ¶ms3); if(status.statusCode){ fprintf(stderr,"Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return 0;} minChi += output3.chiSquare; fprintf(stderr, "Entering LALPulsarMarginalize for H2\n"); LALPulsarMarginalize(&status, &prob3, &output3, ¶ms3);} if (iGEO){ fprintf(stderr, "Entering LALCoarseFitToPulsar for GEO\n"); LALCoarseFitToPulsar(&status,&output4, &input4_chi, ¶ms4); if(status.statusCode){ fprintf(stderr,"Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return 0;} minChi += output4.chiSquare; fprintf(stderr, "Entering LALPulsarMarginalize for GEO\n"); LALPulsarMarginalize(&status, &prob4, &output4, ¶ms4); } } else if (flag == 2) { if (iL1){ fprintf(stderr, "Entering FitToPulsarStudentT for L1\n"); LALFitToPulsarStudentT(&status,&output1, &input1, ¶ms1); if(status.statusCode){ fprintf(stderr,"Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return 0;} minChi += output1.chiSquare; fprintf(stderr, "Entering LALPulsarMarginalize for L1\n"); LALPulsarMarginalize(&status, &prob1, &output1, ¶ms1);} if (iH1){ fprintf(stderr, "Entering FitToPulsarStudentT for H1\n"); LALFitToPulsarStudentT(&status,&output2, &input2, ¶ms2); if(status.statusCode){ fprintf(stderr,"Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return 0;} minChi += output2.chiSquare; fprintf(stderr, "Entering LALPulsarMarginalize for H1\n"); LALPulsarMarginalize(&status, &prob2, &output2, ¶ms2);} if (iH2){ fprintf(stderr, "Entering FitToPulsarStudentT for H2\n"); LALFitToPulsarStudentT(&status,&output3, &input3, ¶ms3); if(status.statusCode){ fprintf(stderr,"Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return 0;} minChi += output3.chiSquare; fprintf(stderr, "Entering LALPulsarMarginalize for H2\n"); LALPulsarMarginalize(&status, &prob3, &output3, ¶ms3);} if (iGEO){ fprintf(stderr, "Entering FitToPulsarStudentT for GEO\n"); LALFitToPulsarStudentT(&status,&output4, &input4, ¶ms4); if(status.statusCode){ fprintf(stderr,"Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return 0;} minChi += output4.chiSquare; fprintf(stderr, "Entering LALPulsarMarginalize for GEO\n"); LALPulsarMarginalize(&status, &prob4, &output4, ¶ms4);} } /************ BEGIN MARGINALIZE FOR JOINT PDF *******************************/ /* if there is data from more that one IFO then calculate joint pdfs */ if (iL1+iH1+iH2+iGEO>1) { /* initialize to zero */ for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++) { prob.pdf->data[iH0] = 0.0; prob.cdf->data[iH0] = 0.0; } for (iPhase=0; iPhase < params1.meshPhase[2]; iPhase++) { prob.pdfPhase->data[iPhase] = 0.0; prob.cdfPhase->data[iPhase] = 0.0; } for (iPsi=0;iPsi< params1.meshPsi[2]; iPsi++) { prob.pdfPsi->data[iPsi] = 0.0; prob.cdfPsi->data[iPsi] = 0.0; } for (iCosIota = 0; iCosIota < params1.meshCosIota[2];iCosIota++) { prob.pdfCosIota->data[iCosIota] = 0.0; prob.cdfCosIota->data[iCosIota] = 0.0; } /* marginalize over angles to get p(h0|Bk) */ for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++) for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++) for (iCosIota = 0; iCosIota < params1.meshCosIota[2];iCosIota++) for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++){ arg = iH0 + params1.meshH0[2]*(iCosIota + params1.meshCosIota[2]*(iPhase + params1.meshPhase[2]*iPsi)); if (iL1) outL1 = output1.mChiSquare->data[arg]; else outL1 = 0.0; if (iH1) outH1 = output2.mChiSquare->data[arg]; else outH1 = 0.0; if (iH2) outH2 = output3.mChiSquare->data[arg]; else outH2 = 0.0; if (iGEO) outGEO = output4.mChiSquare->data[arg]; else outGEO = 0.0; prob.pdf->data[iH0] += exp((minChi - (outL1 + outH1 + outH2 + outGEO))/2.0); } area = 0.0; for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++) area += prob.pdf->data[iH0]*params1.meshH0[1]; for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++) prob.pdf->data[iH0] = prob.pdf->data[iH0]/area; prob.cdf->data[0] = prob.pdf->data[0]*params1.meshH0[1]; for (iH0 = 1; iH0 < params1.meshH0[2]; iH0++) prob.cdf->data[iH0] = prob.pdf->data[iH0]*params1.meshH0[1] + prob.cdf->data[iH0-1]; /* marginalize over h0, psi, cosIota to get p(phase|Bk) */ for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++) for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++) for (iCosIota = 0; iCosIota < params1.meshCosIota[2];iCosIota++) for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++){ arg = iH0 + params1.meshH0[2]*(iCosIota + params1.meshCosIota[2]*(iPhase + params1.meshPhase[2]*iPsi)); if (iL1) outL1 = output1.mChiSquare->data[arg]; else outL1 = 0.0; if (iH1) outH1 = output2.mChiSquare->data[arg]; else outH1 = 0.0; if (iH2) outH2 = output3.mChiSquare->data[arg]; else outH2 = 0.0; if (iGEO) outGEO = output4.mChiSquare->data[arg]; else outGEO = 0.0; prob.pdfPhase->data[iPhase] += exp((minChi - (outL1 + outH1 + outH2 + outGEO))/2.0); } area = 0.0; for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++) area += prob.pdfPhase->data[iPhase]*params1.meshPhase[1]; for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++) prob.pdfPhase->data[iPhase] = prob.pdfPhase->data[iPhase]/area; prob.cdfPhase->data[0] = prob.pdfPhase->data[0]*params1.meshPhase[1]; for (iPhase = 1; iPhase < params1.meshPhase[2]; iPhase++) prob.cdfPhase->data[iPhase] = prob.pdf->data[iPhase]*params1.meshPhase[1] + prob.cdf->data[iPhase-1]; /* marginalize over phase, h0, and cosIota to get p(Psi|Bk) */ for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++) for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++) for (iCosIota = 0; iCosIota < params1.meshCosIota[2];iCosIota++) for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++){ arg = iH0 + params1.meshH0[2]*(iCosIota + params1.meshCosIota[2]*(iPhase + params1.meshPhase[2]*iPsi)); if (iL1) outL1 = output1.mChiSquare->data[arg]; else outL1 = 0.0; if (iH1) outH1 = output2.mChiSquare->data[arg]; else outH1 = 0.0; if (iH2) outH2 = output3.mChiSquare->data[arg]; else outH2 = 0.0; if (iGEO) outGEO = output4.mChiSquare->data[arg]; else outGEO = 0.0; prob.pdfPsi->data[iPsi] += exp((minChi - (outL1 + outH1 + outH2 + outGEO))/2.0); } area = 0.0; for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++) area += prob.pdfPsi->data[iPsi]*params1.meshPsi[1]; for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++) prob.pdfPsi->data[iPsi] = prob.pdfPsi->data[iPsi]/area; prob.cdfPsi->data[0] = prob.pdfPsi->data[0]*params1.meshPsi[1]; for (iPsi = 1; iPsi < params1.meshPsi[2]; iPsi++) prob.cdfPsi->data[iPsi] = prob.pdfPsi->data[iPsi]*params1.meshPsi[1] + prob.cdfPsi->data[iPsi-1]; /* marginalize over phase, psi, and h0 to get p(Cosiota|Bk) */ for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++) for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++) for (iH0 = 0; iH0 < params1.meshH0[2];iH0++) for (iCosIota = 0; iCosIota < params1.meshCosIota[2]; iCosIota++){ arg = iH0 + params1.meshH0[2]*(iCosIota + params1.meshCosIota[2]*(iPhase + params1.meshPhase[2]*iPsi)); if (iL1) outL1 = output1.mChiSquare->data[arg]; else outL1 = 0.0; if (iH1) outH1 = output2.mChiSquare->data[arg]; else outH1 = 0.0; if (iH2) outH2 = output3.mChiSquare->data[arg]; else outH2 = 0.0; if (iGEO) outGEO = output4.mChiSquare->data[arg]; else outGEO = 0.0; prob.pdfCosIota->data[iCosIota] += exp((minChi - (outL1 + outH1 + outH2 + outGEO))/2.0); } area = 0.0; for (iCosIota = 0; iCosIota < params1.meshCosIota[2]; iCosIota++) area += prob.pdfCosIota->data[iCosIota]*params1.meshCosIota[1]; for (iCosIota = 0; iCosIota < params1.meshCosIota[2]; iCosIota++) prob.pdfCosIota->data[iCosIota] = prob.pdfCosIota->data[iCosIota]/area; prob.cdfCosIota->data[0] = prob.pdfCosIota->data[0]*params1.meshCosIota[1]; for (iCosIota = 1; iCosIota < params1.meshCosIota[2]; iCosIota++) prob.cdfCosIota->data[iCosIota] = prob.pdfCosIota->data[iCosIota]*params1.meshCosIota[1] + prob.cdfCosIota->data[iCosIota-1]; } /************ END MARGINALIZE FOR JOINT PDF *******************************/ /********************* BEGIN WRITING OUTPUT FILES *********************************/ if (iL1) { if (flag == 1) { sprintf(outfile1,"%s/%s/pdf.%s_L1", argv[2], pulsar_name, pulsar_name); sprintf(outfile1Phase,"%s/%s/pdfPhase.%s_L1", argv[2], pulsar_name, pulsar_name); sprintf(outfile1Psi,"%s/%s/pdfPsi.%s_L1", argv[2], pulsar_name, pulsar_name); sprintf(outfile1CosIota,"%s/%s/pdfCosIota.%s_L1", argv[2], pulsar_name, pulsar_name); } else if (flag == 2) { sprintf(outfile1,"%s/pdfoutputs/pdf_st.%s_L1", argv[2], pulsar_name); sprintf(outfile1Phase,"%s/pdfoutputs/pdfPhase_st.%s_L1", argv[2], pulsar_name); sprintf(outfile1Psi,"%s/pdfoutputs/pdfPsi_st.%s_L1", argv[2], pulsar_name); sprintf(outfile1CosIota,"%s/pdfoutputs/pdfCosIota_st.%s_L1", argv[2], pulsar_name); } fp_pdf1 = fopen(outfile1, "w"); fp_pdf1Phase = fopen(outfile1Phase, "w"); fp_pdf1Psi = fopen(outfile1Psi, "w"); fp_pdf1CosIota = fopen(outfile1CosIota, "w"); for (i=0;i<params1.meshH0[2];i++) fprintf(fp_pdf1,"%e\t%e\t%e\n", params1.meshH0[0]+(float)i*params1.meshH0[1],prob1.pdf->data[i], prob1.cdf->data[i]); for (i=0;i<params1.meshPhase[2];i++) fprintf(fp_pdf1Phase,"%e\t%e\t%e\n", params1.meshPhase[0]+(float)i*params1.meshPhase[1],prob1.pdfPhase->data[i], prob1.cdfPhase->data[i]); for (i=0;i<params1.meshPsi[2];i++) fprintf(fp_pdf1Psi,"%e\t%e\t%e\n", params1.meshPsi[0]+(float)i*params1.meshPsi[1],prob1.pdfPsi->data[i], prob1.cdfPsi->data[i]); for (i=0;i<params1.meshCosIota[2];i++) fprintf(fp_pdf1CosIota,"%e\t%e\t%e\n", params1.meshCosIota[0]+(float)i*params1.meshCosIota[1],prob1.pdfCosIota->data[i], prob1.cdfCosIota->data[i]); fclose(fp_pdf1); fclose(fp_pdf1Phase); fclose(fp_pdf1Psi); fclose(fp_pdf1CosIota); } if (iH1) { if (flag ==1) { sprintf(outfile2,"%s/%s/pdf.%s_H1", argv[2], pulsar_name, pulsar_name); sprintf(outfile2Phase,"%s/%s/pdfPhase.%s_H1", argv[2], pulsar_name, pulsar_name); sprintf(outfile2Psi,"%s/%s/pdfPsi.%s_H1", argv[2], pulsar_name, pulsar_name); sprintf(outfile2CosIota,"%s/%s/pdfCosIota.%s_H1", argv[2], pulsar_name, pulsar_name); } else if (flag == 2) { sprintf(outfile2,"%s/pdfoutputs/pdf_st.%s_H1", argv[2], pulsar_name); sprintf(outfile2Phase,"%s/pdfoutputs/pdfPhase_st.%s_H1", argv[2], pulsar_name); sprintf(outfile2Psi,"%s/pdfoutputs/pdfPsi_st.%s_H1", argv[2], pulsar_name); sprintf(outfile2CosIota,"%s/pdfoutputs/pdfCosIota_st.%s_H1", argv[2], pulsar_name); } fp_pdf2 = fopen(outfile2, "w"); fp_pdf2Phase = fopen(outfile2Phase, "w"); fp_pdf2Psi = fopen(outfile2Psi, "w"); fp_pdf2CosIota = fopen(outfile2CosIota, "w"); for (i=0;i<params1.meshH0[2];i++) fprintf(fp_pdf2,"%e\t%e\t%e\n", params2.meshH0[0]+(float)i*params2.meshH0[1], prob2.pdf->data[i], prob2.cdf->data[i]); for (i=0;i<params1.meshPhase[2];i++) fprintf(fp_pdf2Phase,"%e\t%e\t%e\n", params2.meshPhase[0]+(float)i*params2.meshPhase[1], prob2.pdfPhase->data[i], prob2.cdfPhase->data[i]); for (i=0;i<params1.meshPsi[2];i++) fprintf(fp_pdf2Psi,"%e\t%e\t%e\n", params2.meshPsi[0]+(float)i*params2.meshPsi[1], prob2.pdfPsi->data[i], prob2.cdfPsi->data[i]); for (i=0;i<params1.meshCosIota[2];i++) fprintf(fp_pdf2CosIota,"%e\t%e\t%e\n", params2.meshCosIota[0]+(float)i*params2.meshCosIota[1], prob2.pdfCosIota->data[i], prob2.cdfCosIota->data[i]); fclose(fp_pdf2); fclose(fp_pdf2Phase); fclose(fp_pdf2Psi); fclose(fp_pdf2CosIota); } if (iH2) { if (flag ==1) { sprintf(outfile3,"%s/%s/pdf.%s_H2", argv[2], pulsar_name, pulsar_name); sprintf(outfile3Phase,"%s/%s/pdfPhase.%s_H2", argv[2], pulsar_name, pulsar_name); sprintf(outfile3Psi,"%s/%s/pdfPsi.%s_H2", argv[2], pulsar_name, pulsar_name); sprintf(outfile3CosIota,"%s/%s/pdfCosIota.%s_H2", argv[2], pulsar_name, pulsar_name); } else if (flag == 2) { sprintf(outfile3,"%s/pdfoutputs/pdf_st.%s_H2", argv[2], pulsar_name); sprintf(outfile3Phase,"%s/pdfoutputs/pdfPhase_st.%s_H2", argv[2], pulsar_name); sprintf(outfile3Psi,"%s/pdfoutputs/pdfPsi_st.%s_H2", argv[2], pulsar_name); sprintf(outfile3CosIota,"%s/pdfoutputs/pdfCosIota_st.%s_H2", argv[2], pulsar_name); } fp_pdf3 = fopen(outfile3, "w"); fp_pdf3Phase = fopen(outfile3Phase, "w"); fp_pdf3Psi = fopen(outfile3Psi, "w"); fp_pdf3CosIota = fopen(outfile3CosIota, "w"); for (i=0;i<params1.meshH0[2];i++) fprintf(fp_pdf3,"%e\t%e\t%e\n", params3.meshH0[0]+(float)i*params3.meshH0[1], prob3.pdf->data[i], prob3.cdf->data[i]); for (i=0;i<params1.meshPhase[2];i++) fprintf(fp_pdf3Phase,"%e\t%e\t%e\n", params3.meshPhase[0]+(float)i*params3.meshPhase[1], prob3.pdfPhase->data[i], prob3.cdfPhase->data[i]); for (i=0;i<params1.meshPsi[2];i++) fprintf(fp_pdf3Psi,"%e\t%e\t%e\n", params3.meshPsi[0]+(float)i*params3.meshPsi[1], prob3.pdfPsi->data[i], prob3.cdfPsi->data[i]); for (i=0;i<params1.meshCosIota[2];i++) fprintf(fp_pdf3CosIota,"%e\t%e\t%e\n", params3.meshCosIota[0]+(float)i*params3.meshCosIota[1], prob3.pdfCosIota->data[i], prob3.cdfCosIota->data[i]); fclose(fp_pdf3); fclose(fp_pdf3Phase); fclose(fp_pdf3Psi); fclose(fp_pdf3CosIota); } if (iGEO){ if (flag ==1) { sprintf(outfile4,"%s/%s/pdf.%s_GEO", argv[2], pulsar_name, pulsar_name); sprintf(outfile4Phase,"%s/%s/pdfPhase.%s_GEO", argv[2], pulsar_name, pulsar_name); sprintf(outfile4Psi,"%s/%s/pdfPsi.%s_GEO", argv[2], pulsar_name, pulsar_name); sprintf(outfile4CosIota,"%s/%s/pdfCosIota.%s_GEO", argv[2], pulsar_name, pulsar_name); } else if (flag == 2) { sprintf(outfile4,"%s/pdfoutputs/pdf_st.%s_GEO", argv[2], pulsar_name); sprintf(outfile4Phase,"%s/pdfoutputs/pdfPhase_st.%s_GEO", argv[2], pulsar_name); sprintf(outfile4Psi,"%s/pdfoutputs/pdfPsi_st.%s_GEO", argv[2], pulsar_name); sprintf(outfile4CosIota,"%s/pdfoutputs/pdfCosIota_st.%s_GEO", argv[2], pulsar_name); } fp_pdf4 = fopen(outfile4, "w"); fp_pdf4Phase = fopen(outfile4Phase, "w"); fp_pdf4Psi = fopen(outfile4Psi, "w"); fp_pdf4CosIota = fopen(outfile4CosIota, "w"); for (i=0;i<params1.meshH0[2];i++) fprintf(fp_pdf4,"%e\t%e\t%e\n", params4.meshH0[0]+(float)i*params4.meshH0[1], prob4.pdf->data[i], prob4.cdf->data[i]); for (i=0;i<params1.meshPhase[2];i++) fprintf(fp_pdf4Phase,"%e\t%e\t%e\n", params4.meshPhase[0]+(float)i*params4.meshPhase[1], prob4.pdfPhase->data[i], prob4.cdfPhase->data[i]); for (i=0;i<params1.meshPsi[2];i++) fprintf(fp_pdf4Psi,"%e\t%e\t%e\n", params4.meshPsi[0]+(float)i*params4.meshPsi[1], prob4.pdfPsi->data[i], prob4.cdfPsi->data[i]); for (i=0;i<params1.meshCosIota[2];i++) fprintf(fp_pdf4CosIota,"%e\t%e\t%e\n", params4.meshCosIota[0]+(float)i*params4.meshCosIota[1], prob4.pdfCosIota->data[i], prob4.cdfCosIota->data[i]); fclose(fp_pdf4); fclose(fp_pdf4Phase); fclose(fp_pdf4Psi); fclose(fp_pdf4CosIota); } if (iL1+iH1+iH2+iGEO>1) { if (flag ==1) { sprintf(outfile,"%s/%s/pdf.%s_Joint", argv[2], pulsar_name, pulsar_name); sprintf(outfilePhase,"%s/%s/pdfPhase.%s_Joint", argv[2], pulsar_name, pulsar_name); sprintf(outfilePsi,"%s/%s/pdfPsi.%s_Joint", argv[2], pulsar_name, pulsar_name); sprintf(outfileCosIota,"%s/%s/pdfCosIota.%s_Joint", argv[2], pulsar_name, pulsar_name); } else if (flag == 2) { sprintf(outfile,"%s/pdfoutputs/pdf_st.%s_Joint", argv[2], pulsar_name); sprintf(outfilePhase,"%s/pdfoutputs/pdfPhase_st.%s_Joint", argv[2], pulsar_name); sprintf(outfilePsi,"%s/pdfoutputs/pdfPsi_st.%s_Joint", argv[2], pulsar_name); sprintf(outfileCosIota,"%s/pdfoutputs/pdfCosIota_st.%s_Joint", argv[2], pulsar_name); } fp_joint = fopen(outfile, "w"); fp_jointPhase = fopen(outfilePhase, "w"); fp_jointPsi = fopen(outfilePsi, "w"); fp_jointCosIota = fopen(outfileCosIota, "w"); for (i=0;i<params1.meshH0[2];i++) fprintf(fp_joint,"%e\t%e\t%e\n", params1.meshH0[0]+(float)i*params1.meshH0[1], prob.pdf->data[i], prob.cdf->data[i]); for (i=0;i<params1.meshPhase[2];i++) fprintf(fp_jointPhase,"%e\t%e\t%e\n", params1.meshPhase[0]+(float)i*params1.meshPhase[1], prob.pdfPhase->data[i], prob.cdfPhase->data[i]); for (i=0;i<params1.meshPsi[2];i++) fprintf(fp_jointPsi,"%e\t%e\t%e\n", params1.meshPsi[0]+(float)i*params1.meshPsi[1], prob.pdfPsi->data[i], prob.cdfPsi->data[i]); for (i=0;i<params1.meshCosIota[2];i++) fprintf(fp_jointCosIota,"%e\t%e\t%e\n", params1.meshCosIota[0]+(float)i*params1.meshCosIota[1], prob.pdfCosIota->data[i], prob.cdfCosIota->data[i]); fclose(fp_joint);fclose(fp_jointPhase);fclose(fp_jointPsi);fclose(fp_jointCosIota); } /********************* END WRITING OUTPUT FILES*********************************/ /* print out best fit information for each IFO */ if (iL1){fprintf(stderr, "BEST FIT FOR L1:\n"); fprintf(stderr,"h0 = %e\tcosIota = %f\tpsi = %f\tphase = %f\nchisquare = %f\n", output1.h0, output1.cosIota, output1.psi, output1.phase, output1.chiSquare);} if (iH1){fprintf(stderr, "\nBEST FIT FOR H1:\n"); fprintf(stderr,"h0 = %e\tcosIota = %f\tpsi = %f\tphase = %f\nchisquare = %f\n", output2.h0, output2.cosIota, output2.psi, output2.phase, output2.chiSquare);} if (iH2){fprintf(stderr, "\nBEST FIT FOR H2:\n"); fprintf(stderr,"h0 = %e\tcosIota = %f\tpsi = %f\tphase = %f\nchisquare = %f\n", output3.h0, output3.cosIota, output3.psi, output3.phase, output3.chiSquare);} if (iGEO){fprintf(stderr, "\nBEST FIT FOR GEO:\n"); fprintf(stderr,"h0 = %e\tcosIota = %f\tpsi = %f\tphase = %f\nchisquare = %f\n", output4.h0, output4.cosIota, output4.psi, output4.phase, output4.chiSquare);} fprintf(stderr,"iL1 = %d\tiH1=%d\tiH2=%d\tiGEO=%d\n", iL1, iH1, iH2, iGEO); /* free allocated memory */ if (iL1) { if (flag == 1) LALZDestroyVector(&status, &input1_chi.B); else if (flag ==2) LALZDestroyVector(&status, &input1.B); LALDDestroyVector(&status, &output1.mChiSquare); LALDestroyVector(&status, &prob1.pdf); LALDestroyVector(&status, &prob1.cdf); LALDestroyVector(&status, &prob1.pdfPhase); LALDestroyVector(&status, &prob1.cdfPhase); LALDestroyVector(&status, &prob1.pdfPsi); LALDestroyVector(&status, &prob1.cdfPsi); LALDestroyVector(&status, &prob1.pdfCosIota); LALDestroyVector(&status, &prob1.cdfCosIota); } if (iH1){ if (flag == 1) LALZDestroyVector(&status, &input2_chi.B); else if (flag == 2) LALZDestroyVector(&status, &input2.B); LALDDestroyVector(&status, &output2.mChiSquare); LALDestroyVector(&status, &prob2.pdf); LALDestroyVector(&status, &prob2.cdf); LALDestroyVector(&status, &prob2.pdfPhase); LALDestroyVector(&status, &prob2.cdfPhase); LALDestroyVector(&status, &prob2.pdfPsi); LALDestroyVector(&status, &prob2.cdfPsi); LALDestroyVector(&status, &prob2.pdfCosIota); LALDestroyVector(&status, &prob2.cdfCosIota); } if (iH2){ if (flag == 1) LALZDestroyVector(&status, &input3_chi.B); else if (flag == 2) LALZDestroyVector(&status, &input3.B); LALDDestroyVector(&status, &output3.mChiSquare); LALDestroyVector(&status, &prob3.pdf); LALDestroyVector(&status, &prob3.cdf); LALDestroyVector(&status, &prob3.pdfPhase); LALDestroyVector(&status, &prob3.cdfPhase); LALDestroyVector(&status, &prob3.pdfPsi); LALDestroyVector(&status, &prob3.cdfPsi); LALDestroyVector(&status, &prob3.pdfCosIota); LALDestroyVector(&status, &prob3.cdfCosIota); } if (iGEO){ if (flag == 1) LALZDestroyVector(&status, &input4_chi.B); else if (flag == 2) LALZDestroyVector(&status, &input4.B); LALDDestroyVector(&status, &output4.mChiSquare); LALDestroyVector(&status, &prob4.pdf); LALDestroyVector(&status, &prob4.cdf); LALDestroyVector(&status, &prob4.pdfPhase); LALDestroyVector(&status, &prob4.cdfPhase); LALDestroyVector(&status, &prob4.pdfPsi); LALDestroyVector(&status, &prob4.cdfPsi); LALDestroyVector(&status, &prob4.pdfCosIota); LALDestroyVector(&status, &prob4.cdfCosIota); } if (iL1+iH1+iH2+iGEO>1) { LALDestroyVector(&status, &prob.pdf); LALDestroyVector(&status, &prob.cdf); LALDestroyVector(&status, &prob.pdfPhase); LALDestroyVector(&status, &prob.cdfPhase); LALDestroyVector(&status, &prob.pdfPsi); LALDestroyVector(&status, &prob.cdfPsi); LALDestroyVector(&status, &prob.pdfCosIota); LALDestroyVector(&status, &prob.cdfCosIota); } LALCheckMemoryLeaks(); return(0); } /* main */
int main(void) { static LALStatus status; LALDetector detector; LALSource pulsar; CoarseFitOutput output; CoarseFitInput input; CoarseFitParams params; LIGOTimeGPS tgps[FITTOPULSARTEST_LENGTH]; REAL4 cosIota; REAL4 phase; REAL4 psi; REAL4 h0; REAL4 cos2phase, sin2phase; static RandomParams *randomParams; static REAL4Vector *noise; INT4 seed = 0; LALDetAndSource detAndSource; LALDetAMResponseSeries pResponseSeries = {NULL,NULL,NULL}; REAL4TimeSeries Fp, Fc, Fs; LALTimeIntervalAndNSample time_info; UINT4 i; /* Allocate memory */ input.B = NULL; input.var = NULL; LALZCreateVector( &status, &input.B, FITTOPULSARTEST_LENGTH); LALZCreateVector( &status, &input.var, FITTOPULSARTEST_LENGTH); noise = NULL; LALCreateVector( &status, &noise, FITTOPULSARTEST_LENGTH); LALCreateRandomParams( &status, &randomParams, seed); Fp.data = NULL; Fc.data = NULL; Fs.data = NULL; pResponseSeries.pPlus = &(Fp); pResponseSeries.pCross = &(Fc); pResponseSeries.pScalar = &(Fs); LALSCreateVector(&status, &(pResponseSeries.pPlus->data), 1); LALSCreateVector(&status, &(pResponseSeries.pCross->data), 1); LALSCreateVector(&status, &(pResponseSeries.pScalar->data), 1); input.t = tgps; /******** GENERATE FAKE INPUT **********/ time_info.epoch.gpsSeconds = FITTOPULSARTEST_T0; time_info.epoch.gpsNanoSeconds = 0; time_info.deltaT = 60; time_info.nSample = FITTOPULSARTEST_LENGTH; cosIota = 0.5; psi = 0.1; phase = 0.4; h0 = 5.0; cos2phase = cos(2.0*phase); sin2phase = sin(2.0*phase); detector = lalCachedDetectors[LALDetectorIndexGEO600DIFF]; /* use GEO 600 detector for tests */ pulsar.equatorialCoords.longitude = 1.4653; /* right ascention of pulsar */ pulsar.equatorialCoords.latitude = -1.2095; /* declination of pulsar */ pulsar.equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; /* coordinate system */ pulsar.orientation = psi; /* polarization angle */ strcpy(pulsar.name, "fakepulsar"); /* name of pulsar */ detAndSource.pDetector = &detector; detAndSource.pSource = &pulsar; LALNormalDeviates( &status, noise, randomParams ); LALComputeDetAMResponseSeries(&status, &pResponseSeries, &detAndSource, &time_info); for (i = 0;i < FITTOPULSARTEST_LENGTH; i++) { input.t[i].gpsSeconds = FITTOPULSARTEST_T0 + 60*i; input.t[i].gpsNanoSeconds = 0; input.B->data[i] = crect( pResponseSeries.pPlus->data->data[i]*h0*(1.0 + cosIota*cosIota)*cos2phase + 2.0*pResponseSeries.pCross->data->data[i]*h0*cosIota*sin2phase, pResponseSeries.pPlus->data->data[i]*h0*(1.0 + cosIota*cosIota)*sin2phase - 2.0*pResponseSeries.pCross->data->data[i]*h0*cosIota*cos2phase ); input.var->data[i] = crect( noise->data[FITTOPULSARTEST_LENGTH-i-1]*noise->data[FITTOPULSARTEST_LENGTH-i-1], noise->data[i]*noise->data[i] ); } input.B->length = FITTOPULSARTEST_LENGTH; input.var->length = FITTOPULSARTEST_LENGTH; /******* TEST RESPONSE TO VALID DATA ************/ /* Test that valid data generate the correct answers */ params.detector = detector; params.pulsarSrc = pulsar; params.meshH0[0] = 4.0; params.meshH0[1] = 0.2; params.meshH0[2] = 10; params.meshCosIota[0] = 0.0; params.meshCosIota[1] = 0.1; params.meshCosIota[2] = 10; params.meshPhase[0] = 0.0; params.meshPhase[1] = 0.1; params.meshPhase[2] = 10; params.meshPsi[0] = 0.0; params.meshPsi[1] = 0.1; params.meshPsi[2] = 10; output.mChiSquare = NULL; LALDCreateVector( &status, &output.mChiSquare,params.meshH0[2]*params.meshCosIota[2]*params.meshPhase[2]*params.meshPsi[2]); LALCoarseFitToPulsar(&status,&output, &input, ¶ms); if(status.statusCode) { printf("Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return FITTOPULSARTESTC_EFLS; } if(output.phase > phase + params.meshPhase[2] || output.phase < phase - params.meshPhase[2]) { printf("Got incorrect phase %f when expecting %f \n", output.phase, phase); return FITTOPULSARTESTC_EFLS; } if(output.cosIota > cosIota + params.meshCosIota[2] || output.cosIota < cosIota - params.meshCosIota[2]) { printf("Got incorrect cosIota %f when expecting %f \n", output.cosIota, cosIota); return FITTOPULSARTESTC_EFLS; } if(output.psi > psi + params.meshPsi[2] || output.psi < psi - params.meshPsi[2]) { printf("Got incorrect psi %f when expecting %f \n", output.psi, psi); return FITTOPULSARTESTC_EFLS; } /******* TEST RESPONSE OF LALCoarseFitToPulsar TO INVALID DATA ************/ #ifndef LAL_NDEBUG if ( ! lalNoDebug ) { /* Test that all the error conditions are correctly detected by the function */ LALCoarseFitToPulsar(&status, NULL, &input, ¶ms); if (status.statusCode != FITTOPULSARH_ENULLOUTPUT || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLOUTPUT)) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription); printf( "Expected error code %d and message %s\n", FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT); return FITTOPULSARTESTC_ECHK; } LALCoarseFitToPulsar(&status, &output, NULL, ¶ms); if (status.statusCode != FITTOPULSARH_ENULLINPUT || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLINPUT)) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription); printf( "Expected error code %d and message %s\n", FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT); return FITTOPULSARTESTC_ECHK; } LALCoarseFitToPulsar(&status, &output, &input, NULL); if (status.statusCode != FITTOPULSARH_ENULLPARAMS || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLPARAMS)) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription); printf( "Expected error code %d and message %s\n", FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS); return FITTOPULSARTESTC_ECHK; } /* try having two input vectors of different length */ input.var->length = 1; LALCoarseFitToPulsar(&status, &output, &input, ¶ms); if (status.statusCode != FITTOPULSARH_EVECSIZE || strcmp(status.statusDescription, FITTOPULSARH_MSGEVECSIZE)) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription); printf( "Expected error code %d and message %s\n", FITTOPULSARH_EVECSIZE, FITTOPULSARH_MSGEVECSIZE); return FITTOPULSARTESTC_ECHK; } input.var->length = FITTOPULSARTEST_LENGTH; } /* if ( ! lalNoDebug ) */ #endif /* LAL_NDEBUG */ /******* CLEAN UP ************/ LALZDestroyVector(&status, &input.B); LALZDestroyVector(&status, &input.var); LALDestroyVector(&status, &noise); LALDDestroyVector(&status, &output.mChiSquare); LALDestroyRandomParams(&status, &randomParams); LALSDestroyVector(&status, &(pResponseSeries.pPlus->data)); LALSDestroyVector(&status, &(pResponseSeries.pCross->data)); LALSDestroyVector(&status, &(pResponseSeries.pScalar->data)); LALCheckMemoryLeaks(); return FITTOPULSARTESTC_ENOM; }
/* void RunGeneratePulsarSignalTest(LALStatus *status, int argc, char **argv) */ /* 02/02/05 gam */ void RunGeneratePulsarSignalTest(LALStatus *status) { INT4 i, j, k; /* all purpose indices */ INT4 iSky = 0; /* for loop over sky positions */ INT4 jDeriv = 0; /* for loop over spindowns */ INT4 testNumber = 0; /* which test is being run */ /* The input and output structs used by the functions being tested */ PulsarSignalParams *pPulsarSignalParams = NULL; REAL4TimeSeries *signalvec = NULL; SFTParams *pSFTParams = NULL; SkyConstAndZeroPsiAMResponse *pSkyConstAndZeroPsiAMResponse; SFTandSignalParams *pSFTandSignalParams; SFTVector *outputSFTs = NULL; SFTVector *fastOutputSFTs = NULL; REAL4 renorm; /* to renormalize SFTs to account for different effective sample rates */ /* containers for detector and ephemeris data */ LALDetector cachedDetector; CHAR IFO[6] = "LHO"; EphemerisData *edat = NULL; char earthFile[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz"; char sunFile[] = TEST_DATA_DIR "sun00-19-DE405.dat.gz"; /* containers for sky position and spindown data */ REAL8 **skyPosData; REAL8 **freqDerivData; INT4 numSkyPosTotal = 8; INT4 numSpinDown = 1; INT4 numFreqDerivTotal = 2; INT4 numFreqDerivIncludingNoSpinDown; /* set below */ INT4 iFreq = 0; REAL8 cosTmpDEC; REAL8 tmpDeltaRA; REAL8 DeltaRA = 0.01; REAL8 DeltaDec = 0.01; REAL8 DeltaFDeriv1 = -1.0e-10; REAL8 DeltaFDeriv2 = 0.0; REAL8 DeltaFDeriv3 = 0.0; REAL8 DeltaFDeriv4 = 0.0; REAL8 DeltaFDeriv5 = 0.0; /* containers for number of SFTs, times to generate SFTs, reference time, and gap */ INT4 numSFTs = 4; REAL8 f0SFT = 943.12; REAL8 bandSFT = 0.5; UINT4 gpsStartTimeSec = 765432109; /* GPS start time of data requested seconds; example = Apr 08 2004 04:01:36 UTC */ UINT4 gpsStartTimeNan = 0; /* GPS start time of data requested nanoseconds */ LIGOTimeGPSVector *timeStamps; LIGOTimeGPS GPSin; /* holder for reference-time for pulsar parameters at the detector; will convert to SSB! */ REAL8 sftGap = 73.0; /* extra artificial gap between SFTs */ REAL8 tSFT = 1800.0; REAL8 duration = tSFT + (numSFTs - 1)*(tSFT + sftGap); INT4 nBinsSFT = (INT4)(bandSFT*tSFT + 0.5); /* additional parameters that determine what signals to test; note f0SGNL and bandSGNL must be compatible with f0SFT and bandSFT */ REAL8 f0SGNL = f0SFT + bandSFT/2.0; REAL8 dfSGNL = 1.0/tSFT; REAL8 bandSGNL = 0.005; INT4 nBinsSGNL = (INT4)(bandSGNL*tSFT + 0.5); INT4 nsamples = 18000; /* nsamples from SFT header; 2 x this would be the effective number of time samples used to create an SFT from raw data */ INT4 Dterms = 3; /* 09/07/05 gam; use Dterms to fill in SFT bins with fake data as per LALDemod else fill in bin with zero */ REAL8 h_0 = 7.0e-22; /* Source amplitude; use arbitrary small number for default */ REAL8 cosIota; /* cosine of inclination angle iota of the source */ /* variables for comparing differences */ REAL4 maxDiffSFTMod, diffAtMaxPower; REAL4 overallMaxDiffSFTMod; REAL4 maxMod, fastMaxMod; INT4 jMaxMod, jFastMaxMod; REAL4 tmpDiffSFTMod, sftMod, fastSFTMod; REAL4 smallMod = 1.e-30; REAL4 epsDiffMod; REAL4 epsBinErrorRate; /* 10/12/04 gam; Allowed bin error rate */ INT4 binErrorCount = 0; /* 10/12/04 gam; Count number of bin errors */ /* randval is always set to a default value or given a random value to generate certain signal parameters or mismatch */ REAL4 randval; #ifdef INCLUDE_RANDVAL_MISMATCH INT4 seed=0; INT4 rndCount; RandomParams *randPar=NULL; FILE *fpRandom; #endif INITSTATUS(status); ATTATCHSTATUSPTR(status); /* generate timeStamps */ timeStamps = (LIGOTimeGPSVector *)LALMalloc(sizeof(LIGOTimeGPSVector)); timeStamps->data =(LIGOTimeGPS *)LALMalloc (numSFTs*sizeof(LIGOTimeGPS)); timeStamps->length = numSFTs; for (i = 0; i < numSFTs; i++) { timeStamps->data[i].gpsSeconds = gpsStartTimeSec + (UINT4)(i*(tSFT + sftGap)); timeStamps->data[i].gpsNanoSeconds = 0; } /* for i < numSFTs */ /* generate skyPosData */ skyPosData=(REAL8 **)LALMalloc(numSkyPosTotal*sizeof(REAL8 *)); for(iSky=0;iSky<numSkyPosTotal;iSky++) { skyPosData[iSky] = (REAL8 *)LALMalloc(2*sizeof(REAL8)); /* Try fairly random sky positions skyPosData[iSky][0] = RA, skyPosData[iSky][1] = DEC */ if (iSky == 0) { skyPosData[iSky][0] = 0.02*LAL_TWOPI; skyPosData[iSky][1] = 0.03*LAL_PI/2.0; } else if (iSky == 1) { skyPosData[iSky][0] = 0.23*LAL_TWOPI; skyPosData[iSky][1] = -0.57*LAL_PI/2.0; } else if (iSky == 2) { skyPosData[iSky][0] = 0.47*LAL_TWOPI; skyPosData[iSky][1] = 0.86*LAL_PI/2.0; } else if (iSky == 3) { skyPosData[iSky][0] = 0.38*LAL_TWOPI; skyPosData[iSky][1] = -0.07*LAL_PI/2.0; } else if (iSky == 4) { skyPosData[iSky][0] = 0.65*LAL_TWOPI; skyPosData[iSky][1] = 0.99*LAL_PI/2.0; } else if (iSky == 5) { skyPosData[iSky][0] = 0.72*LAL_TWOPI; skyPosData[iSky][1] = -0.99*LAL_PI/2.0; } else if (iSky == 6) { skyPosData[iSky][0] = 0.81*LAL_TWOPI; skyPosData[iSky][1] = 0.19*LAL_PI/2.0; } else if (iSky == 7) { skyPosData[iSky][0] = 0.99*LAL_TWOPI; skyPosData[iSky][1] = 0.01*LAL_PI/2.0; } else { skyPosData[iSky][0] = 0.0; skyPosData[iSky][1] = 0.0; } /* END if (k == 0) ELSE ... */ } /* END for(iSky=0;iSky<numSkyPosTotal;iSky++) */ freqDerivData = NULL; /* 02/02/05 gam */ if (numSpinDown > 0) { freqDerivData=(REAL8 **)LALMalloc(numFreqDerivTotal*sizeof(REAL8 *)); for(jDeriv=0;jDeriv<numFreqDerivTotal;jDeriv++) { freqDerivData[jDeriv] = (REAL8 *)LALMalloc(numSpinDown*sizeof(REAL8)); if (jDeriv == 0) { for(k=0;k<numSpinDown;k++) { freqDerivData[jDeriv][k] = 0.0; } } else if (jDeriv == 1) { for(k=0;k<numSpinDown;k++) { freqDerivData[jDeriv][k] = 1.e-9; /* REALLY THIS IS ONLY GOOD FOR numSpinDown = 1; */ } } else { for(k=0;k<numSpinDown;k++) { freqDerivData[jDeriv][k] = 0.0; } } /* END if (k == 0) ELSE ... */ } /* END for(jDeriv=0;jDeriv<numFreqDerivTotal;jDeriv++) */ numFreqDerivIncludingNoSpinDown = numFreqDerivTotal; } else { numFreqDerivIncludingNoSpinDown = 1; /* Even if numSpinDown = 0 still need to count case of zero spindown. */ } /* END if (numSpinDown > 0) ELSE ... */ /* Initialize ephemeris data */ XLAL_CHECK_LAL (status, ( edat = XLALInitBarycenter( earthFile, sunFile ) ) != NULL, XLAL_EFUNC); /* Allocate memory for PulsarSignalParams and initialize */ pPulsarSignalParams = (PulsarSignalParams *)LALMalloc(sizeof(PulsarSignalParams)); pPulsarSignalParams->pulsar.position.system = COORDINATESYSTEM_EQUATORIAL; pPulsarSignalParams->pulsar.spindown = NULL; if (numSpinDown > 0) { LALDCreateVector(status->statusPtr, &(pPulsarSignalParams->pulsar.spindown),((UINT4)numSpinDown)); CHECKSTATUSPTR (status); } pPulsarSignalParams->orbit.asini = 0 /* isolated pulsar */; pPulsarSignalParams->transfer = NULL; pPulsarSignalParams->dtDelayBy2 = 0; pPulsarSignalParams->dtPolBy2 = 0; /* Set up pulsar site */ if (strstr(IFO, "LHO")) { cachedDetector = lalCachedDetectors[LALDetectorIndexLHODIFF]; } else if (strstr(IFO, "LLO")) { cachedDetector = lalCachedDetectors[LALDetectorIndexLLODIFF]; } else if (strstr(IFO, "GEO")) { cachedDetector = lalCachedDetectors[LALDetectorIndexGEO600DIFF]; } else if (strstr(IFO, "VIRGO")) { cachedDetector = lalCachedDetectors[LALDetectorIndexVIRGODIFF]; } else if (strstr(IFO, "TAMA")) { cachedDetector = lalCachedDetectors[LALDetectorIndexTAMA300DIFF]; } else { /* "Invalid or null IFO" */ ABORT( status, GENERATEPULSARSIGNALTESTC_EIFO, GENERATEPULSARSIGNALTESTC_MSGEIFO); } pPulsarSignalParams->site = &cachedDetector; pPulsarSignalParams->ephemerides = edat; pPulsarSignalParams->startTimeGPS.gpsSeconds = (INT4)gpsStartTimeSec; pPulsarSignalParams->startTimeGPS.gpsNanoSeconds = (INT4)gpsStartTimeNan; pPulsarSignalParams->duration = (UINT4)duration; pPulsarSignalParams->samplingRate = (REAL8)ceil(2.0*bandSFT); /* Make sampleRate an integer so that T*samplingRate = integer for integer T */ pPulsarSignalParams->fHeterodyne = f0SFT; GPSin.gpsSeconds = timeStamps->data[0].gpsSeconds; GPSin.gpsNanoSeconds = timeStamps->data[0].gpsNanoSeconds; /* Allocate memory for SFTParams and initialize */ pSFTParams = (SFTParams *)LALCalloc(1, sizeof(SFTParams)); pSFTParams->Tsft = tSFT; pSFTParams->timestamps = timeStamps; pSFTParams->noiseSFTs = NULL; #ifdef INCLUDE_RANDVAL_MISMATCH /* Initial seed and randPar to use LALUniformDeviate to generate random mismatch during Monte Carlo. */ fpRandom = fopen("/dev/urandom","r"); rndCount = fread(&seed, sizeof(INT4),1, fpRandom); fclose(fpRandom); /* seed = 1234; */ /* Test value */ LALCreateRandomParams(status->statusPtr, &randPar, seed); CHECKSTATUSPTR (status); #endif /* allocate memory for structs needed by LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs */ pSkyConstAndZeroPsiAMResponse = (SkyConstAndZeroPsiAMResponse *)LALMalloc(sizeof(SkyConstAndZeroPsiAMResponse)); pSkyConstAndZeroPsiAMResponse->skyConst = (REAL8 *)LALMalloc((2*numSpinDown*(numSFTs+1)+2*numSFTs+3)*sizeof(REAL8)); pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi = (REAL4 *)LALMalloc(numSFTs*sizeof(REAL4)); pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi = (REAL4 *)LALMalloc(numSFTs*sizeof(REAL4)); pSFTandSignalParams = (SFTandSignalParams *)LALMalloc(sizeof(SFTandSignalParams)); /* create lookup table (LUT) values for doing trig */ /* pSFTandSignalParams->resTrig = 64; */ /* length sinVal and cosVal; resolution of trig functions = 2pi/resTrig */ /* pSFTandSignalParams->resTrig = 128; */ /* 10/08/04 gam; length sinVal and cosVal; domain = -2pi to 2pi inclusive; resolution = 4pi/resTrig */ pSFTandSignalParams->resTrig = 0; /* 10/12/04 gam; turn off using LUTs since this is more typical. */ /* 02/02/05 gam; if NOT pSFTandSignalParams->resTrig > 0 should not create trigArg etc... */ if (pSFTandSignalParams->resTrig > 0) { pSFTandSignalParams->trigArg = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8)); pSFTandSignalParams->sinVal = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8)); pSFTandSignalParams->cosVal = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8)); for (k=0; k<=pSFTandSignalParams->resTrig; k++) { /* pSFTandSignalParams->trigArg[k]= ((REAL8)LAL_TWOPI) * ((REAL8)k) / ((REAL8)pSFTandSignalParams->resTrig); */ /* 10/08/04 gam */ pSFTandSignalParams->trigArg[k]= -1.0*((REAL8)LAL_TWOPI) + 2.0 * ((REAL8)LAL_TWOPI) * ((REAL8)k) / ((REAL8)pSFTandSignalParams->resTrig); pSFTandSignalParams->sinVal[k]=sin( pSFTandSignalParams->trigArg[k] ); pSFTandSignalParams->cosVal[k]=cos( pSFTandSignalParams->trigArg[k] ); } } pSFTandSignalParams->pSigParams = pPulsarSignalParams; pSFTandSignalParams->pSFTParams = pSFTParams; pSFTandSignalParams->nSamples = nsamples; pSFTandSignalParams->Dterms = Dterms; /* 09/07/05 gam */ /* ********************************************************/ /* */ /* START SECTION: LOOP OVER SKY POSITIONS */ /* */ /* ********************************************************/ for(iSky=0;iSky<numSkyPosTotal;iSky++) { /* set source sky position declination (DEC) */ randval = 0.5; /* Gives default value */ #ifdef INCLUDE_SEQUENTIAL_MISMATCH randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) ); #endif #ifdef INCLUDE_RANDVAL_MISMATCH LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status); #endif pPulsarSignalParams->pulsar.position.latitude = skyPosData[iSky][1] + (((REAL8)randval) - 0.5)*DeltaDec; cosTmpDEC = cos(skyPosData[iSky][1]); if (cosTmpDEC != 0.0) { tmpDeltaRA = DeltaRA/cosTmpDEC; } else { tmpDeltaRA = 0.0; /* We are at a celestial pole */ } /* set source sky position right ascension (RA) */ randval = 0.5; /* Gives default value */ #ifdef INCLUDE_SEQUENTIAL_MISMATCH randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) ); #endif #ifdef INCLUDE_RANDVAL_MISMATCH LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status); #endif pPulsarSignalParams->pulsar.position.longitude = skyPosData[iSky][0] + (((REAL8)randval) - 0.5)*tmpDeltaRA; /* Find reference time in SSB for this sky positions */ int ret = XLALConvertGPS2SSB ( &(pPulsarSignalParams->pulsar.refTime), GPSin, pPulsarSignalParams ); if ( ret != XLAL_SUCCESS ) { XLALPrintError ("XLALConvertGPS2SSB() failed with xlalErrno = %d\n", xlalErrno ); ABORTXLAL (status); } /* one per sky position fill in SkyConstAndZeroPsiAMResponse for use with LALFastGeneratePulsarSFTs */ LALComputeSkyAndZeroPsiAMResponse (status->statusPtr, pSkyConstAndZeroPsiAMResponse, pSFTandSignalParams); CHECKSTATUSPTR (status); /* ********************************************************/ /* */ /* START SECTION: LOOP OVER SPINDOWN */ /* */ /* ********************************************************/ for(jDeriv=0;jDeriv<numFreqDerivIncludingNoSpinDown;jDeriv++) { /* source spindown parameters */ if (numSpinDown > 0) { for(k=0;k<numSpinDown;k++) { randval = 0.5; /* Gives default value */ #ifdef INCLUDE_SEQUENTIAL_MISMATCH if (freqDerivData[jDeriv][k] < 0.0) { randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) ); } else { randval = 0.5; /* If derivative is not negative (i.e., it is zero) then do not add in mismatch; keep it zero. */ } #endif #ifdef INCLUDE_RANDVAL_MISMATCH LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status); #endif if (k == 0) { pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv1; } else if (k == 1) { pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv2; } else if (k == 2) { pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv3; } else if (k == 3) { pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv4; } else if (k == 4) { pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv5; } /* END if (k == 0) ELSE ... */ } } /* ***************************************************/ /* */ /* START SECTION: LOOP OVER FREQUENCIES */ /* */ /* ***************************************************/ for(iFreq=0;iFreq<nBinsSGNL;iFreq++) { /* set source orientation psi */ randval = 0.5; /* Gives default value */ #ifdef INCLUDE_SEQUENTIAL_MISMATCH randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) ); #endif #ifdef INCLUDE_RANDVAL_MISMATCH LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status); #endif pPulsarSignalParams->pulsar.psi = (randval - 0.5) * ((REAL4)LAL_PI_2); /* set angle between source spin axis and direction from source to SSB, cosIota */ randval = 1.0; /* Gives default value */ #ifdef INCLUDE_SEQUENTIAL_MISMATCH randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) ); #endif #ifdef INCLUDE_RANDVAL_MISMATCH LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status); #endif cosIota = 2.0*((REAL8)randval) - 1.0; /* h_0 is fixed above; get A_+ and A_x from h_0 and cosIota */ pPulsarSignalParams->pulsar.aPlus = (REAL4)(0.5*h_0*(1.0 + cosIota*cosIota)); pPulsarSignalParams->pulsar.aCross = (REAL4)(h_0*cosIota); /* get random value for phi0 */ randval = 0.125; /* Gives default value pi/4*/ #ifdef INCLUDE_SEQUENTIAL_MISMATCH randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) ); #endif #ifdef INCLUDE_RANDVAL_MISMATCH LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status); #endif pPulsarSignalParams->pulsar.phi0 = ((REAL8)randval) * ((REAL8)LAL_TWOPI); /* randval steps through various mismatches to frequencies centered on a bin */ /* Note that iFreq = nBinsSGNL/2 gives randval = 0.5 gives no mismatch from frequency centered on a bin */ randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) ); #ifdef INCLUDE_RANDVAL_MISMATCH LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status); #endif pPulsarSignalParams->pulsar.f0 = f0SGNL + iFreq*dfSGNL + (((REAL8)randval) - 0.5)*dfSGNL; testNumber++; /* Update count of which test we about to do. */ /* FIRST: Use LALGeneratePulsarSignal and LALSignalToSFTs to generate outputSFTs */ signalvec = NULL; LALGeneratePulsarSignal(status->statusPtr, &signalvec, pPulsarSignalParams); CHECKSTATUSPTR (status); outputSFTs = NULL; LALSignalToSFTs(status->statusPtr, &outputSFTs, signalvec, pSFTParams); CHECKSTATUSPTR (status); #ifdef PRINT_OUTPUTSFT if (testNumber == TESTNUMBER_TO_PRINT) { i=SFTINDEX_TO_PRINT; /* index of which outputSFT to output */ fprintf(stdout,"iFreq = %i, inject h_0 = %23.10e \n",iFreq,h_0); fprintf(stdout,"iFreq = %i, inject cosIota = %23.10e, A_+ = %23.10e, A_x = %23.10e \n",iFreq,cosIota,pPulsarSignalParams->pulsar.aPlus,pPulsarSignalParams->pulsar.aCross); fprintf(stdout,"iFreq = %i, inject psi = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.psi); fprintf(stdout,"iFreq = %i, inject phi0 = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.phi0); fprintf(stdout,"iFreq = %i, search f0 = %23.10e, inject f0 = %23.10e \n",iFreq,f0SGNL + iFreq*dfSGNL,pPulsarSignalParams->pulsar.f0); fprintf(stdout,"outputSFTs->data[%i].data->length = %i \n",i,outputSFTs->data[i].data->length); renorm = ((REAL4)nsamples)/((REAL4)(outputSFTs->data[i].data->length - 1)); for(j=0;j<nBinsSFT;j++) { /* fprintf(stdout,"%i %g %g \n", j, renorm*outputSFTs->data[i].data->data[j].re, renorm*outputSFTs->data[i].data->data[j].im); */ fprintf(stdout,"%i %g \n",j,renorm*renorm*outputSFTs->data[i].data->data[j].re*outputSFTs->data[i].data->data[j].re + renorm*renorm*outputSFTs->data[i].data->data[j].im*outputSFTs->data[i].data->data[j].im); fflush(stdout); } } #endif /* SECOND: Use LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs to generate outputSFTs */ LALFastGeneratePulsarSFTs (status->statusPtr, &fastOutputSFTs, pSkyConstAndZeroPsiAMResponse, pSFTandSignalParams); CHECKSTATUSPTR (status); #ifdef PRINT_FASTOUTPUTSFT if (testNumber == TESTNUMBER_TO_PRINT) { REAL4 fPlus; REAL4 fCross; i=SFTINDEX_TO_PRINT; /* index of which outputSFT to output */ fPlus = pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi[i]*cos(2.0*pPulsarSignalParams->pulsar.psi) + pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi[i]*sin(2.0*pPulsarSignalParams->pulsar.psi); fCross = pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi[i]*cos(2.0*pPulsarSignalParams->pulsar.psi) - pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi[i]*sin(2.0*pPulsarSignalParams->pulsar.psi); fprintf(stdout,"iFreq = %i, inject h_0 = %23.10e \n",iFreq,h_0); fprintf(stdout,"iFreq = %i, inject cosIota = %23.10e, A_+ = %23.10e, A_x = %23.10e \n",iFreq,cosIota,pPulsarSignalParams->pulsar.aPlus,pPulsarSignalParams->pulsar.aCross); fprintf(stdout,"iFreq = %i, inject psi = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.psi); fprintf(stdout,"iFreq = %i, fPlus, fCross = %23.10e, %23.10e \n",iFreq,fPlus,fCross); fprintf(stdout,"iFreq = %i, inject phi0 = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.phi0); fprintf(stdout,"iFreq = %i, search f0 = %23.10e, inject f0 = %23.10e \n",iFreq,f0SGNL + iFreq*dfSGNL,pPulsarSignalParams->pulsar.f0); fprintf(stdout,"fastOutputSFTs->data[%i].data->length = %i \n",i,fastOutputSFTs->data[i].data->length); fflush(stdout); for(j=0;j<nBinsSFT;j++) { /* fprintf(stdout,"%i %g %g \n",j,fastOutputSFTs->data[i].data->data[j].re,fastOutputSFTs->data[i].data->data[j].im); */ fprintf(stdout,"%i %g \n",j,fastOutputSFTs->data[i].data->data[j].re*fastOutputSFTs->data[i].data->data[j].re + fastOutputSFTs->data[i].data->data[j].im*fastOutputSFTs->data[i].data->data[j].im); fflush(stdout); } } #endif /* find maximum difference in power */ epsDiffMod = 0.20; /* maximum allowed percent difference */ /* 10/12/04 gam */ overallMaxDiffSFTMod = 0.0; for (i = 0; i < numSFTs; i++) { renorm = ((REAL4)nsamples)/((REAL4)(outputSFTs->data[i].data->length - 1)); maxDiffSFTMod = 0.0; diffAtMaxPower = 0.0; maxMod = 0.0; fastMaxMod = 0.0; jMaxMod = -1; jFastMaxMod = -1; /* Since doppler shifts can move the signal by an unknown number of bins search the whole band for max modulus: */ for(j=0;j<nBinsSFT;j++) { sftMod = renorm*renorm*crealf(outputSFTs->data[i].data->data[j])*crealf(outputSFTs->data[i].data->data[j]) + renorm*renorm*cimagf(outputSFTs->data[i].data->data[j])*cimagf(outputSFTs->data[i].data->data[j]); sftMod = sqrt(sftMod); fastSFTMod = crealf(fastOutputSFTs->data[i].data->data[j])*crealf(fastOutputSFTs->data[i].data->data[j]) + cimagf(fastOutputSFTs->data[i].data->data[j])*cimagf(fastOutputSFTs->data[i].data->data[j]); fastSFTMod = sqrt(fastSFTMod); if (fabs(sftMod) > smallMod) { tmpDiffSFTMod = fabs((sftMod - fastSFTMod)/sftMod); if (tmpDiffSFTMod > maxDiffSFTMod) { maxDiffSFTMod = tmpDiffSFTMod; } if (tmpDiffSFTMod > overallMaxDiffSFTMod) { overallMaxDiffSFTMod = tmpDiffSFTMod; } if (sftMod > maxMod) { maxMod = sftMod; jMaxMod = j; } if (fastSFTMod > fastMaxMod) { fastMaxMod = fastSFTMod; jFastMaxMod = j; } } } if (fabs(maxMod) > smallMod) { diffAtMaxPower = fabs((maxMod - fastMaxMod)/maxMod); } #ifdef PRINT_MAXSFTPOWER fprintf(stdout,"maxSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jMaxMod,maxMod); fprintf(stdout,"maxFastSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jFastMaxMod,fastMaxMod); fflush(stdout); #endif #ifdef PRINT_MAXDIFFSFTPOWER fprintf(stdout,"maxDiffSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jMaxDiff,maxDiffSFTMod); fflush(stdout); #endif #ifdef PRINT_DIFFATMAXPOWER fprintf(stdout,"diffAtMaxPower, testNumber %i, SFT %i, bins %i and %i = %g \n",testNumber,i,jMaxMod,jFastMaxMod,diffAtMaxPower); fflush(stdout); #endif #ifdef PRINT_ERRORATMAXPOWER if (diffAtMaxPower > epsDiffMod) { fprintf(stdout,"diffAtMaxPower, testNumber %i, SFT %i, bins %i and %i = %g exceeded epsDiffMod = %g \n",testNumber,i,jMaxMod,jFastMaxMod,diffAtMaxPower,epsDiffMod); fflush(stdout); /* break; */ /* only report 1 error per test */ } if (jMaxMod != jFastMaxMod) { fprintf(stdout,"MaxPower occurred in different bins: testNumber %i, SFT %i, bins %i and %i\n",testNumber,i,jMaxMod,jFastMaxMod); fflush(stdout); /* break; */ /* only report 1 error per test */ } #endif if (jMaxMod != jFastMaxMod) { binErrorCount++; /* 10/12/04 gam; count up bin errors; if too ABORT at bottom of code */ } if ( diffAtMaxPower > epsDiffMod ) { ABORT( status, GENERATEPULSARSIGNALTESTC_EMOD, GENERATEPULSARSIGNALTESTC_MSGEMOD); } /* 10/12/04 gam; turn on test above and add test below */ if ( fabs(((REAL8)(jMaxMod - jFastMaxMod))) > 1.1 ) { ABORT( status, GENERATEPULSARSIGNALTESTC_EBIN, GENERATEPULSARSIGNALTESTC_MSGEBIN); } } /* END for(i = 0; i < numSFTs; i++) */ #ifdef PRINT_OVERALLMAXDIFFSFTPOWER fprintf(stdout,"overallMaxDiffSFTMod, testNumber = %i, SFT %i, bin %i = %g \n",testNumber,iOverallMaxDiffSFTMod,jOverallMaxDiff,overallMaxDiffSFTMod); fflush(stdout); #endif /* 09/07/05 gam; Initialize fastOutputSFTs since only 2*Dterms bins are changed by LALFastGeneratePulsarSFTs */ for (i = 0; i < numSFTs; i++) { for(j=0;j<nBinsSFT;j++) { fastOutputSFTs->data[i].data->data[j] = 0.0; } } XLALDestroySFTVector( outputSFTs); LALFree(signalvec->data->data); LALFree(signalvec->data); LALFree(signalvec); } /* END for(iFreq=0;iFreq<nBinsSGNL;iFreq++) */ /* ***************************************************/ /* */ /* END SECTION: LOOP OVER FREQUENCIES */ /* */ /* ***************************************************/ } /* END for(jDeriv=0;jDeriv<numFreqDerivIncludingNoSpinDown;jDeriv++) */ /* ********************************************************/ /* */ /* END SECTION: LOOP OVER SPINDOWN */ /* */ /* ********************************************************/ } /* END for(iSky=0;iSky<numSkyPosTotal;iSky++) */ /* ********************************************************/ /* */ /* END SECTION: LOOP OVER SKY POSITIONS */ /* */ /* ********************************************************/ /* 10/12/04 gam; check if too many bin errors */ epsBinErrorRate = 0.20; /* 10/12/04 gam; maximum allowed bin errors */ if ( (((REAL4)binErrorCount)/((REAL4)testNumber)) > epsBinErrorRate ) { ABORT( status, GENERATEPULSARSIGNALTESTC_EBINS, GENERATEPULSARSIGNALTESTC_MSGEBINS); } #ifdef INCLUDE_RANDVAL_MISMATCH LALDestroyRandomParams(status->statusPtr, &randPar); CHECKSTATUSPTR (status); #endif /* fprintf(stdout,"Total number of tests completed = %i. \n", testNumber); fflush(stdout); */ LALFree(pSFTParams); if (numSpinDown > 0) { LALDDestroyVector(status->statusPtr, &(pPulsarSignalParams->pulsar.spindown)); CHECKSTATUSPTR (status); } LALFree(pPulsarSignalParams); /* deallocate memory for structs needed by LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs */ XLALDestroySFTVector( fastOutputSFTs); LALFree(pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi); LALFree(pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi); LALFree(pSkyConstAndZeroPsiAMResponse->skyConst); LALFree(pSkyConstAndZeroPsiAMResponse); /* 02/02/05 gam; if NOT pSFTandSignalParams->resTrig > 0 should not create trigArg etc... */ if (pSFTandSignalParams->resTrig > 0) { LALFree(pSFTandSignalParams->trigArg); LALFree(pSFTandSignalParams->sinVal); LALFree(pSFTandSignalParams->cosVal); } LALFree(pSFTandSignalParams); /* deallocate skyPosData */ for(i=0;i<numSkyPosTotal;i++) { LALFree(skyPosData[i]); } LALFree(skyPosData); if (numSpinDown > 0) { /* deallocate freqDerivData */ for(i=0;i<numFreqDerivTotal;i++) { LALFree(freqDerivData[i]); } LALFree(freqDerivData); } LALFree(timeStamps->data); LALFree(timeStamps); XLALDestroyEphemerisData(edat); CHECKSTATUSPTR (status); DETATCHSTATUSPTR (status); }
void LALGenerateRing( LALStatus *stat, CoherentGW *output, REAL4TimeSeries UNUSED *series, SimRingdownTable *simRingdown, RingParamStruc *params ) { UINT4 i; /* number of and index over samples */ REAL8 t, dt; /* time, interval */ REAL8 gtime ; /* central time, decay time */ REAL8 f0, quality; /* frequency and quality factor */ REAL8 twopif0; /* 2*pi*f0 */ REAL4 h0; /* peak strain for ringdown */ REAL4 *fData; /* pointer to frequency data */ REAL8 *phiData; /* pointer to phase data */ REAL8 init_phase; /*initial phase of injection */ REAL4 *aData; /* pointer to frequency data */ UINT4 nPointInj; /* number of data points in a block */ #if 0 UINT4 n; REAL8 t0; REAL4TimeSeries signalvec; /* start time of block that injection is injected into */ LALTimeInterval interval; INT8 geoc_tns; /* geocentric_start_time of the injection in ns */ INT8 block_tns; /* start time of block in ns */ REAL8 deltaTns; INT8 inj_diff; /* time between start of segment and injection */ LALTimeInterval dummyInterval; #endif INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Make sure parameter and output structures exist. */ ASSERT( params, stat, GENERATERINGH_ENUL, GENERATERINGH_MSGENUL ); ASSERT( output, stat, GENERATERINGH_ENUL, GENERATERINGH_MSGENUL ); /* Make sure output fields don't exist. */ ASSERT( !( output->a ), stat, GENERATERINGH_EOUT, GENERATERINGH_MSGEOUT ); ASSERT( !( output->f ), stat, GENERATERINGH_EOUT, GENERATERINGH_MSGEOUT ); ASSERT( !( output->phi ), stat, GENERATERINGH_EOUT, GENERATERINGH_MSGEOUT ); ASSERT( !( output->shift ), stat, GENERATERINGH_EOUT, GENERATERINGH_MSGEOUT ); /* Set up some other constants, to avoid repeated dereferencing. */ dt = params->deltaT; /* N_point = 2 * floor(0.5+ 1/ dt); */ nPointInj = 163840; /* Generic ring parameters */ h0 = simRingdown->amplitude; quality = (REAL8)simRingdown->quality; f0 = (REAL8)simRingdown->frequency; twopif0 = f0*LAL_TWOPI; init_phase = simRingdown->phase; if ( ( output->a = (REAL4TimeVectorSeries *) LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) { ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } memset( output->a, 0, sizeof(REAL4TimeVectorSeries) ); if ( ( output->f = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } memset( output->f, 0, sizeof(REAL4TimeSeries) ); if ( ( output->phi = (REAL8TimeSeries *) LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } memset( output->phi, 0, sizeof(REAL8TimeSeries) ); /* Set output structure metadata fields. */ output->position.longitude = simRingdown->longitude; output->position.latitude = simRingdown->latitude; output->position.system = params->system; output->psi = simRingdown->polarization; /* set epoch of output time series to that of the block */ output->a->epoch = output->f->epoch = output->phi->epoch = simRingdown->geocent_start_time; output->a->deltaT = params->deltaT; output->f->deltaT = output->phi->deltaT = params->deltaT; output->a->sampleUnits = lalStrainUnit; output->f->sampleUnits = lalHertzUnit; output->phi->sampleUnits = lalDimensionlessUnit; snprintf( output->a->name, LALNameLength, "Ring amplitudes" ); snprintf( output->f->name, LALNameLength, "Ring frequency" ); snprintf( output->phi->name, LALNameLength, "Ring phase" ); /* Allocate phase and frequency arrays. */ LALSCreateVector( stat->statusPtr, &( output->f->data ), nPointInj ); BEGINFAIL( stat ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); LALDCreateVector( stat->statusPtr, &( output->phi->data ), nPointInj ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); /* Allocate amplitude array. */ { CreateVectorSequenceIn in; /* input to create output->a */ in.length = nPointInj; in.vectorLength = 2; LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); } /* set arrays to zero */ memset( output->f->data->data, 0, sizeof( REAL4 ) * output->f->data->length ); memset( output->phi->data->data, 0, sizeof( REAL8 ) * output->phi->data->length ); memset( output->a->data->data, 0, sizeof( REAL4 ) * output->a->data->length * output->a->data->vectorLength ); /* Fill frequency and phase arrays starting at time of injection NOT start */ fData = output->f->data->data; phiData = output->phi->data->data; aData = output->a->data->data; if ( !( strcmp( simRingdown->waveform, "Ringdown" ) ) ) { for ( i = 0; i < nPointInj; i++ ) { t = i * dt; gtime = twopif0 / 2 / quality * t ; *(fData++) = f0; *(phiData++) = twopif0 * t+init_phase; *(aData++) = h0 * ( 1.0 + pow( cos( simRingdown->inclination ), 2 ) ) * exp( - gtime ); *(aData++) = h0* 2.0 * cos( simRingdown->inclination ) * exp( - gtime ); } } else { ABORT( stat, GENERATERINGH_ETYP, GENERATERINGH_MSGETYP ); } /* Set output field and return. */ DETATCHSTATUSPTR( stat ); RETURN( stat ); }
/** \see See \ref DetInverse_c for documentation */ void LALDMatrixInverse( LALStatus *stat, REAL8 *det, REAL8Array *matrix, REAL8Array *inverse ) { INT2 sgn; /* sign of permutation. */ UINT4 n, i, j, ij; /* array dimension and indecies */ UINT4Vector *indx = NULL; /* permutation storage vector */ REAL8Vector *col = NULL; /* columns of inverse matrix */ INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Check dimension length. Other argument testing is done by the subroutines. */ ASSERT( matrix, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( matrix->dimLength, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( matrix->dimLength->data, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( inverse, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( inverse->dimLength, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( inverse->dimLength->data, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( inverse->dimLength->length == 2, stat, MATRIXUTILSH_EDIM, MATRIXUTILSH_MSGEDIM ); n = inverse->dimLength->data[0]; ASSERT( n, stat, MATRIXUTILSH_EDIM, MATRIXUTILSH_MSGEDIM ); ASSERT( n == inverse->dimLength->data[1], stat, MATRIXUTILSH_EDIM, MATRIXUTILSH_MSGEDIM ); /* Allocate vectors to store the matrix permutation and column vectors. */ TRY( LALU4CreateVector( stat->statusPtr, &indx, n ), stat ); LALDCreateVector( stat->statusPtr, &col, n ); BEGINFAIL( stat ) { TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat ); } ENDFAIL( stat ); /* Decompose the matrix. */ LALDLUDecomp( stat->statusPtr, &sgn, matrix, indx ); BEGINFAIL( stat ) { TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &col ), stat ); } ENDFAIL( stat ); /* Compute the determinant, if available. */ if ( det ) { *det = sgn; for ( i = 0; i < n; i++ ) *det *= matrix->data[i*(n+1)]; } /* Compute each column of inverse matrix. */ for ( j = 0; j < n; j++ ) { memset( col->data, 0, n*sizeof(REAL8) ); col->data[j] = 1.0; LALDLUBackSub( stat->statusPtr, col, matrix, indx ); BEGINFAIL( stat ) { TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &col ), stat ); } ENDFAIL( stat ); for ( i = 0, ij = j; i < n; i++, ij += n ) inverse->data[ij] = col->data[i]; } /* Clean up. */ TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &col ), stat ); DETATCHSTATUSPTR( stat ); RETURN( stat ); }
int main(int argc, char **argv) { /* top-level status structure */ UINT4 numPSDpts=8193; static LALStatus status; static InspiralCoarseBankIn coarseIn; void *noisemodel = LALLIGOIPsd; double beta; SnglInspiralTable *tiles=NULL, *first=NULL; FILE *fpr; /* Number of templates is nlist */ INT4 nlist1, j; fpr = fopen("BCVSpinTemplates.out", "w"); nlist1 = 0; coarseIn.HighGM = 6.; coarseIn.LowGM = -4.; coarseIn.fLower = 40.L; coarseIn.fUpper = 400.L; coarseIn.tSampling = 4096.L; coarseIn.order = twoPN; coarseIn.mmCoarse = 0.90; coarseIn.mmFine = 0.90; coarseIn.iflso = 0.0L; coarseIn.mMin = 3.0; coarseIn.mMax = 20.0; coarseIn.MMax = coarseIn.mMax * 2.; coarseIn.massRange = MinMaxComponentMass; /* coarseIn.massRange = MinComponentMassMaxTotalMass;*/ /* minimum value of eta */ coarseIn.etamin = coarseIn.mMin * ( coarseIn.MMax - coarseIn.mMin) / pow(coarseIn.MMax,2.); coarseIn.psi0Min = 1.0e4; coarseIn.psi0Max = 6.0e4; coarseIn.psi3Min = -5.0e2; coarseIn.psi3Max = 1.0e1; coarseIn.alpha = 0.L; coarseIn.numFcutTemplates = 1; coarseIn.betaMin = 10.0; coarseIn.betaMax = 700.; coarseIn.spinBank = 2; coarseIn.iseed = 9295883; coarseIn.nTIni = 10000; coarseIn.ShMaxSz = 1024; coarseIn.gridSpacing = Hexagonal; coarseIn.insidePolygon = True; memset( &(coarseIn.shf), 0, sizeof(REAL8FrequencySeries) ); coarseIn.shf.f0 = 0; LALDCreateVector( &status, &(coarseIn.shf.data), numPSDpts ); coarseIn.shf.deltaF = coarseIn.tSampling / (2.*(REAL8) coarseIn.shf.data->length + 1.L); LALNoiseSpectralDensity (&status, coarseIn.shf.data, noisemodel, coarseIn.shf.deltaF ); coarseIn.approximant = BCVSpin; coarseIn.space = Psi0Psi3; LALInspiralBCVSpinRandomBank (&status, &tiles, &nlist1, &coarseIn); /* LALInspiralBankGeneration(&status, &coarseIn, &tiles, &nlist1); */ LALDDestroyVector( &status, &(coarseIn.shf.data) ); fprintf (fpr, "#numtemplaes=%d %e %e %e %e %e %e\n", nlist1, coarseIn.psi0Min, coarseIn.psi0Max, coarseIn.psi3Min, coarseIn.psi3Max, coarseIn.betaMin, coarseIn.betaMax); beta = tiles->beta; first = tiles; for (j=0; j<nlist1; j++) { fprintf(fpr, "%7.3f %e %e\n", beta, tiles->psi0, tiles->psi3); tiles = tiles->next; if (tiles != NULL && beta != tiles->beta) { beta = tiles->beta; } } fclose(fpr); tiles = first; for (j=0; j<nlist1; j++) { first = tiles ->next; if (tiles != NULL) LALFree(tiles); tiles = first; } LALCheckMemoryLeaks(); return 0; }
/* Function to generate time domain waveform for injection */ void GenerateTimeDomainWaveformForInjection ( LALStatus *status, REAL4Vector *buff, InspiralTemplate *param ) { CoherentGW waveform; PPNParamStruc ppnParams; INT4 nStartPad = 0; INITSTATUS(status); ATTATCHSTATUSPTR(status); memset( &waveform, 0, sizeof(CoherentGW) ); ppnParams.deltaT = 1.0 / param->tSampling; ppnParams.mTot = param->mass1 + param->mass2; ppnParams.eta = param->eta; ppnParams.d = param->distance; ppnParams.inc = param->inclination; ppnParams.phi = param->startPhase; ppnParams.fStartIn = param->fLower; ppnParams.fStopIn = -1.0 / (6.0 * sqrt(6.0) * LAL_PI * ppnParams.mTot * LAL_MTSUN_SI); ppnParams.position.longitude = param->sourcePhi; ppnParams.position.latitude = param->sourceTheta; ppnParams.position.system = COORDINATESYSTEM_EQUATORIAL; ppnParams.psi = param->polarisationAngle; ppnParams.epoch.gpsSeconds = 0; ppnParams.epoch.gpsNanoSeconds = 0; /* the waveform generation itself */ /* Note that in the call to LALInspiralWaveForInjection, * the param.nStartPad will be reset to zero. We do * not want to lose the information. So we should save it * somewhere (in a temporary variable) before the function * call. */ nStartPad = param->nStartPad; LALInspiralWaveForInjection(status->statusPtr, &waveform, param, &ppnParams); CHECKSTATUSPTR(status); /* Now reinstate nStartPad from saved value */ param->nStartPad = nStartPad; /* Generate F+ and Fx and combine it with h+ and hx to get * the correct waveform. See equation from BCV2 (Eq 29, * 30). */ { REAL8 t, p, s, a1, a2, phi, phi0, shift; REAL8 fp, fc, hp, hc; UINT4 kk; t = cos(param->sourceTheta); p = 2. * param->sourcePhi; s = 2. * param->polarisationAngle; fp = 0.5*(1 + t*t)*cos(p)*cos(s) - t*sin(p)*sin(s); fc = 0.5*(1 + t*t)*cos(p)*sin(s) + t*sin(p)*cos(s); phi0 = waveform.phi->data->data[0]; for (kk=0; kk < waveform.phi->data->length; kk++) { a1 = waveform.a->data->data[2*kk]; a2 = waveform.a->data->data[2*kk+1]; /* phi = waveform.phi->data->data[kk] - phi0 - * param->startPhase;*/ phi = waveform.phi->data->data[kk] - phi0; shift = waveform.shift->data->data[kk]; hp = a1*cos(shift)*cos(phi) - a2*sin(shift)*sin(phi); hc = a1*sin(shift)*cos(phi) + a2*cos(shift)*sin(phi); buff->data[kk + param->nStartPad] = fp*hp + fc*hc; } LALSDestroyVectorSequence( status->statusPtr, &(waveform.a->data) ); CHECKSTATUSPTR( status ); LALSDestroyVector( status->statusPtr, &(waveform.f->data) ); CHECKSTATUSPTR( status ); LALDDestroyVector( status->statusPtr, &(waveform.phi->data) ); CHECKSTATUSPTR( status ); LALSDestroyVector( status->statusPtr, &(waveform.shift->data) ); CHECKSTATUSPTR( status ); LALFree( waveform.a ); LALFree( waveform.f ); LALFree( waveform.phi ); LALFree( waveform.shift ); } param->fFinal = ppnParams.fStop; DETATCHSTATUSPTR(status); RETURN(status); }
int main(int argc, char **argv) { /* Command-line parsing variables. */ int arg; /* command-line argument counter */ static LALStatus stat; /* status structure */ CHAR *sourcefile = NULL; /* name of sourcefile */ CHAR *respfile = NULL; /* name of respfile */ CHAR *infile = NULL; /* name of infile */ CHAR *outfile = NULL; /* name of outfile */ INT4 seed = 0; /* random number seed */ INT4 sec = SEC; /* ouput epoch.gpsSeconds */ INT4 nsec = NSEC; /* ouput epoch.gpsNanoSeconds */ INT4 npt = NPT; /* number of output points */ REAL8 dt = DT; /* output sampling interval */ REAL4 sigma = SIGMA; /* noise amplitude */ /* File reading variables. */ FILE *fp = NULL; /* generic file pointer */ BOOLEAN ok = 1; /* whether input format is correct */ UINT4 i; /* generic index over file lines */ INT8 epoch; /* epoch stored as an INT8 */ /* Other global variables. */ RandomParams *params = NULL; /* parameters of pseudorandom sequence */ DetectorResponse detector; /* the detector in question */ INT2TimeSeries output; /* detector ACD output */ /******************************************************************* * PARSE ARGUMENTS (arg stores the current position) * *******************************************************************/ /* Exit gracefully if no arguments were given. if ( argc <= 1 ) { INFO( "No testing done." ); return 0; } */ arg = 1; while ( arg < argc ) { /* Parse source file option. */ if ( !strcmp( argv[arg], "-s" ) ) { if ( argc > arg + 1 ) { arg++; sourcefile = argv[arg++]; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse response file option. */ else if ( !strcmp( argv[arg], "-r" ) ) { if ( argc > arg + 1 ) { arg++; respfile = argv[arg++]; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse input file option. */ else if ( !strcmp( argv[arg], "-i" ) ) { if ( argc > arg + 1 ) { arg++; infile = argv[arg++]; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse noise output option. */ else if ( !strcmp( argv[arg], "-n" ) ) { if ( argc > arg + 5 ) { arg++; sec = atoi( argv[arg++] ); nsec = atoi( argv[arg++] ); npt = atoi( argv[arg++] ); dt = atof( argv[arg++] ); sigma = atof( argv[arg++] ); }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse output file option. */ else if ( !strcmp( argv[arg], "-o" ) ) { if ( argc > arg + 1 ) { arg++; outfile = argv[arg++]; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse debug level option. */ else if ( !strcmp( argv[arg], "-d" ) ) { if ( argc > arg + 1 ) { arg++; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse random seed option. */ else if ( !strcmp( argv[arg], "-e" ) ) { if ( argc > arg + 1 ) { arg++; seed = atoi( argv[arg++] ); }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Check for unrecognized options. */ else if ( argv[arg][0] == '-' ) { ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* End of argument parsing loop. */ /* Check for redundant or bad argument values. */ CHECKVAL( npt, 0, 2147483647 ); CHECKVAL( dt, 0, LAL_REAL4_MAX ); /******************************************************************* * SETUP * *******************************************************************/ /* Set up output, detector, and random parameter structures. */ output.data = NULL; detector.transfer = (COMPLEX8FrequencySeries *) LALMalloc( sizeof(COMPLEX8FrequencySeries) ); if ( !(detector.transfer) ) { ERROR( BASICINJECTTESTC_EMEM, BASICINJECTTESTC_MSGEMEM, 0 ); return BASICINJECTTESTC_EMEM; } detector.transfer->data = NULL; detector.site = NULL; SUB( LALCreateRandomParams( &stat, ¶ms, seed ), &stat ); /* Set up units. */ output.sampleUnits = lalADCCountUnit; if (XLALUnitDivide( &(detector.transfer->sampleUnits), &lalADCCountUnit, &lalStrainUnit ) == NULL) { return LAL_EXLAL; } /* Read response function. */ if ( respfile ) { REAL4VectorSequence *resp = NULL; /* response as vector sequence */ COMPLEX8Vector *response = NULL; /* response as complex vector */ COMPLEX8Vector *unity = NULL; /* vector of complex 1's */ if ( ( fp = fopen( respfile, "r" ) ) == NULL ) { ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE, respfile ); return BASICINJECTTESTC_EFILE; } /* Read header. */ ok &= ( fscanf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", &epoch ) == 1 ); I8ToLIGOTimeGPS( &( detector.transfer->epoch ), epoch ); ok &= ( fscanf( fp, "# f0 = %lf\n", &( detector.transfer->f0 ) ) == 1 ); ok &= ( fscanf( fp, "# deltaF = %lf\n", &( detector.transfer->deltaF ) ) == 1 ); if ( !ok ) { ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT, respfile ); return BASICINJECTTESTC_EINPUT; } /* Read and convert body to a COMPLEX8Vector. */ SUB( LALSReadVectorSequence( &stat, &resp, fp ), &stat ); fclose( fp ); if ( resp->vectorLength != 2 ) { ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT, respfile ); return BASICINJECTTESTC_EINPUT; } SUB( LALCCreateVector( &stat, &response, resp->length ), &stat ); memcpy( response->data, resp->data, 2*resp->length*sizeof(REAL4) ); SUB( LALSDestroyVectorSequence( &stat, &resp ), &stat ); /* Convert response function to a transfer function. */ SUB( LALCCreateVector( &stat, &unity, response->length ), &stat ); for ( i = 0; i < response->length; i++ ) { unity->data[i] = 1.0; } SUB( LALCCreateVector( &stat, &( detector.transfer->data ), response->length ), &stat ); SUB( LALCCVectorDivide( &stat, detector.transfer->data, unity, response ), &stat ); SUB( LALCDestroyVector( &stat, &response ), &stat ); SUB( LALCDestroyVector( &stat, &unity ), &stat ); } /* No response file, so generate a unit response. */ else { I8ToLIGOTimeGPS( &( detector.transfer->epoch ), EPOCH ); detector.transfer->f0 = 0.0; detector.transfer->deltaF = 1.5*FSTOP; SUB( LALCCreateVector( &stat, &( detector.transfer->data ), 2 ), &stat ); detector.transfer->data->data[0] = 1.0; detector.transfer->data->data[1] = 1.0; } /* Read input data. */ if ( infile ) { REAL4VectorSequence *input = NULL; /* input as vector sequence */ if ( ( fp = fopen( infile, "r" ) ) == NULL ) { ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE, infile ); return BASICINJECTTESTC_EFILE; } /* Read header. */ ok &= ( fscanf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", &epoch ) == 1 ); I8ToLIGOTimeGPS( &( output.epoch ), epoch ); ok &= ( fscanf( fp, "# deltaT = %lf\n", &( output.deltaT ) ) == 1 ); if ( !ok ) { ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT, infile ); return BASICINJECTTESTC_EINPUT; } /* Read and convert body. */ SUB( LALSReadVectorSequence( &stat, &input, fp ), &stat ); fclose( fp ); if ( input->vectorLength != 1 ) { ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT, infile ); return BASICINJECTTESTC_EINPUT; } SUB( LALI2CreateVector( &stat, &( output.data ), input->length ), &stat ); for ( i = 0; i < input->length; i++ ) output.data->data[i] = (INT2)( input->data[i] ); SUB( LALSDestroyVectorSequence( &stat, &input ), &stat ); } /* No input file, so generate one randomly. */ else { output.epoch.gpsSeconds = sec; output.epoch.gpsNanoSeconds = nsec; output.deltaT = dt; SUB( LALI2CreateVector( &stat, &( output.data ), npt ), &stat ); if ( sigma == 0 ) { memset( output.data->data, 0, npt*sizeof(INT2) ); } else { REAL4Vector *deviates = NULL; /* unit Gaussian deviates */ SUB( LALSCreateVector( &stat, &deviates, npt ), &stat ); SUB( LALNormalDeviates( &stat, deviates, params ), &stat ); for ( i = 0; i < (UINT4)( npt ); i++ ) output.data->data[i] = (INT2) floor( sigma*deviates->data[i] + 0.5 ); SUB( LALSDestroyVector( &stat, &deviates ), &stat ); } } /******************************************************************* * INJECTION * *******************************************************************/ /* Open sourcefile. */ if ( sourcefile ) { if ( ( fp = fopen( sourcefile, "r" ) ) == NULL ) { ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE, sourcefile ); return BASICINJECTTESTC_EFILE; } } /* For each line in the sourcefile... */ while ( ok ) { PPNParamStruc ppnParams; /* wave generation parameters */ REAL4 m1, m2, dist, inc, phic; /* unconverted parameters */ CoherentGW waveform; /* amplitude and phase structure */ REAL4TimeSeries signalvec; /* GW signal */ REAL8 time; /* length of GW signal */ CHAR timeCode; /* code for signal time alignment */ CHAR message[MSGLEN]; /* warning/info messages */ /* Read and convert input line. */ if ( sourcefile ) { ok &= ( fscanf( fp, "%c %" LAL_INT8_FORMAT " %f %f %f %f %f\n", &timeCode, &epoch, &m1, &m2, &dist, &inc, &phic ) == 7 ); ppnParams.mTot = m1 + m2; ppnParams.eta = m1*m2/( ppnParams.mTot*ppnParams.mTot ); ppnParams.d = dist*LAL_PC_SI*1000.0; ppnParams.inc = inc*LAL_PI/180.0; ppnParams.phi = phic*LAL_PI/180.0; } else { timeCode = 'i'; ppnParams.mTot = M1 + M2; ppnParams.eta = M1*M2/( ppnParams.mTot*ppnParams.mTot ); ppnParams.d = DIST; ppnParams.inc = INC; ppnParams.phi = PHIC; epoch = EPOCH; } if ( ok ) { /* Set up other parameter structures. */ ppnParams.epoch.gpsSeconds = ppnParams.epoch.gpsNanoSeconds = 0; ppnParams.position.latitude = ppnParams.position.longitude = 0.0; ppnParams.position.system = COORDINATESYSTEM_EQUATORIAL; ppnParams.psi = 0.0; ppnParams.fStartIn = FSTART; ppnParams.fStopIn = FSTOP; ppnParams.lengthIn = 0; ppnParams.ppn = NULL; ppnParams.deltaT = DELTAT; memset( &waveform, 0, sizeof(CoherentGW) ); /* Generate waveform at zero epoch. */ SUB( LALGeneratePPNInspiral( &stat, &waveform, &ppnParams ), &stat ); snprintf( message, MSGLEN, "%d: %s", ppnParams.termCode, ppnParams.termDescription ); INFO( message ); if ( ppnParams.dfdt > 2.0 ) { snprintf( message, MSGLEN, "Waveform sampling interval is too large:\n" "\tmaximum df*dt = %f", ppnParams.dfdt ); WARNING( message ); } /* Compute epoch for waveform. */ time = waveform.a->data->length*DELTAT; if ( timeCode == 'f' ) epoch -= (INT8)( 1000000000.0*time ); else if ( timeCode == 'c' ) epoch -= (INT8)( 1000000000.0*ppnParams.tc ); I8ToLIGOTimeGPS( &( waveform.a->epoch ), epoch ); waveform.f->epoch = waveform.phi->epoch = waveform.a->epoch; /* Generate and inject signal. */ signalvec.epoch = waveform.a->epoch; signalvec.epoch.gpsSeconds -= 1; signalvec.deltaT = output.deltaT/4.0; signalvec.f0 = 0; signalvec.data = NULL; time = ( time + 2.0 )/signalvec.deltaT; SUB( LALSCreateVector( &stat, &( signalvec.data ), (UINT4)time ), &stat ); SUB( LALSimulateCoherentGW( &stat, &signalvec, &waveform, &detector ), &stat ); SUB( LALSI2InjectTimeSeries( &stat, &output, &signalvec, params ), &stat ); SUB( LALSDestroyVectorSequence( &stat, &( waveform.a->data ) ), &stat ); SUB( LALSDestroyVector( &stat, &( waveform.f->data ) ), &stat ); SUB( LALDDestroyVector( &stat, &( waveform.phi->data ) ), &stat ); LALFree( waveform.a ); LALFree( waveform.f ); LALFree( waveform.phi ); SUB( LALSDestroyVector( &stat, &( signalvec.data ) ), &stat ); } /* If there is no source file, inject only one source. */ if ( !sourcefile ) ok = 0; } /* Input file is exhausted (or has a badly-formatted line ). */ if ( sourcefile ) fclose( fp ); /******************************************************************* * CLEANUP * *******************************************************************/ /* Print output file. */ if ( outfile ) { if ( ( fp = fopen( outfile, "w" ) ) == NULL ) { ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE, outfile ); return BASICINJECTTESTC_EFILE; } epoch = 1000000000LL*(INT8)( output.epoch.gpsSeconds ); epoch += (INT8)( output.epoch.gpsNanoSeconds ); fprintf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", epoch ); fprintf( fp, "# deltaT = %23.16e\n", output.deltaT ); for ( i = 0; i < output.data->length; i++ ) fprintf( fp, "%8.1f\n", (REAL4)( output.data->data[i] ) ); fclose( fp ); } /* Destroy remaining memory. */ SUB( LALDestroyRandomParams( &stat, ¶ms ), &stat ); SUB( LALI2DestroyVector( &stat, &( output.data ) ), &stat ); SUB( LALCDestroyVector( &stat, &( detector.transfer->data ) ), &stat ); LALFree( detector.transfer ); /* Done! */ LALCheckMemoryLeaks(); INFO( BASICINJECTTESTC_MSGENORM ); return BASICINJECTTESTC_ENORM; }
int main( int argc, char *argv[] ) { static LALStatus status; /* Status structure */ PtoleMetricIn in; /* PtoleMetric() input structure */ REAL8 mismatch; /* mismatch threshold of mesh */ REAL8Vector *metric; /* Parameter-space metric */ int j, k; /* Parameter-space indices */ int opt; /* Command-line option. */ BOOLEAN grace; /* Whether or not we use xmgrace */ BOOLEAN nongrace; /* Whether or not to output data to file*/ int ra, dec, i; /* Loop variables for xmgrace option */ FILE *pvc = NULL; /* Temporary file for xmgrace option */ FILE *fnongrace = NULL;/* File contaning ellipse coordinates */ int metric_code; /* Which metric code to use: */ /* 1 = Ptolemetric */ /* 2 = CoherentMetric + DTBarycenter */ /* 3 = CoherentMetric + DTEphemeris */ REAL8Vector *tevlambda; /* (f, a, d, ...) for CoherentMetric */ MetricParamStruc tevparam; /* Input structure for CoherentMetric */ PulsarTimesParamStruc tevpulse; /* Input structure for CoherentMetric */ /* (this is a member of tevparam) */ EphemerisData *eph; /* To store ephemeris data */ int detector; /* Which detector to use: */ /* 1 = Hanford, 2 = Livingston, */ /* 3 = Virgo, 4 = GEO, 5 = TAMA */ REAL8 ra_point; /* RA at which metric is evaluated */ REAL8 dec_point; /* dec at which metric is evaluated */ float a,b,c,d,e,f; /* To input point in standard format */ int ra_min, ra_max; /* Min and max RA for ellipse plot */ int dec_min, dec_max; /* Min and max dec for ellipse plot */ float c_ellipse; /* Centers of ellipses */ float r_ellipse; /* Radii of ellipses */ REAL8 determinant; /* Determinant of projected metric */ REAL4 f0; /* carrier frequency */ UINT2 numSpindown; /* Number of spindowns */ char earth[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz"; char sun[] = TEST_DATA_DIR "sun00-19-DE405.dat.gz"; /* Defaults that can be overwritten: */ metric_code = 1; in.epoch.gpsSeconds = tevpulse.epoch.gpsSeconds = 731265908; in.epoch.gpsNanoSeconds = tevpulse.epoch.gpsNanoSeconds = 0.0; mismatch = 0.02; nongrace = 0; in.duration = tevparam.deltaT = DEFAULT_DURATION; grace = 0; detector = 4; ra_point = (24.1/60)*LAL_PI_180; /* 47 Tuc */ dec_point = -(72+5./60)*LAL_PI_180; ra_min = 0; ra_max = 90; dec_min = 0; dec_max = 85; f0 = 1000; numSpindown = 0; /* Parse options. */ while ((opt = LALgetopt( argc, argv, "a:b:c:d:ef:l:m:n:pt:s:x" )) != -1) { switch (opt) { case 'a': metric_code = atoi( LALoptarg ); break; case 'b': in.epoch.gpsSeconds = tevpulse.epoch.gpsSeconds = atoi( LALoptarg ); break; case 'c': if( sscanf( LALoptarg, "%f:%f:%f:%f:%f:%f", &a, &b, &c, &d, &e, &f ) != 6) { fprintf( stderr, "coordinates should be hh:mm:ss:dd:mm:ss\n" ); } ra_point = (15*a+b/4+c/240)*LAL_PI_180; dec_point = (d+e/60+f/3600)*LAL_PI_180; break; case 'd': detector = atoi( LALoptarg ); break; case 'e': break; case 'f': f0 = atof( LALoptarg ); break; case 'l': if( sscanf( LALoptarg, "%d:%d:%d:%d", &ra_min, &ra_max, &dec_min, &dec_max) != 4) { fprintf( stderr, "coordinates should be ra_min, ra_max, dec_min, dec_max all in degrees" ); } break; case 'm': mismatch = atof( LALoptarg ); break; case 'n': numSpindown = atoi( LALoptarg ); break; case 'p': nongrace = 1; break; case 's': break; case 't': in.duration = tevparam.deltaT = atof( LALoptarg ); break; case 'x': grace = 1; break; } } /* Allocate storage. */ metric = NULL; LALDCreateVector( &status, &metric, (3+numSpindown)*(4+numSpindown)/2 ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMEM ); return GENERALMETRICTESTC_EMEM; } tevlambda = NULL; LALDCreateVector( &status, &tevlambda, 3+numSpindown ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMEM ); return GENERALMETRICTESTC_EMEM; } /* Position in parameter space (sky, frequency, spindowns) */ in.position.system = COORDINATESYSTEM_EQUATORIAL; in.position.longitude = tevlambda->data[1] = ra_point; in.position.latitude = tevlambda->data[2] = dec_point; in.maxFreq = tevlambda->data[0] = f0; in.spindown = NULL; if( numSpindown > 0 ) { LALCreateVector( &status, &(in.spindown), numSpindown ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMEM ); return GENERALMETRICTESTC_EMEM; } for( i=0; i<numSpindown; i++ ) { in.spindown->data[i] = 0; tevlambda->data[i+3] = 0; } } /* Detector site */ if(detector==1) tevpulse.site = &lalCachedDetectors[LALDetectorIndexLHODIFF]; if(detector==2) tevpulse.site = &lalCachedDetectors[LALDetectorIndexLLODIFF]; if(detector==3) tevpulse.site = &lalCachedDetectors[LALDetectorIndexVIRGODIFF]; if(detector==4) tevpulse.site = &lalCachedDetectors[LALDetectorIndexGEO600DIFF]; if(detector==5) tevpulse.site = &lalCachedDetectors[LALDetectorIndexTAMA300DIFF]; in.site = tevpulse.site; tevpulse.latitude = in.site->frDetector.vertexLatitudeRadians; tevpulse.longitude = in.site->frDetector.vertexLongitudeRadians; /* CoherentMetric constants */ tevparam.constants = &tevpulse; tevparam.n = 1; tevparam.errors = 0; tevparam.start = 0; /* start time relative to epoch */ tevpulse.t0 = 0.0; /* spindown definition time relative to epoch */ /* Fill in the fields tevpulse.tMidnight & tevpulse.tAutumn: */ LALGetEarthTimes( &status, &tevpulse ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESUB ); return GENERALMETRICTESTC_ESUB; } /* Read in ephemeris data from files: */ eph = (EphemerisData *)LALMalloc(sizeof(EphemerisData)); eph->ephiles.earthEphemeris = earth; eph->ephiles.sunEphemeris = sun; LALInitBarycenter( &status, eph ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESUB ); return GENERALMETRICTESTC_ESUB; } tevpulse.ephemeris = eph; /* Choose CoherentMetric timing function */ if( metric_code == 2 ) { tevpulse.t1 = LALTBaryPtolemaic; tevpulse.dt1 = LALDTBaryPtolemaic; } if( metric_code == 3 ) { tevpulse.t1 = LALTEphemeris; tevpulse.dt1 = LALDTEphemeris; } tevpulse.t2 = LALTSpin; tevpulse.dt2 = LALDTSpin; tevpulse.constants1 = &tevpulse; tevpulse.constants2 = &tevpulse; tevpulse.nArgs = 2; if( numSpindown > 0 ) { tevparam.dtCanon = LALDTComp; } else { if( metric_code == 2 ) tevparam.dtCanon = LALDTBaryPtolemaic; if( metric_code == 3 ) tevparam.dtCanon = LALDTEphemeris; } /* Evaluate metric components. */ if(metric_code==1) { LALPtoleMetric( &status, metric, &in ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESUB ); return GENERALMETRICTESTC_ESUB; } } if(metric_code==2 || metric_code==3) { LALCoherentMetric( &status, metric, tevlambda, &tevparam ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESUB ); return GENERALMETRICTESTC_ESUB; } } /* Print metric. */ printf("\nmetric (f0, alpha, delta, ...) at the requested point\n"); for (j=0; j<=2+numSpindown; j++) { for (k=0; k<=j; k++) printf( " %+.4e", metric->data[k+j*(j+1)/2] ); printf("\n"); } /* Print determinants. */ determinant = metric->data[5]*metric->data[2] - pow(metric->data[4],2); printf( "\nSky-determinant %e\n", determinant ); if( numSpindown == 1 ) { determinant = metric->data[2] * metric->data[5] * metric->data[9] - metric->data[2] * metric->data[8] * metric->data[8] + metric->data[4] * metric->data[8] * metric->data[7] - metric->data[4] * metric->data[4] * metric->data[9] + metric->data[7] * metric->data[4] * metric->data[8] - metric->data[7] * metric->data[7] * metric->data[5]; printf( "S&S determinant %e\n", determinant ); } /* Project carrier frequency out of metric. */ LALProjectMetric( &status, metric, 0 ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESUB ); return GENERALMETRICTESTC_ESUB; } /* Print projected metric. */ printf("\nf-projected metric (alpha, delta, ...) at the requested point\n"); for (j=1; j<=2+numSpindown; j++) { for (k=1; k<=j; k++) printf( " %+.4e", metric->data[k+j*(j+1)/2] ); printf( "\n" ); } /* Print determinants. */ determinant = metric->data[5]*metric->data[2] - pow(metric->data[4],2); printf( "\nSky-determinant %e\n", determinant ); if( numSpindown == 1 ) { determinant = metric->data[2] * metric->data[5] * metric->data[9] - metric->data[2] * metric->data[8] * metric->data[8] + metric->data[4] * metric->data[8] * metric->data[7] - metric->data[4] * metric->data[4] * metric->data[9] + metric->data[7] * metric->data[4] * metric->data[8] - metric->data[7] * metric->data[7] * metric->data[5]; printf( "S&S determinant %e\n", determinant ); } /* Here is the code that uses xmgrace with the -x option, */ /* and outputs data to a file with the -t option. */ if (grace || nongrace) { /* Take care of preliminaries. */ if(grace) { pvc = popen( "xmgrace -pipe", "w" ); if( !pvc ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESYS ); return GENERALMETRICTESTC_ESYS; } fprintf( pvc, "@xaxis label \"Right ascension (degrees)\"\n" ); fprintf( pvc, "@yaxis label \"Declination (degrees)\"\n" ); } if(nongrace) { fnongrace = fopen( "nongrace.data", "w" ); if( !fnongrace ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESYS ); return GENERALMETRICTESTC_ESYS; } } /* Step around the sky: a grid in ra and dec. */ j = 0; for (dec=dec_max; dec>=dec_min; dec-=10) { for (ra=ra_min; ra<=ra_max; ra+=15) { REAL8 gaa, gad, gdd, angle, smaj, smin; /* Get the metric at this ra, dec. */ in.position.longitude = tevlambda->data[1] = ra*LAL_PI_180; in.position.latitude = tevlambda->data[2] = dec*LAL_PI_180; /* Evaluate metric: */ if(metric_code==1) { LALPtoleMetric( &status, metric, &in ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESUB ); return GENERALMETRICTESTC_ESUB; } } if(metric_code==2 || metric_code==3) { LALCoherentMetric( &status, metric, tevlambda, &tevparam ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESUB ); return GENERALMETRICTESTC_ESUB; } } /* Project metric: */ LALProjectMetric( &status, metric, 0 ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGESUB ); return GENERALMETRICTESTC_ESUB; } determinant = metric->data[5]*metric->data[2]-pow(metric->data[4],2.0); if(determinant < 0.0) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMET ); return GENERALMETRICTESTC_EMET; } /* Rename \gamma_{\alpha\alpha}. */ gaa = metric->data[2]; /* Rename \gamma_{\alpha\delta}. */ gad = metric->data[4]; /* Rename \gamma_{\delta\delta}. */ gdd = metric->data[5]; /* Semiminor axis from larger eigenvalue of metric. */ smin = gaa+gdd + sqrt( pow(gaa-gdd,2) + pow(2*gad,2) ); smin = sqrt(2*mismatch/smin); /* Semiminor axis from smaller eigenvalue of metric. */ smaj = gaa+gdd - sqrt( pow(gaa-gdd,2) + pow(2*gad,2) ); /*printf("ra = %d, dec = %d, temp = %g\n", ra, dec, smaj);*/ smaj = sqrt(2*mismatch/smaj); /* Angle of semimajor axis with "horizontal" (equator). */ angle = atan2( gad, mismatch/smaj/smaj-gdd ); if (angle <= -LAL_PI_2) angle += LAL_PI; if (angle > LAL_PI_2) angle -= LAL_PI; if(grace) { /* Print set header. */ fprintf( pvc, "@s%d color (0,0,0)\n", j ); fprintf( pvc, "@target G0.S%d\n@type xy\n", j++ ); /* Print center of patch. */ fprintf( pvc, "%16.8g %16.8g\n", (float)ra, (float)dec ); } if(nongrace) /* Print center of patch. */ fprintf( fnongrace, "%16.8g %16.8g\n", (float)ra, (float)dec ); /* Loop around patch ellipse. */ for (i=0; i<=SPOKES; i++) { c_ellipse = LAL_TWOPI*i/SPOKES; r_ellipse = MAGNIFY*LAL_180_PI*smaj*smin / sqrt( pow(smaj*sin(c_ellipse),2) + pow(smin*cos(c_ellipse),2) ); if(grace) fprintf( pvc, "%e %e\n", ra+r_ellipse*cos(angle-c_ellipse), dec+r_ellipse*sin(angle-c_ellipse) ); if(nongrace) fprintf( fnongrace, "%e %e\n", ra+r_ellipse*cos(angle-c_ellipse), dec+r_ellipse*sin(angle-c_ellipse) ); } /* for (a...) */ } /* for (ra...) */ } /* for (dec...) */ if(grace) fclose( pvc ); if(nongrace) fclose( fnongrace ); } /* if (grace || nongrace) */ printf("\nCleaning up and leaving...\n"); LALFree( eph->ephemE ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMEM ); return GENERALMETRICTESTC_EMEM; } LALFree( eph->ephemS ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMEM ); return GENERALMETRICTESTC_EMEM; } LALFree( eph ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMEM ); return GENERALMETRICTESTC_EMEM; } LALDDestroyVector( &status, &metric ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMEM ); return GENERALMETRICTESTC_EMEM; } LALDDestroyVector( &status, &tevlambda ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMEM ); return GENERALMETRICTESTC_EMEM; } if( in.spindown ) LALDestroyVector( &status, &(in.spindown) ); if( status.statusCode ) { printf( "%s line %d: %s\n", __FILE__, __LINE__, GENERALMETRICTESTC_MSGEMEM ); return GENERALMETRICTESTC_EMEM; } LALCheckMemoryLeaks(); return 0; } /* main() */
/** * \brief Computes the parameter space metric for a coherent pulsar search. * \author Creighton, T. D., Jolien Creighton * \date 2000 - 2003 * \ingroup StackMetric_h * * This function computes the metric \f$g_{\alpha\beta}(\mathbf{\lambda})\f$, as * discussed in \ref StackMetric_h, under the assumption * that the search consists of scanning the Fourier power spectrum * constructed from a single time interval \f$\Delta t\f$. The indecies * \f$\alpha\f$ and \f$\beta\f$ are assumed to run from 0 to \f$n\f$, where \f$n\f$ is * the total number of shape parameters. * The argument \c metric is normally a vector of length * \f$(n+1)(n+2)/2\f$ storing all non-redundant coefficients of * \f$g_{\alpha\beta}\f$. The indexing scheme is as follows: Let us assume * that \f$\alpha\geq\beta\f$. Then * \f$g_{\alpha\beta} = g_{\beta\alpha} = \f$metric->data[\f$\beta + \alpha(\alpha+1)/2]\f$. * If <tt>params->errors</tt> is nonzero, then \a *metric must be double * this length, and LALCoherentMetric() will store metric * components and their estimated uncertainty in alternate slots; i.e. * the metric component * \f$g_{\alpha\beta}=\f$metric->data[\f$2\beta+\alpha(\alpha+1)]\f$, * and the uncertainty * \f$s_{\alpha\beta}=\f$metric->data[\f$1+2\beta+\alpha(\alpha+1)]\f$. * * The argument \a lambda is another vector, of length \f$n+1\f$, * storing the components of \f$\mathbf{\lambda}=(\lambda^0,\ldots,\lambda^n)\f$ * for the parameter space point at which the metric is being evaluated. * The argument \a *params stores the remaining parameters for * computing the metric, as given in the Structures section of StackMetric.h. * * ### Algorithm ### * * This routine simply computes the function given in \eqref{eq_gab_phi} * of \ref StackMetric_h. Most of the work is done by the * function \a params->dtCanon(), which computes the value and * parameter derivatives of the canonical time coordinate * \f$\tau[t;\vec{\lambda}]\f$. Since the phase function is simply * \f$\phi[t;\mathbf{\lambda}]=2\pi\lambda^0 \tau[t;\vec\lambda]\f$, where * \f$\lambda^0=f_0\f$, the metric components are simply: * \f{eqnarray}{ * g_{00}(\mathbf{\lambda}) & = & * 4\pi^2\bigg\langle\!(\tau[t;\vec\lambda])^2\bigg\rangle - * 4\pi^2\bigg\langle\!\tau[t;\vec\lambda]\bigg\rangle^2 \; , \\ * g_{i0}(\mathbf{\lambda}) \;\; = \;\; * g_{0i}(\mathbf{\lambda}) & = & * 4\pi^2 f_0\bigg\langle\! * \tau[t;\vec\lambda] * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^i} * \bigg\rangle * - * 4\pi^2 f_0\bigg\langle\! * \tau[t;\vec\lambda] * \bigg\rangle * \bigg\langle * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^i} * \bigg\rangle \; ,\\ * g_{ij}(\mathbf{\lambda}) & = & * 4\pi^2 f_0^2\bigg\langle * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^i} * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^j} * \bigg\rangle * - * 4\pi^2 f_0^2\bigg\langle * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^i} * \bigg\rangle * \bigg\langle * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^j} * \bigg\rangle \; , * \f} * where the indecies \f$i\f$ and \f$j\f$ run from 1 to \f$n\f$. * * In the rigorous definition of the metric, the angle brackets denote an * average over the \em canonical time, not the detector time, so we have: * \f{eqnarray}{ * \bigg\langle\ldots\bigg\rangle * & = & \frac{1}{\tau(t_\mathrm{start}+\Delta t)-\tau(t_\mathrm{start})} * \int_{\tau(t_\mathrm{start})}^{\tau(t_\mathrm{start}+\Delta t)} * \ldots\,d\tau\\ * & = & \frac{1}{\tau(t_\mathrm{start}+\Delta t)-\tau(t_\mathrm{start})} * \int_{t_\mathrm{start}}^{t_\mathrm{start}+\Delta t} * \ldots\frac{\partial\tau}{\partial t}\,dt\\ * & \approx & \frac{1}{\Delta t} * \int_{t_\mathrm{start}}^{t_\mathrm{start}+\Delta t} * \ldots\,dt \; , * \f} * where the approximation is good to order \f$\epsilon\f$ equal to the * maximum difference between 1 and \f$\partial\tau/\partial t\f$. For an * Earth-motion barycentred time coordinate, for instance, \f$\epsilon\f$ is * of order \f$10^{-4}\f$ and the approximation is quite good. However, the * current implementation of the metric algorithm uses the second, exact * formula. If speed considerations become important, this is one * obvious area for simplification. * * At present, the time averaging is performed by evaluating \f$\tau\f$ and * its derivatives at equally-spaced points over \f$\Delta t\f$ and applying * a trapezoidal method; i.e. * \f[ * \frac{1}{T}\int_0^T F(t)\,dt \approx \frac{1}{N}\left(\frac{1}{2}F_0 * + F_1 + F_2 + \ldots + F_{N-1} + \frac{1}{2}F_N \right) \; , * \f] * where \f$F_k=F(kT/N)\f$ are the \f$N+1\f$ sample points of the integrand. The * number of points is a compiled-in constant. The error is on the order * of \f$F''T^2/N^2\f$, where \f$F''\f$ is the second derivative of \f$F(t)\f$ at * some point in the interval; we liberally estimate the error to be: * \f[ * \sigma = \max_{k\in\{1,\ldots,N-1\}} * \left\{F_{k-1} - 2F_k + F_{k+1}\right\} \; . * \f] * Other more sophisticated integration techniques may be considered in * future. To save on recomputing costs, the derivatives of \f$\tau\f$ at * all times are stored in a large vector sequence. */ void LALCoherentMetric( LALStatus *stat, REAL8Vector *metric, REAL8Vector *lambda, MetricParamStruc *params ) { UINT4 s = 0; /* The number of parameters. */ UINT4 i, j, k, l; /* Indecies. */ REAL8 dt; /* The sampling interval, in s. */ REAL8 f0; /* The frequency scale, lambda->data[0]. */ REAL8 *data; /* Multipurpose pointer to vector data. */ REAL8Vector *a=NULL; /* Data for the first time average. */ REAL8Vector *b=NULL; /* Data for the second time average. */ REAL8Vector *c=NULL; /* Data for the third time average. */ REAL8Vector d; /* Temporary variable. */ REAL8Vector *variables=NULL; /* Input to time function. */ REAL8VectorSequence *dSeq=NULL; /* Phase derivatives. */ CreateVectorSequenceIn in; /* Input structure. */ PulsarTimesParamStruc *constants; /* Timing constants. */ INITSTATUS(stat); ATTATCHSTATUSPTR(stat); /* Make sure parameter structures and their fields exist. */ ASSERT(metric,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL); ASSERT(metric->data,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL); ASSERT(lambda,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL); ASSERT(lambda->data,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL); ASSERT(params,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL); ASSERT(params->dtCanon,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL); /* Make sure parameters are valid. */ s=lambda->length; ASSERT(s,stat,STACKMETRICH_EBAD,STACKMETRICH_MSGEBAD); if(params->errors) { ASSERT(metric->length==s*(s+1),stat,STACKMETRICH_EBAD, STACKMETRICH_MSGEBAD); } else { ASSERT(metric->length==(s*(s+1))>>1,stat,STACKMETRICH_EBAD, STACKMETRICH_MSGEBAD); } ASSERT(params->n==1,stat,STACKMETRICH_EBAD, STACKMETRICH_MSGEBAD); /* Set vector sequence creation structure, and compute sampling rate. */ in.vectorLength=s+1; in.length=COHERENTMETRICC_NPTS; dt=params->deltaT/(COHERENTMETRICC_NPTS-1.0); /* Create temporary storage. */ TRY(LALDCreateVector(stat->statusPtr,&a,COHERENTMETRICC_NPTS),stat); LALDCreateVector(stat->statusPtr,&b,COHERENTMETRICC_NPTS); BEGINFAIL(stat) TRY(LALDDestroyVector(stat->statusPtr,&a),stat); ENDFAIL(stat); LALDCreateVector(stat->statusPtr,&c,COHERENTMETRICC_NPTS); BEGINFAIL(stat) { TRY(LALDDestroyVector(stat->statusPtr,&a),stat); TRY(LALDDestroyVector(stat->statusPtr,&b),stat); } ENDFAIL(stat); LALDCreateVectorSequence(stat->statusPtr,&dSeq,&in); BEGINFAIL(stat) { TRY(LALDDestroyVector(stat->statusPtr,&a),stat); TRY(LALDDestroyVector(stat->statusPtr,&b),stat); TRY(LALDDestroyVector(stat->statusPtr,&c),stat); } ENDFAIL(stat); LALDCreateVector(stat->statusPtr,&variables,s); BEGINFAIL(stat) { TRY(LALDDestroyVector(stat->statusPtr,&a),stat); TRY(LALDDestroyVector(stat->statusPtr,&b),stat); TRY(LALDDestroyVector(stat->statusPtr,&c),stat); TRY(LALDDestroyVectorSequence(stat->statusPtr,&dSeq),stat); } ENDFAIL(stat); /* Set up passing structure for the canonical time function. */ memcpy(variables->data,lambda->data,s*sizeof(REAL8)); *(variables->data)=params->start; f0=lambda->data[0]; constants=params->constants; d.length=s+1; d.data=dSeq->data; l=COHERENTMETRICC_NPTS; /* Compute canonical time and its derivatives. */ while(l--){ (params->dtCanon)(stat->statusPtr,&d,variables,constants); BEGINFAIL(stat) { TRY(LALDDestroyVector(stat->statusPtr,&a),stat); TRY(LALDDestroyVector(stat->statusPtr,&b),stat); TRY(LALDDestroyVector(stat->statusPtr,&c),stat); TRY(LALDDestroyVectorSequence(stat->statusPtr,&dSeq),stat); TRY(LALDDestroyVector(stat->statusPtr,&variables),stat); } ENDFAIL(stat); *(variables->data)+=dt; d.data+=s+1; } /* Compute the overall correction factor to convert the canonical time interval into the detector time interval. */ #ifndef APPROXIMATE dt=params->deltaT/(dSeq->data[(s+1)*(COHERENTMETRICC_NPTS-1)] - dSeq->data[0]); #else dt=1.0; #endif /* Compute metric components. First generate the g00 component. */ /* Fill integrand arrays. */ data=dSeq->data+1; l=COHERENTMETRICC_NPTS; k=0; while(l--){ #ifndef APPROXIMATE a->data[l]=*data*data[-1]*data[-1]; b->data[l]=c->data[l]=*data*data[-1]; #else a->data[l]=data[-1]*data[-1]; b->data[l]=c->data[l]=data[-1]; #endif data+=s+1; } /* Integrate to get the metric component. */ if(params->errors){ REAL8 aErr=0,bErr=0,cErr=0; REAL8 aAvg=Average(a,&aErr); REAL8 bAvg=Average(b,&bErr); REAL8 cAvg=Average(c,&cErr); metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*(aAvg-dt*bAvg*cAvg); metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt* (aErr + dt*bErr*fabs(cAvg) + dt*cErr*fabs(bAvg)); }else metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt* (Average(a,0)-dt*Average(b,0)*Average(c,0)); for(i=1;i<s;i++){ /* Now generate the gi0 components. */ /* Fill integrand arrays. */ data=dSeq->data+1; l=COHERENTMETRICC_NPTS; while(l--){ #ifndef APPROXIMATE a->data[l]=*data*data[-1]*f0*data[i]; b->data[l]=*data*data[-1]; c->data[l]=*data*f0*data[i]; #else a->data[l]=data[-1]*f0*data[i]; b->data[l]=data[-1]; c->data[l]=f0*data[i]; #endif data+=s+1; } /* Integrate to get the metric component. */ if(params->errors){ REAL8 aErr=0,bErr=0,cErr=0; REAL8 aAvg=Average(a,&aErr); REAL8 bAvg=Average(b,&bErr); REAL8 cAvg=Average(c,&cErr); metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*(aAvg-dt*bAvg*cAvg); metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt* (aErr + dt*bErr*fabs(cAvg) + dt*cErr*fabs(bAvg)); }else metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt* (Average(a,0)-dt*Average(b,0)*Average(c,0)); for(j=1;j<=i;j++){ /* Now generate the gij components. */ /* Fill integrand arrays. */ data=dSeq->data+1; l=COHERENTMETRICC_NPTS; while(l--){ #ifndef APPROXIMATE a->data[l]=*data*f0*f0*data[i]*data[j]; b->data[l]=*data*f0*data[i]; c->data[l]=*data*f0*data[j]; #else a->data[l]=f0*f0*data[i]*data[j]; b->data[l]=f0*data[i]; c->data[l]=f0*data[j]; #endif data+=s+1; } /* Integrate to get the metric component. */ if(params->errors){ REAL8 aErr=0,bErr=0,cErr=0; REAL8 aAvg=Average(a,&aErr); REAL8 bAvg=Average(b,&bErr); REAL8 cAvg=Average(c,&cErr); metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*(aAvg-dt*bAvg*cAvg); metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt* (aErr + dt*bErr*fabs(cAvg) + dt*cErr*fabs(bAvg)); }else metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt* (Average(a,0)-dt*Average(b,0)*Average(c,0)); } } /* Destroy temporary storage, and exit. */ TRY(LALDDestroyVector(stat->statusPtr,&a),stat); TRY(LALDDestroyVector(stat->statusPtr,&b),stat); TRY(LALDDestroyVector(stat->statusPtr,&c),stat); TRY(LALDDestroyVectorSequence(stat->statusPtr,&dSeq),stat); TRY(LALDDestroyVector(stat->statusPtr,&variables),stat); DETATCHSTATUSPTR(stat); RETURN(stat); }
void LALExtractFrameResponse(LALStatus * status, COMPLEX8FrequencySeries * output, LALCache * calCache, CalibrationUpdateParams * calfacts) { const LALUnit strainPerCount = { 0, {0, 0, 0, 0, 0, 1, -1}, {0, 0, 0, 0, 0, 0, 0} }; LALCache *refCache = NULL; LALCache *facCache = NULL; LALFrStream *refStream = NULL; LALFrStream *facStream = NULL; FrChanIn frameChan; LALFrStreamPos facPos; CHAR facDsc[LALNameLength]; CHAR channelName[LALNameLength]; COMPLEX8FrequencySeries R0; COMPLEX8FrequencySeries C0; COMPLEX8TimeSeries ab; COMPLEX8TimeSeries a; /* * COMPLEX8Vector abVec; * COMPLEX8Vector aVec; * COMPLEX8 abData; * COMPLEX8 aData; */ CalibrationFunctions calfuncs; LIGOTimeGPS seekEpoch; UINT4 length; REAL8 duration_real; const REAL8 fuzz = 0.1 / 16384.0; INITSTATUS(status); ATTATCHSTATUSPTR(status); ASSERT(output, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(output->data, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(output->data->data, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(calCache, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(calfacts, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(calfacts->ifo, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(crealf(calfacts->alpha) == 0, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(cimagf(calfacts->alpha) == 0, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(crealf(calfacts->alphabeta) == 0, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(cimagf(calfacts->alphabeta) == 0, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); /* * * set up and clear the structures to hold the input data * */ memset(&R0, 0, sizeof(COMPLEX8FrequencySeries)); memset(&C0, 0, sizeof(COMPLEX8FrequencySeries)); memset(&ab, 0, sizeof(COMPLEX8TimeSeries)); memset(&a, 0, sizeof(COMPLEX8TimeSeries)); memset(&calfuncs, 0, sizeof(CalibrationFunctions)); calfuncs.responseFunction = &R0; calfuncs.sensingFunction = &C0; calfacts->openLoopFactor = &ab; calfacts->sensingFactor = &a; calfacts->epoch = output->epoch; frameChan.name = channelName; /* * * get the reference calibration and cavity gain frequency series * */ /* sieve the calibration cache for the reference frame */ refCache = XLALCacheDuplicate(calCache); XLALCacheSieve(refCache, 0, 0, NULL, REF_TYPE, NULL); if (!refCache->length) { /* if we don't have a reference calibration, we can't do anything */ XLALDestroyCache(refCache); ABORT(status, FRAMECALIBRATIONH_ECREF, FRAMECALIBRATIONH_MSGECREF); } /* open the reference calibration frame */ LALFrCacheOpen(status->statusPtr, &refStream, refCache); if (status->statusPtr->statusCode) { /* if we don't have a reference calibration, we can't do anything */ XLALDestroyCache(refCache); ABORT(status, FRAMECALIBRATIONH_EOREF, FRAMECALIBRATIONH_MSGEOREF); } XLALDestroyCache(refCache); if (status->statusPtr->statusCode) { TRY(LALFrClose(status->statusPtr, &refStream), status); ABORT(status, FRAMECALIBRATIONH_EDCHE, FRAMECALIBRATIONH_MSGEDCHE); } /* read in the frequency series for the reference calbration */ snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" RESPONSE_CHAN, calfacts->ifo); LALFrGetCOMPLEX8FrequencySeries(status->statusPtr, &R0, &frameChan, refStream); if (status->statusCode) { /* if we don't have a reference calibration, we can't do anything */ XLALDestroyCache(refCache); ABORT(status, FRAMECALIBRATIONH_EREFR, FRAMECALIBRATIONH_MSGEREFR); } /* read in the reference cavity gain frequency series */ snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" CAV_GAIN_CHAN, calfacts->ifo); LALFrGetCOMPLEX8FrequencySeries(status->statusPtr, &C0, &frameChan, refStream); BEGINFAIL(status) { /* no cavity gain response to update point cal */ XLALDestroyCache(refCache); TRY(LALFrClose(status->statusPtr, &refStream), status); RETURN_POINT_CAL; } ENDFAIL(status); LALFrClose(status->statusPtr, &refStream); BEGINFAIL(status) { RETURN_POINT_CAL; } ENDFAIL(status); /* * * get the factors necessary to update the reference calibration * */ /* try and get some update factors. first we try to get a cache */ /* containing sensemon frames. if that fails, try the S1 type */ /* calibration data, otherwise just return the point calibration */ do { /* try and get sensemon frames */ snprintf(facDsc, LALNameLength * sizeof(CHAR), SENSEMON_FAC_TYPE); facCache = XLALCacheDuplicate(calCache); XLALCacheSieve(facCache, 0, 0, NULL, facDsc, NULL); if (!facCache) { RETURN_POINT_CAL; } if (facCache->length) { /* sensemon stores fac times series as real_8 adc trend data */ REAL8TimeSeries sensemonTS; REAL8 alphaDeltaT; UINT4 i; memset(&sensemonTS, 0, sizeof(REAL8TimeSeries)); OPEN_FAC; snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" CAV_FAC_CHAN ".mean", calfacts->ifo); /* get the sample rate of the alpha channel */ LALFrGetREAL8TimeSeries(status->statusPtr, &sensemonTS, &frameChan, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* determine number of calibration points required */ duration_real = XLALGPSGetREAL8(&(calfacts->duration)); length = (UINT4) ceil(duration_real / sensemonTS.deltaT); ++length; /* make sure we get the first point before the requested cal time */ alphaDeltaT = sensemonTS.deltaT; seekEpoch = output->epoch; XLALGPSAdd(&seekEpoch, fuzz - sensemonTS.deltaT); sensemonTS.epoch = seekEpoch; GET_POS; /* create memory for the alpha values */ LALDCreateVector(status->statusPtr, &(sensemonTS.data), length); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* get the alpha values */ LALFrGetREAL8TimeSeries(status->statusPtr, &sensemonTS, &frameChan, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); LALCCreateVector(status->statusPtr, &(a.data), length); BEGINFAIL(status) { TRY(LALDDestroyVector(status->statusPtr, &(sensemonTS.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); for (i = 0; i < length; ++i) { a.data->data[i] = crectf( (REAL4) sensemonTS.data->data[i], 0 ); } a.epoch = sensemonTS.epoch; a.deltaT = sensemonTS.deltaT; strncpy(a.name, sensemonTS.name, LALNameLength); LALFrSetPos(status->statusPtr, &facPos, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* get the alpha*beta values */ snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" OLOOP_FAC_CHAN ".mean", calfacts->ifo); LALFrGetREAL8TimeSeries(status->statusPtr, &sensemonTS, &frameChan, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* check that alpha and alpha*beta have the same sample rate */ if (fabs(alphaDeltaT - sensemonTS.deltaT) > LAL_REAL8_EPS) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; ABORT(status, FRAMECALIBRATIONH_EDTMM, FRAMECALIBRATIONH_MSGEDTMM); } LALCCreateVector(status->statusPtr, &(ab.data), length); BEGINFAIL(status) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALDDestroyVector(status->statusPtr, &(sensemonTS.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); for (i = 0; i < length; ++i) { ab.data->data[i] = crectf( (REAL4) sensemonTS.data->data[i], 0 ); } ab.epoch = sensemonTS.epoch; ab.deltaT = sensemonTS.deltaT; strncpy(ab.name, sensemonTS.name, LALNameLength); /* destroy the sensemonTS.data */ LALDDestroyVector(status->statusPtr, &(sensemonTS.data)); CHECKSTATUSPTR(status); break; } /* destroy the empty frame cache and try again */ XLALDestroyCache(facCache); /* try and get the the factors from lalapps_mkcalfac frames */ facCache = XLALCacheDuplicate(calCache); XLALCacheSieve(facCache, 0, 0, NULL, FAC_TYPE, NULL); if (!facCache) { RETURN_POINT_CAL; } if (facCache->length) { /* the lalapps frames are complex_8 proc data */ OPEN_FAC; snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" CAV_FAC_CHAN, calfacts->ifo); /* get the sample rate of the alpha channel */ LALFrGetCOMPLEX8TimeSeries(status->statusPtr, &a, &frameChan, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* determine number of calibration points required */ duration_real = XLALGPSGetREAL8(&(calfacts->duration)); length = (UINT4) ceil(duration_real / a.deltaT); ++length; /* make sure we get the first point before the requested cal time */ seekEpoch = output->epoch; XLALGPSAdd(&seekEpoch, fuzz - a.deltaT); a.epoch = ab.epoch = seekEpoch; GET_POS; /* create storage for the alpha values */ LALCCreateVector(status->statusPtr, &(a.data), length); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* get the alpha values */ LALFrGetCOMPLEX8TimeSeries(status->statusPtr, &a, &frameChan, facStream); BEGINFAIL(status) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); LALFrSetPos(status->statusPtr, &facPos, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* create storage for the alpha*beta values */ LALCCreateVector(status->statusPtr, &(ab.data), length); BEGINFAIL(status) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* get the alpha*beta values */ snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" OLOOP_FAC_CHAN, calfacts->ifo); LALFrGetCOMPLEX8TimeSeries(status->statusPtr, &ab, &frameChan, facStream); BEGINFAIL(status) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALCDestroyVector(status->statusPtr, &(ab.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* check that alpha and alpha*beta have the same sample rate */ if (fabs(a.deltaT - ab.deltaT) > LAL_REAL8_EPS) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALCDestroyVector(status->statusPtr, &(ab.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; ABORT(status, FRAMECALIBRATIONH_EDTMM, FRAMECALIBRATIONH_MSGEDTMM); } break; }
/** * \author Sintes, A. M. * * \brief Gets data cleaned from line harmonic interference given a time domain reference signal. * * ### Description ### * * This routine cleans data in the time domain from line harmonic interference * (from the first harmonic up to the Nyquist frequency). The inputs are: * * <tt>*in1</tt> the time domain data of type \c REAL4TVectorCLR, * containing also the interference fundamental frequency \f$f_0\f$ and the * sampling spacing. This information is needed in order to obtain * the total number of harmonics contained in the data. * <dl> * <dt><tt>in1->length</tt></dt><dd> The number of elements in <tt>in1->data</tt> \f$=n\f$.</dd> * <dt><tt>in1->data</tt></dt><dd> The (real) time domain data, \f$x(t)\f$.</dd> * <dt><tt>in1->deltaT</tt></dt><dd> The sample spacing in seconds.</dd> * <dt><tt>in1->fLine</tt></dt><dd> The interference fundamental frequency \f$f_0\f$ * (in Hz), e.g., 60 Hz.</dd> * </dl> * * <tt>*in2</tt> the time domain reference signal (a complex vector). * <dl> * <dt><tt>in2->length</tt></dt><dd> The number of elements in * <tt>in2->data</tt> \f$=n\f$.</dd> * <dt><tt>in2->data</tt></dt><dd> The \f$M(t)\f$ complex data.</dd> * </dl> * * The output <tt>*out</tt> is a real vector containing the clean data. * <dl> * <dt><tt>out->length</tt></dt><dd> The number of elements in * <tt>out->data</tt> \f$=n\f$.</dd> * <dt><tt>out->data</tt></dt><dd> The clean (real) time domain data.</dd> * </dl> * * ### Algorithm ### * * It takes the reference signal \f$M(t)\f$ and, for all possible harmonics * \f$j\f$ * (\f$j=1,\ldots,\f$<tt>floor(1.0/fabs( 2.02* in1->deltaT * in1->fLine))</tt> ), * from the fundamental frequency up to the Nyquist frequency, * constructs \f$M(t)^j\f$, performs a least-squares fit, i.e., * minimizes the power \f$\vert x(t) -\rho_j M(t)^j\vert^2\f$ with * respect to \f$\rho_j\f$, and subtracts \f$\rho_j M(t)^j\f$ from the * original data, \f$x(t)\f$. */ void LALCleanAll (LALStatus *status,/**< LAL status pointer */ REAL4Vector *out, /**< clean data */ COMPLEX8Vector *in2, /**< M(t), ref. interference */ REAL4TVectorCLR *in1) /**< x(t), data + information */ { INT4 n; INT4 i,j; INT4 maxH; REAL4 *x; REAL4 *xc; COMPLEX8 *m; COMPLEX16 rho,rhon; REAL8 rhod; REAL8 mr,mi; REAL8 amj,phj; COMPLEX16Vector *mj = NULL; REAL8Vector *ampM2 = NULL; REAL8Vector *phaM = NULL; /* --------------------------------------------- */ INITSTATUS(status); ATTATCHSTATUSPTR (status); /* Make sure the arguments are not NULL: */ ASSERT (out, status, CLRH_ENULL, CLRH_MSGENULL); ASSERT (in1, status, CLRH_ENULL, CLRH_MSGENULL); ASSERT (in2, status, CLRH_ENULL, CLRH_MSGENULL); /* Make sure the data pointers are not NULL: */ ASSERT (out->data, status, CLRH_ENULL, CLRH_MSGENULL); ASSERT (in1->data, status, CLRH_ENULL, CLRH_MSGENULL); ASSERT (in2->data, status, CLRH_ENULL, CLRH_MSGENULL); /* Make sure that the size is correct: */ ASSERT (out->length > 0, status, CLRH_ESIZE, CLRH_MSGESIZE); /* Make sure that the lengths are correct (size mismatch): */ ASSERT (in1->length == out->length, status, CLRH_ESZMM, CLRH_MSGESZMM); ASSERT (in2->length == out->length, status, CLRH_ESZMM, CLRH_MSGESZMM); /* Make sure the arguments are not pointing to the same memory location */ /* ASSERT (out != in2, status, CLRH_ESAME, CLRH_MSGESAME); */ /* Make sure F_Nyquist > fLine */ ASSERT (fabs(in1->deltaT * in1->fLine) < 0.495, status, CLRH_EFREQ, CLRH_MSGEFREQ); /* margin 0.495 and not 0.5 in order to avoid errors */ /* ------------------------------------------- */ n = out->length; m = in2->data; x = in1->data; xc = out->data; /* ------------------------------------------- */ /* Removing the fundamental harmonic */ /* ------------------------------------------- */ rhon = 0.0; rhod = 0.0; for (i=0; i<n; ++i) { mr = crealf(m[i]); mi = cimagf(m[i]); rhon += crect( x[i]*mr, -x[i]*mi ); rhod += mr*mr + mi*mi; } rho = (rhon / ((REAL8) rhod)); for (i=0; i<n; ++i) { xc[i] = x[i] - 2.0*(creal(rho) * crealf(m[i]) - cimag(rho) * cimagf(m[i]) ); } /* ------------------------------------------- */ /* Removing the other harmonics */ /* ------------------------------------------- */ maxH= floor(1.0/fabs( 2.02* in1->deltaT * in1->fLine)); if (maxH > 1) /* in case there are more harmonics */ { /* Create Vectors amplitude and phase m(t) */ TRY(LALDCreateVector(status->statusPtr, &M2, n), status); TRY(LALDCreateVector(status->statusPtr, &phaM, n), status); /* reserve space for m^j(t) */ TRY(LALZCreateVector(status->statusPtr, &mj ,n), status); for (i=0; i<n; ++i) { /* calculation of amplitude^2 and phase of m(t) */ mr = crealf(m[i]); mi = cimagf(m[i]); ampM2->data[i] = mr*mr+ mi*mi; if( ampM2->data[i] < LAL_REAL4_MIN) { phaM->data[i] = 0.0; /* to avoid NaN */ } else { phaM->data[i] = atan2(mi,mr); } } for(j=2; j<= maxH; ++j) { rhon = 0.0; rhod = 0.0; for (i=0; i<n; ++i) { /* calculation of m^j(t) for a fixed t */ amj = pow( ampM2->data[i], 0.5*j); phj = j * phaM->data[i]; mj->data[i] = crect( amj * cos(phj), amj * sin(phj) ); mr = creal(mj->data[i]); mi = cimag(mj->data[i]); rhon += crect( xc[i]*mr, -xc[i]*mi ); rhod += mr*mr + mi*mi; } rho = (rhon / ((REAL8) rhod)); for (i=0; i<n; ++i) { xc[i] += - 2.0*(creal(rho) * creal(mj->data[i]) - cimag(rho) * cimag(mj->data[i]) ); } } /* closes for all harmonics */ /* Destroy Vectors */ TRY(LALDDestroyVector(status->statusPtr, &M2), status); TRY(LALDDestroyVector(status->statusPtr, &phaM), status); TRY(LALZDestroyVector(status->statusPtr, &mj), status); } /* closes if */ /* ------------------------------------------- */ DETATCHSTATUSPTR (status); /* normal exit */ RETURN (status); }
int main(int argc, char **argv) { /* Variables for parsing command-line arguments. */ INT4 arg; /* argument list counter */ CHAR *metricfile = NULL; /* metric output filename */ CHAR *rangefile = NULL; /* parameter range output filename */ UINT4 n = NSTACKS; /* number of stacks */ REAL8 dt = STACKLENGTH; /* length of each stack (s) */ REAL8 t0 = STARTTIME; /* start time of first stack (GPS s) */ REAL8 f0 = FREQUENCY; /* maximum frequency of search */ REAL8 lat = LATITUDE; /* latitude of detector (degrees N) */ REAL8 lon = LONGITUDE; /* longitude of detector (degrees E) */ REAL8 ra[2], dec[2]; /* RA and dec ranges (degrees) */ /* Other variables. */ UINT4 i, j, k; /* indecies */ UINT4 nRA, nDec; /* sizes of metric grid in RA and dec */ REAL8 dRA, dDec; /* grid intervals in RA and dec */ UINT4 warnings = 0; /* points with large uncertainties */ UINT4 errors = 0; /* points with bad metrics */ static LALStatus stat; /* top-level status structure */ static LIGOTimeGPS start; /* GPS start time of first stack */ REAL4Grid *metricGrid = NULL; /* grid of metric values */ REAL4 *gData; /* pointer to metricGrid->data->data */ REAL4Grid *rangeGrid = NULL; /* grid of range delimiters */ REAL4 *rData; /* pointer to rangeGrid->data->data */ REAL4 propVol = 0.0; /* average proper volume element */ UINT4 nVol = 0; /* number of points used in average */ UINT4Vector *dimLength = NULL; /* used to allocate metricGrid */ REAL8Vector *lambda = NULL; /* metric parameter space vector */ REAL8Vector *metric = NULL; /* metric components */ REAL8 *mData; /* pointer to metric->data */ INT4 *topRange, *botRange; /* preliminary grid range limits */ INT4 *topRange2, *botRange2; /* adjusted grid range limits */ static MetricParamStruc params; /* metric computation parameters */ static PulsarTimesParamStruc baryParams; /* barycentring parameters */ /* Some more initializations. */ ra[0] = RA_MIN; dec[0] = DEC_MIN; ra[1] = RA_MAX; dec[1] = DEC_MAX; /****************************************************************** * ARGUMENT PARSING * ******************************************************************/ /* Parse argument list. arg stores the current position. */ arg = 1; while ( arg < argc ) { /* Parse output file option. */ if ( !strcmp( argv[arg], "-o" ) ) { if ( argc > arg + 2 ) { arg++; metricfile = argv[arg++]; rangefile = argv[arg++]; } else { ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return SKYMETRICTESTC_EARG; } } /* Parse search parameter option. */ else if ( !strcmp( argv[arg], "-p" ) ) { if ( argc > arg + 4 ) { arg++; n = atoi( argv[arg++] ); dt = atof( argv[arg++] ); t0 = atof( argv[arg++] ); f0 = atof( argv[arg++] ); } else { ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return SKYMETRICTESTC_EARG; } } /* Parse detector position option. */ else if ( !strcmp( argv[arg], "-l" ) ) { if ( argc > arg + 2 ) { arg++; lat = atof( argv[arg++] ); lon = atof( argv[arg++] ); } else { ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return SKYMETRICTESTC_EARG; } } /* Parse parameter space range option. */ else if ( !strcmp( argv[arg], "-r" ) ) { if ( argc > arg + 4 ) { arg++; ra[0] = atof( argv[arg++] ); ra[1] = atof( argv[arg++] ); dec[0] = atof( argv[arg++] ); dec[1] = atof( argv[arg++] ); } else { ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return SKYMETRICTESTC_EARG; } } /* Parse debug level option. */ else if ( !strcmp( argv[arg], "-d" ) ) { if ( argc > arg + 1 ) { arg++; } else { ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return SKYMETRICTESTC_EARG; } } /* Check for unrecognized options. */ else if ( argv[arg][0] == '-' ) { ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return SKYMETRICTESTC_EARG; } } /* End of argument parsing loop. */ /* Do error trapping on input parameters. */ if ( lalDebugLevel & LALERROR ) { CHECKVAL( n, 0, NMAX ); CHECKVAL( f0, 0.0, F0MAX ); CHECKVAL( dt, 1.0/f0, DTMAX ); CHECKVAL( lat, -90.0, 90.0 ); CHECKVAL( lon, -360.0, 360.0 ); } /****************************************************************** * METRIC COMPUTATION * ******************************************************************/ /* Set up start time. */ start.gpsSeconds = (INT4)t0; start.gpsNanoSeconds = (INT4)( 1.0e9*( t0 - start.gpsSeconds ) ); t0 = 0.0; /* Set up constant parameters for barycentre transformation. */ baryParams.epoch = start; baryParams.latitude = LAL_PI_180*lat; baryParams.longitude = LAL_PI_180*lon; SUB( LALGetEarthTimes( &stat, &baryParams ), &stat ); /* Set up constant parameters for metric calculation. */ params.dtCanon = LALDTBaryPtolemaic; params.constants = &baryParams; params.start = t0; params.deltaT = dt; params.n = n; params.errors = 1; /* Set up the metric vector, metric grid, and parameter vector. */ if ( params.errors ) SUB( LALDCreateVector( &stat, &metric, 12 ), &stat ); else SUB( LALDCreateVector( &stat, &metric, 6 ), &stat ); mData = metric->data; SUB( LALU4CreateVector( &stat, &dimLength, 3 ), &stat ); nRA = (UINT4)( ( ra[1] - ra[0] )/SPACING ) + 2; nDec = (UINT4)( ( dec[1] - dec[0] )/SPACING ) + 2; dimLength->data[0] = nDec; dimLength->data[1] = nRA; dimLength->data[2] = 3; SUB( LALSCreateGrid( &stat, &metricGrid, dimLength, 2 ), &stat ); SUB( LALU4DestroyVector( &stat, &dimLength ), &stat ); metricGrid->offset->data[0] = dec[0]; metricGrid->offset->data[1] = ra[0]; metricGrid->interval->data[0] = dDec = ( dec[1] - dec[0] )/( nDec - 1.0 ); metricGrid->interval->data[1] = dRA = ( ra[1] - ra[0] )/( nRA - 1.0 ); gData = metricGrid->data->data; SUB( LALDCreateVector( &stat, &lambda, 3 ), &stat ); lambda->data[0] = f0; /* Set up preliminary range delimiters. */ topRange = (INT4 *)LALMalloc( nRA*sizeof( INT4 ) ); botRange = (INT4 *)LALMalloc( nRA*sizeof( INT4 ) ); if ( !topRange || !botRange ) { ERROR( SKYMETRICTESTC_EMEM, SKYMETRICTESTC_MSGEMEM, 0 ); return SKYMETRICTESTC_EMEM; } for ( i = 0; i < nRA; i++ ) { topRange[i] = 0; botRange[i] = nRA; } /* Fill the metric grid with the projected metric. */ k = 0; fprintf( stdout, "Computing metric on %ix%i grid:\n", nDec, nRA ); for ( i = 0; i < nDec; i++ ) { BOOLEAN bottom = 1, top = 0; /* whether we're at the bottom or top of the grid column */ lambda->data[2] = LAL_PI_180*( dec[0] + i*dDec ); for ( j = 0; j < nRA; j++ ) { if ( top ) fprintf( stdout, "o" ); else { REAL4 gxx, gyy, gxy; /* metric components */ lambda->data[1] = LAL_PI_180*( ra[0] + j*dRA ); SUB( LALStackMetric( &stat, metric, lambda, ¶ms ), &stat ); SUB( LALProjectMetric( &stat, metric, params.errors ), &stat ); /* If uncertainties are given, generate conservative metric. */ if ( params.errors ) { INT2 sign = 1; /* sign of xy metric component */ gxx = mData[10] + mData[11]; gyy = mData[4] + mData[5]; gxy = mData[8]; if ( gxy < 0.0 ) sign = -1; if ( fabs( gxy ) <= fabs( mData[9] ) ) gxy = 0.0; else gxy = sign*( fabs( gxy ) - fabs( mData[9] ) ); if ( gxx < 0.0 || gyy < 0.0 || gxx*gyy - gxy*gxy < 0.0 ) { errors++; fprintf( stdout, "o" ); } else if ( fabs( mData[4]*mData[11] ) + fabs( mData[5]*mData[10] ) + fabs( mData[8]*mData[9] )*2.0 >= mData[4]*mData[10] - mData[8]*mData[8] ) { warnings++; fprintf( stdout, "*" ); } else fprintf( stdout, "+" ); } /* If uncertainties are not given, just use best estimate. */ else { gxx = mData[5]; gxy = mData[4]; gyy = mData[2]; if ( gxx < 0.0 || gyy < 0.0 || gxx*gyy - gxy*gxy < 0.0 ) { errors++; fprintf( stdout, "o" ); } else fprintf( stdout, "+" ); } /* See whether we've crossed a range boundary. */ if ( gxx > 0.0 && gyy > 0.0 && gxx*gyy - gxy*gxy > 0.0 ) { if ( bottom ) { bottom = 0; botRange[i] = j - 1; } propVol += LAL_PI_180*LAL_PI_180*sqrt( gxx*gyy - gxy*gxy ); nVol++; } else { if ( !bottom ) { top = 1; topRange[i] = j; } } *(gData++) = LAL_PI_180*LAL_PI_180*gxx; *(gData++) = LAL_PI_180*LAL_PI_180*gyy; *(gData++) = LAL_PI_180*LAL_PI_180*gxy; } fflush( stdout ); } if ( !top ) topRange[i] = j; fprintf( stdout, "\n" ); } /* Free memory that's no longer needed. */ SUB( LALDDestroyVector( &stat, &metric ), &stat ); SUB( LALDDestroyVector( &stat, &lambda ), &stat ); /* Warn if any points had bad values or large uncertainties. */ if ( errors ) { CHAR msg[MSGLEN]; snprintf( msg, MSGLEN, "%i of %i points had" " non-positive-definite metric", warnings, nRA*nDec ); WARNING( msg ); } if ( warnings ) { CHAR msg[MSGLEN]; snprintf( msg, MSGLEN, "%i of %i points had metric component" " errors larger than values", warnings, nRA*nDec ); WARNING( msg ); } /* Write the proper volume element. */ fprintf( stdout, "Average proper volume element: %10.3e per square" " degree\n", propVol /= nVol ); /****************************************************************** * RANGE COMPUTATION * ******************************************************************/ /* Each bad metric point affects the four squares adjoining it, so top and bottom ranges need to be adjusted down or up one point based on the adjoining columns. */ topRange2 = (INT4 *)LALMalloc( nDec*sizeof(INT4) ); botRange2 = (INT4 *)LALMalloc( nDec*sizeof(INT4) ); if ( !topRange2 || !botRange2 ) { ERROR( SKYMETRICTESTC_EMEM, SKYMETRICTESTC_MSGEMEM, 0 ); return SKYMETRICTESTC_EMEM; } topRange2[0] = topRange[1] < topRange[0] ? topRange[1] - 1 : topRange[0] - 1; botRange2[0] = botRange[1] > botRange[0] ? botRange[1] + 1 : botRange[0] + 1; topRange2[nDec-1] = topRange[nDec] < topRange[nDec-1] ? topRange[nDec] - 1 : topRange[nDec-1] - 1; botRange2[nDec-1] = botRange[nDec] > botRange[nDec-1] ? botRange[nDec] + 1 : botRange[nDec-1] + 1; for ( i = 1; i < nDec - 1; i++ ) { INT4 topMin = topRange[i-1], botMax = botRange[i-1]; if ( topRange[i] < topMin ) topMin = topRange[i]; if ( topRange[i+1] < topMin ) topMin = topRange[i+1]; if ( botRange[i] > botMax ) botMax = botRange[i]; if ( botRange[i+1] > botMax ) botMax = botRange[i+1]; topRange2[i] = topMin - 1; botRange2[i] = botMax + 1; } LALFree( topRange ); LALFree( botRange ); /* Determine the contiguous domain with open range intervals. */ if ( topRange2[0] > botRange2[0] && topRange2[1] > botRange2[1] ) i = 0; else { i = 1; while ( i < nDec - 1 && topRange2[i] <= botRange2[i] && topRange2[i+1] <= botRange2[i+1] ) i++; } j = i; while ( j < nDec - 1 && topRange2[j+1] > botRange2[j+1] ) j++; if ( j == i ) { ERROR( SKYMETRICTESTC_ERNG, SKYMETRICTESTC_MSGERNG, 0 ); return SKYMETRICTESTC_ERNG; } /* Set up range grid. */ j = j - i + 1; SUB( LALU4CreateVector( &stat, &dimLength, 2 ), &stat ); dimLength->data[0] = j; dimLength->data[1] = 2; SUB( LALSCreateGrid( &stat, &rangeGrid, dimLength, 1 ), &stat ); SUB( LALU4DestroyVector( &stat, &dimLength ), &stat ); rangeGrid->offset->data[0] = dec[0] + i*dDec; rangeGrid->interval->data[0] = dDec; rData = rangeGrid->data->data; nVol = 0; for ( k = 0; k < j; k++ ) { *(rData++) = ra[0] + botRange2[k]*dRA; *(rData++) = ra[0] + topRange2[k]*dRA; nVol += topRange2[k] - botRange2[k] - 1; } nVol -= topRange2[j-1] - botRange2[j-1] - 1; LALFree( topRange2 ); LALFree( botRange2 ); /* Write the total proper volume of the covered range. */ fprintf( stdout, "Total proper volume: %10.3e\n", propVol*nVol*dRA*dDec ); /****************************************************************** * FINISH * ******************************************************************/ /* Write the output files, if requested. */ if ( metricfile ) { FILE *fp = fopen( metricfile, "w" ); /* output file pointer */ if ( !fp ) { ERROR( SKYMETRICTESTC_EFILE, "- " SKYMETRICTESTC_MSGEFILE, metricfile ); return SKYMETRICTESTC_EFILE; } SUB( LALSWriteGrid( &stat, fp, metricGrid ), &stat ); fclose( fp ); } if ( rangefile ) { FILE *fp = fopen( rangefile, "w" ); /* output file pointer */ if ( !fp ) { ERROR( SKYMETRICTESTC_EFILE, "- " SKYMETRICTESTC_MSGEFILE, rangefile ); return SKYMETRICTESTC_EFILE; } SUB( LALSWriteGrid( &stat, fp, rangeGrid ), &stat ); fclose( fp ); } /* Clean up and exit. */ SUB( LALSDestroyGrid( &stat, &metricGrid ), &stat ); SUB( LALSDestroyGrid( &stat, &rangeGrid ), &stat ); LALCheckMemoryLeaks(); INFO( SKYMETRICTESTC_MSGENORM ); return SKYMETRICTESTC_ENORM; }
int main( void ) { static LALStatus status; REAL4Sequence *sSequenceIn; REAL4Sequence *sSequenceOut; REAL8Sequence *dSequenceIn; REAL8Sequence *dSequenceOut; COMPLEX8Sequence *cSequenceIn; COMPLEX8Sequence *cSequenceOut; COMPLEX16Sequence *zSequenceIn; COMPLEX16Sequence *zSequenceOut; REAL4FrequencySeries sFrequencySeries; REAL8FrequencySeries dFrequencySeries; COMPLEX8FrequencySeries cFrequencySeries; COMPLEX16FrequencySeries zFrequencySeries; REAL4FrequencySeries sFrequencySeries2; REAL8FrequencySeries dFrequencySeries2; COMPLEX8FrequencySeries cFrequencySeries2; COMPLEX16FrequencySeries zFrequencySeries2; REAL4TimeSeries sTimeSeries; REAL8TimeSeries dTimeSeries; COMPLEX8TimeSeries cTimeSeries; COMPLEX16TimeSeries zTimeSeries; REAL4TimeSeries sTimeSeries2; REAL8TimeSeries dTimeSeries2; COMPLEX8TimeSeries cTimeSeries2; COMPLEX16TimeSeries zTimeSeries2; REAL4 *sData; REAL8 *dData; COMPLEX8 *cData; COMPLEX16 *zData; /* Boolean Vars */ BOOLEAN unitComp; /* variables for units */ RAT4 raise; LALUnit strainToMinus2; LALUnit adcToMinus2; LALUnit adcStrain; /* This routine should generate a file with data */ /* to be read by ReadFTSeries.c*/ LIGOTimeGPS t; UINT4 i; /* Data Test Variable */ UINT4 j; fprintf(stderr,"Testing value of LALUnitTextSize ... "); if ( (int)LALSupportUnitTextSize != (int)LALUnitTextSize ) { fprintf(stderr,"UnitTextSize mismatch: [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } fprintf(stderr,"PASS\n"); t.gpsSeconds = 0; t.gpsNanoSeconds = 0; fprintf(stderr,"Testing Print/Read COMPLEX8FrequencySeries ... "); cSequenceIn = NULL; LALCCreateVector(&status, &cSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, cData=cSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, cData++ ) { *(cData) = crectf( i, i+1 ); } strncpy(cFrequencySeries.name,"Complex frequency series",LALNameLength); cFrequencySeries.sampleUnits = lalHertzUnit; cFrequencySeries.deltaF = 1; cFrequencySeries.epoch = t; cFrequencySeries.f0 = 5; cFrequencySeries.data = cSequenceIn; LALCPrintFrequencySeries(&cFrequencySeries, "cFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } cSequenceOut = NULL; LALCCreateVector( &status, &cSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } cFrequencySeries2.data = cSequenceOut; LALCReadFrequencySeries(&status, &cFrequencySeries2, "./cFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(cFrequencySeries.deltaF - cFrequencySeries.deltaF)/ cFrequencySeries.deltaF > READFTSERIESTEST_TOL) { fprintf(stderr,"DeltaF MisMatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(cFrequencySeries.name,cFrequencySeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cFrequencySeries.epoch.gpsSeconds) != (cFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Second Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cFrequencySeries.epoch.gpsNanoSeconds) != (cFrequencySeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch NanosecondMismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cFrequencySeries.f0) ? (fabs(cFrequencySeries.f0 - cFrequencySeries2.f0)/cFrequencySeries.f0) : (fabs(cFrequencySeries.f0 - cFrequencySeries2.f0) > READFTSERIESTEST_TOL)) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&cFrequencySeries.sampleUnits,&cFrequencySeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < cSequenceIn->length;j++) { if ((crealf(cSequenceIn->data[j]) ? fabs((crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j])) /crealf(cSequenceIn->data[j])) :fabs(crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cimagf(cSequenceIn->data[j]) ? fabs((cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j])) /cimagf(cSequenceIn->data[j])) :fabs(cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read COMPLEX16FrequencySeries ... "); /* Test case 2 */ t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; zSequenceIn = NULL; LALZCreateVector( &status, &zSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, zData=zSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, zData++ ) { *(zData) = crect( i/4.0, (i+1)/5.0 ); } zFrequencySeries.sampleUnits = lalDimensionlessUnit; strncpy(zFrequencySeries.name,"Complex frequency series",LALNameLength); zFrequencySeries.deltaF = 1.3; zFrequencySeries.epoch = t; zFrequencySeries.f0 = 0; zFrequencySeries.data = zSequenceIn; LALZPrintFrequencySeries(&zFrequencySeries, "zFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } zSequenceOut = NULL; LALZCreateVector( &status, &zSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } zFrequencySeries2.data = zSequenceOut; LALZReadFrequencySeries(&status, &zFrequencySeries2, "./zFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if ((zFrequencySeries.deltaF) != (zFrequencySeries2.deltaF)) { fprintf(stderr,"DeltaF Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(zFrequencySeries.name,zFrequencySeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((zFrequencySeries.epoch.gpsSeconds) != (zFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((zFrequencySeries.epoch.gpsNanoSeconds) != (zFrequencySeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (zFrequencySeries.f0 ? (fabs(zFrequencySeries.f0 - zFrequencySeries2.f0)/zFrequencySeries.f0) : (fabs(zFrequencySeries.f0 - zFrequencySeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&zFrequencySeries.sampleUnits,&zFrequencySeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < zSequenceIn->length;j++) { if ((creal(zSequenceIn->data[j]) ? fabs((creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j])) /creal(zSequenceIn->data[j])) : fabs(creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cimag(zSequenceIn->data[j]) ? fabs((cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j])) /cimag(zSequenceIn->data[j])) : fabs(cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read REAL8FrequencySeries ... "); /* Test case 3 */ t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; dSequenceIn = NULL; LALDCreateVector( &status, &dSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, dData=dSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, dData++ ) { *(dData) = 0.005; } strncpy(dFrequencySeries.name,"Complex frequency series",LALNameLength); /* set units */ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&dFrequencySeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dFrequencySeries.deltaF = 1.3; dFrequencySeries.epoch = t; dFrequencySeries.f0 = 0; dFrequencySeries.data = dSequenceIn; LALDPrintFrequencySeries(&dFrequencySeries, "dFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dSequenceOut = NULL; LALDCreateVector( &status, &dSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dFrequencySeries2.data = dSequenceOut; LALDReadFrequencySeries(&status, &dFrequencySeries2, "./dFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if ((dFrequencySeries.deltaF) != (dFrequencySeries.deltaF)) { fprintf(stderr,"DeltaF Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(dFrequencySeries.name,dFrequencySeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((dFrequencySeries.epoch.gpsSeconds) != (dFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((dFrequencySeries.epoch.gpsSeconds) != (dFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (dFrequencySeries.f0 ? (fabs(dFrequencySeries.f0 - dFrequencySeries2.f0)/dFrequencySeries.f0) : (fabs(dFrequencySeries.f0 - dFrequencySeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&dFrequencySeries.sampleUnits,&dFrequencySeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < dSequenceIn->length;j++) { if ((dSequenceIn->data[j] ? fabs((dSequenceIn->data[j] - dSequenceOut->data[j]) /dSequenceIn->data[j]) :fabs(dSequenceIn->data[j] - dSequenceOut->data[j])) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read REAL4FrequencySeries ... "); /* Test case 4 */ t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; sSequenceIn = NULL; LALSCreateVector( &status, &sSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, sData=sSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, sData++ ) { *(sData) = 0.005; } strncpy(sFrequencySeries.name,"Complex frequency series",LALNameLength); /* set units */ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&sFrequencySeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } sFrequencySeries.deltaF = 1.3; sFrequencySeries.epoch = t; sFrequencySeries.f0 = 5; sFrequencySeries.data = sSequenceIn; sSequenceOut = NULL; LALSCreateVector( &status, &sSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } sFrequencySeries2.data = sSequenceOut; LALSPrintFrequencySeries(&sFrequencySeries, "sFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSReadFrequencySeries(&status, &sFrequencySeries2, "./sFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(sFrequencySeries.deltaF - sFrequencySeries2.deltaF) /sFrequencySeries.deltaF > READFTSERIESTEST_TOL) { fprintf(stderr,"Deltaf Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(sFrequencySeries.name,sFrequencySeries2.name)!=0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((sFrequencySeries.epoch.gpsSeconds) != (sFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((sFrequencySeries.epoch.gpsNanoSeconds) != (sFrequencySeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (sFrequencySeries.f0 ? (fabs(sFrequencySeries.f0 - sFrequencySeries2.f0)/sFrequencySeries.f0) : (fabs(sFrequencySeries.f0 - sFrequencySeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&sFrequencySeries.sampleUnits,&sFrequencySeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < sSequenceIn->length;j++) { if ((sSequenceIn->data[j] ? fabs((sSequenceIn->data[j] - sSequenceOut->data[j]) /sSequenceIn->data[j]) :fabs(sSequenceIn->data[j] - sSequenceOut->data[j])) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } LALCDestroyVector(&status, &cSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALCDestroyVector(&status, &cSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALZDestroyVector(&status, &zSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALZDestroyVector(&status, &zSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALDDestroyVector(&status, &dSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALDDestroyVector(&status, &dSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSDestroyVector(&status, &sSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSDestroyVector(&status, &sSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read REAL4TimeSeries ... "); /* Here is where testing for ReadTimeSeries is done */ /* S Case ReadTimeSeries */ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&sTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; sSequenceIn = NULL; LALSCreateVector( &status, &sSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, sData=sSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, sData++ ) { *(sData) = 0.005; } strncpy(sTimeSeries.name,"Real4 Time series",LALNameLength); sTimeSeries.deltaT = 1.3; sTimeSeries.epoch = t; sTimeSeries.data = sSequenceIn; sTimeSeries.f0 = 5; LALSPrintTimeSeries(&sTimeSeries, "sTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } sSequenceOut = NULL; LALSCreateVector( &status, &sSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } sTimeSeries2.data = sSequenceOut; LALSReadTimeSeries(&status, &sTimeSeries2, "./sTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(sTimeSeries.deltaT-sTimeSeries2.deltaT) / sTimeSeries.deltaT > READFTSERIESTEST_TOL) { fprintf(stderr,"DeltaT Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(sFrequencySeries.name,sFrequencySeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((sTimeSeries.epoch.gpsSeconds) != (sTimeSeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((sTimeSeries.epoch.gpsNanoSeconds) != (sTimeSeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } /* printf("%f ... %f f0 value\n",sTimeSeries.f0,sTimeSeries2.f0);*/ if (sTimeSeries.f0 ? (fabs(sTimeSeries.f0 - sTimeSeries2.f0)/sTimeSeries.f0) : (fabs(sTimeSeries.f0 - sTimeSeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&sTimeSeries.sampleUnits,&sTimeSeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < sSequenceIn->length;j++) { if ((sSequenceIn->data[j] ? fabs((sSequenceIn->data[j] - sSequenceOut->data[j]) /sSequenceIn->data[j]) :fabs(sSequenceIn->data[j] - sSequenceOut->data[j])) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read COMPLEX16TimeSeries ... "); /* Z case ReadTimeSeries*/ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&zTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; zSequenceIn = NULL; LALZCreateVector( &status, &zSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, zData=zSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, zData++ ) { *(zData) = crect( 0.005, 1 ); } strncpy(zTimeSeries.name,"Complex16 Time series",LALNameLength); zTimeSeries.deltaT = 1.3; zTimeSeries.epoch = t; zTimeSeries.data = zSequenceIn; zTimeSeries.f0 = 0; LALZPrintTimeSeries(&zTimeSeries, "zTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } zSequenceOut = NULL; LALZCreateVector( &status, &zSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } zTimeSeries2.data = zSequenceOut; LALZReadTimeSeries(&status, &zTimeSeries2, "./zTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(zTimeSeries.deltaT) - (zTimeSeries2.deltaT)/zTimeSeries.deltaT > READFTSERIESTEST_TOL) { fprintf(stderr,"Mismatch DeltaT [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(zTimeSeries.name,zTimeSeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((zTimeSeries.epoch.gpsSeconds) != (zTimeSeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Second Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ( (zTimeSeries.epoch.gpsNanoSeconds) != (zTimeSeries2.epoch.gpsNanoSeconds) ) { fprintf(stderr,"Epoch Nanosecond Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (zTimeSeries.f0 ? (fabs(zTimeSeries.f0 - zTimeSeries2.f0)/zTimeSeries.f0) : (fabs(zTimeSeries.f0 - zTimeSeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&zTimeSeries.sampleUnits,&zTimeSeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFUN; } for (j = 0; j < zSequenceIn->length;j++) { if ((creal(zSequenceIn->data[j]) ? fabs((creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j])) /creal(zSequenceIn->data[j])) :fabs(creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cimag(zSequenceIn->data[j]) ? fabs((cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j])) /cimag(zSequenceIn->data[j])) :fabs(cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read REAL8TimeSeries ... "); /* D case ReadTimeSeries*/ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&sTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } strncpy(dTimeSeries.name,"REAL8 Time series",LALNameLength); dTimeSeries.sampleUnits = lalHertzUnit; t.gpsSeconds = 4578; t.gpsNanoSeconds = 890634; dSequenceIn = NULL; LALDCreateVector( &status, &dSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, dData=dSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, dData++ ) { *(dData) = 0.005; } dTimeSeries.deltaT = 1.3; dTimeSeries.epoch = t; dTimeSeries.data = dSequenceIn; dTimeSeries.f0 = 0; LALDPrintTimeSeries(&dTimeSeries, "dTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dSequenceOut = NULL; LALDCreateVector( &status, &dSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dTimeSeries2.data = dSequenceOut; LALDReadTimeSeries(&status, &dTimeSeries2, "./dTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(dTimeSeries.deltaT) - (dTimeSeries2.deltaT)/dTimeSeries.deltaT > READFTSERIESTEST_TOL) { fprintf(stderr,"DeltaT Mismatch [ReadFTSeriesTest:%d,%s]\n",status.statusCode, status.statusDescription ); return READFTSERIESTESTC_EFLS; } if (strcmp(dTimeSeries.name,dTimeSeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%d,%s]\n",status.statusCode, status.statusDescription ); return READFTSERIESTESTC_EFLS; } if ((dTimeSeries.epoch.gpsSeconds) != (dTimeSeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((dTimeSeries.epoch.gpsNanoSeconds) != (dTimeSeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch Nanoseconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (dTimeSeries.f0 ? (fabs(dTimeSeries.f0 - dTimeSeries2.f0)/dTimeSeries.f0) : (fabs(dTimeSeries.f0 - dTimeSeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&dTimeSeries.sampleUnits,&dTimeSeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < dSequenceIn->length;j++) { if ((dSequenceIn->data[j] ? fabs((dSequenceIn->data[j] - dSequenceOut->data[j]) /dSequenceIn->data[j]) :fabs(dSequenceIn->data[j] - dSequenceOut->data[j])) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read COMPLEX8TimeSeries ... "); /* C case ReadTimeSeries*/ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&cTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; cSequenceIn = NULL; LALCCreateVector( &status, &cSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, cData=cSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, cData++ ) { *(cData) = crectf( 0.005, 1 ); } strncpy(cTimeSeries.name,"Complex8 Time series",LALNameLength); cTimeSeries.deltaT = 1.3; cTimeSeries.epoch = t; cTimeSeries.data = cSequenceIn; cTimeSeries.f0 = 0; cSequenceOut = NULL; LALCPrintTimeSeries(&cTimeSeries, "cTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALCCreateVector( &status, &cSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } cTimeSeries2.data = cSequenceOut; LALCReadTimeSeries(&status, &cTimeSeries2, "./cTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(cTimeSeries.deltaT - cTimeSeries2.deltaT)/cTimeSeries.deltaT > READFTSERIESTEST_TOL) { fprintf(stderr,"DeltaT Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(cTimeSeries.name,cTimeSeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cTimeSeries.epoch.gpsSeconds) != (cTimeSeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cTimeSeries.epoch.gpsNanoSeconds)!=(cTimeSeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch Nanoseconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (cTimeSeries.f0 ? (fabs(cTimeSeries.f0 - cTimeSeries2.f0)/cTimeSeries.f0) : (fabs(cTimeSeries.f0 - cTimeSeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&cTimeSeries.sampleUnits,&cTimeSeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < cSequenceIn->length;j++) { if ((crealf(cSequenceIn->data[j]) ? fabs((crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j])) /crealf(cSequenceIn->data[j])) :fabs(crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cimagf(cSequenceIn->data[j]) ? fabs((cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j])) /cimagf(cSequenceIn->data[j])) :fabs(cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); /* *******************Deallocate all memory****************** */ LALCDestroyVector(&status, &cSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALCDestroyVector(&status, &cSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALZDestroyVector(&status, &zSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALZDestroyVector(&status, &zSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALDDestroyVector(&status, &dSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALDDestroyVector(&status, &dSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSDestroyVector(&status, &sSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSDestroyVector(&status, &sSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALCheckMemoryLeaks(); fprintf(stderr,"ReadFTSeries passed all tests.\n"); return READFTSERIESTESTC_ENOM; }
/** * \author Creighton, T. D. * * \brief Computes the response of a detector to a coherent gravitational wave. * * This function takes a quasiperiodic gravitational waveform given in * <tt>*signal</tt>, and estimates the corresponding response of the * detector whose position, orientation, and transfer function are * specified in <tt>*detector</tt>. The result is stored in * <tt>*output</tt>. * * The fields <tt>output-\>epoch</tt>, <tt>output->deltaT</tt>, and * <tt>output-\>data</tt> must already be set, in order to specify the time * period and sampling rate for which the response is required. If * <tt>output-\>f0</tt> is nonzero, idealized heterodyning is performed (an * amount \f$2\pi f_0(t-t_0)\f$ is subtracted from the phase before computing * the sinusoid, where \f$t_0\f$ is the heterodyning epoch defined in * \c detector). For the input signal, <tt>signal-\>h</tt> is ignored, * and the signal is treated as zero at any time for which either * <tt>signal-\>a</tt> or <tt>signal-\>phi</tt> is not defined. * * This routine will convert <tt>signal-\>position</tt> to equatorial * coordinates, if necessary. * * ### Algorithm ### * * The routine first accounts for the time delay between the detector and * the solar system barycentre, based on the detector position * information stored in <tt>*detector</tt> and the propagation direction * specified in <tt>*signal</tt>. Values of the propagation delay are * precomuted at fixed intervals and stored in a table, with the * intervals \f$\Delta T_\mathrm{delay}\f$ chosen such that the value * interpolated from adjacent table entries will never differ from the * true value by more than some timing error \f$\sigma_T\f$. This implies * that: * \f[ * \Delta T_\mathrm{delay} \leq \sqrt{ * \frac{8\sigma_T}{\max\{a/c\}} } \; , * \f] * where \f$\max\{a/c\}=1.32\times10^{-10}\mathrm{s}^{-1}\f$ is the maximum * acceleration of an Earth-based detector in the barycentric frame. The * total propagation delay also includes Einstein and Shapiro delay, but * these are more slowly varying and thus do not constrain the table * spacing. At present, a 400s table spacing is hardwired into the code, * implying \f$\sigma_T\approx3\mu\f$s, comparable to the stated accuracy of * <tt>LALBarycenter()</tt>. * * Next, the polarization response functions of the detector * \f$F_{+,\times}(\alpha,\delta)\f$ are computed for every 10 minutes of the * signal's duration, using the position of the source in <tt>*signal</tt>, * the detector information in <tt>*detector</tt>, and the function * <tt>LALComputeDetAMResponseSeries()</tt>. Subsequently, the * polarization functions are estimated for each output sample by * interpolating these precomputed values. This guarantees that the * interpolated value is accurate to \f$\sim0.1\%\f$. * * Next, the frequency response of the detector is estimated in the * quasiperiodic limit as follows: * <ul> * <li> At each sample point in <tt>*output</tt>, the propagation delay is * computed and added to the sample time, and the instantaneous * amplitudes \f$A_1\f$, \f$A_2\f$, frequency \f$f\f$, phase \f$\phi\f$, and polarization * shift \f$\Phi\f$ are found by interpolating the nearest values in * <tt>signal-\>a</tt>, <tt>signal-\>f</tt>, <tt>signal-\>phi</tt>, and * <tt>signal-\>shift</tt>, respectively. If <tt>signal-\>f</tt> is not * defined at that point in time, then \f$f\f$ is estimated by differencing * the two nearest values of \f$\phi\f$, as \f$f\approx\Delta\phi/2\pi\Delta * t\f$. If <tt>signal-\>shift</tt> is not defined, then \f$\Phi\f$ is treated as * zero.</li> * <li> The complex transfer function of the detector the frequency \f$f\f$ * is found by interpolating <tt>detector-\>transfer</tt>. The amplitude of * the transfer function is multiplied with \f$A_1\f$ and \f$A_2\f$, and the * phase of the transfer function is added to \f$\phi\f$,</li> * <li> The plus and cross contributions \f$o_+\f$, \f$o_\times\f$ to the * detector output are computed as in \eqref{eq_quasiperiodic_hpluscross} * of \ref PulsarSimulateCoherentGW_h, but * using the response-adjusted amplitudes and phase.</li> * <li> The final detector response \f$o\f$ is computed as * \f$o=(o_+F_+)+(o_\times F_\times)\f$.</li> * </ul> * * ### A note on interpolation: ### * * Much of the computational work in this routine involves interpolating * various time series to find their values at specific output times. * The algorithm is summarized below. * * Let \f$A_j = A( t_A + j\Delta t_A )\f$ be a sampled time series, which we * want to resample at new (output) time intervals \f$t_k = t_0 + k\Delta * t\f$. We first precompute the following quantities: * \f{eqnarray}{ * t_\mathrm{off} & = & \frac{t_0-t_A}{\Delta t_A} \; , \\ * dt & = & \frac{\Delta t}{\Delta t_A} \; . * \f} * Then, for each output sample time \f$t_k\f$, we compute: * \f{eqnarray}{ * t & = & t_\mathrm{off} + k \times dt \; , \\ * j & = & \lfloor t \rfloor \; , \\ * f & = & t - j \; , * \f} * where \f$\lfloor x\rfloor\f$ is the "floor" function; i.e.\ the largest * integer \f$\leq x\f$. The time series sampled at the new time is then: * \f[ * A(t_k) = f \times A_{j+1} + (1-f) \times A_j \; . * \f] * * ### Notes ### * * The major computational hit in this routine comes from computing the * sine and cosine of the phase angle in * \eqref{eq_quasiperiodic_hpluscross} of * \ref PulsarSimulateCoherentGW_h. For better online performance, these can * be replaced by other (approximate) trig functions. Presently the code * uses the native \c libm functions by default, or the function * <tt>sincosp()</tt> in \c libsunmath \e if this function is * available \e and the constant \c ONLINE is defined. * Differences at the level of 0.01 begin to appear only for phase * arguments greater than \f$10^{14}\f$ or so (corresponding to over 500 * years between phase epoch and observation time for frequencies of * around 1kHz). * * To activate this feature, be sure that <tt>sunmath.h</tt> and * \c libsunmath are on your system, and add <tt>-DONLINE</tt> to the * <tt>--with-extra-cppflags</tt> configuration argument. In future this * flag may be used to turn on other efficient trig algorithms on other * (non-Solaris) platforms. * */ void LALPulsarSimulateCoherentGW( LALStatus *stat, REAL4TimeSeries *output, PulsarCoherentGW *CWsignal, PulsarDetectorResponse *detector ) { INT4 i, n; /* index over output->data, and its final value */ INT4 nMax; /* used to store limits on index ranges */ INT4 fInit, fFinal; /* index range for which CWsignal->f is defined */ INT4 shiftInit, shiftFinal; /* ditto for CWsignal->shift */ UINT4 dtDelayBy2; /* delay table half-interval (s) */ UINT4 dtPolBy2; /* polarization table half-interval (s) */ REAL4 *outData; /* pointer to output data */ REAL8 delayMin, delayMax; /* min and max values of time delay */ SkyPosition source; /* source sky position */ BOOLEAN transfer; /* 1 if transfer function is specified */ BOOLEAN fFlag = 0; /* 1 if frequency left detector->transfer range */ BOOLEAN pFlag = 0; /* 1 if frequency was estimated from phase */ /* get delay table and polaristion tables half intervals if defined (>0) in the PulsarCoherentGW structure otherwise default to 400s for dtDelatBy2 and 300s for dtPolBy2 */ dtDelayBy2 = CWsignal->dtDelayBy2 > 0 ? CWsignal->dtDelayBy2 : 400; dtPolBy2 = CWsignal->dtPolBy2 > 0 ? CWsignal->dtPolBy2 : 300; /* The amplitude, frequency, phase, polarization shift, polarization response, and propagation delay are stored in arrays that must be interpolated. For a quantity x, we define a pointer xData to the data array. At some time t measured in units of output->deltaT, the interpolation point in xData is given by ( xOff + t*xDt ), where xOff is an offset and xDt is a relative sampling rate. */ LALDetAMResponseSeries polResponse; REAL8Vector *delay = NULL; REAL4 *aData, *fData, *shiftData, *plusData, *crossData; REAL8 *phiData, *delayData; REAL8 aOff, fOff, phiOff, shiftOff, polOff, delayOff; REAL8 aDt, fDt, phiDt, shiftDt, polDt, delayDt; /* Frequencies in the detector transfer function are interpolated similarly, except everything is normalized with respect to detector->transfer->deltaF. */ REAL4Vector *aTransfer = NULL; REAL4Vector *phiTransfer = NULL; REAL4Vector *phiTemp = NULL; REAL4 *aTransData = NULL, *phiTransData = NULL; REAL8 f0 = 1.0; REAL8 phiFac = 1.0, fFac = 1.0; /* Heterodyning phase factor LAL_TWOPI*output->f0*output->deltaT, and phase offset at the start of the series LAL_TWOPI*output->f0*(time offset). */ REAL8 heteroFac, phi0; /* Variables required by the TCENTRE() macro, above. */ REAL8 realIndex; INT4 intIndex; REAL8 indexFrac; INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Make sure parameter structures and their fields exist. */ ASSERT( CWsignal, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); if ( !( CWsignal->a ) ) { ABORT( stat, SIMULATECOHERENTGWH_ESIG, SIMULATECOHERENTGWH_MSGESIG ); } ASSERT( CWsignal->a->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( CWsignal->a->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); if ( !( CWsignal->phi ) ) { ABORT( stat, SIMULATECOHERENTGWH_ESIG, SIMULATECOHERENTGWH_MSGESIG ); } ASSERT( CWsignal->phi->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( CWsignal->phi->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); if ( CWsignal->f ) { ASSERT( CWsignal->f->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( CWsignal->f->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); } if ( CWsignal->shift ) { ASSERT( CWsignal->shift->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( CWsignal->shift->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); } ASSERT( detector, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); if ( ( transfer = ( detector->transfer != NULL ) ) ) { ASSERT( detector->transfer->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( detector->transfer->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); } ASSERT( output, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( output->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( output->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); /* Check dimensions of amplitude array. */ ASSERT( CWsignal->a->data->vectorLength == 2, stat, SIMULATECOHERENTGWH_EDIM, SIMULATECOHERENTGWH_MSGEDIM ); /* Make sure we never divide by zero. */ ASSERT( CWsignal->a->deltaT != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); ASSERT( CWsignal->phi->deltaT != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); aDt = output->deltaT / CWsignal->a->deltaT; phiDt = output->deltaT / CWsignal->phi->deltaT; ASSERT( aDt != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); ASSERT( phiDt != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); if ( CWsignal->f ) { ASSERT( CWsignal->f->deltaT != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); fDt = output->deltaT / CWsignal->f->deltaT; ASSERT( fDt != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); } else fDt = 0.0; if ( CWsignal->shift ) { ASSERT( CWsignal->shift->deltaT != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); shiftDt = output->deltaT / CWsignal->shift->deltaT; ASSERT( shiftDt != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); } else shiftDt = 0.0; if ( transfer ) { ASSERT( detector->transfer->deltaF != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); fFac = 1.0 / detector->transfer->deltaF; phiFac = fFac / ( LAL_TWOPI*CWsignal->phi->deltaT ); f0 = detector->transfer->f0/detector->transfer->deltaF; } heteroFac = LAL_TWOPI*output->f0*output->deltaT; phi0 = (REAL8)( output->epoch.gpsSeconds - detector->heterodyneEpoch.gpsSeconds ); phi0 += 0.000000001*(REAL8)( output->epoch.gpsNanoSeconds - detector->heterodyneEpoch.gpsNanoSeconds ); phi0 *= LAL_TWOPI*output->f0; if ( phi0 > 1.0/LAL_REAL8_EPS ) { LALWarning( stat, "REAL8 arithmetic is not sufficient to maintain" " heterodyne phase to within a radian." ); } /* Check units on input, and set units on output. */ { ASSERT( XLALUnitCompare( &(CWsignal->f->sampleUnits), &lalHertzUnit ) == 0, stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT ); ASSERT( XLALUnitCompare( &(CWsignal->phi->sampleUnits), &lalDimensionlessUnit ) == 0, stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT ); if( CWsignal->shift ) { ASSERT( XLALUnitCompare( &(CWsignal->shift->sampleUnits), &lalDimensionlessUnit ) == 0, stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT ); } if ( transfer ) { if ( XLALUnitMultiply( &(output->sampleUnits), &(CWsignal->a->sampleUnits), &(detector->transfer->sampleUnits) ) == NULL ) { ABORT( stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT ); } } else { output->sampleUnits = CWsignal->a->sampleUnits; } snprintf( output->name, LALNameLength, "response to %s", CWsignal->a->name ); } /* Define temporary variables to access the data of CWsignal->a, CWsignal->f, and CWsignal->phi. */ aData = CWsignal->a->data->data; INT4 aLen = CWsignal->a->data->length * CWsignal->a->data->vectorLength; phiData = CWsignal->phi->data->data; INT4 phiLen = CWsignal->phi->data->length; outData = output->data->data; INT4 fLen=0, shiftLen=0; if ( CWsignal->f ) { fData = CWsignal->f->data->data; fLen = CWsignal->f->data->length; } else { fData = NULL; } if ( CWsignal->shift ) { shiftData = CWsignal->shift->data->data; shiftLen = CWsignal->shift->data->length; } else { shiftData = NULL; } /* Convert source position to equatorial coordinates, if required. */ if ( detector->site ) { source = CWsignal->position; if ( source.system != COORDINATESYSTEM_EQUATORIAL ) { ConvertSkyParams params; /* parameters for conversion */ EarthPosition location; /* location of detector */ params.gpsTime = &( output->epoch ); params.system = COORDINATESYSTEM_EQUATORIAL; if ( source.system == COORDINATESYSTEM_HORIZON ) { params.zenith = &( location.geodetic ); location.x = detector->site->location[0]; location.y = detector->site->location[1]; location.z = detector->site->location[2]; TRY( LALGeocentricToGeodetic( stat->statusPtr, &location ), stat ); } TRY( LALConvertSkyCoordinates( stat->statusPtr, &source, &source, ¶ms ), stat ); } } /* Generate the table of propagation delays. dtDelayBy2 = (UINT4)( 38924.9/sqrt( output->f0 + 1.0/output->deltaT ) ); */ delayDt = output->deltaT/( 2.0*dtDelayBy2 ); nMax = (UINT4)( output->data->length*delayDt ) + 3; TRY( LALDCreateVector( stat->statusPtr, &delay, nMax ), stat ); delayData = delay->data; /* Compute delay from solar system barycentre. */ if ( detector->site && detector->ephemerides ) { LIGOTimeGPS gpsTime; /* detector time when we compute delay */ EarthState state; /* Earth position info at that time */ BarycenterInput input; /* input structure to LALBarycenter() */ EmissionTime emit; /* output structure from LALBarycenter() */ /* Arrange nested pointers, and set initial values. */ gpsTime = input.tgps = output->epoch; gpsTime.gpsSeconds -= dtDelayBy2; input.tgps.gpsSeconds -= dtDelayBy2; input.site = *(detector->site); for ( i = 0; i < 3; i++ ) input.site.location[i] /= LAL_C_SI; input.alpha = source.longitude; input.delta = source.latitude; input.dInv = 0.0; delayMin = delayMax = 1.1*LAL_AU_SI/( LAL_C_SI*output->deltaT ); delayMax *= -1; /* Compute table. */ for ( i = 0; i < nMax; i++ ) { REAL8 tDelay; /* propagation time */ LALBarycenterEarth( stat->statusPtr, &state, &gpsTime, detector->ephemerides ); BEGINFAIL( stat ) TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); ENDFAIL( stat ); LALBarycenter( stat->statusPtr, &emit, &input, &state ); BEGINFAIL( stat ) TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); ENDFAIL( stat ); delayData[i] = tDelay = emit.deltaT/output->deltaT; if ( tDelay < delayMin ) delayMin = tDelay; if ( tDelay > delayMax ) delayMax = tDelay; gpsTime.gpsSeconds += 2*dtDelayBy2; input.tgps.gpsSeconds += 2*dtDelayBy2; } } /* No information from which to compute delays. */ else { LALInfo( stat, "Detector site and ephemerides absent; simulating hplus with no" " propagation delays" ); memset( delayData, 0, nMax*sizeof(REAL8) ); delayMin = delayMax = 0.0; } /* Generate the table of polarization response functions. */ polDt = output->deltaT/( 2.0*dtPolBy2 ); nMax = (UINT4)( output->data->length*polDt ) + 3; memset( &polResponse, 0, sizeof( LALDetAMResponseSeries ) ); polResponse.pPlus = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ); polResponse.pCross = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ); polResponse.pScalar = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ); if ( !polResponse.pPlus || !polResponse.pCross || !polResponse.pScalar ) { if ( polResponse.pPlus ) LALFree( polResponse.pPlus ); if ( polResponse.pCross ) LALFree( polResponse.pCross ); if ( polResponse.pScalar ) LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); ABORT( stat, SIMULATECOHERENTGWH_EMEM, SIMULATECOHERENTGWH_MSGEMEM ); } memset( polResponse.pPlus, 0, sizeof(REAL4TimeSeries) ); memset( polResponse.pCross, 0, sizeof(REAL4TimeSeries) ); memset( polResponse.pScalar, 0, sizeof(REAL4TimeSeries) ); LALSCreateVector( stat->statusPtr, &( polResponse.pPlus->data ), nMax ); BEGINFAIL( stat ) { LALFree( polResponse.pPlus ); LALFree( polResponse.pCross ); LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); } ENDFAIL( stat ); LALSCreateVector( stat->statusPtr, &( polResponse.pCross->data ), nMax ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pPlus->data ) ), stat ); LALFree( polResponse.pPlus ); LALFree( polResponse.pCross ); LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); } ENDFAIL( stat ); LALSCreateVector( stat->statusPtr, &( polResponse.pScalar->data ), nMax ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pPlus->data ) ), stat ); TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pCross->data ) ), stat ); LALFree( polResponse.pPlus ); LALFree( polResponse.pCross ); LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); } ENDFAIL( stat ); plusData = polResponse.pPlus->data->data; crossData = polResponse.pCross->data->data; INT4 plusLen = polResponse.pPlus->data->length; INT4 crossLen = polResponse.pCross->data->length; if ( plusLen != crossLen ) { XLALPrintError ("plusLen = %d != crossLen = %d\n", plusLen, crossLen ); ABORT ( stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); } if ( detector->site ) { LALSource polSource; /* position and polarization angle */ LALDetAndSource input; /* response input structure */ LALTimeIntervalAndNSample params; /* response parameter structure */ /* Arrange nested pointers, and set initial values. */ polSource.equatorialCoords = source; polSource.orientation = (REAL8)( CWsignal->psi ); input.pSource = &polSource; input.pDetector = detector->site; params.epoch = output->epoch; params.epoch.gpsSeconds -= dtPolBy2; params.deltaT = 2.0*dtPolBy2; params.nSample = nMax; /* Compute table of responses. */ LALComputeDetAMResponseSeries( stat->statusPtr, &polResponse, &input, ¶ms ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pPlus->data ) ), stat ); TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pCross->data ) ), stat ); TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pScalar->data ) ), stat ); LALFree( polResponse.pPlus ); LALFree( polResponse.pCross ); LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); } ENDFAIL( stat ); } else {
/** * \brief Unified "wrapper" to provide a uniform interface to LALPtoleMetric() and LALCoherentMetric(). * \author Reinhard Prix * * The parameter structure of LALPtoleMetric() was used, because it's more compact. */ void LALPulsarMetric ( LALStatus *stat, REAL8Vector **metric, PtoleMetricIn *input ) { MetricParamStruc params = empty_MetricParamStruc; PulsarTimesParamStruc spinParams = empty_PulsarTimesParamStruc; PulsarTimesParamStruc baryParams = empty_PulsarTimesParamStruc; PulsarTimesParamStruc compParams = empty_PulsarTimesParamStruc; REAL8Vector *lambda = NULL; UINT4 i, nSpin, dim; INITSTATUS(stat); ATTATCHSTATUSPTR (stat); ASSERT ( input, stat, PTOLEMETRICH_ENULL, PTOLEMETRICH_MSGENULL ); ASSERT ( metric != NULL, stat, PTOLEMETRICH_ENULL, PTOLEMETRICH_MSGENULL ); ASSERT ( *metric == NULL, stat, PTOLEMETRICH_ENONULL, PTOLEMETRICH_MSGENONULL ); if (input->metricType == LAL_PMETRIC_COH_EPHEM) { ASSERT ( input->ephemeris != NULL, stat, PTOLEMETRICH_ENULL, PTOLEMETRICH_MSGENULL); } if ( input->spindown ) nSpin = input->spindown->length; else nSpin = 0; /* allocate the output-metric */ dim = 3 + nSpin; /* dimensionality of parameter-space: Alpha,Delta,f + spindowns */ TRY ( LALDCreateVector (stat->statusPtr, metric, dim * (dim+1)/2), stat); switch (input->metricType) { case LAL_PMETRIC_COH_PTOLE_ANALYTIC: /* use Ben&Ian's analytic ptolemaic metric */ LALPtoleMetric (stat->statusPtr, *metric, input); BEGINFAIL(stat) { LALDDestroyVector (stat->statusPtr, metric); }ENDFAIL(stat); break; case LAL_PMETRIC_COH_PTOLE_NUMERIC: /* use CoherentMetric + Ptolemaic timing */ case LAL_PMETRIC_COH_EPHEM: /* use CoherentMetric + ephemeris timing */ /* Set up constant parameters for barycentre transformation. */ baryParams.epoch = input->epoch; baryParams.t0 = 0; /* FIXME: should be redundant now, with Detector passed */ baryParams.latitude = input->site->frDetector.vertexLatitudeRadians; baryParams.longitude = input->site->frDetector.vertexLongitudeRadians; baryParams.site = input->site; LALGetEarthTimes( stat->statusPtr, &baryParams ); BEGINFAIL(stat) { LALDDestroyVector (stat->statusPtr, metric); }ENDFAIL(stat); /* set timing-function for earth-motion: either ptolemaic or ephemeris */ if (input->metricType == LAL_PMETRIC_COH_PTOLE_NUMERIC) { baryParams.t1 = LALTBaryPtolemaic; baryParams.dt1 = LALDTBaryPtolemaic; } else /* use precise ephemeris-timing */ { baryParams.t1 = LALTEphemeris; /* LAL-bug: fix type of LALTEphemeris! */ baryParams.dt1 = LALDTEphemeris; baryParams.ephemeris = input->ephemeris; } /* Set up input structure for CoherentMetric() */ if (nSpin) { /* Set up constant parameters for spindown transformation. */ spinParams.epoch = input->epoch; spinParams.t0 = 0; /* Set up constant parameters for composed transformation. */ compParams.epoch = input->epoch; compParams.t1 = baryParams.t1; compParams.dt1 = baryParams.dt1; compParams.t2 = LALTSpin; compParams.dt2 = LALDTSpin; compParams.constants1 = &baryParams; compParams.constants2 = &spinParams; compParams.nArgs = 2; params.dtCanon = LALDTComp; params.constants = &compParams; } else /* simple case: just account for earth motion */ { params.dtCanon = baryParams.dt1; params.constants = &baryParams; } params.start = 0; params.deltaT = (REAL8) input->duration; params.n = 1; /* only 1 stack */ params.errors = 0; /* Set up the parameter list. */ LALDCreateVector( stat->statusPtr, &lambda, nSpin + 2 + 1 ); BEGINFAIL(stat) { LALDDestroyVector (stat->statusPtr, metric); }ENDFAIL(stat); lambda->data[0] = (REAL8) input->maxFreq; lambda->data[1] = (REAL8) input->position.longitude; /* Alpha */ lambda->data[2] = (REAL8) input->position.latitude; /* Delta */ if ( nSpin ) { for (i=0; i < nSpin; i++) lambda->data[3 + i] = (REAL8) input->spindown->data[i]; } /* _finally_ we can call the metric */ LALCoherentMetric( stat->statusPtr, *metric, lambda, ¶ms ); BEGINFAIL(stat) { LALDDestroyVector (stat->statusPtr, metric); LALDDestroyVector( stat->statusPtr, &lambda ); }ENDFAIL(stat); LALDDestroyVector( stat->statusPtr, &lambda ); BEGINFAIL(stat) { LALDDestroyVector (stat->statusPtr, metric); }ENDFAIL(stat); break; default: XLALPrintError ("Unknown metric type `%d`\n", input->metricType); ABORT (stat, PTOLEMETRICH_EMETRIC, PTOLEMETRICH_MSGEMETRIC); break; } /* switch type */ DETATCHSTATUSPTR (stat); RETURN (stat); } /* LALPulsarMetric() */
void LALRingInjectSignals( LALStatus *stat, REAL4TimeSeries *series, SimRingdownTable *injections, COMPLEX8FrequencySeries *resp, INT4 calType ) { UINT4 k; INT4 injStartTime; INT4 injStopTime; DetectorResponse detector; COMPLEX8Vector *unity = NULL; CoherentGW waveform; RingParamStruc ringParam; REAL4TimeSeries signalvec; SimRingdownTable *simRingdown=NULL; LALDetector *tmpDetector=NULL /*,*nullDetector=NULL*/; COMPLEX8FrequencySeries *transfer = NULL; INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* set up start and end of injection zone TODO: fix this hardwired 10 */ injStartTime = series->epoch.gpsSeconds - 10; injStopTime = series->epoch.gpsSeconds + 10 + (INT4)(series->data->length * series->deltaT); /* *compute the transfer function */ /* allocate memory and copy the parameters describing the freq series */ memset( &detector, 0, sizeof( DetectorResponse ) ); transfer = (COMPLEX8FrequencySeries *) LALCalloc( 1, sizeof(COMPLEX8FrequencySeries) ); if ( ! transfer ) { ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } memcpy( &(transfer->epoch), &(resp->epoch), sizeof(LIGOTimeGPS) ); transfer->f0 = resp->f0; transfer->deltaF = resp->deltaF; tmpDetector = detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) ); /* set the detector site */ switch ( series->name[0] ) { case 'H': *(detector.site) = lalCachedDetectors[LALDetectorIndexLHODIFF]; LALWarning( stat, "computing waveform for Hanford." ); break; case 'L': *(detector.site) = lalCachedDetectors[LALDetectorIndexLLODIFF]; LALWarning( stat, "computing waveform for Livingston." ); break; default: LALFree( detector.site ); detector.site = NULL; tmpDetector = NULL; LALWarning( stat, "Unknown detector site, computing plus mode " "waveform with no time delay" ); break; } /* set up units for the transfer function */ if (XLALUnitDivide( &(detector.transfer->sampleUnits), &lalADCCountUnit, &lalStrainUnit ) == NULL) { ABORTXLAL(stat); } /* invert the response function to get the transfer function */ LALCCreateVector( stat->statusPtr, &( transfer->data ), resp->data->length ); CHECKSTATUSPTR( stat ); LALCCreateVector( stat->statusPtr, &unity, resp->data->length ); CHECKSTATUSPTR( stat ); for ( k = 0; k < resp->data->length; ++k ) { unity->data[k] = 1.0; } LALCCVectorDivide( stat->statusPtr, transfer->data, unity, resp->data ); CHECKSTATUSPTR( stat ); LALCDestroyVector( stat->statusPtr, &unity ); CHECKSTATUSPTR( stat ); /* Set up a time series to hold signal in ADC counts */ signalvec.deltaT = series->deltaT; if ( ( signalvec.f0 = series->f0 ) != 0 ) { ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } signalvec.sampleUnits = lalADCCountUnit; signalvec.data=NULL; LALSCreateVector( stat->statusPtr, &(signalvec.data), series->data->length ); CHECKSTATUSPTR( stat ); /* loop over list of waveforms and inject into data stream */ simRingdown = injections; while ( simRingdown ) { /* only do the work if the ring is in injection zone */ if( (injStartTime - simRingdown->geocent_start_time.gpsSeconds) * (injStopTime - simRingdown->geocent_start_time.gpsSeconds) > 0 ) { simRingdown = simRingdown->next; continue; } /* set the ring params */ ringParam.deltaT = series->deltaT; if( !( strcmp( simRingdown->coordinates, "HORIZON" ) ) ) { ringParam.system = COORDINATESYSTEM_HORIZON; } else if ( !( strcmp( simRingdown->coordinates, "ZENITH" ) ) ) { /* set coordinate system for completeness */ ringParam.system = COORDINATESYSTEM_EQUATORIAL; detector.site = NULL; } else if ( !( strcmp( simRingdown->coordinates, "GEOGRAPHIC" ) ) ) { ringParam.system = COORDINATESYSTEM_GEOGRAPHIC; } else if ( !( strcmp( simRingdown->coordinates, "EQUATORIAL" ) ) ) { ringParam.system = COORDINATESYSTEM_EQUATORIAL; } else if ( !( strcmp( simRingdown->coordinates, "ECLIPTIC" ) ) ) { ringParam.system = COORDINATESYSTEM_ECLIPTIC; } else if ( !( strcmp( simRingdown->coordinates, "GALACTIC" ) ) ) { ringParam.system = COORDINATESYSTEM_GALACTIC; } else ringParam.system = COORDINATESYSTEM_EQUATORIAL; /* generate the ring */ memset( &waveform, 0, sizeof(CoherentGW) ); LALGenerateRing( stat->statusPtr, &waveform, series, simRingdown, &ringParam ); CHECKSTATUSPTR( stat ); /* print the waveform to a file */ if ( 0 ) { FILE *fp; char fname[512]; UINT4 jj, kplus, kcross; snprintf( fname, sizeof(fname) / sizeof(*fname), "waveform-%d-%d-%s.txt", simRingdown->geocent_start_time.gpsSeconds, simRingdown->geocent_start_time.gpsNanoSeconds, simRingdown->waveform ); fp = fopen( fname, "w" ); for( jj = 0, kplus = 0, kcross = 1; jj < waveform.phi->data->length; ++jj, kplus += 2, kcross +=2 ) { fprintf(fp, "%d %e %e %le %e\n", jj, waveform.a->data->data[kplus], waveform.a->data->data[kcross], waveform.phi->data->data[jj], waveform.f->data->data[jj]); } fclose( fp ); } /* end */ #if 0 fprintf( stderr, "a->epoch->gpsSeconds = %d\na->epoch->gpsNanoSeconds = %d\n", waveform.a->epoch.gpsSeconds, waveform.a->epoch.gpsNanoSeconds ); fprintf( stderr, "phi->epoch->gpsSeconds = %d\nphi->epoch->gpsNanoSeconds = %d\n", waveform.phi->epoch.gpsSeconds, waveform.phi->epoch.gpsNanoSeconds ); fprintf( stderr, "f->epoch->gpsSeconds = %d\nf->epoch->gpsNanoSeconds = %d\n", waveform.f->epoch.gpsSeconds, waveform.f->epoch.gpsNanoSeconds ); #endif /* must set the epoch of signal since it's used by coherent GW */ signalvec.epoch = series->epoch; memset( signalvec.data->data, 0, signalvec.data->length * sizeof(REAL4) ); /* decide which way to calibrate the data; defaul to old way */ if( calType ) detector.transfer=NULL; else detector.transfer=transfer; /* convert this into an ADC signal */ LALSimulateCoherentGW( stat->statusPtr, &signalvec, &waveform, &detector ); CHECKSTATUSPTR( stat ); /* print the waveform to a file */ if ( 0 ) { FILE *fp; char fname[512]; UINT4 jj; snprintf( fname, sizeof(fname) / sizeof(*fname), "signal-%d-%d-%s.txt", simRingdown->geocent_start_time.gpsSeconds, simRingdown->geocent_start_time.gpsNanoSeconds, simRingdown->waveform ); fp = fopen( fname, "w" ); for( jj = 0; jj < signalvec.data->length; ++jj ) { fprintf( fp, "%d %le\n", jj, signalvec.data->data[jj] ); } fclose( fp ); } /* end */ #if 0 fprintf( stderr, "series.epoch->gpsSeconds = %d\nseries.epoch->gpsNanoSeconds = %d\n", series->epoch.gpsSeconds, series->epoch.gpsNanoSeconds ); fprintf( stderr, "signalvec->epoch->gpsSeconds = %d\nsignalvec->epoch->gpsNanoSeconds = %d\n", signalvec.epoch.gpsSeconds, signalvec.epoch.gpsNanoSeconds ); #endif /* if calibration using RespFilt */ if( calType == 1 ) XLALRespFilt(&signalvec, transfer); /* inject the signal into the data channel */ LALSSInjectTimeSeries( stat->statusPtr, series, &signalvec ); CHECKSTATUSPTR( stat ); /* free memory in coherent GW structure. TODO: fix this */ LALSDestroyVectorSequence( stat->statusPtr, &( waveform.a->data ) ); CHECKSTATUSPTR( stat ); LALSDestroyVector( stat->statusPtr, &( waveform.f->data ) ); CHECKSTATUSPTR( stat ); LALDDestroyVector( stat->statusPtr, &( waveform.phi->data ) ); CHECKSTATUSPTR( stat ); LALFree( waveform.a ); waveform.a = NULL; LALFree( waveform.f ); waveform.f = NULL; LALFree( waveform.phi ); waveform.phi = NULL; /* reset the detector site information in case it changed */ detector.site = tmpDetector; /* move on to next one */ simRingdown = simRingdown->next; } /* destroy the signal */ LALSDestroyVector( stat->statusPtr, &(signalvec.data) ); CHECKSTATUSPTR( stat ); LALCDestroyVector( stat->statusPtr, &( transfer->data ) ); CHECKSTATUSPTR( stat ); if ( detector.site ) LALFree( detector.site ); LALFree( transfer ); DETATCHSTATUSPTR( stat ); RETURN( stat ); }
void LALFindChirpTDTemplate ( LALStatus *status, FindChirpTemplate *fcTmplt, InspiralTemplate *tmplt, FindChirpTmpltParams *params ) { UINT4 j; UINT4 shift; UINT4 waveLength; UINT4 numPoints; REAL4 *xfac; REAL8 deltaF; REAL8 deltaT; REAL8 sampleRate; const REAL4 cannonDist = 1.0; /* Mpc */ /*CHAR infomsg[512];*/ PPNParamStruc ppnParams; CoherentGW waveform; REAL4Vector *tmpxfac = NULL; /* Used for band-passing */ INITSTATUS(status); ATTATCHSTATUSPTR( status ); /* * * check that the arguments are reasonable * */ /* check that the output structures exist */ ASSERT( fcTmplt, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL ); ASSERT( fcTmplt->data, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL ); ASSERT( fcTmplt->data->data, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL ); /* check that the parameter structure exists */ ASSERT( params, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL ); ASSERT( params->xfacVec, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL ); ASSERT( params->xfacVec->data, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL ); /* check we have an fft plan for the template */ ASSERT( params->fwdPlan, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL ); /* check that the timestep is positive */ ASSERT( params->deltaT > 0, status, FINDCHIRPTDH_EDELT, FINDCHIRPTDH_MSGEDELT ); /* check that the input exists */ ASSERT( tmplt, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL ); /* check that the parameter structure is set to a time domain approximant */ switch ( params->approximant ) { case TaylorT1: case TaylorT2: case TaylorT3: case TaylorT4: case GeneratePPN: case PadeT1: case EOB: case EOBNR: case FindChirpPTF: case EOBNRv2: case IMRPhenomB: case IMRPhenomC: break; default: ABORT( status, FINDCHIRPTDH_EMAPX, FINDCHIRPTDH_MSGEMAPX ); break; } /* store deltaT and zero out the time domain waveform vector */ deltaT = params->deltaT; sampleRate = 1.0 / deltaT; xfac = params->xfacVec->data; numPoints = params->xfacVec->length; memset( xfac, 0, numPoints * sizeof(REAL4) ); ASSERT( numPoints == (2 * (fcTmplt->data->length - 1)), status, FINDCHIRPTDH_EMISM, FINDCHIRPTDH_MSGEMISM ); /* choose the time domain template */ if ( params->approximant == GeneratePPN ) { /* * * generate the waveform using LALGeneratePPNInspiral() from inject * */ /* input parameters */ memset( &ppnParams, 0, sizeof(PPNParamStruc) ); ppnParams.deltaT = deltaT; ppnParams.mTot = tmplt->mass1 + tmplt->mass2; ppnParams.eta = tmplt->mass1 * tmplt->mass2 / ( ppnParams.mTot * ppnParams.mTot ); ppnParams.d = 1.0; ppnParams.fStartIn = params->fLow; ppnParams.fStopIn = -1.0 / (6.0 * sqrt(6.0) * LAL_PI * ppnParams.mTot * LAL_MTSUN_SI); /* generate waveform amplitude and phase */ memset( &waveform, 0, sizeof(CoherentGW) ); LALGeneratePPNInspiral( status->statusPtr, &waveform, &ppnParams ); CHECKSTATUSPTR( status ); /* print termination information and check sampling */ LALInfo( status, ppnParams.termDescription ); if ( ppnParams.dfdt > 2.0 ) { ABORT( status, FINDCHIRPTDH_ESMPL, FINDCHIRPTDH_MSGESMPL ); } if ( waveform.a->data->length > numPoints ) { ABORT( status, FINDCHIRPTDH_ELONG, FINDCHIRPTDH_MSGELONG ); } /* compute h(t) */ for ( j = 0; j < waveform.a->data->length; ++j ) { xfac[j] = waveform.a->data->data[2*j] * cos( waveform.phi->data->data[j] ); } /* free the memory allocated by LALGeneratePPNInspiral() */ LALSDestroyVectorSequence( status->statusPtr, &(waveform.a->data) ); CHECKSTATUSPTR( status ); LALSDestroyVector( status->statusPtr, &(waveform.f->data) ); CHECKSTATUSPTR( status ); LALDDestroyVector( status->statusPtr, &(waveform.phi->data) ); CHECKSTATUSPTR( status ); LALFree( waveform.a ); LALFree( waveform.f ); LALFree( waveform.phi ); /* waveform parameters needed for findchirp filter */ tmplt->approximant = params->approximant; tmplt->tC = ppnParams.tc; tmplt->fFinal = ppnParams.fStop; fcTmplt->tmpltNorm = params->dynRange / ( cannonDist * 1.0e6 * LAL_PC_SI ); fcTmplt->tmpltNorm *= fcTmplt->tmpltNorm; } else { /* * * generate the waveform by calling LALInspiralWave() from inspiral * */ /* set up additional template parameters */ deltaF = 1.0 / ((REAL8) numPoints * deltaT); tmplt->ieta = 1; tmplt->approximant = params->approximant; tmplt->order = params->order; tmplt->massChoice = m1Andm2; tmplt->tSampling = sampleRate; tmplt->fLower = params->fLow; tmplt->fCutoff = sampleRate / 2.0 - deltaF; /* get the template norm right */ if ( params->approximant==EOBNR ) { /* lalinspiral EOBNR code produces correct norm when fed unit signalAmplitude and non-physical distance */ tmplt->signalAmplitude = 1.0; tmplt->distance = -1.0; } else if ( params->approximant==EOBNRv2 ) { /* this formula sets the ampl0 variable to 1.0 * within the lalsimulation EOBNRv2 waveform engine * which again produces a correct template norm */ tmplt->distance = tmplt->totalMass*LAL_MRSUN_SI; } else if ( (params->approximant==IMRPhenomB) || (params->approximant==IMRPhenomC) ) { /* 1Mpc standard distance - not clear if this produces correct norm */ tmplt->distance = 1.0; tmplt->spin1[2] = 2 * tmplt->chi/(1. + sqrt(1.-4.*tmplt->eta)); } /* compute the tau parameters from the input template */ LALInspiralParameterCalc( status->statusPtr, tmplt ); CHECKSTATUSPTR( status ); /* determine the length of the chirp in sample points */ LALInspiralWaveLength( status->statusPtr, &waveLength, *tmplt ); CHECKSTATUSPTR( status ); if ( waveLength > numPoints ) { ABORT( status, FINDCHIRPTDH_ELONG, FINDCHIRPTDH_MSGELONG ); } /* generate the chirp in the time domain */ LALInspiralWave( status->statusPtr, params->xfacVec, tmplt ); CHECKSTATUSPTR( status ); /* template dependent normalization */ fcTmplt->tmpltNorm = 2 * tmplt->mu; fcTmplt->tmpltNorm *= 2 * LAL_MRSUN_SI / ( cannonDist * 1.0e6 * LAL_PC_SI ); fcTmplt->tmpltNorm *= params->dynRange; fcTmplt->tmpltNorm *= fcTmplt->tmpltNorm; } /* Taper the waveform if required */ if ( params->taperTmplt != LAL_SIM_INSPIRAL_TAPER_NONE ) { if ( XLALSimInspiralREAL4WaveTaper( params->xfacVec, params->taperTmplt ) == XLAL_FAILURE ) { ABORTXLAL( status ); } } /* Find the end of the chirp */ j = numPoints - 1; while ( xfac[j] == 0 ) { /* search for the end of the chirp but don't fall off the array */ if ( --j == 0 ) { ABORT( status, FINDCHIRPTDH_EEMTY, FINDCHIRPTDH_MSGEEMTY ); } } ++j; /* Band pass the template if required */ if ( params->bandPassTmplt ) { REAL4Vector bpVector; /*Used to save time */ /* We want to shift the template to the middle of the vector so */ /* that band-passing will work properly */ shift = ( numPoints - j ) / 2; memmove( xfac + shift, xfac, j * sizeof( *xfac ) ); memset( xfac, 0, shift * sizeof( *xfac ) ); memset( xfac + ( numPoints + j ) / 2, 0, ( numPoints - ( numPoints + j ) / 2 ) * sizeof( *xfac ) ); /* Select an appropriate part of the vector to band pass. */ /* band passing the whole thing takes a lot of time */ if ( j > 2 * sampleRate && 2 * j <= numPoints ) { bpVector.length = 2 * j; bpVector.data = params->xfacVec->data + numPoints / 2 - j; } else if ( j <= 2 * sampleRate && j + 2 * sampleRate <= numPoints ) { bpVector.length = j + 2 * sampleRate; bpVector.data = params->xfacVec->data + ( numPoints - j ) / 2 - (INT4)sampleRate; } else { bpVector.length = params->xfacVec->length; bpVector.data = params->xfacVec->data; } if ( XLALBandPassInspiralTemplate( &bpVector, 0.95 * tmplt->fLower, 1.02 * tmplt->fFinal, sampleRate ) == XLAL_FAILURE ) { ABORTXLAL( status ); } /* Now we need to do the shift to the end. */ /* Use a temporary vector to avoid mishaps */ if ( ( tmpxfac = XLALCreateREAL4Vector( numPoints ) ) == NULL ) { ABORTXLAL( status ); } if ( params->approximant == EOBNR || params->approximant == EOBNRv2 || params->approximant == IMRPhenomB || params->approximant == IMRPhenomC ) { /* We need to do something slightly different for EOBNR */ UINT4 endIndx = (UINT4) (tmplt->tC * sampleRate); memcpy( tmpxfac->data, xfac + ( numPoints - j ) / 2 + endIndx, ( numPoints - ( numPoints - j ) / 2 - endIndx ) * sizeof( *xfac ) ); memcpy( tmpxfac->data + numPoints - ( numPoints - j ) / 2 - endIndx, xfac, ( ( numPoints - j ) / 2 + endIndx ) * sizeof( *xfac ) ); } else { memcpy( tmpxfac->data, xfac + ( numPoints + j ) / 2, ( numPoints - ( numPoints + j ) / 2 ) * sizeof( *xfac ) ); memcpy( tmpxfac->data + numPoints - ( numPoints + j ) / 2, xfac, ( numPoints + j ) / 2 * sizeof( *xfac ) ); } memcpy( xfac, tmpxfac->data, numPoints * sizeof( *xfac ) ); XLALDestroyREAL4Vector( tmpxfac ); tmpxfac = NULL; } else if ( params->approximant == EOBNR || params->approximant == EOBNRv2 || params->approximant == IMRPhenomB || params->approximant == IMRPhenomC ) { /* For EOBNR we shift so that tC is at the end of the vector */ if ( ( tmpxfac = XLALCreateREAL4Vector( numPoints ) ) == NULL ) { ABORTXLAL( status ); } /* Set the coalescence index depending on tC */ j = (UINT4) (tmplt->tC * sampleRate); memcpy( tmpxfac->data + numPoints - j, xfac, j * sizeof( *xfac ) ); memcpy( tmpxfac->data, xfac + j, ( numPoints - j ) * sizeof( *xfac ) ); memcpy( xfac, tmpxfac->data, numPoints * sizeof( *xfac ) ); XLALDestroyREAL4Vector( tmpxfac ); tmpxfac = NULL; } else { /* No need for so much shifting around if not band passing */ /* shift chirp to end of vector so it is the correct place for the filter */ memmove( xfac + numPoints - j, xfac, j * sizeof( *xfac ) ); memset( xfac, 0, ( numPoints - j ) * sizeof( *xfac ) ); } /* * * create the frequency domain findchirp template * */ /* fft chirp */ if ( XLALREAL4ForwardFFT( fcTmplt->data, params->xfacVec, params->fwdPlan ) == XLAL_FAILURE ) { ABORTXLAL( status ); } /* copy the template parameters to the findchirp template structure */ memcpy( &(fcTmplt->tmplt), tmplt, sizeof(InspiralTemplate) ); /* normal exit */ DETATCHSTATUSPTR( status ); RETURN( status ); }
/** * \brief Computes the parameter space metric for a coherent pulsar search. * \author Creighton, T. D. * \date 2000, 2001 * \ingroup StackMetric_h * * ### Description ### * * This function computes the metric \f$g_{\alpha\beta}(\mathbf{\lambda})\f$, as * discussed in \ref StackMetric_h, under the assumption * that the detected power is constructed from the incoherent sum of \f$N\f$ * separate power spectrum, each derived from separate time intervals of * length \f$\Delta t\f$. The indecies \f$\alpha\f$ and \f$\beta\f$ are assumed to * run from 0 to \f$n\f$, where \f$n\f$ is the total number of ``shape'' * parameters. * * This routine has exactly the same calling structure and data storage * as the LALCoherentMetric() function. Thus, the argument * \a *metric is a vector of length \f$(n+1)(n+2)/2\f$ storing all * non-redundant coefficients of \f$g_{\alpha\beta}\f$, or twice this length * if \a params->errors is nonzero. See LALCoherentMetric() for * the indexing scheme. The argument \a lambda is another vector, * of length \f$n+1\f$, storing the components of * \f$\mathbf{\lambda}=(\lambda^0,\ldots,\lambda^n)\f$ for the parameter space * point at which the metric is being evaluated. The argument * \a *params stores the remaining parameters for computing the * metric, as given in the Structures section of \ref StackMetric_h. * * ### Algorithm ### * * Most of what this routine does is set up arguments to be passed to the * function LALCoherentMetric(). Each metric component in the stack * metric is given simply by: * \f[ * g_{\alpha\beta}(\mathbf{\lambda}) = \frac{1}{N} \sum_{k=1}^N * g^{(k)}_{\alpha\beta}(\mathbf{\lambda}) \; , * \f] * where \f$g^{(k)}_{\alpha\beta}\f$ is just the coherent metric computed on * the time interval \f$[t_\mathrm{start}+(k-1)\Delta t, * t_\mathrm{start}+k\Delta t]\f$. The estimated uncertainty * \f$s_{\alpha\beta}\f$ in this component is taken to be: * \f[ * s_{\alpha\beta} = \frac{1}{\sqrt{N}} \max_{k\in\{1,\ldots,N\}} * s^{(k)}_{\alpha\beta} \; . * \f] * There are no clever tricks involved in any of these computations. */ void LALStackMetric( LALStatus *stat, REAL8Vector *metric, REAL8Vector *lambda, MetricParamStruc *params ) { INT4 n; /* Number of metric coefficients. */ INT4 i; /* An index. */ INT4 j; /* Another index. */ REAL8 t; /* Time at start of each coherent stretch. */ REAL8Vector *subMetric=NULL; /* Coherent metric on each stack. */ MetricParamStruc subParams; /* Parameters passed to coherent metric computation. */ INITSTATUS(stat); ATTATCHSTATUSPTR(stat); /* Make sure parameter structures and their fields exist. */ ASSERT(metric,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL); ASSERT(metric->data,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL); /* Make sure that metric length is positive. */ n=metric->length; ASSERT(n>0,stat,STACKMETRICH_EBAD,STACKMETRICH_MSGEBAD); /* Set up parameters for coherent metric computation. */ memset(metric->data,0,n*sizeof(REAL8)); memcpy(&subParams,params,sizeof(MetricParamStruc)); subParams.n=1; TRY(LALDCreateVector(stat->statusPtr,&subMetric,n),stat); t=params->start; /* Compute coherent metrics and accumulate them. */ i=params->n; while(i--){ subParams.start=t; LALCoherentMetric(stat->statusPtr,subMetric,lambda,&subParams); BEGINFAIL(stat) TRY(LALDDestroyVector(stat->statusPtr,&subMetric),stat); ENDFAIL(stat); if(params->errors) for(j=0;j<n;j+=2){ metric->data[j]+=subMetric->data[j]; if(metric->data[j+1]<subMetric->data[j+1]) metric->data[j+1]=subMetric->data[j+1]; } else for(j=0;j<n;j++) metric->data[j]+=subMetric->data[j]; t+=params->deltaT; } /* Compute the average. */ if(params->errors) for(j=0;j<n;j+=2){ metric->data[j]/=params->n; metric->data[j+1]/=sqrt(params->n); } else for(j=0;j<n;j++) metric->data[j]/=params->n; /* Cleanup and exit. */ TRY(LALDDestroyVector(stat->statusPtr,&subMetric),stat); DETATCHSTATUSPTR(stat); RETURN(stat); }