/** * load a full multi-dim template grid from the file init->gridFile, * the file-format is: lines of 6 columns, which are: * * Freq Alpha Delta f1dot f2dot f3dot * * \note * *) this function returns the effective spinRange covered by the read-in template bank * by storing it in scan->spinRange, potentially overwriting any previous user-input values in there. * * *) a possible future extension should probably *clip* the template-bank to the user-specified ranges, * then return the effective ranges spanned by the resultant template bank. * * *) in order to avoid surprises until such a feature is implemented, we currently return an error if * any of the input spinRanges are non-zero * */ int XLALLoadFullGridFile ( DopplerFullScanState *scan, const DopplerFullScanInit *init ) { XLAL_CHECK ( (scan != NULL) && (init != NULL), XLAL_EINVAL ); XLAL_CHECK ( init->gridFile != NULL, XLAL_EINVAL ); XLAL_CHECK ( scan->state == STATE_IDLE, XLAL_EINVAL ); REAL8VectorList XLAL_INIT_DECL(head); REAL8VectorList *tail = NULL; REAL8Vector *entry = NULL; UINT4 numTemplates; FILE *fp; /* Check that all user-input spin- and sky-ranges are zero, otherwise fail! * * NOTE: In the future we should allow combining the user-input ranges with * those found in the grid-file by forming the intersection, ie *clipping* * of the read-in grids to the user-input ranges. * Right now we require empty ranges input, and report back the ranges from the grid-file * */ if ( init->searchRegion.skyRegionString != NULL ) { XLAL_ERROR ( XLAL_EINVAL, "\nnon-NULL skyRegion input currently not supported! skyRegion = '%s'\n\n", init->searchRegion.skyRegionString ); } for ( UINT4 s = 0; s < PULSAR_MAX_SPINS; s ++ ) { if ( (init->searchRegion.fkdot[s] != 0) || (init->searchRegion.fkdotBand[s] != 0 )) { XLAL_ERROR ( XLAL_EINVAL, "\nnon-zero input spinRanges currently not supported! fkdot[%d] = %g, fkdotBand[%d] = %g\n\n", s, init->searchRegion.fkdot[s], s, init->searchRegion.fkdotBand[s] ); } } /* for s < max_spins */ /* open input data file */ XLAL_CHECK ( (fp = LALFopen (init->gridFile, "r")) != NULL, XLAL_ESYS, "Could not open data-file: `%s`\n\n", init->gridFile ); /* prepare grid-entry buffer */ XLAL_CHECK ( (entry = XLALCreateREAL8Vector ( 6 ) ) != NULL, XLAL_EFUNC ); /* keep track of the sky- and spinRanges spanned by the template bank */ REAL8 FreqMax = - LAL_REAL4_MAX, FreqMin = LAL_REAL4_MAX; // only using REAL4 ranges to avoid over/under flows, and should be enough REAL8 f1dotMax = - LAL_REAL4_MAX, f1dotMin = LAL_REAL4_MAX; REAL8 f2dotMax = - LAL_REAL4_MAX, f2dotMin = LAL_REAL4_MAX; REAL8 f3dotMax = - LAL_REAL4_MAX, f3dotMin = LAL_REAL4_MAX; REAL8 alphaMax = - LAL_REAL4_MAX, alphaMin = LAL_REAL4_MAX; REAL8 deltaMax = - LAL_REAL4_MAX, deltaMin = LAL_REAL4_MAX; /* parse this list of lines into a full grid */ numTemplates = 0; tail = &head; /* head will remain empty! */ CHAR line[2048]; while ( ! feof ( fp ) && ! ferror ( fp ) && fgets( line, sizeof(line), fp ) != NULL ) { // Skip over any comment lines if ( line[0] == '#' || line[0] == '%' ) { continue; } // File format expects lines containing 6 columns: Freq Alpha Delta f1dot f2dot f3dot REAL8 Freq, Alpha, Delta, f1dot, f2dot, f3dot; if ( 6 != sscanf( line, "%" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT "\n", &Freq, &Alpha, &Delta, &f1dot, &f2dot, &f3dot ) ) { XLALPrintError ("ERROR: Failed to parse 6 REAL8's from line %d in grid-file '%s'\n\n", numTemplates + 1, init->gridFile); if ( head.next ) { XLALREAL8VectorListDestroy (head.next); } XLAL_ERROR ( XLAL_EINVAL ); } /* keep track of maximal spans */ alphaMin = fmin ( Alpha, alphaMin ); deltaMin = fmin ( Delta, deltaMin ); FreqMin = fmin ( Freq, FreqMin ); f1dotMin = fmin ( f1dot, f1dotMin ); f2dotMin = fmin ( f2dot, f2dotMin ); f3dotMin = fmin ( f3dot, f3dotMin ); alphaMax = fmax ( Alpha, alphaMax ); deltaMax = fmax ( Delta, deltaMax ); FreqMax = fmax ( Freq, FreqMax ); f1dotMax = fmax ( f1dot, f1dotMax ); f2dotMax = fmax ( f2dot, f2dotMax ); f3dotMax = fmax ( f3dot, f3dotMax ); /* add this entry to template-bank list */ entry->data[0] = Freq; entry->data[1] = Alpha; entry->data[2] = Delta; entry->data[3] = f1dot; entry->data[4] = f2dot; entry->data[5] = f3dot; if ( (tail = XLALREAL8VectorListAddEntry (tail, entry)) == NULL ) { if ( head.next ) { XLALREAL8VectorListDestroy (head.next); } XLAL_ERROR ( XLAL_EINVAL ); } numTemplates ++ ; } /* while !feof(fp) && ... */ if ( ferror ( fp ) ) { XLAL_ERROR ( XLAL_EIO ); } XLALDestroyREAL8Vector ( entry ); /* ---------- update scan-state ---------- */ // ----- report back ranges actually spanned by grid-file CHAR *skyRegionString = NULL; REAL8 eps = LAL_REAL8_EPS; XLAL_CHECK ( (skyRegionString = XLALSkySquare2String ( alphaMin, deltaMin, (alphaMax - alphaMin) + eps, (deltaMax - deltaMin) + eps )) != NULL, XLAL_EFUNC ); // note: we slight expanded the enclosing sky-square by eps to avoid complaints when a grid-file contains // only points in a line, which is perfectly valid here. XLAL_CHECK ( XLALParseSkyRegionString ( &scan->skyRegion, skyRegionString ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALFree ( skyRegionString ); scan->spinRange.fkdot[0] = FreqMin; scan->spinRange.fkdotBand[0] = FreqMax - FreqMin; scan->spinRange.fkdot[1] = f1dotMin; scan->spinRange.fkdotBand[1] = f1dotMax - f1dotMin; scan->spinRange.fkdot[2] = f2dotMin; scan->spinRange.fkdotBand[2] = f2dotMax - f2dotMin; scan->spinRange.fkdot[3] = f3dotMin; scan->spinRange.fkdotBand[3] = f3dotMax - f3dotMin; scan->numTemplates = numTemplates; scan->covering = head.next; /* pass result (without head!) */ scan->thisGridPoint = scan->covering; /* init to start */ XLALPrintInfo ( "Template grid: nTot = %.0f\n", 1.0 * numTemplates ); XLALPrintInfo ( "Spanned ranges: Freq in [%g, %g], f1dot in [%g, %g], f2dot in [%g, %g], f3dot in [%g, %g]\n", FreqMin, FreqMax, f1dotMin, f1dotMax, f2dotMin, f2dotMax, f3dotMin, f3dotMax ); return XLAL_SUCCESS; } /* XLALLoadFullGridFile() */
/* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv------------------------------------ */ int main(int argc, char *argv[]){ static LALStatus status; /* LALStatus pointer */ static LALDetector detector; static LIGOTimeGPSVector timeV; static REAL8Cart3CoorVector velV; static HOUGHptfLUTVector lutV; /* the Look Up Table vector*/ static HOUGHPeakGramVector pgV; static PHMDVectorSequence phmdVS; /* the partial Hough map derivatives */ static UINT8FrequencyIndexVector freqInd; static HOUGHResolutionPar parRes; static HOUGHPatchGrid patch; /* Patch description */ static HOUGHParamPLUT parLut; /* parameters needed to build lut */ static HOUGHDemodPar parDem; /* demodulation parameters or */ static HOUGHSizePar parSize; static VelocityPar velPar; static HOUGHMapTotal ht; /* the total Hough map */ /* ------------------------------------------------------- */ CHAR *earthEphemeris = NULL; CHAR *sunEphemeris = NULL; INT4 ifo; REAL8 vel[3]; INT4 mObsCoh; UINT2 maxNBins, maxNBorders; INT8 f0Bin; /* freq. bin to construct LUT */ INT8 fBin; UINT2 xSide, ySide; CHAR *fname = NULL; /* The output filename */ FILE *fp=NULL; /* Output file */ INT4 arg; /* Argument counter */ UINT4 i,j; /* Index counter, etc */ INT4 k; REAL8 f0, alpha, delta; REAL8 patchSizeX, patchSizeY; REAL8 Xx,Xy,Xz; /******************************************************************/ /* Set up the default parameters. */ /* ****************************************************************/ detector = lalCachedDetectors[LALDetectorIndexGEO600DIFF]; /* default */ ifo = IFO; if (ifo ==1) detector=lalCachedDetectors[LALDetectorIndexGEO600DIFF]; if (ifo ==2) detector=lalCachedDetectors[LALDetectorIndexLLODIFF]; if (ifo ==3) detector=lalCachedDetectors[LALDetectorIndexLHODIFF]; earthEphemeris = EARTHEPHEMERIS; sunEphemeris = SUNEPHEMERIS; mObsCoh = MOBSCOH; timeV.length = mObsCoh; velV.length = mObsCoh; lutV.length = mObsCoh; pgV.length = mObsCoh; phmdVS.length = mObsCoh; freqInd.length = mObsCoh; phmdVS.nfSize = NFSIZE; freqInd.deltaF = DF; phmdVS.deltaF = DF; timeV.time = NULL; velV.data = NULL; lutV.lut = NULL; pgV.pg = NULL; phmdVS.phmd = NULL; freqInd.data = NULL; ht.map = NULL; f0 = F0; f0Bin = F0*TCOH; parRes.f0Bin = f0Bin; parRes.deltaF = DF; /* * parRes.patchSkySizeX = patchSizeX = 1.0/(TCOH*F0*VEPI); * parRes.patchSkySizeY = patchSizeY = 1.0/(TCOH*F0*VEPI); */ parRes.patchSkySizeX = patchSizeX = PATCHSIZEX; parRes.patchSkySizeY = patchSizeY = PATCHSIZEY; parRes.pixelFactor = PIXELFACTOR; parRes.pixErr = PIXERR; parRes.linErr = LINERR; parRes.vTotC = VTOT; /* Case: no spins & Non demodulation */ parDem.deltaF = DF; parDem.skyPatch.alpha = ALPHA; parDem.skyPatch.delta = DELTA; parDem.timeDiff = 0.0; parDem.spin.length = 0; parDem.spin.data = NULL; parDem.positC.x = 0.0; parDem.positC.y = 0.0; parDem.positC.z = 0.0; velPar.detector = detector; velPar.tBase = TCOH; velPar.vTol = ACCURACY; alpha = ALPHA; delta = DELTA; /*****************************************************************/ /*****************************************************************/ /* Parse argument list. i stores the current position. */ /*****************************************************************/ arg = 1; while ( arg < argc ) { /* Parse debuglevel option. */ if ( !strcmp( argv[arg], "-d" ) ) { if ( argc > arg + 1 ) { arg++; } else { ERROR( VALIDATION1_EARG, VALIDATION1_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EARG; } } /* Parse interferometer option. */ else if ( !strcmp( argv[arg], "-i" ) ) { if ( argc > arg + 1 ) { arg++; ifo = atoi( argv[arg++] ); if (ifo ==1) detector=lalCachedDetectors[LALDetectorIndexGEO600DIFF]; if (ifo ==2) detector=lalCachedDetectors[LALDetectorIndexLLODIFF]; if (ifo ==3) detector=lalCachedDetectors[LALDetectorIndexLHODIFF]; velPar.detector = detector; } else { ERROR( VALIDATION1_EARG, VALIDATION1_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EARG; } } /* Parse filename of earth ephemeris data option. */ else if ( !strcmp( argv[arg], "-E" ) ) { if ( argc > arg + 1 ) { arg++; earthEphemeris = argv[arg++]; } else { ERROR( VALIDATION1_EARG, VALIDATION1_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EARG; } } /* Parse filename of sun ephemeris data option. */ else if ( !strcmp( argv[arg], "-S" ) ) { if ( argc > arg + 1 ) { arg++; sunEphemeris = argv[arg++]; } else { ERROR( VALIDATION1_EARG, VALIDATION1_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EARG; } } /* Parse output file option. */ else if ( !strcmp( argv[arg], "-o" ) ) { if ( argc > arg + 1 ) { arg++; fname = argv[arg++]; } else { ERROR( VALIDATION1_EARG, VALIDATION1_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EARG; } } /* Parse frequency option. */ else if ( !strcmp( argv[arg], "-f" ) ) { if ( argc > arg + 1 ) { arg++; f0 = atof(argv[arg++]); f0Bin = f0*TCOH; parRes.f0Bin = f0Bin; } else { ERROR( VALIDATION1_EARG, VALIDATION1_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EARG; } } /* Parse sky position options. */ else if ( !strcmp( argv[arg], "-p" ) ) { if ( argc > arg + 2 ) { arg++; alpha = atof(argv[arg++]); delta = atof(argv[arg++]); parDem.skyPatch.alpha = alpha; parDem.skyPatch.delta = delta; } else { ERROR( VALIDATION1_EARG, VALIDATION1_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EARG; } } /* Parse patch size option. */ else if ( !strcmp( argv[arg], "-s" ) ) { if ( argc > arg + 2 ) { arg++; parRes.patchSkySizeX = patchSizeX = atof(argv[arg++]); parRes.patchSkySizeY = patchSizeY = atof(argv[arg++]); } else { ERROR( VALIDATION1_EARG, VALIDATION1_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EARG; } } /* Unrecognized option. */ else { ERROR( VALIDATION1_EARG, VALIDATION1_MSGEARG, 0 ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EARG; } } /* End of argument parsing loop. */ /******************************************************************/ if ( f0 < 0 ) { ERROR( VALIDATION1_EBAD, VALIDATION1_MSGEBAD, "freq<0:" ); XLALPrintError( USAGE, *argv ); return VALIDATION1_EBAD; } /******************************************************************/ /******************************************************************/ /* create time stamps (for a test) */ /******************************************************************/ timeV.time = (LIGOTimeGPS *)LALMalloc(mObsCoh*sizeof(LIGOTimeGPS)); timeV.time[0].gpsSeconds = T0SEC; timeV.time[0].gpsNanoSeconds = T0NSEC; for(j=1; j<timeV.length; ++j){ timeV.time[j].gpsSeconds = timeV.time[j-1].gpsSeconds + TCOH + JUMPTIME; timeV.time[j].gpsNanoSeconds = T0NSEC; } /******************************************************************/ /* compute detector velocity for those time stamps (for a test) */ /******************************************************************/ velV.data = (REAL8Cart3Coor *)LALMalloc(mObsCoh*sizeof(REAL8Cart3Coor)); velPar.edat = NULL; { EphemerisData *edat=NULL; /* ephemeris info */ edat = (EphemerisData *)LALMalloc(sizeof(EphemerisData)); (*edat).ephiles.earthEphemeris = earthEphemeris; (*edat).ephiles.sunEphemeris = sunEphemeris; /* read in ephemeris data */ SUB( LALInitBarycenter( &status, edat), &status); velPar.edat = edat; for(j=0; j<velV.length; ++j){ velPar.startTime.gpsSeconds = timeV.time[j].gpsSeconds; velPar.startTime.gpsNanoSeconds = timeV.time[j].gpsNanoSeconds; SUB( LALAvgDetectorVel ( &status, vel, &velPar), &status ); velV.data[j].x= vel[0]; velV.data[j].y= vel[1]; velV.data[j].z= vel[2]; } LALFree(edat->ephemE); LALFree(edat->ephemS); LALFree(edat); } /******************************************************************/ /******************************************************************/ /* create patch grid */ /******************************************************************/ SUB( LALHOUGHComputeNDSizePar( &status, &parSize, &parRes ), &status ); xSide = parSize.xSide; ySide = parSize.ySide; maxNBins = parSize.maxNBins; maxNBorders = parSize.maxNBorders; /* allocate memory based on xSide and ySide */ patch.xSide = xSide; patch.ySide = ySide; /* allocate memory based on xSide and ySide */ patch.xCoor = NULL; patch.yCoor = NULL; patch.xCoor = (REAL8 *)LALMalloc(xSide*sizeof(REAL8)); patch.yCoor = (REAL8 *)LALMalloc(ySide*sizeof(REAL8)); SUB( LALHOUGHFillPatchGrid( &status, &patch, &parSize ), &status ); /******************************************************************/ /******************************************************************/ /* memory allocation and settings */ /******************************************************************/ lutV.lut = (HOUGHptfLUT *)LALMalloc(mObsCoh*sizeof(HOUGHptfLUT)); pgV.pg = (HOUGHPeakGram *)LALMalloc(mObsCoh*sizeof(HOUGHPeakGram)); phmdVS.phmd =(HOUGHphmd *)LALMalloc(mObsCoh*NFSIZE*sizeof(HOUGHphmd)); freqInd.data = ( UINT8 *)LALMalloc(mObsCoh*sizeof(UINT8)); for(j=0; j<lutV.length; ++j){ lutV.lut[j].maxNBins = maxNBins; lutV.lut[j].maxNBorders = maxNBorders; lutV.lut[j].border = (HOUGHBorder *)LALMalloc(maxNBorders*sizeof(HOUGHBorder)); lutV.lut[j].bin = (HOUGHBin2Border *)LALMalloc(maxNBins*sizeof(HOUGHBin2Border)); } for(j=0; j<phmdVS.length * phmdVS.nfSize; ++j){ phmdVS.phmd[j].maxNBorders = maxNBorders; phmdVS.phmd[j].leftBorderP = (HOUGHBorder **)LALMalloc(maxNBorders*sizeof(HOUGHBorder *)); phmdVS.phmd[j].rightBorderP = (HOUGHBorder **)LALMalloc(maxNBorders*sizeof(HOUGHBorder *)); } ht.xSide = xSide; ht.ySide = ySide; ht.map = NULL; ht.map = (HoughTT *)LALMalloc(xSide*ySide*sizeof(HoughTT)); for(j=0; j<phmdVS.length * phmdVS.nfSize; ++j){ phmdVS.phmd[j].ySide = ySide; phmdVS.phmd[j].firstColumn = NULL; phmdVS.phmd[j].firstColumn = (UCHAR *)LALMalloc(ySide*sizeof(UCHAR)); } for (j=0; j<lutV.length ; ++j){ for (i=0; i<maxNBorders; ++i){ lutV.lut[j].border[i].ySide = ySide; lutV.lut[j].border[i].xPixel = (COORType *)LALMalloc(ySide*sizeof(COORType)); } } /******************************************************************/ /******************************************************************/ /* create Peakgrams for testing */ /******************************************************************/ /* let us fix a source at a given position (not at the center of the patch, but a pixel center) */ { UINT2 xPos, yPos; REAL8Cart2Coor sourceProjected; REAL8UnitPolarCoor sourceRotated; REAL8UnitPolarCoor skyPatchCenter; REAL8UnitPolarCoor sourceLocation; xPos = xSide/2; yPos = ySide/2; sourceProjected.x = patch.xCoor[xPos]; sourceProjected.y = patch.yCoor[yPos]; skyPatchCenter.alpha = parDem.skyPatch.alpha; skyPatchCenter.delta = parDem.skyPatch.delta; /* invert the stereographic projection for a point on the projected plane */ SUB( LALStereoInvProjectCart( &status, &sourceRotated, &sourceProjected ), &status ); /* undo roation in case the patch is not centered at the south pole */ SUB( LALInvRotatePolarU( &status, &sourceLocation, &sourceRotated, &skyPatchCenter ), &status ); Xx= cos(sourceLocation.delta)* cos(sourceLocation.alpha); Xy= cos(sourceLocation.delta)* sin(sourceLocation.alpha); Xz= sin(sourceLocation.delta); } for (j=0;j< mObsCoh; ++j) { /* create all the peakgrams */ REAL8 veldotX; pgV.pg[j].deltaF = DF; /* * pgV.pg[j].fBinIni = f0Bin/2; * pgV.pg[j].fBinFin = f0Bin*2; */ pgV.pg[j].fBinIni = f0Bin-maxNBins; pgV.pg[j].fBinFin = f0Bin+3*maxNBins; /* pgV.pg[j].length = 2; */ pgV.pg[j].length = 1; pgV.pg[j].peak = NULL; pgV.pg[j].peak = (INT4 *)LALMalloc( ( pgV.pg[j].length) * sizeof(INT4)); veldotX = Xx*velV.data[j].x + Xy*velV.data[j].y + Xz*velV.data[j].z; /* fBin = [ f0Bin * ( 1 + veldotX ) ] */ pgV.pg[j].peak[0]= floor( f0Bin*(1.0+veldotX) +0.5) - pgV.pg[j].fBinIni; /* pgV.pg[j].peak[1]= pgV.pg[j].peak[0]+2; */ } /******************************************************************/ /******************************************************************/ /* create all the LUTs */ /******************************************************************/ for (j=0;j< mObsCoh;++j){ /* create all the LUTs */ parDem.veloC.x = velV.data[j].x; parDem.veloC.y = velV.data[j].y; parDem.veloC.z = velV.data[j].z; /* calculate parameters needed for buiding the LUT */ SUB( LALNDHOUGHParamPLUT( &status, &parLut, &parSize, &parDem ), &status ); /* build the LUT */ SUB( LALHOUGHConstructPLUT( &status, &(lutV.lut[j]), &patch, &parLut ), &status ); } /******************************************************************/ /* starting the search (A very simple case for only 1 frequency) */ /******************************************************************/ /* build the set of PHMD starting at f0Bin*/ /******************************************************************/ fBin = f0Bin; phmdVS.fBinMin = fBin; SUB( LALHOUGHConstructSpacePHMD(&status, &phmdVS, &pgV, &lutV), &status ); /* shift the structure one frequency bin */ /* SUB( LALHOUGHupdateSpacePHMDup(&status, &phmdVS, &pgV, &lutV), &status );*/ /******************************************************************/ /* initializing the Hough map space */ /******************************************************************/ SUB( LALHOUGHInitializeHT( &status, &ht, &patch ), &status ); /******************************************************************/ /* construction of a total Hough map */ /******************************************************************/ for (j=0;j< mObsCoh;++j){ freqInd.data[j]= fBin; } SUB( LALHOUGHConstructHMT( &status, &ht, &freqInd, &phmdVS ), &status ); /******************************************************************/ /* printing the results into a particular file */ /* if the -o option was given, or into FILEOUT */ /******************************************************************/ if ( fname ) { fp = fopen( fname, "w" ); } else { fp = fopen( FILEOUT , "w" ); } if ( !fp ){ ERROR( VALIDATION1_EFILE, VALIDATION1_MSGEFILE, 0 ); return VALIDATION1_EFILE; } for(k=ySide-1; k>=0; --k){ for(i=0;i<xSide;++i){ fprintf( fp ," %d", ht.map[k*xSide +i]); fflush( fp ); } fprintf( fp ," \n"); fflush( fp ); } fclose( fp ); /******************************************************************/ /* Free memory and exit */ /******************************************************************/ for (j=0;j< mObsCoh;++j){ LALFree( pgV.pg[j].peak); /* All of them */ } for (j=0; j<lutV.length ; ++j){ for (i=0; i<maxNBorders; ++i){ LALFree( lutV.lut[j].border[i].xPixel); } LALFree( lutV.lut[j].border); LALFree( lutV.lut[j].bin); } for(j=0; j<phmdVS.length * phmdVS.nfSize; ++j){ LALFree( phmdVS.phmd[j].leftBorderP); LALFree( phmdVS.phmd[j].rightBorderP); LALFree( phmdVS.phmd[j].firstColumn); } LALFree(timeV.time); LALFree(velV.data); LALFree(lutV.lut); LALFree(pgV.pg); LALFree(phmdVS.phmd); LALFree(freqInd.data); LALFree(ht.map); LALFree(patch.xCoor); LALFree(patch.yCoor); LALCheckMemoryLeaks(); INFO( VALIDATION1_MSGENORM ); return VALIDATION1_ENORM; }
/** * Compute the "data-quality factor" \f$\mathcal{Q}(f) = \sum_X \frac{\epsilon_X}{\mathcal{S}_X(f)}\f$ over the given SFTs. * The input \a multiPSD is a pre-computed PSD map \f$\mathcal{S}_{X,i}(f)\f$, over IFOs \f$X\f$, SFTs \f$i\f$ * and frequency \f$f\f$. * * \return the output is a vector \f$\mathcal{Q}(f)\f$. * */ REAL8FrequencySeries * XLALComputeSegmentDataQ ( const MultiPSDVector *multiPSDVect, /**< input PSD map over IFOs, SFTs, and frequencies */ LALSeg segment /**< segment to compute Q for */ ) { /* check input consistency */ if ( multiPSDVect == NULL ) { XLALPrintError ("%s: NULL input 'multiPSDVect'\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } if ( multiPSDVect->length == 0 || multiPSDVect->data==0 ) { XLALPrintError ("%s: invalid multiPSDVect input (length=0 or data=NULL)\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } REAL8 Tseg = XLALGPSDiff ( &segment.end, &segment.start ); if ( Tseg <= 0 ) { XLALPrintError ("%s: negative segment-duration '%g'\n", __func__, Tseg ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } REAL8 Tsft = 1.0 / multiPSDVect->data[0]->data[0].deltaF; REAL8 f0 = multiPSDVect->data[0]->data[0].f0; REAL8 dFreq = multiPSDVect->data[0]->data[0].deltaF; UINT4 numFreqs = multiPSDVect->data[0]->data[0].data->length; REAL8FrequencySeries *Q, *SXinv; if ( (Q = XLALCreateREAL8FrequencySeries ( "Qfactor", &segment.start, f0, dFreq, &lalHertzUnit, numFreqs )) == NULL ) { XLALPrintError ("%s: Q = XLALCreateREAL8FrequencySeries(numFreqs=%d) failed with xlalErrno = %d\n", __func__, numFreqs, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } if ( (SXinv = XLALCreateREAL8FrequencySeries ( "SXinv", &segment.start, f0, dFreq, &lalHertzUnit, numFreqs )) == NULL ) { XLALPrintError ("%s: SXinv = XLALCreateREAL8FrequencySeries(numFreqs=%d) failed with xlalErrno = %d\n", __func__, numFreqs, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* initialize Q-array to zero, as we'll keep adding to it */ memset ( Q->data->data, 0, Q->data->length * sizeof(Q->data->data[0]) ); /* ----- loop over IFOs ----- */ UINT4 numIFOs = multiPSDVect->length; UINT4 X; for ( X = 0; X < numIFOs; X ++ ) { PSDVector *thisPSDVect = multiPSDVect->data[X]; /* initialize SXinv-array to zero, as we'll keep adding to it */ memset ( SXinv->data->data, 0, SXinv->data->length * sizeof(SXinv->data->data[0]) ); UINT4 numSFTsInSeg = 0; /* reset counter of SFTs within this segment */ /* ----- loop over all timestamps ----- */ /* find SFTs inside segment, count them and combine their PSDs */ UINT4 numTS = thisPSDVect->length; UINT4 iTS; for ( iTS = 0; iTS < numTS; iTS++ ) { REAL8FrequencySeries *thisPSD = &thisPSDVect->data[iTS]; /* some internal consistency/paranoia checks */ if ( ( f0 != thisPSD->f0) || ( dFreq != thisPSD->deltaF ) || (numFreqs != thisPSD->data->length ) ) { XLALPrintError ("%s: %d-th timestamp %f: inconsistent PSDVector: f0 = %g : %g, dFreq = %g : %g, numFreqs = %d : %d \n", __func__, iTS, XLALGPSGetREAL8( &thisPSD->epoch ), f0, thisPSD->f0, dFreq, thisPSD->deltaF, numFreqs, thisPSD->data->length ); XLAL_ERROR_NULL ( XLAL_EDOM ); } int cmp = XLALCWGPSinRange( thisPSD->epoch, &segment.start, &segment.end ); if ( cmp < 0 ) /* SFT-end before segment => advance to the next one */ continue; if ( cmp > 0 ) /* SFT-start past end of segment: ==> terminate loop */ break; if ( cmp == 0 ) /* this SFT is inside segment */ { numSFTsInSeg ++; /* add SXinv(f) += 1/SX_i(f) over all frequencies */ UINT4 iFreq; for ( iFreq = 0; iFreq < numFreqs; iFreq++ ) SXinv->data->data[iFreq] += 1.0 / thisPSD->data->data[iFreq] ; } /* if SFT inside segment */ } /* for iTS < numTS */ /* compute duty-cycle eps_X = nX * Tsft / Tseg for this IFO */ REAL8 duty_X = numSFTsInSeg * Tsft / Tseg; /* sanity check: eps in [0, 1]*/ if ( (duty_X < 0) && (duty_X > 1 ) ) { XLALPrintError ("%s: something is WRONG: duty-cyle = %g not within [0,1]!\n", __func__, duty_X ); XLAL_ERROR_NULL ( XLAL_EFAILED ); } /* add duty_X-weighted SXinv to Q */ UINT4 iFreq; for ( iFreq = 0; iFreq < numFreqs; iFreq ++ ) Q->data->data[iFreq] += duty_X * SXinv->data->data[iFreq] / numSFTsInSeg; } /* for X < numIFOs */ /* clean up, free memory */ XLALDestroyREAL8FrequencySeries ( SXinv ); return Q; } /* XLALComputeSegmentDataQ() */
/** * XLAL function to compute Kopeikin terms that include the effect of * binary orbital parameters of parallax */ void XLALComputeKopeikinTerms( KopeikinTerms *kop, BinaryPulsarParams *params, BinaryPulsarInput *in ){ REAL8 sini, cosi, tani; REAL8 sin_delta, cos_delta, sin_alpha, cos_alpha; REAL8 delta_i0, delta_j0; REAL8 sin_omega, cos_omega; REAL8 ca, sa, cd, sd; REAL8 delt; REAL8 posPulsar[3], velPulsar[3], psrPos[3]; REAL8 tt0; REAL8 dpara; /* parallax */ REAL8 x; sini = sin(params->kin); cosi = cos(params->kin); tani = sini / cosi; sin_omega = sin(params->kom); cos_omega = cos(params->kom); /* ki_dot is set in tempo2 function, but not used */ /* ki_dot = -params.pmra * sin_omega + params.pmdec*cos_omega; */ /* Equation 8 in Kopeikin 1996 */ // (*x) += ((*x)*ki_dot/tani)*tt0; /* Equation 9 in Kopeikin 1996 */ //(*omz) += (pmra*cos_omega+pmdec*sin_omega)/sini*tt0; /* Now modify x and omega due to the annual-orbital parallax term * as described in Kopeikin 1995 * * Require knowledge of the barycentric earth position vector - earth_ssb */ /* get pulsar vector */ ca = cos(params->ra); sa = sin(params->ra); cd = cos(params->dec); sd = sin(params->dec); posPulsar[0] = ca*cd; posPulsar[1] = sa*cd; posPulsar[2] = sd; velPulsar[0] = -params->pmra/cos(params->dec)*sa*cd - params->pmdec*ca*sd; velPulsar[1] = params->pmra/cos(params->dec)*ca*cd - params->pmdec*sa*sd; velPulsar[2] = params->pmdec*cd; delt = in->tb - params->posepoch; /* add proper motion onto the pulsar position */ for( UINT4 i = 0; i < 3; i++ ) psrPos[i] = posPulsar[i] + delt*velPulsar[i]; /* Obtain vector pointing at the pulsar */ sin_delta = psrPos[2]; cos_delta = cos(asin(sin_delta)); sin_alpha = psrPos[1] / cos_delta; cos_alpha = psrPos[0] / cos_delta; /* Equation 15 in Kopeikin 1995 */ delta_i0 = -in->earth.posNow[0]/AULTSC*sin_alpha + in->earth.posNow[1]/AULTSC*cos_alpha; /* Equation 16 in Kopeikin 1995 */ delta_j0 = -in->earth.posNow[0]/AULTSC * sin_delta*cos_alpha - in->earth.posNow[1]/AULTSC * sin_delta*sin_alpha + in->earth.posNow[2]/AULTSC * cos_delta; dpara = params->px; x = params->x; /* xpr and ypr are set in tempo2 function, but not used */ /* xpr = delta_i0*sin_omega - delta_j0*cos_omega; ypr = delta_i0*cos_omega + delta_j0*sin_omega; */ /* Equations 18 and 19 in Kopeikin 1995 */ if( params->daopset ){ REAL8 daop = params->daop; kop->DK011 = - x / daop / sini*delta_i0*sin_omega; kop->DK012 = - x / daop / sini*delta_j0*cos_omega; kop->DK013 = - x / daop / sini*delta_i0*cos_omega; kop->DK014 = x / daop / sini*delta_j0*sin_omega; kop->DK021 = x / daop / tani*delta_i0*cos_omega; kop->DK022 = -x / daop / tani*delta_j0*sin_omega; kop->DK023 = x / daop / tani*delta_i0*sin_omega; kop->DK024 = x / daop / tani*delta_j0*cos_omega; } else{ kop->DK011 = -x * dpara / sini*delta_i0*sin_omega; kop->DK012 = -x * dpara / sini*delta_j0*cos_omega; kop->DK013 = -x * dpara / sini*delta_i0*cos_omega; kop->DK014 = x * dpara / sini*delta_j0*sin_omega; kop->DK021 = x * dpara / tani*delta_i0*cos_omega; kop->DK022 = -x * dpara / tani*delta_j0*sin_omega; kop->DK023 = x * dpara / tani*delta_i0*sin_omega; kop->DK024 = x * dpara / tani*delta_j0*cos_omega; } if( params->T0 != 0. ) tt0 = in->tb - params->T0; else if( params->Tasc != 0. ) tt0 = in->tb - params->Tasc; else{ XLALPrintError("%s: Neither T0 or Tasc is defined!\n", __func__); XLAL_ERROR_VOID( XLAL_EINVAL ); } kop->DK031 = x * tt0 / sini*params->pmra*sin_omega; kop->DK032 = x * tt0 / sini*params->pmdec*cos_omega; kop->DK033 = x * tt0 / sini*params->pmra*cos_omega; kop->DK034 = -x * tt0 / sini*params->pmdec*sin_omega; kop->DK041 = x * tt0 / tani*params->pmra*cos_omega; kop->DK042 = -x * tt0 / tani*params->pmdec*sin_omega; kop->DK043 = -x * tt0 / tani*params->pmra*sin_omega; kop->DK044 = -x * tt0 / tani*params->pmdec*cos_omega; }
int XLALGetInspiralMoments ( InspiralMomentsEtc *moments, REAL8 fLower, REAL8 fCutoff, REAL8FrequencySeries *psd ) { size_t k; REAL8 xmin; REAL8 xmax; REAL8 ndx; REAL8 norm; /* Check inputs */ if (!moments){ XLALPrintError("Moments is NULL\n"); XLAL_ERROR(XLAL_EFAULT); } if (!psd){ XLALPrintError("PSD is NULL\n"); XLAL_ERROR(XLAL_EFAULT); } if (fLower <= 0 || fCutoff <= fLower){ XLALPrintError("fLower must be between 0 and fCutoff\n"); XLAL_ERROR(XLAL_EDOM); }; /* Constants needed in computing the moments */ moments->a01 = 3.L/5.L; moments->a21 = 11.L * LAL_PI/12.L; moments->a22 = 743.L/2016.L * cbrt(25.L/(2.L*LAL_PI*LAL_PI)); moments->a31 = -3.L/2.L; moments->a41 = 617.L * LAL_PI * LAL_PI / 384.L; moments->a42 = 5429.L/5376.L * cbrt(25.L*LAL_PI/2.L); moments->a43 = 1.5293365L/1.0838016L * cbrt(5.L/(4.L*LAL_PI*LAL_PI*LAL_PI*LAL_PI)); /* Divide all frequencies by fLower, a scaling that is used in solving */ /* the moments integral */ psd->f0 /= fLower; psd->deltaF /= fLower; xmin = fLower / fLower; xmax = fCutoff / fLower; /* First compute the norm and print if requested */ norm = 1.L; ndx = 7.L/3.L; moments->j[7]=XLALInspiralMoments(xmin, xmax, ndx, norm, psd); if (XLAL_IS_REAL8_FAIL_NAN(moments->j[7])){ XLAL_ERROR(XLAL_EFUNC); } norm = moments->j[7]; /* Then compute the normalised moments of the noise PSD from 1/3 to 17/3. */ for ( k = 1; k <= 17; ++k ) { ndx = (REAL8) k / 3.L; moments->j[k]=XLALInspiralMoments(xmin, xmax, ndx, norm, psd); } /* Moments are done: Rescale deltaF and f0 back to their original values */ psd->deltaF *= fLower; psd->f0 *= fLower; return XLAL_SUCCESS; }
/* Parse command line, sanity check arguments, and return a newly * allocated GSParams object */ static GSParams *parse_args(ssize_t argc, char **argv) { ssize_t i; GSParams *params; params = (GSParams *) XLALMalloc(sizeof(GSParams)); memset(params, 0, sizeof(GSParams)); /* Set default values to the arguments */ params->waveFlags = XLALSimInspiralCreateWaveformFlags(); params->nonGRparams = NULL; params->approximant = TaylorT1; params->domain = LAL_SIM_DOMAIN_TIME; params->phaseO = 7; params->ampO = 0; params->phiRef = 0.; params->deltaT = 1./4096.; params->deltaF = 0.125; params->m1 = 10. * LAL_MSUN_SI; params->m2 = 1.4 * LAL_MSUN_SI; params->f_min = 40.; params->fRef = 0.; params->f_max = 0.; /* Generate as much as possible */ params->distance = 100. * 1e6 * LAL_PC_SI; params->inclination = 0.; params->s1x = 0.; params->s1y = 0.; params->s1z = 0.; params->s2x = 0.; params->s2y = 0.; params->s2z = 0.; params->lambda1 = 0.; params->lambda2 = 0.; strncpy(params->outname, "simulation.dat", 256); /* output to this file */ params->ampPhase = 0; /* output h+ and hx */ params->verbose = 0; /* No verbosity */ /* consume command line */ for (i = 1; i < argc; ++i) { if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) { printf("%s", usage); XLALFree(params); exit(0); } else if (strcmp(argv[i], "--verbose") == 0) { params->verbose = 1; } else if (strcmp(argv[i], "--amp-phase") == 0) { params->ampPhase = 1; } else if ( ( i == argc ) || ( !argv[i+1] ) ) { XLALPrintError("Error: value required for option %s\n", argv[i]); } else if (strcmp(argv[i], "--approximant") == 0) { params->approximant = XLALSimInspiralGetApproximantFromString(argv[++i]); if ( (int) params->approximant == XLAL_FAILURE) { XLALPrintError("Error: invalid value %s for --interaction-flag\n", argv[i]); goto fail; } } else if (strcmp(argv[i], "--domain") == 0) { i++; if (strcmp(argv[i], "TD") == 0) params->domain = LAL_SIM_DOMAIN_TIME; else if (strcmp(argv[i], "FD") == 0) params->domain = LAL_SIM_DOMAIN_FREQUENCY; else { XLALPrintError("Error: Unknown domain\n"); goto fail; } } else if (strcmp(argv[i], "--phase-order") == 0) { params->phaseO = atoi(argv[++i]); } else if (strcmp(argv[i], "--amp-order") == 0) { params->ampO = atoi(argv[++i]); } else if (strcmp(argv[i], "--phiRef") == 0) { params->phiRef = atof(argv[++i]); } else if (strcmp(argv[i], "--fRef") == 0) { params->fRef = atof(argv[++i]); } else if (strcmp(argv[i], "--sample-rate") == 0) { params->deltaT = 1./atof(argv[++i]); } else if (strcmp(argv[i], "--deltaF") == 0) { params->deltaF = atof(argv[++i]); } else if (strcmp(argv[i], "--m1") == 0) { params->m1 = atof(argv[++i]) * LAL_MSUN_SI; } else if (strcmp(argv[i], "--m2") == 0) { params->m2 = atof(argv[++i]) * LAL_MSUN_SI; } else if (strcmp(argv[i], "--spin1x") == 0) { params->s1x = atof(argv[++i]); } else if (strcmp(argv[i], "--spin1y") == 0) { params->s1y = atof(argv[++i]); } else if (strcmp(argv[i], "--spin1z") == 0) { params->s1z = atof(argv[++i]); } else if (strcmp(argv[i], "--spin2x") == 0) { params->s2x = atof(argv[++i]); } else if (strcmp(argv[i], "--spin2y") == 0) { params->s2y = atof(argv[++i]); } else if (strcmp(argv[i], "--spin2z") == 0) { params->s2z = atof(argv[++i]); } else if (strcmp(argv[i], "--tidal-lambda1") == 0) { params->lambda1 = atof(argv[++i]); } else if (strcmp(argv[i], "--tidal-lambda2") == 0) { params->lambda2 = atof(argv[++i]); } else if (strcmp(argv[i], "--spin-order") == 0) { XLALSimInspiralSetSpinOrder( params->waveFlags, atoi(argv[++i]) ); } else if (strcmp(argv[i], "--tidal-order") == 0) { XLALSimInspiralSetTidalOrder( params->waveFlags, atoi(argv[++i]) ); } else if (strcmp(argv[i], "--f-min") == 0) { params->f_min = atof(argv[++i]); } else if (strcmp(argv[i], "--f-max") == 0) { params->f_max = atof(argv[++i]); } else if (strcmp(argv[i], "--distance") == 0) { params->distance = atof(argv[++i]) * 1e6 * LAL_PC_SI; } else if (strcmp(argv[i], "--inclination") == 0) { params->inclination = atof(argv[++i]); } else if (strcmp(argv[i], "--axis") == 0) { XLALSimInspiralSetFrameAxis( params->waveFlags, XLALGetFrameAxisFromString(argv[++i]) ); if ( (int) XLALSimInspiralGetFrameAxis(params->waveFlags) == (int) XLAL_FAILURE) { XLALPrintError("Error: invalid value %s for --axis\n", argv[i]); goto fail; } } else if (strcmp(argv[i], "--modes") == 0) { XLALSimInspiralSetModesChoice( params->waveFlags, XLALGetHigherModesFromString(argv[++i]) ); if ( (int) XLALSimInspiralGetModesChoice(params->waveFlags) == (int) XLAL_FAILURE) { XLALPrintError("Error: invalid value %s for --modes\n", argv[i]); goto fail; } } else if (strcmp(argv[i], "--nonGRpar") == 0) { char name[100]; strcpy(name,argv[++i]); if ( ( i == argc ) || ( !argv[i+1] ) ) { XLALPrintError("Error: 'name value' pair required for option %s\n", argv[i-1]); } else if (params->nonGRparams==NULL) { params->nonGRparams=XLALSimInspiralCreateTestGRParam(name,atof(argv[++i])); } else { XLALSimInspiralAddTestGRParam(¶ms->nonGRparams,name,atof(argv[++i])); } } else if (strcmp(argv[i], "--outname") == 0) { strncpy(params->outname, argv[++i], 256); } else { XLALPrintError("Error: invalid option: %s\n", argv[i]); goto fail; } } return params; fail: printf("%s", usage); XLALFree(params); exit(1); }
int main(int argc, char *argv[]) { ConfigVariables XLAL_INIT_DECL(config); UserVariables_t XLAL_INIT_DECL(uvar); DopplerMetricParams XLAL_INIT_DECL(metricParams); vrbflg = 1; /* verbose error-messages */ /* set LAL error-handler */ lal_errhandler = LAL_ERR_EXIT; /* register user-variables */ if ( initUserVars(&uvar) != XLAL_SUCCESS ) { XLALPrintError( "%s(): initUserVars() failed\n", __func__ ); return EXIT_FAILURE; } /* read cmdline & cfgfile */ if ( XLALUserVarReadAllInput(argc,argv) != XLAL_SUCCESS ) { XLALPrintError( "%s(): XLALUserVarReadAllInput() failed\n", __func__ ); return EXIT_FAILURE; } if (uvar.help) /* help requested: we're done */ return 0; CHAR *VCSInfoString; if ( (VCSInfoString = XLALGetVersionString(0)) == NULL ) { XLALPrintError("XLALGetVersionString(0) failed.\n"); exit(1); } if ( uvar.version ) { printf ( "%s\n", VCSInfoString ); return 0; } if ( uvar.coordsHelp ) { CHAR *helpstr; if ( (helpstr = XLALDopplerCoordinateHelpAll()) == NULL ) { LogPrintf ( LOG_CRITICAL, "XLALDopplerCoordinateHelpAll() failed!\n\n"); return -1; } printf ( "\n%s\n", helpstr ); XLALFree ( helpstr ); return 0; } /* if coordsHelp */ /* basic setup and initializations */ XLAL_CHECK ( XLALInitCode( &config, &uvar, argv[0] ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALInitCode() failed with xlalErrno = %d\n\n", xlalErrno ); config.history->VCSInfoString = VCSInfoString; /* parse detector motion string */ int detMotionType = XLALParseDetectorMotionString( uvar.detMotionStr ); XLAL_CHECK ( detMotionType != XLAL_FAILURE, XLAL_EFUNC, "Failed to pass detector motion string '%s'", uvar.detMotionStr ); metricParams.detMotionType = detMotionType; metricParams.segmentList = config.segmentList; metricParams.coordSys = config.coordSys; metricParams.multiIFO = config.multiIFO; metricParams.multiNoiseFloor = config.multiNoiseFloor; metricParams.signalParams = config.signalParams; metricParams.projectCoord = uvar.projection - 1; /* user-input counts from 1, but interally we count 0=1st coord. (-1==no projection) */ metricParams.approxPhase = uvar.approxPhase; /* ----- compute metric full metric + Fisher matrix ---------- */ DopplerPhaseMetric *Pmetric = NULL; if ( uvar.metricType == 0 || uvar.metricType == 2 ) { if ( (Pmetric = XLALComputeDopplerPhaseMetric ( &metricParams, config.edat )) == NULL ) { LogPrintf (LOG_CRITICAL, "Something failed in XLALComputeDopplerPhaseMetric(). xlalErrno = %d\n\n", xlalErrno); return -1; } } DopplerFstatMetric *Fmetric = NULL; if ( uvar.metricType == 1 || uvar.metricType == 2 ) { if ( (Fmetric = XLALComputeDopplerFstatMetric ( &metricParams, config.edat )) == NULL ) { LogPrintf (LOG_CRITICAL, "Something failed in XLALComputeDopplerFstatMetric(). xlalErrno = %d\n\n", xlalErrno); return -1; } } /* ---------- output results ---------- */ if ( uvar.outputMetric ) { FILE *fpMetric; if ( (fpMetric = fopen ( uvar.outputMetric, "wb" )) == NULL ) { LogPrintf (LOG_CRITICAL, "%s: failed to open '%s' for writing. error = '%s'\n", __func__, uvar.outputMetric, strerror(errno)); return FSTATMETRIC_EFILE; } if ( XLALOutputDopplerMetric ( fpMetric, Pmetric, Fmetric, config.history ) != XLAL_SUCCESS ) { LogPrintf (LOG_CRITICAL, "%s: failed to write Doppler metric into output-file '%s'. xlalErrno = %d\n\n", __func__, uvar.outputMetric, xlalErrno ); return FSTATMETRIC_EFILE; } fclose ( fpMetric ); } /* if outputMetric */ /* ----- done: free all memory */ XLALDestroyDopplerPhaseMetric ( Pmetric ); XLALDestroyDopplerFstatMetric ( Fmetric ); if ( XLALDestroyConfig( &config ) != XLAL_SUCCESS ) { LogPrintf (LOG_CRITICAL, "%s: XLADestroyConfig() failed, xlalErrno = %d.\n\n", __func__, xlalErrno ); return FSTATMETRIC_EXLAL; } LALCheckMemoryLeaks(); return 0; } /* main */
/** * Get the 'detector state' (ie detector-tensor, position, velocity, etc) for the given * vector of timestamps, shifted by a common time-shift \a tOffset. * * This function just calls XLALBarycenterEarth() and XLALBarycenter() for the * given vector of timestamps (shifted by tOffset) and returns the positions, * velocities and LMSTs of the detector, stored in a DetectorStateSeries. * There is also an entry containing the EarthState at each timestamp, which * can be used as input for subsequent calls to XLALBarycenter(). * * \a tOffset allows one to easily use the midpoints of SFT-timestamps, for example. * */ DetectorStateSeries * XLALGetDetectorStates ( const LIGOTimeGPSVector *timestamps, /**< array of GPS timestamps t_i */ const LALDetector *detector, /**< detector info */ const EphemerisData *edat, /**< ephemeris file data */ REAL8 tOffset /**< compute detector states at timestamps SHIFTED by tOffset */ ) { /* check input consistency */ if ( !timestamps || !detector || !edat ) { XLALPrintError ("%s: invalid NULL input, timestamps=%p, detector=%p, edat=%p\n", __func__, timestamps, detector, edat ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } /* prepare return vector */ UINT4 numSteps = timestamps->length; DetectorStateSeries *ret = NULL; if ( ( ret = XLALCreateDetectorStateSeries ( numSteps )) == NULL ) { XLALPrintError ("%s: XLALCreateDetectorStateSeries(%d) failed.\n", __func__, numSteps ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* enter detector-info into the head of the state-vector */ ret->detector = (*detector); /* set 'time-span' associated with each timestamp */ ret->deltaT = timestamps->deltaT; /* set SSB coordinate system used: EQUATORIAL for Earth-based, ECLIPTIC for LISA */ if ( detector->frDetector.prefix[0] == 'Z' ) /* LISA */ ret->system = COORDINATESYSTEM_ECLIPTIC; else /* Earth-based */ ret->system = COORDINATESYSTEM_EQUATORIAL; /* now fill all the vector-entries corresponding to different timestamps */ UINT4 i; for ( i=0; i < numSteps; i++ ) { BarycenterInput baryinput; EmissionTime emit; DetectorState *state = &(ret->data[i]); EarthState *earth = &(state->earthState); LIGOTimeGPS tgps; /* shift timestamp by tOffset */ tgps = timestamps->data[i]; XLALGPSAdd(&tgps, tOffset); /*----- first get earth-state */ if ( XLALBarycenterEarth ( earth, &tgps, edat ) != XLAL_SUCCESS ) { XLALDestroyDetectorStateSeries ( ret ); XLALPrintError("%s: XLALBarycenterEarth() failed with xlalErrno=%d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFAILED ); } /*----- then get detector-specific info */ baryinput.tgps = tgps; baryinput.site = (*detector); baryinput.site.location[0] /= LAL_C_SI; baryinput.site.location[1] /= LAL_C_SI; baryinput.site.location[2] /= LAL_C_SI; baryinput.alpha = baryinput.delta = 0; /* irrelevant */ baryinput.dInv = 0; if ( XLALBarycenter ( &emit, &baryinput, earth) != XLAL_SUCCESS ) { XLALDestroyDetectorStateSeries( ret ); XLALPrintError("%s: XLALBarycenterEarth() failed with xlalErrno=%d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFAILED ); } /*----- extract the output-data from this */ UINT4 j; for (j=0; j < 3; j++) /* copy detector's position and velocity */ { state->rDetector[j] = emit.rDetector[j]; state->vDetector[j] = emit.vDetector[j]; } /* for j < 3 */ /* local mean sidereal time = GMST + longitude */ state->LMST = earth->gmstRad + detector->frDetector.vertexLongitudeRadians; state->LMST = fmod (state->LMST, LAL_TWOPI ); /* normalize */ /* insert timestamp */ state->tGPS = tgps; /* compute the detector-tensor at this time-stamp in SSB-fixed Cartesian coordinates * [EQUATORIAL for Earth-based, ECLIPTIC for LISA] */ if ( XLALFillDetectorTensor ( state, detector ) != 0 ) { XLALDestroyDetectorStateSeries(ret); XLALPrintError ( "%s: XLALFillDetectorTensor() failed ... errno = %d\n\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } } /* for i < numSteps */ /* return result */ return ret; } /* XLALGetDetectorStates() */
/** * Get the detector-time series for the given MultiLIGOTimeGPSVector. * NOTE: contrary to the deprecated XLALGetMultiDetectorStatesFromMultiSFTs() interface, this * function computes detector-states at the given timestamps shifted by tOffset * */ MultiDetectorStateSeries * XLALGetMultiDetectorStates( const MultiLIGOTimeGPSVector *multiTS, /**< [in] multi-IFO timestamps */ const MultiLALDetector *multiIFO, /**< [in] multi-IFO array holding detector info */ const EphemerisData *edat, /**< [in] ephemeris data */ REAL8 tOffset /**< [in] shift all timestamps by this amount */ ) { /* check input consistency */ if ( !multiIFO || !multiTS || !edat ) { XLALPrintError ("%s: invalid NULL input (multiIFO=%p, multiTS=%p or edat=%p)\n", __func__, multiIFO, multiTS, edat ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } UINT4 numDetectors; numDetectors = multiIFO->length; if ( numDetectors != multiTS->length ) { XLALPrintError ("%s: inconsistent number of IFOs in 'multiIFO' (%d) and 'multiTS' (%d)\n", __func__, multiIFO->length, multiTS->length ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } /* prepare return-structure */ MultiDetectorStateSeries *ret = NULL; if ( ( ret = LALCalloc ( 1, sizeof( *ret ) )) == NULL ) { XLALPrintError ("%s: LALCalloc ( 1, %zu ) failed\n", __func__, sizeof(*ret) ); XLAL_ERROR_NULL ( XLAL_ENOMEM ); } if ( ( ret->data = LALCalloc ( numDetectors, sizeof( *(ret->data) ) )) == NULL ) { XLALFree ( ret ); XLALPrintError ("%s: LALCalloc ( %d, %zu ) failed\n", __func__, numDetectors, sizeof(*(ret->data)) ); XLAL_ERROR_NULL ( XLAL_ENOMEM ); } ret->length = numDetectors; REAL8 t0=LAL_REAL4_MAX; REAL8 t1=0; REAL8 deltaT = multiTS->data[0]->deltaT; LIGOTimeGPS startTime = {0, 0}; /* loop over detectors */ UINT4 X; for ( X=0; X < numDetectors; X ++ ) { LIGOTimeGPSVector *tsX = multiTS->data[X]; const LALDetector *detX = &(multiIFO->sites[X]); if ( !tsX || !detX ) { XLALPrintError ("%s: invalid NULL data-vector tsX[%d] = %p, detX[%d] = %p\n", __func__, X, tsX, X, detX ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } if ( multiTS->data[X]->deltaT != deltaT ) { XLALPrintError ("%s: inconsistent time-base multi-timeseries deltaT[%d]=%f != deltaT[0] = %f\n", __func__, X, multiTS->data[X]->deltaT, deltaT ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } /* fill in the detector-state series for this detector */ if ( ( ret->data[X] = XLALGetDetectorStates ( tsX, detX, edat, tOffset )) == NULL ) { XLALPrintError ("%s: XLALGetDetectorStates() failed.\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* keep track of earliest/latest timestamp in order to determine total Tspan */ UINT4 numTS = tsX->length; REAL8 t0_X = XLALGPSGetREAL8( &tsX->data[0] ); REAL8 t1_X = XLALGPSGetREAL8( &tsX->data[numTS-1] ); if ( t0_X < t0 ) { t0 = t0_X; startTime = tsX->data[0]; } if ( t1_X > t1 ) t1 = t1_X; } /* for X < numDetectors */ ret->Tspan = t1 - t0 + deltaT; /* total time spanned by all SFTs */ ret->startTime = startTime; /* earliest start-time of observation */ return ret; } /* XLALGetMultiDetectorStates() */
/** * Wrapper to iterate over the entries in a sim_burst linked list and * inject them into a time series. Passing NULL for the response disables * it (input time series is strain). */ int XLALBurstInjectSignals( REAL8TimeSeries *series, const SimBurst *sim_burst, const TimeSlide *time_slide_table_head, const COMPLEX16FrequencySeries *response ) { /* to be deduced from the time series' channel name */ const LALDetector *detector; /* FIXME: fix the const entanglement so as to get rid of this */ LALDetector detector_copy; /* + and x time series for injection waveform */ REAL8TimeSeries *hplus = NULL; REAL8TimeSeries *hcross = NULL; /* injection time series as added to detector's */ REAL8TimeSeries *h; /* skip injections whose geocentre times are more than this many * seconds outside of the target time series */ const double injection_window = 100.0; /* turn the first two characters of the channel name into a * detector */ detector = XLALDetectorPrefixToLALDetector(series->name); if(!detector) XLAL_ERROR(XLAL_EFUNC); XLALPrintInfo("%s(): channel name is '%s', instrument appears to be '%s'\n", __func__, series->name, detector->frDetector.prefix); detector_copy = *detector; /* iterate over injections */ for(; sim_burst; sim_burst = sim_burst->next) { LIGOTimeGPS time_geocent_gps; const TimeSlide *time_slide_row; /* determine the offset to be applied to this injection */ time_slide_row = XLALTimeSlideConstGetByIDAndInstrument(time_slide_table_head, sim_burst->time_slide_id, detector->frDetector.prefix); if(!time_slide_row) { XLALPrintError("%s(): cannot find time shift offset for injection 'sim_burst:simulation_id:%ld'. need 'time_slide:time_slide_id:%ld' for instrument '%s'", __func__, sim_burst->simulation_id, sim_burst->time_slide_id, detector->frDetector.prefix); XLAL_ERROR(XLAL_EINVAL); } /* skip injections whose "times" are too far outside of the * target time series */ time_geocent_gps = sim_burst->time_geocent_gps; XLALGPSAdd(&time_geocent_gps, -time_slide_row->offset); if(XLALGPSDiff(&series->epoch, &time_geocent_gps) > injection_window || XLALGPSDiff(&time_geocent_gps, &series->epoch) > (series->data->length * series->deltaT + injection_window)) continue; XLALPrintInfo("%s(): injection 'sim_burst:simulation_id:%ld' in '%s' at %d.%09u s (GPS) will be shifted by %.16g s to %d.%09u s (GPS)\n", __func__, sim_burst->simulation_id, series->name, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, -time_slide_row->offset, time_geocent_gps.gpsSeconds, time_geocent_gps.gpsNanoSeconds); /* construct the h+ and hx time series for the injection * waveform. */ if(XLALGenerateSimBurst(&hplus, &hcross, sim_burst, series->deltaT)) XLAL_ERROR(XLAL_EFUNC); #if 0 { char name[100]; FILE *f; unsigned i; sprintf(name, "%d.%09u_%s.txt", sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, series->name); f = fopen(name, "w"); for(i = 0; i < hplus->data->length; i++) { LIGOTimeGPS t = hplus->epoch; XLALGPSAdd(&t, i * hplus->deltaT); fprintf(f, "%.16g %.16g %.16g\n", XLALGPSGetREAL8(&t), hplus->data->data[i], hcross->data->data[i]); } fclose(f); } #endif /* project the wave onto the detector to produce the strain * in the detector. */ h = XLALSimDetectorStrainREAL8TimeSeries(hplus, hcross, sim_burst->ra, sim_burst->dec, sim_burst->psi, &detector_copy); XLALDestroyREAL8TimeSeries(hplus); XLALDestroyREAL8TimeSeries(hcross); hplus = hcross = NULL; if(!h) XLAL_ERROR(XLAL_EFUNC); /* shift the waveform by the time slide offset */ XLALGPSAdd(&h->epoch, -time_slide_row->offset); #if 0 { char name[100]; FILE *f; unsigned i; sprintf(name, "%d.%09u_%s.txt", sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, series->name); f = fopen(name, "w"); for(i = 0; i < h->data->length; i++) { LIGOTimeGPS t = h->epoch; XLALGPSAdd(&t, i * h->deltaT); fprintf(f, "%d.%09u %.16g\n", t.gpsSeconds, t.gpsNanoSeconds, h->data->data[i]); } fclose(f); } #endif /* add the injection strain time series to the detector * data */ if(XLALSimAddInjectionREAL8TimeSeries(series, h, response)) { XLALDestroyREAL8TimeSeries(h); XLAL_ERROR(XLAL_EFUNC); } XLALDestroyREAL8TimeSeries(h); } /* done */ return 0; }
/** * Generate the + and x time series for a single sim_burst table row. * Note: only the row pointed to by sim_burst is processed, the linked * list is not iterated over. The hplus and hcross time series objects * will be allocated by this function. The time-at-geocentre is applied, * but the time shift offset must be applied separately. delta_t is the * sample interval for the time series. The return value is 0 in success, * non-0 on failure. */ int XLALGenerateSimBurst( REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const SimBurst *sim_burst, double delta_t ) { if(!strcmp(sim_burst->waveform, "BTLWNB")) { /* E_{GW}/r^{2} is in M_{sun} / pc^{2}, so we multiply by * (M_{sun} c^2) to convert to energy/pc^{2}, and divide by * (distance/pc)^{2} to convert to energy/distance^{2}, * which is then multiplied by (4 G / c^3) to convert to a * value of \int \dot{h}^{2} \diff t. From the values of * the LAL constants, the total factor multiplying * egw_over_rsquared is 1.8597e-21. */ double int_hdot_squared_dt = sim_burst->egw_over_rsquared * LAL_GMSUN_SI * 4 / LAL_C_SI / LAL_PC_SI / LAL_PC_SI; /* the waveform number is interpreted as the seed for GSL's * Mersenne twister random number generator */ gsl_rng *rng = gsl_rng_alloc(gsl_rng_mt19937); if(!rng) { XLALPrintError("%s(): failure creating random number generator\n", __func__); XLAL_ERROR(XLAL_ENOMEM); } gsl_rng_set(rng, sim_burst->waveform_number); XLALPrintInfo("%s(): BTLWNB @ %9d.%09u s (GPS): f = %.16g Hz, df = %.16g Hz, dt = %.16g s, hdot^2 = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->frequency, sim_burst->bandwidth, sim_burst->duration, int_hdot_squared_dt); if(XLALGenerateBandAndTimeLimitedWhiteNoiseBurst(hplus, hcross, sim_burst->duration, sim_burst->frequency, sim_burst->bandwidth, sim_burst->pol_ellipse_e, int_hdot_squared_dt, delta_t, rng)) { gsl_rng_free(rng); XLAL_ERROR(XLAL_EFUNC); } gsl_rng_free(rng); } else if(!strcmp(sim_burst->waveform, "StringCusp")) { XLALPrintInfo("%s(): string cusp @ %9d.%09u s (GPS): A = %.16g, fhigh = %.16g Hz\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->amplitude, sim_burst->frequency); if(XLALGenerateStringCusp(hplus, hcross, sim_burst->amplitude, sim_burst->frequency, delta_t)) XLAL_ERROR(XLAL_EFUNC); } else if(!strcmp(sim_burst->waveform, "SineGaussian")) { XLALPrintInfo("%s(): sine-Gaussian @ %9d.%09u s (GPS): f = %.16g Hz, Q = %.16g, hrss = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->frequency, sim_burst->q, sim_burst->hrss); if(XLALSimBurstSineGaussian(hplus, hcross, sim_burst->q, sim_burst->frequency, sim_burst->hrss, sim_burst->pol_ellipse_e, sim_burst->pol_ellipse_angle, delta_t)) XLAL_ERROR(XLAL_EFUNC); } else if(!strcmp(sim_burst->waveform, "Gaussian")) { XLALPrintInfo("%s(): Gaussian @ %9d.%09u s (GPS): duration = %.16g, hrss = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->duration, sim_burst->hrss); if(XLALSimBurstGaussian(hplus, hcross, sim_burst->duration, sim_burst->hrss, delta_t)) XLAL_ERROR(XLAL_EFUNC); } else if(!strcmp(sim_burst->waveform, "Impulse")) { XLALPrintInfo("%s(): impulse @ %9d.%09u s (GPS): hpeak = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->amplitude); if(XLALGenerateImpulseBurst(hplus, hcross, sim_burst->amplitude, delta_t)) XLAL_ERROR(XLAL_EFUNC); } else { /* unrecognized waveform */ XLALPrintError("%s(): error: unrecognized waveform\n", __func__); XLAL_ERROR(XLAL_EINVAL); } /* add the time of the injection at the geocentre to the start * times of the h+ and hx time series. after this, their epochs * mark the start of those time series at the geocentre. */ if(!XLALGPSAddGPS(&(*hcross)->epoch, &sim_burst->time_geocent_gps) || !XLALGPSAddGPS(&(*hplus)->epoch, &sim_burst->time_geocent_gps)) { XLALPrintError("%s(): bad geocentre time or waveform too long\n", __func__); XLALDestroyREAL8TimeSeries(*hcross); XLALDestroyREAL8TimeSeries(*hplus); *hplus = *hcross = NULL; XLAL_ERROR(XLAL_EFUNC); } /* done */ return 0; }
/** * Wrapper similar to XLALSimInspiralChooseFDWaveform() for waveforms to be generated a specific freqencies. * Returns the waveform in the frequency domain at the frequencies of the REAL8Sequence frequencies. */ int XLALSimInspiralChooseFDWaveformSequence( COMPLEX16FrequencySeries **hptilde, /**< FD plus polarization */ COMPLEX16FrequencySeries **hctilde, /**< FD cross polarization */ REAL8 phiRef, /**< reference orbital phase (rad) */ REAL8 m1, /**< mass of companion 1 (kg) */ REAL8 m2, /**< mass of companion 2 (kg) */ REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */ REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */ REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */ REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */ REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */ REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */ REAL8 f_ref, /**< Reference frequency (Hz) */ REAL8 distance, /**< distance of source (m) */ REAL8 inclination, /**< inclination of source (rad) */ LALDict *LALpars, /**< LALDictionary containing non-mandatory variables/flags */ Approximant approximant, /**< post-Newtonian approximant to use for waveform production */ REAL8Sequence *frequencies /**< sequence of frequencies for which the waveform will be computed. Pass in NULL (or None in python) for standard f_min to f_max sequence. */ ) { int ret; unsigned int j; REAL8 pfac, cfac; REAL8 LNhatx, LNhaty, LNhatz; /* Support variables for precessing wfs*/ REAL8 incl; REAL8 spin1x,spin1y,spin1z; REAL8 spin2x,spin2y,spin2z; /* Variables for IMRPhenomP and IMRPhenomPv2 */ REAL8 chi1_l, chi2_l, chip, thetaJ, alpha0; /* General sanity checks that will abort * * If non-GR approximants are added, include them in * XLALSimInspiralApproximantAcceptTestGRParams() */ if ( !XLALSimInspiralWaveformParamsNonGRAreDefault(LALpars) && XLALSimInspiralApproximantAcceptTestGRParams(approximant) != LAL_SIM_INSPIRAL_TESTGR_PARAMS ) { XLALPrintError("XLAL Error - %s: Passed in non-NULL testGRparams for an approximant that does not use them\n", __func__); XLAL_ERROR(XLAL_EINVAL); } if (!frequencies) XLAL_ERROR(XLAL_EFAULT); REAL8 f_min = frequencies->data[0]; /* General sanity check the input parameters - only give warnings! */ if( m1 < 0.09 * LAL_MSUN_SI ) XLALPrintWarning("XLAL Warning - %s: Small value of m1 = %e (kg) = %e (Msun) requested...Perhaps you have a unit conversion error?\n", __func__, m1, m1/LAL_MSUN_SI); if( m2 < 0.09 * LAL_MSUN_SI ) XLALPrintWarning("XLAL Warning - %s: Small value of m2 = %e (kg) = %e (Msun) requested...Perhaps you have a unit conversion error?\n", __func__, m2, m2/LAL_MSUN_SI); if( m1 + m2 > 1000. * LAL_MSUN_SI ) XLALPrintWarning("XLAL Warning - %s: Large value of total mass m1+m2 = %e (kg) = %e (Msun) requested...Signal not likely to be in band of ground-based detectors.\n", __func__, m1+m2, (m1+m2)/LAL_MSUN_SI); if( S1x*S1x + S1y*S1y + S1z*S1z > 1.000001 ) XLALPrintWarning("XLAL Warning - %s: S1 = (%e,%e,%e) with norm > 1 requested...Are you sure you want to violate the Kerr bound?\n", __func__, S1x, S1y, S1z); if( S2x*S2x + S2y*S2y + S2z*S2z > 1.000001 ) XLALPrintWarning("XLAL Warning - %s: S2 = (%e,%e,%e) with norm > 1 requested...Are you sure you want to violate the Kerr bound?\n", __func__, S2x, S2y, S2z); if( f_min < 1. ) XLALPrintWarning("XLAL Warning - %s: Small value of fmin = %e requested...Check for errors, this could create a very long waveform.\n", __func__, f_min); if( f_min > 40.000001 ) XLALPrintWarning("XLAL Warning - %s: Large value of fmin = %e requested...Check for errors, the signal will start in band.\n", __func__, f_min); /* The non-precessing waveforms return h(f) for optimal orientation * (i=0, Fp=1, Fc=0; Lhat pointed toward the observer) * To get generic polarizations we multiply by inclination dependence * and note hc(f) \propto -I * hp(f) * Non-precessing waveforms multiply hp by pfac, hc by -I*cfac */ cfac = cos(inclination); pfac = 0.5 * (1. + cfac*cfac); REAL8 lambda1=XLALSimInspiralWaveformParamsLookupTidalLambda1(LALpars); REAL8 lambda2=XLALSimInspiralWaveformParamsLookupTidalLambda2(LALpars); switch (approximant) { /* inspiral-only models */ case TaylorF2: /* Waveform-specific sanity checks */ if( !XLALSimInspiralWaveformParamsFrameAxisIsDefault(LALpars) ) ABORT_NONDEFAULT_FRAME_AXIS(LALpars); if( !XLALSimInspiralWaveformParamsModesChoiceIsDefault(LALpars) ) ABORT_NONDEFAULT_MODES_CHOICE(LALpars); if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) ) ABORT_NONZERO_TRANSVERSE_SPINS(LALpars); /* Call the waveform driver routine */ ret = XLALSimInspiralTaylorF2Core(hptilde, frequencies, phiRef, m1, m2, S1z, S2z, f_ref, 0., distance, LALpars); if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC); /* Produce both polarizations */ *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross", &((*hptilde)->epoch), (*hptilde)->f0, 0.0, &((*hptilde)->sampleUnits), (*hptilde)->data->length); for(j = 0; j < (*hptilde)->data->length; j++) { (*hctilde)->data->data[j] = -I*cfac * (*hptilde)->data->data[j]; (*hptilde)->data->data[j] *= pfac; } break; /* inspiral-merger-ringdown models */ case SEOBNRv1_ROM_EffectiveSpin: /* Waveform-specific sanity checks */ if( !XLALSimInspiralWaveformParamsFlagsAreDefault(LALpars) ) ABORT_NONDEFAULT_LALDICT_FLAGS(LALpars); if (!checkAlignedSpinsEqual(S1z, S2z)) ABORT_NONZERO_TRANSVERSE_SPINS(LALpars); if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) ) ABORT_NONZERO_TRANSVERSE_SPINS(LALpars); if( !checkTidesZero(lambda1, lambda2) ) ABORT_NONZERO_TIDES(LALpars); if( !checkTidesZero(lambda1, lambda2) ) ABORT_NONZERO_TIDES(LALpars); ret = XLALSimIMRSEOBNRv1ROMEffectiveSpinFrequencySequence(hptilde, hctilde, frequencies, phiRef, f_ref, distance, inclination, m1, m2, XLALSimIMRPhenomBComputeChi(m1, m2, S1z, S2z)); break; case SEOBNRv1_ROM_DoubleSpin: /* Waveform-specific sanity checks */ if( !XLALSimInspiralWaveformParamsFlagsAreDefault(LALpars) ) ABORT_NONDEFAULT_LALDICT_FLAGS(LALpars); if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) ) ABORT_NONZERO_TRANSVERSE_SPINS(LALpars); if( !checkTidesZero(lambda1, lambda2) ) ABORT_NONZERO_TIDES(LALpars); ret = XLALSimIMRSEOBNRv1ROMDoubleSpinFrequencySequence(hptilde, hctilde, frequencies, phiRef, f_ref, distance, inclination, m1, m2, S1z, S2z); break; case SEOBNRv2_ROM_EffectiveSpin: /* Waveform-specific sanity checks */ if( !XLALSimInspiralWaveformParamsFlagsAreDefault(LALpars) ) ABORT_NONDEFAULT_LALDICT_FLAGS(LALpars); if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) ) ABORT_NONZERO_TRANSVERSE_SPINS(LALpars); if( !checkTidesZero(lambda1, lambda2) ) ABORT_NONZERO_TIDES(LALpars); ret = XLALSimIMRSEOBNRv2ROMEffectiveSpinFrequencySequence(hptilde, hctilde, frequencies, phiRef, f_ref, distance, inclination, m1, m2, XLALSimIMRPhenomBComputeChi(m1, m2, S1z, S2z)); break; case SEOBNRv2_ROM_DoubleSpin: /* Waveform-specific sanity checks */ if( !XLALSimInspiralWaveformParamsFlagsAreDefault(LALpars) ) ABORT_NONDEFAULT_LALDICT_FLAGS(LALpars); if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) ) ABORT_NONZERO_TRANSVERSE_SPINS(LALpars); if( !checkTidesZero(lambda1, lambda2) ) ABORT_NONZERO_TIDES(LALpars); ret = XLALSimIMRSEOBNRv2ROMDoubleSpinFrequencySequence(hptilde, hctilde, frequencies, phiRef, f_ref, distance, inclination, m1, m2, S1z, S2z); break; case SEOBNRv2_ROM_DoubleSpin_HI: /* Waveform-specific sanity checks */ if( !XLALSimInspiralWaveformParamsFlagsAreDefault(LALpars) ) ABORT_NONDEFAULT_LALDICT_FLAGS(LALpars); if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) ) ABORT_NONZERO_TRANSVERSE_SPINS(LALpars); if( !checkTidesZero(lambda1, lambda2) ) ABORT_NONZERO_TIDES(LALpars); ret = XLALSimIMRSEOBNRv2ROMDoubleSpinHIFrequencySequence(hptilde, hctilde, frequencies, phiRef, f_ref, distance, inclination, m1, m2, S1z, S2z, -1); break; case Lackey_Tidal_2013_SEOBNRv2_ROM: /* Waveform-specific sanity checks */ if( !XLALSimInspiralWaveformParamsFlagsAreDefault(LALpars) ) ABORT_NONDEFAULT_LALDICT_FLAGS(LALpars); if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) ) ABORT_NONZERO_TRANSVERSE_SPINS(LALpars); ret = XLALSimIMRLackeyTidal2013FrequencySequence(hptilde, hctilde, frequencies, phiRef, f_ref, distance, inclination, m1, m2, S1z, lambda2); break; case IMRPhenomP: XLALSimInspiralInitialConditionsPrecessingApproxs(&incl,&spin1x,&spin1y,&spin1z,&spin2x,&spin2y,&spin2z,inclination,S1x,S1y,S1z,S2x,S2y,S2z,m1,m2,f_ref,phiRef,XLALSimInspiralWaveformParamsLookupFrameAxis(LALpars)); /* Waveform-specific sanity checks */ if( !XLALSimInspiralWaveformParamsFrameAxisIsDefault(LALpars) ) ABORT_NONDEFAULT_FRAME_AXIS(LALpars);/* Default is LAL_SIM_INSPIRAL_FRAME_AXIS_VIEW : z-axis along direction of GW propagation (line of sight). */ if( !XLALSimInspiralWaveformParamsModesChoiceIsDefault(LALpars) ) ABORT_NONDEFAULT_MODES_CHOICE(LALpars); /* Default is (2,2) or l=2 modes. */ if( !checkTidesZero(lambda1, lambda2) ) ABORT_NONZERO_TIDES(LALpars); LNhatx = sin(incl); LNhaty = 0.; LNhatz = cos(incl); /* Tranform to model parameters */ if(f_ref==0.0) f_ref = f_min; /* Default reference frequency is minimum frequency */ XLALSimIMRPhenomPCalculateModelParameters( &chi1_l, &chi2_l, &chip, &thetaJ, &alpha0, m1, m2, f_ref, LNhatx, LNhaty, LNhatz, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z, IMRPhenomPv1_V); /* Call the waveform driver routine */ ret = XLALSimIMRPhenomPFrequencySequence(hptilde, hctilde, frequencies, chi1_l, chi2_l, chip, thetaJ, m1, m2, distance, alpha0, phiRef, f_ref, IMRPhenomPv1_V, NULL); if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC); break; case IMRPhenomPv2: XLALSimInspiralInitialConditionsPrecessingApproxs(&incl,&spin1x,&spin1y,&spin1z,&spin2x,&spin2y,&spin2z,inclination,S1x,S1y,S1z,S2x,S2y,S2z,m1,m2,f_ref,phiRef,XLALSimInspiralWaveformParamsLookupFrameAxis(LALpars)); /* Waveform-specific sanity checks */ if( !XLALSimInspiralWaveformParamsFrameAxisIsDefault(LALpars) ) ABORT_NONDEFAULT_FRAME_AXIS(LALpars);/* Default is LAL_SIM_INSPIRAL_FRAME_AXIS_VIEW : z-axis along direction of GW propagation (line of sight). */ if( !XLALSimInspiralWaveformParamsModesChoiceIsDefault(LALpars) ) ABORT_NONDEFAULT_MODES_CHOICE(LALpars); /* Default is (2,2) or l=2 modes. */ if( !checkTidesZero(lambda1, lambda2) ) ABORT_NONZERO_TIDES(LALpars); LNhatx = sin(incl); LNhaty = 0.; LNhatz = cos(incl); /* Tranform to model parameters */ if(f_ref==0.0) f_ref = f_min; /* Default reference frequency is minimum frequency */ XLALSimIMRPhenomPCalculateModelParameters( &chi1_l, &chi2_l, &chip, &thetaJ, &alpha0, m1, m2, f_ref, LNhatx, LNhaty, LNhatz, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z, IMRPhenomPv2_V); /* Call the waveform driver routine */ ret = XLALSimIMRPhenomPFrequencySequence(hptilde, hctilde, frequencies, chi1_l, chi2_l, chip, thetaJ, m1, m2, distance, alpha0, phiRef, f_ref, IMRPhenomPv2_V, NULL); if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC); break; default: XLALPrintError("FD version of approximant not implemented in lalsimulation\n"); XLAL_ERROR(XLAL_EINVAL); } if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC); return ret; }
/** Store the output TD hplus and hcross in the cache. */ static int StoreTDHCache(LALSimInspiralWaveformCache *cache, REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, REAL8 phiRef, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 S1x, REAL8 S1y, REAL8 S1z, REAL8 S2x, REAL8 S2y, REAL8 S2z, REAL8 f_min, REAL8 f_ref, REAL8 r, REAL8 i, LALDict *LALpars, Approximant approximant ) { /* Clear any frequency-domain data. */ if (cache->hptilde != NULL) { XLALDestroyCOMPLEX16FrequencySeries(cache->hptilde); cache->hptilde = NULL; } if (cache->hctilde != NULL) { XLALDestroyCOMPLEX16FrequencySeries(cache->hctilde); cache->hctilde = NULL; } /* Store params in cache */ cache->phiRef = phiRef; cache->deltaTF = deltaT; cache->m1 = m1; cache->m2 = m2; cache->S1x = S1x; cache->S1y = S1y; cache->S1z = S1z; cache->S2x = S2x; cache->S2y = S2y; cache->S2z = S2z; cache->f_min = f_min; cache->f_ref = f_ref; cache->r = r; cache->i = i; cache->LALpars = LALpars; cache->approximant = approximant; cache->frequencies = NULL; // Copy over the waveforms // NB: XLALCut... creates a new Series object and copies data and metadata XLALDestroyREAL8TimeSeries(cache->hplus); XLALDestroyREAL8TimeSeries(cache->hcross); if (hplus == NULL || hcross == NULL || hplus->data == NULL || hcross->data == NULL){ XLALPrintError("We have null pointers for h+, hx in StoreTDHCache \n"); XLALPrintError("Houston-S, we've got a problem SOS, SOS, SOS, the waveform generator returns NULL!!!... m1 = %.18e, m2 = %.18e, fMin = %.18e, spin1 = {%.18e, %.18e, %.18e}, spin2 = {%.18e, %.18e, %.18e} \n", m1, m2, (double)f_min, S1x, S1y, S1z, S2x, S2y, S2z); return XLAL_ENOMEM; } cache->hplus = XLALCutREAL8TimeSeries(hplus, 0, hplus->data->length); if (cache->hplus == NULL) return XLAL_ENOMEM; cache->hcross = XLALCutREAL8TimeSeries(hcross, 0, hcross->data->length); if (cache->hcross == NULL) { XLALDestroyREAL8TimeSeries(cache->hplus); cache->hplus = NULL; return XLAL_ENOMEM; } return XLAL_SUCCESS; }
/*---------------------------------------------------------------------- * main function *----------------------------------------------------------------------*/ int main(int argc, char *argv[]) { SFTConstraints XLAL_INIT_DECL(constraints); LIGOTimeGPS XLAL_INIT_DECL(minStartTimeGPS); LIGOTimeGPS XLAL_INIT_DECL(maxStartTimeGPS); SFTCatalog *FullCatalog = NULL; CHAR *add_comment = NULL; UINT4 i; REAL8 fMin, fMax; UserInput_t XLAL_INIT_DECL(uvar); /* register all user-variables */ XLAL_CHECK_MAIN ( initUserVars ( &uvar ) == XLAL_SUCCESS, XLAL_EFUNC ); /* read cmdline & cfgfile */ XLAL_CHECK_MAIN ( XLALUserVarReadAllInput (argc, argv) == XLAL_SUCCESS, XLAL_EFUNC ); if (uvar.help) { /* help requested: we're done */ exit (0); } /* ----- make sure output directory exists ---------- */ if ( uvar.outputDir ) { int ret; ret = mkdir ( uvar.outputDir, 0777); if ( (ret == -1) && ( errno != EEXIST ) ) { int errsv = errno; LogPrintf (LOG_CRITICAL, "Failed to create directory '%s': %s\n", uvar.outputDir, strerror(errsv) ); return -1; } } LIGOTimeGPSVector *timestamps = NULL; if ( uvar.timestampsFile ) { if ( (timestamps = XLALReadTimestampsFile ( uvar.timestampsFile )) == NULL ) { XLALPrintError ("XLALReadTimestampsFile() failed to load timestamps from file '%s'\n", uvar.timestampsFile ); return -1; } } /* use IFO-contraint if one given by the user */ if ( LALUserVarWasSet ( &uvar.IFO ) ) { XLAL_CHECK_MAIN ( (constraints.detector = XLALGetChannelPrefix ( uvar.IFO )) != NULL, XLAL_EINVAL ); } minStartTimeGPS.gpsSeconds = uvar.minStartTime; maxStartTimeGPS.gpsSeconds = uvar.maxStartTime; constraints.minStartTime = &minStartTimeGPS; constraints.maxStartTime = &maxStartTimeGPS; constraints.timestamps = timestamps; /* get full SFT-catalog of all matching (multi-IFO) SFTs */ XLAL_CHECK_MAIN ( (FullCatalog = XLALSFTdataFind ( uvar.inputSFTs, &constraints )) != NULL, XLAL_EFUNC ); if ( constraints.detector ) { XLALFree ( constraints.detector ); } XLAL_CHECK_MAIN ( (FullCatalog != NULL) && (FullCatalog->length > 0), XLAL_EINVAL, "\nSorry, didn't find any matching SFTs with pattern '%s'!\n\n", uvar.inputSFTs ); /* build up full comment-string to be added to SFTs: 1) converted by ConvertToSFTv2, VCS ID 2) user extraComment */ { UINT4 len = 128; len += strlen ( uvar.inputSFTs ); if ( uvar.extraComment ) len += strlen ( uvar.extraComment ); XLAL_CHECK_MAIN ( ( add_comment = LALCalloc ( 1, len )) != NULL, XLAL_ENOMEM ); /** \deprecated FIXME: the following code uses obsolete CVS ID tags. * It should be modified to use git version information. */ sprintf ( add_comment, "Converted by $Id$, inputSFTs = '%s';", uvar.inputSFTs ); if ( uvar.extraComment ) { strcat ( add_comment, "\n"); strcat ( add_comment, uvar.extraComment ); } } /* construct comment-string */ /* which frequency-band to extract? */ fMin = -1; /* default: all */ fMax = -1; if ( LALUserVarWasSet ( &uvar.fmin ) ) fMin = uvar.fmin; if ( LALUserVarWasSet ( &uvar.fmax ) ) fMax = uvar.fmax; FILE *fpSingleSFT = NULL; if ( uvar.outputSingleSFT ) XLAL_CHECK ( ( fpSingleSFT = fopen ( uvar.outputSingleSFT, "wb" )) != NULL, XLAL_EIO, "Failed to open singleSFT file '%s' for writing\n", uvar.outputSingleSFT ); /* loop over all SFTs in SFTCatalog */ for ( i=0; i < FullCatalog->length; i ++ ) { SFTCatalog oneSFTCatalog; SFTVector *thisSFT = NULL; const CHAR *sft_comment; CHAR *new_comment; UINT4 comment_len = 0; /* set catalog containing only one SFT */ oneSFTCatalog.length = 1; oneSFTCatalog.data = &(FullCatalog->data[i]); comment_len = strlen ( add_comment ) + 10; sft_comment = oneSFTCatalog.data->comment; if ( sft_comment ) comment_len += strlen ( sft_comment ); XLAL_CHECK_MAIN ( ( new_comment = LALCalloc (1, comment_len )) != NULL, XLAL_ENOMEM ); if ( sft_comment ) { strcpy ( new_comment, sft_comment ); strcat ( new_comment, ";\n"); } strcat ( new_comment, add_comment ); XLAL_CHECK_MAIN ( (thisSFT = XLALLoadSFTs ( &oneSFTCatalog, fMin, fMax )) != NULL, XLAL_EFUNC ); if ( uvar.mysteryFactor != 1.0 ) { XLAL_CHECK_MAIN ( applyFactor2SFTs ( thisSFT, uvar.mysteryFactor ) == XLAL_SUCCESS, XLAL_EFUNC ); } // if user asked for single-SFT output, add this SFT to the open file if ( uvar.outputSingleSFT ) XLAL_CHECK ( XLAL_SUCCESS == XLALWriteSFT2fp( &(thisSFT->data[0]), fpSingleSFT, new_comment ), XLAL_EFUNC, "XLALWriteSFT2fp() failed to write SFT to '%s'!\n", uvar.outputSingleSFT ); // if user asked for directory output, write this SFT into that directory if ( uvar.outputDir ) { XLAL_CHECK_MAIN ( XLALWriteSFTVector2Dir ( thisSFT, uvar.outputDir, new_comment, uvar.descriptionMisc ) == XLAL_SUCCESS, XLAL_EFUNC ); } XLALDestroySFTVector ( thisSFT ); XLALFree ( new_comment ); } /* for i < numSFTs */ if ( fpSingleSFT ) { fclose ( fpSingleSFT ); } /* free memory */ XLALFree ( add_comment ); XLALDestroySFTCatalog ( FullCatalog ); XLALDestroyUserVars(); XLALDestroyTimestampVector ( timestamps ); LALCheckMemoryLeaks(); return 0; } /* main */
/** * \brief Deserializes a \c PulsarDopplerParams structure from a VOTable XML document * * This function takes a VOTable XML document and deserializes (extracts) * the \c PulsarDopplerParams structure identified by the given name. * * \param xmlDocument [in] Pointer to the VOTable XML document containing the structure * \param name [in] Unique identifier of the particular \c PulsarDopplerParams structure to be deserialized * \param pdp [out] Pointer to an empty \c PulsarDopplerParams structure to store the deserialized instance * * \return \c XLAL_SUCCESS if the specified \c PulsarDopplerParams structure could be found and * deserialized successfully. * * \sa XLALVOTXML2PulsarDopplerParamsByName * \sa XLALGetSingleNodeContentByXPath * * \author Oliver Bock\n * Albert-Einstein-Institute Hannover, Germany */ INT4 XLALVOTDoc2PulsarDopplerParamsByName ( const xmlDocPtr xmlDocument, const char *name, PulsarDopplerParams *pdp ) { /* set up local variables */ CHAR childNameRefTime[NAMESTR_MAXLEN] = {0}; CHAR *nodeContent = NULL; /* sanity checks */ if(!xmlDocument) { XLALPrintError("Invalid input parameter: xmlDocument\n"); XLAL_ERROR(XLAL_EINVAL); } if(!name || strlen(name) <= 0) { XLALPrintError("Invalid input parameter: name\n"); XLAL_ERROR(XLAL_EINVAL); } if(!pdp) { XLALPrintError("Invalid input parameter: pdp\n"); XLAL_ERROR(XLAL_EINVAL); } /* compile child name attribute (refTime) */ if(!strncpy(childNameRefTime, name, NAMESTR_MAXLEN) || !strncat(childNameRefTime, ".refTime", NAMESTR_MAXLEN)) { XLALPrintError("Child attribute preparation failed: PulsarDopplerParams.refTime\n"); XLAL_ERROR(XLAL_EFAILED); } /* retrieve PulsarDopplerParams.refTime */ if(XLALVOTDoc2LIGOTimeGPSByName(xmlDocument, childNameRefTime, &pdp->refTime)) { XLALPrintError("Error parsing XML document content: %s.refTime\n", childNameRefTime); XLAL_ERROR(XLAL_EFAILED); } /* retrieve PulsarDopplerParams.Alpha */ nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "Alpha", VOT_PARAM, VOT_VALUE ); if(!nodeContent || sscanf( nodeContent, "%lf", &pdp->Alpha) == EOF) { if(nodeContent) XLALFree(nodeContent); XLALPrintError("Invalid node content encountered: %s.Alpha\n", name); XLAL_ERROR(XLAL_EDATA); } XLALFree ( nodeContent ); /* retrieve PulsarDopplerParams.Delta */ nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "Delta", VOT_PARAM, VOT_VALUE ); if(!nodeContent || sscanf( nodeContent, "%lf", &pdp->Delta) == EOF) { if(nodeContent) XLALFree(nodeContent); XLALPrintError("Invalid node content encountered: %s.Delta\n", name); XLAL_ERROR(XLAL_EDATA); } XLALFree ( nodeContent ); /* retrieve PulsarDopplerParams.fkdot */ if ( XLALVOTDoc2PulsarSpinsByName(xmlDocument, name, "fkdot", pdp->fkdot)) { XLALPrintError("Error parsing XML document content: %s.fkdot\n", name); XLAL_ERROR(XLAL_EFAILED); } /* compile child name attribute (tp) */ CHAR childName[NAMESTR_MAXLEN]; if ( snprintf ( childName, NAMESTR_MAXLEN, "%s.%s", name, "tp") >= NAMESTR_MAXLEN ) { XLALPrintError("Child attribute preparation failed: PulsarDopplerParams.tp\n"); XLAL_ERROR(XLAL_EFAILED); } /* retrieve PulsarDopplerParams.tp */ if ( XLALVOTDoc2LIGOTimeGPSByName(xmlDocument, childName, &pdp->tp)) { XLALPrintError("Error parsing XML document content: %s.tp\n", childName); XLAL_ERROR(XLAL_EFAILED); } /* retrieve PulsarDopplerParams.argp content */ nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "argp", VOT_PARAM, VOT_VALUE ); if( !nodeContent || sscanf( nodeContent, "%lf", &pdp->argp) == EOF) { if ( nodeContent ) XLALFree (nodeContent); XLALPrintError("Invalid node content encountered: %s.argp\n", name); XLAL_ERROR(XLAL_EDATA); } XLALFree (nodeContent); /* retrieve PulsarDopplerParams.asini content */ nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "asini", VOT_PARAM, VOT_VALUE ); if( !nodeContent || sscanf( nodeContent, "%lf", &pdp->asini) == EOF) { if ( nodeContent ) XLALFree (nodeContent); XLALPrintError("Invalid node content encountered: %s.asini\n", name); XLAL_ERROR(XLAL_EDATA); } XLALFree (nodeContent); /* retrieve PulsarDopplerParams.ecc content */ nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "ecc", VOT_PARAM, VOT_VALUE ); if( !nodeContent || sscanf( nodeContent, "%lf", &pdp->ecc) == EOF) { if ( nodeContent ) XLALFree (nodeContent); XLALPrintError("Invalid node content encountered: %s.ecc\n", name); XLAL_ERROR(XLAL_EDATA); } XLALFree (nodeContent); /* retrieve PulsarDopplerParams.period content */ nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "period", VOT_PARAM, VOT_VALUE ); if(!nodeContent || sscanf( nodeContent, "%lf", &pdp->period) == EOF ) { if(nodeContent) XLALFree (nodeContent); XLALPrintError("Invalid node content encountered: %s.period\n", name); XLAL_ERROR(XLAL_EDATA); } XLALFree(nodeContent); return XLAL_SUCCESS; } /* XLALVOTDoc2PulsarDopplerParamsByName() */
/** * Function to compute the LWL detector-tensor for the given \a detector in * SSB-fixed cartesian coordinates at time tgps. * The coordinates used are: EQUATORIAL for Earth-based detectors, but ECLIPTIC for LISA. * RETURN: 0 = OK, -1 = ERROR */ int XLALFillDetectorTensor (DetectorState *detState, /**< [out,in]: detector state: fill in detector-tensor */ const LALDetector *detector /**< [in]: which detector */ ) { const CHAR *prefix; if ( !detState || !detector ) { xlalErrno = XLAL_EINVAL; return -1; } prefix = detector->frDetector.prefix; /* we need to distinguish two cases: space-borne (i.e. LISA) and Earth-based detectors */ if ( prefix[0] == 'Z' ) /* LISA */ { if ( XLALprecomputeLISAarms ( detState ) != 0 ) { XLALPrintError ("\nXLALprecomputeLISAarms() failed !\n\n"); xlalErrno = XLAL_EINVAL; return -1; } if ( XLALgetLISADetectorTensorLWL ( &(detState->detT), detState->detArms, prefix[1] ) != 0 ) { XLALPrintError ("\nXLALgetLISADetectorTensorLWL() failed !\n\n"); xlalErrno = XLAL_EINVAL; return -1; } } /* if LISA */ else { REAL4 sinG, cosG, sinGcosG, sinGsinG, cosGcosG; SymmTensor3 *detT = &(detState->detT); XLAL_CHECK( XLALSinCosLUT ( &sinG, &cosG, detState->earthState.gmstRad ) == XLAL_SUCCESS, XLAL_EFUNC ); sinGsinG = sinG * sinG; sinGcosG = sinG * cosG; cosGcosG = cosG * cosG; /* printf("GMST = %fdeg; cosG = %f, sinG= %f\n", LAL_180_PI * atan2(sinG,cosG), cosG, sinG); */ detT->d11 = detector->response[0][0] * cosGcosG - 2 * detector->response[0][1] * sinGcosG + detector->response[1][1] * sinGsinG; detT->d22 = detector->response[0][0] * sinGsinG + 2 * detector->response[0][1] * sinGcosG + detector->response[1][1] * cosGcosG; detT->d12 = (detector->response[0][0] - detector->response[1][1]) * sinGcosG + detector->response[0][1] * (cosGcosG - sinGsinG); detT->d13 = detector->response[0][2] * cosG - detector->response[1][2] * sinG; detT->d23 = detector->response[0][2] * sinG + detector->response[1][2] * cosG; detT->d33 = detector->response[2][2]; /* printf("d = (%f %f %f\n",detT->d11,detT->d12,detT->d13); printf(" %f %f %f\n",detT->d12,detT->d22,detT->d23); printf(" %f %f %f)\n",detT->d13,detT->d23,detT->d33); printf("d*= (%f %f %f\n",detector->response[0][0], detector->response[0][1],detector->response[0][2]); printf(" %f %f %f\n",detector->response[1][0], detector->response[1][1],detector->response[1][2]); printf(" %f %f %f)\n",detector->response[2][0], detector->response[2][1],detector->response[2][2]); */ } /* if Earth-based */ return 0; } /* XLALFillDetectorTensor() */
/** * \brief Serializes a \c PulsarSpins array into a VOTable XML %node * * This function takes a \c PulsarSpins array and serializes it into a VOTable * \c PARAM %node identified by the given name. The returned \c xmlNode can then be * embedded into an existing %node hierarchy. * * \param spins [in] Pointer to the \c PulsarSpins array to be serialized * \param name [in] Unique identifier of this particular \c PulsarSpins array instance * * \return A pointer to a \c xmlNode that holds the VOTable fragment that represents * the \c PulsarSpins array. In case of an error, a null-pointer is returned.\n * \b Important: the caller is responsible to free the allocated memory (when the * fragment isn't needed anymore) using \c xmlFreeNode. Alternatively, \c xmlFreeDoc * can be used later on when the returned fragment has been embedded in a XML document. * * \sa XLALCreateVOTParamNode * * \author Oliver Bock\n * Albert-Einstein-Institute Hannover, Germany */ xmlNodePtr XLALPulsarSpins2VOTNode(const PulsarSpins *const spins, const char *name) { /* set up local variables */ xmlNodePtr xmlParamNode = NULL; int i; CHAR spinArraySize[PULSARSPINSTR_MAXLEN] = {0}; CHAR spinArrayString[PULSAR_MAX_SPINS*REAL8STR_MAXLEN] = {0}; CHAR spinArrayStringItem[REAL8STR_MAXLEN] = {0}; /* sanity checks */ if(!spins || !(*spins)) { XLALPrintError("Invalid input parameter: spins\n"); XLAL_ERROR_NULL(XLAL_EINVAL); } if(sizeof(*spins)/sizeof(REAL8) != PULSAR_MAX_SPINS) { XLALPrintError("Invalid input parameter: spins (actual size %i differs from defined size %i)\n", sizeof(*spins)/sizeof(REAL8), PULSAR_MAX_SPINS); XLAL_ERROR_NULL(XLAL_EINVAL); } if(!name || strlen(name) <= 0) { XLALPrintError("Invalid input parameter: name\n"); XLAL_ERROR_NULL(XLAL_EINVAL); } /* parse input array */ for(i = 0; i < PULSAR_MAX_SPINS; ++i) { if(snprintf(spinArrayStringItem, REAL8STR_MAXLEN, "%g", (*spins)[i]) < 0) { XLALPrintError("Invalid input parameter: spins[%i]\n", i); XLAL_ERROR_NULL(XLAL_EINVAL); } if(!strncat(spinArrayString, spinArrayStringItem, REAL8STR_MAXLEN)) { XLALPrintError("Couldn't serialize parameter: spins[%i]\n", i); XLAL_ERROR_NULL(XLAL_EFAILED); } /* add delimiter (SPACE)*/ if(i<PULSAR_MAX_SPINS-1 && !strncat(spinArrayString, " ", 1)) { XLALPrintError("Couldn't add delimiter to parameter: spins[%i]\n", i); XLAL_ERROR_NULL(XLAL_EFAILED); } } /* set array size attribute */ if(snprintf(spinArraySize, PULSARSPINSTR_MAXLEN, "%i", PULSAR_MAX_SPINS) < 0) { XLALPrintError("Couldn't prepare attribute: arraysize\n"); XLAL_ERROR_NULL(XLAL_EFAILED); } /* set up PARAM node */ xmlParamNode = XLALCreateVOTParamNode(name, NULL, VOT_REAL8, spinArraySize, spinArrayString); if(!xmlParamNode) { XLALPrintError("Couldn't create PARAM node: %s\n", name); XLAL_ERROR_NULL(XLAL_EFAILED); } /* return PARAM node (needs to be xmlFreeNode'd or xmlFreeDoc'd by caller!!!) */ return xmlParamNode; }
/** * Core function for computing the ROM waveform. * Interpolate projection coefficient data and evaluate coefficients at desired (q, chi). * Construct 1D splines for amplitude and phase. * Compute strain waveform from amplitude and phase. */ static int SEOBNRv1ROMEffectiveSpinCore( COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, double phiRef, double fRef, double distance, double inclination, double Mtot_sec, double q, double chi, const REAL8Sequence *freqs_in, /* Frequency points at which to evaluate the waveform (Hz) */ double deltaF /* If deltaF > 0, the frequency points given in freqs are uniformly spaced with * spacing deltaF. Otherwise, the frequency points are spaced non-uniformly. * Then we will use deltaF = 0 to create the frequency series we return. */ ) { /* Check output arrays */ if(!hptilde || !hctilde) XLAL_ERROR(XLAL_EFAULT); SEOBNRROMdata *romdata=&__lalsim_SEOBNRv1ROMSS_data; if(*hptilde || *hctilde) { XLALPrintError("(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p",(*hptilde),(*hctilde)); XLAL_ERROR(XLAL_EFAULT); } int retcode=0; // 'Nudge' parameter values to allowed boundary values if close by if (q < 1.0) nudge(&q, 1.0, 1e-6); if (q > 100.0) nudge(&q, 100.0, 1e-6); if (chi < -1.0) nudge(&chi, -1.0, 1e-6); if (chi > 0.6) nudge(&chi, 0.6, 1e-6); /* If either spin > 0.6, model not available, exit */ if ( chi < -1.0 || chi > 0.6 ) { XLALPrintError( "XLAL Error - %s: chi smaller than -1 or larger than 0.6!\nSEOBNRv1ROMEffectiveSpin is only available for spins in the range -1 <= a/M <= 0.6.\n", __func__); XLAL_ERROR( XLAL_EDOM ); } if (q > 100) { XLALPrintError( "XLAL Error - %s: q=%lf larger than 100!\nSEOBNRv1ROMEffectiveSpin is only available for q in the range 1 <= q <= 100.\n", __func__,q); XLAL_ERROR( XLAL_EDOM ); } if (q >= 20 && q <= 40 && chi < -0.75 && chi > -0.9) { XLALPrintWarning( "XLAL Warning - %s: q in [20,40] and chi in [-0.8]. The SEOBNRv1 model is not trustworthy in this region!\nSee Fig 15 in CQG 31 195010, 2014 for details.", __func__); XLAL_ERROR( XLAL_EDOM ); } /* Find frequency bounds */ if (!freqs_in) XLAL_ERROR(XLAL_EFAULT); double fLow = freqs_in->data[0]; double fHigh = freqs_in->data[freqs_in->length - 1]; if(fRef==0.0) fRef=fLow; /* Convert to geometric units for frequency */ double Mf_ROM_min = fmax(gA[0], gPhi[0]); // lowest allowed geometric frequency for ROM double Mf_ROM_max = fmin(gA[nk_amp-1], gPhi[nk_phi-1]); // highest allowed geometric frequency for ROM double fLow_geom = fLow * Mtot_sec; double fHigh_geom = fHigh * Mtot_sec; double fRef_geom = fRef * Mtot_sec; double deltaF_geom = deltaF * Mtot_sec; // Enforce allowed geometric frequency range if (fLow_geom < Mf_ROM_min) XLAL_ERROR(XLAL_EDOM, "Starting frequency Mflow=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min); if (fHigh_geom == 0) fHigh_geom = Mf_ROM_max; else if (fHigh_geom > Mf_ROM_max) { XLALPrintWarning("Maximal frequency Mf_high=%g is greater than highest ROM frequency Mf_ROM_Max=%g. Using Mf_high=Mf_ROM_Max.", fHigh_geom, Mf_ROM_max); fHigh_geom = Mf_ROM_max; } else if (fHigh_geom < Mf_ROM_min) XLAL_ERROR(XLAL_EDOM, "End frequency %g is smaller than starting frequency %g!\n", fHigh_geom, fLow_geom); if (fRef_geom > Mf_ROM_max) { XLALPrintWarning("Reference frequency Mf_ref=%g is greater than maximal frequency in ROM Mf=%g. Starting at maximal frequency in ROM.\n", fRef_geom, Mf_ROM_max); fRef_geom = Mf_ROM_max; // If fref > fhigh we reset fref to default value of cutoff frequency. } if (fRef_geom < Mf_ROM_min) { XLALPrintWarning("Reference frequency Mf_ref=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min); fRef_geom = Mf_ROM_min; } /* Internal storage for w.f. coefficiencts */ SEOBNRROMdata_coeff *romdata_coeff=NULL; SEOBNRROMdata_coeff_Init(&romdata_coeff); REAL8 amp_pre; /* Interpolate projection coefficients and evaluate them at (q,chi) */ retcode=TP_Spline_interpolation_2d( q, // Input: q-value for which projection coefficients should be evaluated chi, // Input: chi-value for which projection coefficients should be evaluated romdata->cvec_amp, // Input: data for spline coefficients for amplitude romdata->cvec_phi, // Input: data for spline coefficients for phase romdata->cvec_amp_pre, // Input: data for spline coefficients for amplitude prefactor romdata_coeff->c_amp, // Output: interpolated projection coefficients for amplitude romdata_coeff->c_phi, // Output: interpolated projection coefficients for phase &_pre // Output: interpolated amplitude prefactor ); if(retcode!=0) { SEOBNRROMdata_coeff_Cleanup(romdata_coeff); XLAL_ERROR(retcode, "Parameter-space interpolation failed."); } // Compute function values of amplitude an phase on sparse frequency points by evaluating matrix vector products // amp_pts = B_A^T . c_A // phi_pts = B_phi^T . c_phi gsl_vector* amp_f = gsl_vector_alloc(nk_amp); gsl_vector* phi_f = gsl_vector_alloc(nk_phi); gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bamp, romdata_coeff->c_amp, 0.0, amp_f); gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bphi, romdata_coeff->c_phi, 0.0, phi_f); // Setup 1d splines in frequency gsl_interp_accel *acc_amp = gsl_interp_accel_alloc(); gsl_spline *spline_amp = gsl_spline_alloc(gsl_interp_cspline, nk_amp); gsl_spline_init(spline_amp, gA, gsl_vector_const_ptr(amp_f,0), nk_amp); gsl_interp_accel *acc_phi = gsl_interp_accel_alloc(); gsl_spline *spline_phi = gsl_spline_alloc(gsl_interp_cspline, nk_phi); gsl_spline_init(spline_phi, gPhi, gsl_vector_const_ptr(phi_f,0), nk_phi); size_t npts = 0; LIGOTimeGPS tC = {0, 0}; UINT4 offset = 0; // Index shift between freqs and the frequency series REAL8Sequence *freqs = NULL; if (deltaF > 0) { // freqs contains uniform frequency grid with spacing deltaF; we start at frequency 0 /* Set up output array with size closest power of 2 */ npts = NextPow2(fHigh_geom / deltaF_geom) + 1; if (fHigh_geom < fHigh * Mtot_sec) /* Resize waveform if user wants f_max larger than cutoff frequency */ npts = NextPow2(fHigh * Mtot_sec / deltaF_geom) + 1; XLALGPSAdd(&tC, -1. / deltaF); /* coalesce at t=0 */ *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts); *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts); // Recreate freqs using only the lower and upper bounds UINT4 iStart = (UINT4) ceil(fLow_geom / deltaF_geom); UINT4 iStop = (UINT4) ceil(fHigh_geom / deltaF_geom); freqs = XLALCreateREAL8Sequence(iStop - iStart); if (!freqs) { XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed."); } for (UINT4 i=iStart; i<iStop; i++) freqs->data[i-iStart] = i*deltaF_geom; offset = iStart; } else { // freqs contains frequencies with non-uniform spacing; we start at lowest given frequency npts = freqs_in->length; *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts); *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts); offset = 0; freqs = XLALCreateREAL8Sequence(freqs_in->length); if (!freqs) { XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed."); } for (UINT4 i=0; i<freqs_in->length; i++) freqs->data[i] = freqs_in->data[i] * Mtot_sec; } if (!(*hptilde) || !(*hctilde)) { XLALDestroyREAL8Sequence(freqs); gsl_spline_free(spline_amp); gsl_spline_free(spline_phi); gsl_interp_accel_free(acc_amp); gsl_interp_accel_free(acc_phi); gsl_vector_free(amp_f); gsl_vector_free(phi_f); SEOBNRROMdata_coeff_Cleanup(romdata_coeff); XLAL_ERROR(XLAL_EFUNC, "Waveform allocation failed."); } memset((*hptilde)->data->data, 0, npts * sizeof(COMPLEX16)); memset((*hctilde)->data->data, 0, npts * sizeof(COMPLEX16)); XLALUnitMultiply(&(*hptilde)->sampleUnits, &(*hptilde)->sampleUnits, &lalSecondUnit); XLALUnitMultiply(&(*hctilde)->sampleUnits, &(*hctilde)->sampleUnits, &lalSecondUnit); COMPLEX16 *pdata=(*hptilde)->data->data; COMPLEX16 *cdata=(*hctilde)->data->data; REAL8 cosi = cos(inclination); REAL8 pcoef = 0.5*(1.0 + cosi*cosi); REAL8 ccoef = cosi; REAL8 s = 1.0/sqrt(2.0); // Scale polarization amplitude so that strain agrees with FFT of SEOBNRv1 double Mtot = Mtot_sec / LAL_MTSUN_SI; double amp0 = Mtot * amp_pre * Mtot_sec * LAL_MRSUN_SI / (distance); // Correct overall amplitude to undo mass-dependent scaling used in single-spin ROM // Evaluate reference phase for setting phiRef correctly double phase_change = gsl_spline_eval(spline_phi, fRef_geom, acc_phi) - 2*phiRef; // Assemble waveform from aplitude and phase for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence double f = freqs->data[i]; if (f > Mf_ROM_max) continue; // We're beyond the highest allowed frequency; since freqs may not be ordered, we'll just skip the current frequency and leave zero in the buffer int j = i + offset; // shift index for frequency series if needed double A = gsl_spline_eval(spline_amp, f, acc_amp); double phase = gsl_spline_eval(spline_phi, f, acc_phi) - phase_change; COMPLEX16 htilde = s*amp0*A * cexp(I*phase); pdata[j] = pcoef * htilde; cdata[j] = -I * ccoef * htilde; } /* Correct phasing so we coalesce at t=0 (with the definition of the epoch=-1/deltaF above) */ // Get SEOBNRv1 ringdown frequency for 22 mode double Mf_final = SEOBNRROM_Ringdown_Mf_From_Mtot_q(Mtot_sec, q, chi, chi, SEOBNRv1); UINT4 L = freqs->length; // prevent gsl interpolation errors if (Mf_final > freqs->data[L-1]) Mf_final = freqs->data[L-1]; if (Mf_final < freqs->data[0]) { XLALDestroyREAL8Sequence(freqs); gsl_spline_free(spline_amp); gsl_spline_free(spline_phi); gsl_interp_accel_free(acc_amp); gsl_interp_accel_free(acc_phi); gsl_vector_free(amp_f); gsl_vector_free(phi_f); SEOBNRROMdata_coeff_Cleanup(romdata_coeff); XLAL_ERROR(XLAL_EDOM, "f_ringdown < f_min"); } // Time correction is t(f_final) = 1/(2pi) dphi/df (f_final) // We compute the dimensionless time correction t/M since we use geometric units. REAL8 t_corr = gsl_spline_eval_deriv(spline_phi, Mf_final, acc_phi) / (2*LAL_PI); // Now correct phase for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence double f = freqs->data[i] - fRef_geom; int j = i + offset; // shift index for frequency series if needed pdata[j] *= cexp(-2*LAL_PI * I * f * t_corr); cdata[j] *= cexp(-2*LAL_PI * I * f * t_corr); } XLALDestroyREAL8Sequence(freqs); gsl_spline_free(spline_amp); gsl_spline_free(spline_phi); gsl_interp_accel_free(acc_amp); gsl_interp_accel_free(acc_phi); gsl_vector_free(amp_f); gsl_vector_free(phi_f); SEOBNRROMdata_coeff_Cleanup(romdata_coeff); return(XLAL_SUCCESS); }
/* * main */ int main (int argc , char **argv) { FILE *f; int status; int start_time; COMPLEX16FrequencySeries *hptilde = NULL, *hctilde = NULL; REAL8TimeSeries *hplus = NULL; REAL8TimeSeries *hcross = NULL; GSParams *params; /* set us up to fail hard */ XLALSetErrorHandler(XLALAbortErrorHandler); /* parse commandline */ params = parse_args(argc, argv); /* generate waveform */ start_time = time(NULL); switch (params->domain) { case LAL_SIM_DOMAIN_FREQUENCY: XLALSimInspiralChooseFDWaveform(&hptilde, &hctilde, params->phiRef, params->deltaF, params->m1, params->m2, params->s1x, params->s1y, params->s1z, params->s2x, params->s2y, params->s2z, params->f_min, params->f_max, params->fRef, params->distance, params->inclination, params->lambda1, params->lambda2, params->waveFlags, params->nonGRparams, params->ampO, params->phaseO, params->approximant); break; case LAL_SIM_DOMAIN_TIME: XLALSimInspiralChooseTDWaveform(&hplus, &hcross, params->phiRef, params->deltaT, params->m1, params->m2, params->s1x, params->s1y, params->s1z, params->s2x, params->s2y, params->s2z, params->f_min, params->fRef, params->distance, params->inclination, params->lambda1, params->lambda2, params->waveFlags, params->nonGRparams, params->ampO, params->phaseO, params->approximant); break; default: XLALPrintError("Error: domain must be either TD or FD\n"); } if (params->verbose) XLALPrintInfo("Generation took %.0f seconds\n", difftime(time(NULL), start_time)); if (((params->domain == LAL_SIM_DOMAIN_FREQUENCY) && (!hptilde || !hctilde)) || ((params->domain == LAL_SIM_DOMAIN_TIME) && (!hplus || !hcross))) { XLALPrintError("Error: waveform generation failed\n"); goto fail; } /* dump file */ if ( strlen(params->outname) > 0 ) { f = fopen(params->outname, "w"); if (f==NULL) { printf("**ERROR** Impossible to write file %s\n",params->outname); exit(1); } else { if (params->domain == LAL_SIM_DOMAIN_FREQUENCY) if (params->ampPhase == 1) status = dump_FD2(f, hptilde, hctilde); else status = dump_FD(f, hptilde, hctilde); else if (params->ampPhase == 1) status = dump_TD2(f, hplus, hcross); else status = dump_TD(f, hplus, hcross); fclose(f); } if (status) goto fail; } /* clean up */ XLALSimInspiralDestroyWaveformFlags(params->waveFlags); XLALSimInspiralDestroyTestGRParam(params->nonGRparams); XLALFree(params); XLALDestroyCOMPLEX16FrequencySeries(hptilde); XLALDestroyCOMPLEX16FrequencySeries(hctilde); return 0; fail: XLALSimInspiralDestroyWaveformFlags(params->waveFlags); XLALSimInspiralDestroyTestGRParam(params->nonGRparams); XLALFree(params); XLALDestroyCOMPLEX16FrequencySeries(hptilde); XLALDestroyCOMPLEX16FrequencySeries(hctilde); return 1; }
/** * \brief Serializes an array of \c LALInferenceVariables into a VOTable XML %node * * This function takes a \c LALInferenceVariables structure and serializes it into a VOTable * \c RESOURCE %node identified by the given name. The returned \c xmlNode can then be * embedded into an existing %node hierarchy or turned into a full VOTable document. * A VOTable Table element is returned, with fixed variables as PARAMs and the varying ones as FIELDs. * * \param varsArray [in] Pointer to an array of \c LALInferenceVariables structures to be serialized * \param N [in] Number of items in the array * \param tablename UNDOCUMENTED * * \return A pointer to a \c xmlNode that holds the VOTable fragment that represents * the \c LALInferenceVariables array. * In case of an error, a null-pointer is returned.\n * \b Important: the caller is responsible to free the allocated memory (when the * fragment isn't needed anymore) using \c xmlFreeNode. Alternatively, \c xmlFreeDoc * can be used later on when the returned fragment has been embedded in a XML document. * * \sa XLALCreateVOTParamNode * \sa XLALCreateVOTResourceNode * * \author John Veitch * */ xmlNodePtr XLALInferenceVariablesArray2VOTTable(LALInferenceVariables * const *const varsArray, UINT4 N, const char *tablename) { xmlNodePtr fieldNodeList=NULL; xmlNodePtr paramNodeList=NULL; xmlNodePtr xmlTABLEDATAnode=NULL; xmlNodePtr VOTtableNode=NULL; xmlNodePtr tmpNode=NULL; xmlNodePtr field_ptr,param_ptr; LALInferenceVariableItem *varitem=NULL; UINT4 Nfields=0; UINT4 bufsize=1024; int err; /* Sanity check input */ if(!varsArray) { XLALPrintError("Received null varsArray pointer"); XLAL_ERROR_NULL(XLAL_EFAULT); } if(N==0) return(NULL); field_ptr=fieldNodeList; param_ptr=paramNodeList; char *field_names[varsArray[0]->dimension]; /* Build a list of PARAM and FIELD elements */ for(varitem=varsArray[0]->head;varitem;varitem=varitem->next) { tmpNode=NULL; switch(varitem->vary){ case LALINFERENCE_PARAM_LINEAR: case LALINFERENCE_PARAM_CIRCULAR: case LALINFERENCE_PARAM_OUTPUT: { tmpNode=LALInferenceVariableItem2VOTFieldNode(varitem); if(!tmpNode) { XLALPrintWarning ("%s: xmlAddNextSibling() failed to add field node for %s.\n", __func__, varitem->name ); //XLAL_ERROR_NULL(XLAL_EFAILED); continue; } if(field_ptr) field_ptr=xmlAddNextSibling(field_ptr,tmpNode); else {field_ptr=tmpNode; fieldNodeList=field_ptr;} field_names[Nfields]=varitem->name; Nfields++; break; } case LALINFERENCE_PARAM_FIXED: { tmpNode=LALInferenceVariableItem2VOTParamNode(varitem); if(!tmpNode) { XLALPrintWarning ("%s: xmlAddNextSibling() failed to add param node for %s.\n", __func__, varitem->name ); //XLAL_ERROR_NULL(XLAL_EFAILED); continue; } if(param_ptr) param_ptr=xmlAddNextSibling(param_ptr,tmpNode); else {param_ptr=tmpNode; paramNodeList=param_ptr;} break; } default: { XLALPrintWarning("Unknown param vary type"); } } } if(Nfields>0) { UINT4 row,col; /* create TABLEDATA node */ if ( ( xmlTABLEDATAnode = xmlNewNode ( NULL, CAST_CONST_XMLCHAR("TABLEDATA") ))== NULL ) { XLALPrintError ("%s: xmlNewNode() failed to create 'TABLEDATA' node.\n", __func__ ); err = XLAL_ENOMEM; goto failed; } /* ---------- loop over data-arrays and generate each table-row */ for ( row = 0; row < N; row ++ ) { /* create TR node */ xmlNodePtr xmlThisRowNode = NULL; if ( (xmlThisRowNode = xmlNewNode ( NULL, CAST_CONST_XMLCHAR("TR") )) == NULL ) { XLALPrintError ("%s: xmlNewNode() failed to create new 'TR' node.\n", __func__ ); err = XLAL_EFAILED; goto failed; } if ( xmlAddChild(xmlTABLEDATAnode, xmlThisRowNode ) == NULL ) { XLALPrintError ("%s: failed to insert 'TR' node into 'TABLEDATA' node.\n", __func__ ); err = XLAL_EFAILED; goto failed; } /* ----- loop over columns and generate each table element */ for ( col = 0; col < Nfields; col ++ ) { /* create TD node */ xmlNodePtr xmlThisEntryNode = NULL; if ( (xmlThisEntryNode = xmlNewNode ( NULL, CAST_CONST_XMLCHAR("TD") )) == NULL ) { XLALPrintError ("%s: xmlNewNode() failed to create new 'TD' node.\n", __func__ ); err = XLAL_EFAILED; goto failed; } if ( xmlAddChild(xmlThisRowNode, xmlThisEntryNode ) == NULL ) { XLALPrintError ("%s: failed to insert 'TD' node into 'TR' node.\n", __func__ ); err = XLAL_EFAILED; goto failed; } char *valuestr=XLALCalloc(bufsize,sizeof(char)); varitem = LALInferenceGetItem(varsArray[row],field_names[col]); UINT4 required_size=LALInferencePrintNVariableItem(valuestr,bufsize,varitem); if(required_size>bufsize) { bufsize=required_size; valuestr=XLALRealloc(valuestr,required_size*sizeof(char)); required_size=LALInferencePrintNVariableItem(valuestr,bufsize,varitem); } xmlNodePtr xmlTextNode= xmlNewText (CAST_CONST_XMLCHAR(valuestr) ); if ( xmlTextNode == NULL ) { XLALPrintError("%s: xmlNewText() failed to turn text '%s' into node\n", __func__, valuestr ); err = XLAL_EFAILED; XLALFree(valuestr); goto failed; } if ( xmlAddChild(xmlThisEntryNode, xmlTextNode ) == NULL ) { XLALPrintError ("%s: failed to insert text-node node into 'TD' node.\n", __func__ ); err = XLAL_EFAILED; XLALFree(valuestr); goto failed; } XLALFree(valuestr); } /* for col < numFields */ } /* for row < numRows */ } /* Create a TABLE from the FIELDs, PARAMs, and TABLEDATA nodes */ VOTtableNode= XLALCreateVOTTableNode (tablename, fieldNodeList, paramNodeList, xmlTABLEDATAnode ); return(VOTtableNode); failed: XLAL_ERROR_NULL ( err ); return(NULL); }
int XLALOutputDopplerMetric ( FILE *fp, const DopplerPhaseMetric *Pmetric, const DopplerFstatMetric *Fmetric, const ResultHistory_t *history ) { UINT4 i; REAL8 A, B, C, D; // ----- input sanity checks XLAL_CHECK ( fp != NULL, XLAL_EFAULT ); XLAL_CHECK ( Pmetric != NULL || Fmetric != NULL, XLAL_EFAULT ); const DopplerMetricParams *meta = (Pmetric != NULL) ? &(Pmetric->meta) : &(Fmetric->meta); XLAL_CHECK ( XLALSegListIsInitialized ( &(meta->segmentList) ), XLAL_EINVAL, "Got un-initialized segment list in 'metric->meta.segmentList'\n" ); UINT4 Nseg = meta->segmentList.length; XLAL_CHECK ( Nseg >= 1, XLAL_EDOM, "Got invalid zero-length segment list 'metric->meta.segmentList'\n" ); /* useful shortcuts */ const PulsarDopplerParams *doppler = &(meta->signalParams.Doppler); const PulsarAmplitudeParams *Amp = &(meta->signalParams.Amp); /* output history info */ if ( history ) { if ( history->app_name ) fprintf (fp, "%%%% app_name: %s\n", history->app_name ); if ( history->cmdline) fprintf (fp, "%%%% commandline: %s\n", history->cmdline ); if ( history->VCSInfoString ) fprintf (fp, "%%%% Code Version: %s\n", history->VCSInfoString ); } fprintf ( fp, "DopplerCoordinates = { " ); for ( i=0; i < meta->coordSys.dim; i ++ ) { if ( i > 0 ) fprintf ( fp, ", " ); fprintf ( fp, "\"%s\"", XLALDopplerCoordinateName(meta->coordSys.coordIDs[i])); } fprintf ( fp, "};\n"); { /* output projection info */ const char *pname; if ( meta->projectCoord < 0 ) pname = "None"; else pname = XLALDopplerCoordinateName ( meta->coordSys.coordIDs[meta->projectCoord] ); fprintf ( fp, "%%%% Projection onto subspace orthogonal to coordinate: '%s'\n", pname); } fprintf ( fp, "%%%% DetectorMotionType = '%s'\n", XLALDetectorMotionName(meta->detMotionType) ); fprintf ( fp, "h0 = %g;\ncosi = %g;\npsi = %g;\nphi0 = %g;\n", Amp->h0, Amp->cosi, Amp->psi, Amp->phi0 ); fprintf ( fp, "%%%% DopplerPoint = {\n"); fprintf ( fp, "refTime = %.1f;\n", XLALGPSGetREAL8 ( &doppler->refTime ) ); fprintf ( fp, "Alpha = %f;\nDelta = %f;\n", doppler->Alpha, doppler->Delta ); fprintf ( fp, "fkdot = [%f, %g, %g, %g ];\n", doppler->fkdot[0], doppler->fkdot[1], doppler->fkdot[2], doppler->fkdot[3] ); if ( doppler->asini > 0 ) { fprintf ( fp, "%%%% orbit = { \n"); fprintf ( fp, "%%%% tp = {%d, %d}\n", doppler->tp.gpsSeconds, doppler->tp.gpsNanoSeconds ); fprintf ( fp, "%%%% argp = %g\n", doppler->argp ); fprintf ( fp, "%%%% asini = %g\n", doppler->asini ); fprintf ( fp, "%%%% ecc = %g\n", doppler->ecc ); fprintf ( fp, "%%%% period = %g\n", doppler->period ); fprintf ( fp, "%%%% }\n"); } /* if doppler->orbit */ fprintf ( fp, "%%%% }\n"); LIGOTimeGPS *tStart = &(meta->segmentList.segs[0].start); LIGOTimeGPS *tEnd = &(meta->segmentList.segs[Nseg-1].end); REAL8 Tspan = XLALGPSDiff ( tEnd, tStart ); fprintf ( fp, "startTime = %.1f;\n", XLALGPSGetREAL8 ( tStart ) ); fprintf ( fp, "Tspan = %.1f;\n", Tspan ); fprintf ( fp, "Nseg = %d;\n", Nseg ); fprintf ( fp, "detectors = {"); for ( i=0; i < meta->multiIFO.length; i ++ ) { if ( i > 0 ) fprintf ( fp, ", "); fprintf ( fp, "\"%s\"", meta->multiIFO.sites[i].frDetector.name ); } fprintf ( fp, "};\n"); fprintf ( fp, "detectorWeights = ["); for ( i=0; i < meta->multiNoiseFloor.length; i ++ ) { if ( i > 0 ) fprintf ( fp, ", "); fprintf ( fp, "%f", meta->multiNoiseFloor.sqrtSn[i] ); } fprintf ( fp, "];\n"); /* ----- output phase metric ---------- */ if ( Pmetric != NULL ) { fprintf ( fp, "\ng_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Pmetric->g_ij ); fprintf ( fp, "maxrelerr_gPh = %.2e;\n", Pmetric->maxrelerr ); gsl_matrix *gN_ij = NULL; if ( XLALNaturalizeMetric ( &gN_ij, NULL, Pmetric->g_ij, meta ) != XLAL_SUCCESS ) { XLALPrintError ("%s: something failed Naturalizing phase metric g_ij!\n", __func__ ); XLAL_ERROR ( XLAL_EFUNC ); } fprintf ( fp, "\ngN_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, gN_ij ); gsl_matrix_free ( gN_ij ); gsl_matrix *gDN_ij = NULL; if ( XLALDiagNormalizeMetric ( &gDN_ij, NULL, Pmetric->g_ij ) != XLAL_SUCCESS ) { XLALPrintError ("%s: something failed NormDiagonalizing phase metric g_ij!\n", __func__ ); XLAL_ERROR ( XLAL_EFUNC ); } fprintf ( fp, "\ngDN_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, gDN_ij ); gsl_matrix_free ( gDN_ij ); } /* ----- output F-metric (and related matrices ---------- */ if ( Fmetric != NULL ) { fprintf ( fp, "\ngF_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->gF_ij ); fprintf ( fp, "\ngFav_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->gFav_ij ); fprintf ( fp, "\nm1_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->m1_ij ); fprintf ( fp, "\nm2_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->m2_ij ); fprintf ( fp, "\nm3_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->m3_ij ); fprintf ( fp, "maxrelerr_gF = %.2e;\n", Fmetric->maxrelerr ); } /* ----- output Fisher matrix ---------- */ if ( Fmetric != NULL && Fmetric->Fisher_ab != NULL ) { A = gsl_matrix_get ( Fmetric->Fisher_ab, 0, 0 ); B = gsl_matrix_get ( Fmetric->Fisher_ab, 1, 1 ); C = gsl_matrix_get ( Fmetric->Fisher_ab, 0, 1 ); D = A * B - C * C; fprintf ( fp, "\nA = %.16g;\nB = %.16g;\nC = %.16g;\nD = %.16g;\n", A, B, C, D ); fprintf ( fp, "\nrho2 = %.16g;\n", Fmetric->rho2 ); fprintf (fp, "\nFisher_ab = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->Fisher_ab ); } // ---------- output segment list at the end, as this can potentially become quite long and distracting char *seglist_octave; XLAL_CHECK ( (seglist_octave = XLALSegList2String ( &(meta->segmentList) )) != NULL, XLAL_EFUNC, "XLALSegList2String() with xlalErrno = %d\n", xlalErrno ); fprintf ( fp, "\n\nsegmentList = %s;\n", seglist_octave ); XLALFree ( seglist_octave ); return XLAL_SUCCESS; } /* XLALOutputDopplerMetric() */
/** * Function to calculate associated Legendre function used by the spherical harmonics function */ static REAL8 XLALAssociatedLegendreXIsZero( const int l, const int m ) { REAL8 legendre; if ( l < 0 ) { XLALPrintError( "l cannot be < 0\n" ); XLAL_ERROR_REAL8( XLAL_EINVAL ); } if ( m < 0 || m > l ) { XLALPrintError( "Invalid value of m!\n" ); XLAL_ERROR_REAL8( XLAL_EINVAL ); } /* we will switch on the values of m and n */ switch ( l ) { case 1: switch ( m ) { case 1: legendre = - 1.; break; default: XLAL_ERROR_REAL8( XLAL_EINVAL ); } break; case 2: switch ( m ) { case 2: legendre = 3.; break; case 1: legendre = 0.; break; default: XLAL_ERROR_REAL8( XLAL_EINVAL ); } break; case 3: switch ( m ) { case 3: legendre = -15.; break; case 2: legendre = 0.; break; case 1: legendre = 1.5; break; default: XLAL_ERROR_REAL8( XLAL_EINVAL ); } break; case 4: switch ( m ) { case 4: legendre = 105.; break; case 3: legendre = 0.; break; case 2: legendre = - 7.5; break; case 1: legendre = 0; break; default: XLAL_ERROR_REAL8( XLAL_EINVAL ); } break; case 5: switch ( m ) { case 5: legendre = - 945.; break; case 4: legendre = 0.; break; case 3: legendre = 52.5; break; case 2: legendre = 0; break; case 1: legendre = - 1.875; break; default: XLAL_ERROR_REAL8( XLAL_EINVAL ); } break; case 6: switch ( m ) { case 6: legendre = 10395.; break; case 5: legendre = 0.; break; case 4: legendre = - 472.5; break; case 3: legendre = 0; break; case 2: legendre = 13.125; break; case 1: legendre = 0; break; default: XLAL_ERROR_REAL8( XLAL_EINVAL ); } break; case 7: switch ( m ) { case 7: legendre = - 135135.; break; case 6: legendre = 0.; break; case 5: legendre = 5197.5; break; case 4: legendre = 0.; break; case 3: legendre = - 118.125; break; case 2: legendre = 0.; break; case 1: legendre = 2.1875; break; default: XLAL_ERROR_REAL8( XLAL_EINVAL ); } break; case 8: switch ( m ) { case 8: legendre = 2027025.; break; case 7: legendre = 0.; break; case 6: legendre = - 67567.5; break; case 5: legendre = 0.; break; case 4: legendre = 1299.375; break; case 3: legendre = 0.; break; case 2: legendre = - 19.6875; break; case 1: legendre = 0.; break; default: XLAL_ERROR_REAL8( XLAL_EINVAL ); } break; default: XLALPrintError( "Unsupported (l, m): %d, %d\n", l, m ); XLAL_ERROR_REAL8( XLAL_EINVAL ); } legendre *= sqrt( (REAL8)(2*l+1)*gsl_sf_fact( l-m ) / (4.*LAL_PI*gsl_sf_fact(l+m))); return legendre; }
REAL8 XLALInspiralMoments( REAL8 xmin, REAL8 xmax, REAL8 ndx, REAL8 norm, REAL8FrequencySeries *shf ) { REAL8 moment = 0; REAL8 f0, deltaF; size_t k, kMin, kMax; /* Check inputs */ if (!shf || !(shf->data) || !(shf->data->data)) { XLALPrintError("PSD or its data are NULL\n"); XLAL_ERROR_REAL8(XLAL_EFAULT); } if (xmin <= 0 || xmax <= 0 || xmax <= xmin || norm <= 0) { XLALPrintError("xmin, xmax, and norm must be positive and xmax must be greater than xmin\n"); XLAL_ERROR_REAL8(XLAL_EDOM); } /* set up and check domain of integration */ /* NB: Although these are called f0 and deltaF, they are really supposed to be x0 and deltaX (x = f / f0). That is, you either need to have hacked the PSD's f0 and deltaF values before calling this function or be prepared to rescale the outputs. */ f0 = shf->f0; deltaF = shf->deltaF; kMax = floor((xmax - f0) / deltaF); if ( (xmin < f0) || (kMax > shf->data->length) ) { XLALPrintError("PSD does not cover domain of integration\n"); XLAL_ERROR_REAL8(XLAL_EDOM); } kMin = floor((xmin - f0) / deltaF); /* do the first point of the integral */ if( shf->data->data[kMin] ) { const REAL8 f = f0 + kMin * deltaF; moment += pow( f, -(ndx) ) / ( 2.0 * shf->data->data[kMin] ); } /* do the bulk of the integral */ for ( k = kMin + 1; k < kMax; ++k ) { const REAL8 psd_val = shf->data->data[k]; if ( psd_val ) { const REAL8 f = f0 + k * deltaF; moment += pow( f, -(ndx) ) / psd_val; } } /* Do the last point of the integral, but allow the integration domain to be open on the right if necessary. */ if ( kMax < shf->data->length && shf->data->data[kMax] ) { const REAL8 f = f0 + kMax * deltaF; moment += pow( f, -(ndx) ) / ( 2.0 * shf->data->data[kMax] ); } moment *= deltaF; /* now divide the moment by the user-specified norm */ moment /= norm; return moment; }
/** * Function to calculate the numerical prefix in the Newtonian amplitude. Eqs. 5 - 7. */ static int CalculateThisMultipolePrefix( COMPLEX16 *prefix, /**<< OUTPUT, Prefix value */ const REAL8 m1, /**<< mass 1 */ const REAL8 m2, /**<< mass 2 */ const INT4 l, /**<< Mode l */ const INT4 m /**<< Mode m */ ) { COMPLEX16 n; REAL8 c; REAL8 x1, x2; /* Scaled versions of component masses */ REAL8 mult1, mult2; REAL8 totalMass; REAL8 eta; INT4 epsilon; INT4 sign; /* To give the sign of some additive terms */ n = 0.0; totalMass = m1 + m2; epsilon = ( l + m ) % 2; x1 = m1 / totalMass; x2 = m2 / totalMass; eta = m1*m2/(totalMass*totalMass); if ( abs( m % 2 ) == 0 ) { sign = 1; } else { sign = -1; } /* * Eq. 7 of Damour, Iyer and Nagar 2008. * For odd m, c is proportional to dM = m1-m2. In the equal-mass case, c = dM = 0. * In the equal-mass unequal-spin case, however, when spins are different, the odd m term is generally not zero. * In this case, c can be written as c0 * dM, while spins terms in PN expansion may take the form chiA/dM. * Although the dM's cancel analytically, we can not implement c and chiA/dM with the possibility of dM -> 0. * Therefore, for this case, we give numerical values of c0 for relevant modes, and c0 is calculated as * c / dM in the limit of dM -> 0. Consistently, for this case, we implement chiA instead of chiA/dM * in LALSimIMRSpinEOBFactorizedWaveform.c. */ if ( m1 != m2 || sign == 1 ) { c = pow( x2, l + epsilon - 1 ) + sign * pow(x1, l + epsilon - 1 ); } else { switch( l ) { case 2: c = -1.0; break; case 3: c = -1.0; break; case 4: c = -0.5; break; default: c = 0.0; break; } } /* Eqs 5 and 6. Dependent on the value of epsilon (parity), we get different n */ if ( epsilon == 0 ) { n = I * m; n = cpow( n, (REAL8)l ); mult1 = 8.0 * LAL_PI / gsl_sf_doublefact(2u*l + 1u); mult2 = (REAL8)((l+1) * (l+2)) / (REAL8)(l * ((INT4)l - 1)); mult2 = sqrt(mult2); n *= mult1; n *= mult2; } else if ( epsilon == 1 ) { n = I * m; n = cpow( n, (REAL8)l ); n = -n; mult1 = 16.*LAL_PI / gsl_sf_doublefact( 2u*l + 1u ); mult2 = (REAL8)( (2*l + 1) * (l+2) * (l*l - m*m) ); mult2 /= (REAL8)( (2*l - 1) * (l+1) * l * (l-1) ); mult2 = sqrt(mult2); n *= I * mult1; n *= mult2; } else { XLALPrintError( "Epsilon must be 0 or 1.\n"); XLAL_ERROR( XLAL_EINVAL ); } *prefix = n * eta * c; return XLAL_SUCCESS; }
/* short test for the basic functions of this lib. */ int test_fstat_toplist(UINT8 n, UINT8 m, char*filename) { REAL8 epsilon=1e-5; FILE*fp; toplist_t *tl=NULL, *tl2=NULL; FstatOutputEntry FstatLine; FstatOutputEntry *ll; UINT8 i,ins=0; UINT4 checksum; ll=(FstatOutputEntry*)malloc(m*sizeof(FstatOutputEntry)); if(ll == NULL) { XLALPrintError("Couldn't create list ll\n"); return(-1); } fprintf(stderr,"creating first toplist...\n"); if(create_fstat_toplist(&tl,n)) { XLALPrintError("Couldn't create toplist tl\n"); return(-1); } fprintf(stderr,"creating second toplist...\n"); if(create_fstat_toplist(&tl2,n)) { XLALPrintError("Couldn't create toplist tl2\n"); free_fstat_toplist(&tl); return(-1); } fprintf(stderr,"open file %s for writing...\n",filename); fp=fopen(filename,"w"); if(!fp) { XLALPrintError("Couldn't open file %s for writing\n",filename); free_fstat_toplist(&tl); free_fstat_toplist(&tl2); return(-2); } checksum = 0; fprintf(stderr,"filling toplist...\n"); for(i=0;i<m;i++) { FstatLine.Freq = (double)rand() / (double)RAND_MAX; FstatLine.f1dot = (double)rand() / (double)RAND_MAX; FstatLine.Alpha = (double)rand() / (double)RAND_MAX; FstatLine.Delta = (double)rand() / (double)RAND_MAX; FstatLine.Fstat = (double)rand() / (double)RAND_MAX; ll[i]= FstatLine; if(insert_into_fstat_toplist(tl, FstatLine)) { ins++; write_fstat_toplist_item_to_fp(FstatLine,fp,&checksum); } if(i==n) fprintf(stderr,"array filled now\n"); } fprintf(stderr,"%d inserts actually done of %d\n",(int)ins,m); fclose(fp); fprintf(stderr,"file checksum: %d\n",checksum); fprintf(stderr,"\nLet's see if we really kept the top elements:\n"); fprintf(stderr,"sort the lists completely\n"); qsort_toplist(tl,fstat_smaller); qsort(ll,m,sizeof(FstatOutputEntry),fstat_smaller); /* for(i=0;i<m;i++) print_fstat((void*)&(ll[i])); fprintf(stderr,"...\n"); go_through_toplist(tl,print_fstat); */ fprintf(stderr,"comparing...\n"); for(i=0;i<n;i++) if((((FstatOutputEntry*)toplist_elem(tl,i))->Freq - ll[i].Freq > epsilon) || (((FstatOutputEntry*)toplist_elem(tl,i))->f1dot - ll[i].f1dot > epsilon) || (((FstatOutputEntry*)toplist_elem(tl,i))->Alpha - ll[i].Alpha > epsilon) || (((FstatOutputEntry*)toplist_elem(tl,i))->Delta - ll[i].Delta > epsilon) || (((FstatOutputEntry*)toplist_elem(tl,i))->Fstat - ll[i].Fstat > epsilon)) { XLALPrintError("line %d differs\n",i); fprintf(stderr,"%e %e %e %e %e\n", ((FstatOutputEntry*)toplist_elem(tl,i))->Freq, ((FstatOutputEntry*)toplist_elem(tl,i))->f1dot, ((FstatOutputEntry*)toplist_elem(tl,i))->Alpha, ((FstatOutputEntry*)toplist_elem(tl,i))->Delta, ((FstatOutputEntry*)toplist_elem(tl,i))->Fstat); fprintf(stderr,"%e %e %e %e %e\n", ll[i].Freq, ll[i].f1dot, ll[i].Alpha, ll[i].Delta, ll[i].Fstat); } fprintf(stderr,"\nNow see if we can rebuild the toplist from the written file:\n"); fprintf(stderr,"open file %s for reading...\n",filename); fp=fopen(filename,"r"); if(!fp) { XLALPrintError("Couldn't open file %s for reading\n",filename); free_fstat_toplist(&tl); free_fstat_toplist(&tl2); return(-2); } fprintf(stderr,"reading...\n"); read_fstat_toplist_from_fp(tl2, fp, &checksum, 0); fclose(fp); fprintf(stderr,"checksum: %d\n",checksum); sort_fstat_toplist(tl); fprintf(stderr,"open file %s for writing...\n",filename); fp=fopen(filename,"w"); if(!fp) { XLALPrintError("Couldn't open file %s for writing\n",filename); free_fstat_toplist(&tl); free_fstat_toplist(&tl2); return(-2); } fprintf(stderr,"writing...\n"); if(write_fstat_toplist_to_fp(tl, fp, &checksum)<0) { XLALPrintError("Couldn't write toplist\n",filename); fclose(fp); free_fstat_toplist(&tl); free_fstat_toplist(&tl2); return(-2); } fprintf(stderr,"checksum: %d\n",checksum); fclose(fp); sort_fstat_toplist(tl2); fprintf(stderr,"comparing...\n"); for(i=0;i<n;i++) if((((FstatOutputEntry*)toplist_elem(tl,i))->Freq - ((FstatOutputEntry*)toplist_elem(tl2,i))->Freq > epsilon) || (((FstatOutputEntry*)toplist_elem(tl,i))->f1dot - ((FstatOutputEntry*)toplist_elem(tl2,i))->f1dot > epsilon) || (((FstatOutputEntry*)toplist_elem(tl,i))->Alpha - ((FstatOutputEntry*)toplist_elem(tl2,i))->Alpha > epsilon) || (((FstatOutputEntry*)toplist_elem(tl,i))->Delta - ((FstatOutputEntry*)toplist_elem(tl2,i))->Delta > epsilon) || (((FstatOutputEntry*)toplist_elem(tl,i))->Fstat - ((FstatOutputEntry*)toplist_elem(tl2,i))->Fstat > epsilon)) { XLALPrintError("line %d differs\n",i); fprintf(stderr,"%e %e %e %e %e\n", ((FstatOutputEntry*)toplist_elem(tl,i))->Freq, ((FstatOutputEntry*)toplist_elem(tl,i))->f1dot, ((FstatOutputEntry*)toplist_elem(tl,i))->Alpha, ((FstatOutputEntry*)toplist_elem(tl,i))->Delta, ((FstatOutputEntry*)toplist_elem(tl,i))->Fstat); fprintf(stderr,"%e %e %e %e %e\n", ((FstatOutputEntry*)toplist_elem(tl2,i))->Freq, ((FstatOutputEntry*)toplist_elem(tl2,i))->f1dot, ((FstatOutputEntry*)toplist_elem(tl2,i))->Alpha, ((FstatOutputEntry*)toplist_elem(tl2,i))->Delta, ((FstatOutputEntry*)toplist_elem(tl2,i))->Fstat); } fprintf(stderr,"cleanup...\n"); free_fstat_toplist(&tl); free_fstat_toplist(&tl2); free(ll); return(0); }
/** * \brief Deserializes a \c PulsarSpins array from a VOTable XML document * * This function takes a VOTable XML document and deserializes (extracts) the \c PulsarSpins array * (found as a \c PARAM element with the specified \c RESOURCE parent-path) identified by the given name. * * \return \c XLAL_SUCCESS if the specified \c PulsarSpins array could be found and * deserialized successfully. * * \sa XLALVOTXML2PulsarDopplerParamsByName * \sa XLALGetSingleVOTResourceParamAttribute * * \author Oliver Bock, Reinhard Prix\n * Albert-Einstein-Institute Hannover, Germany */ INT4 XLALVOTDoc2PulsarSpinsByName ( const xmlDocPtr xmlDocument, /**< [in] Pointer to the VOTable XML document containing the array */ const char *resourcePath, /**< [in] (optional) parent RESOURCE path */ const char *paramName, /**< [in] Name of the PulsarSpins PARAM element */ PulsarSpins spins /**< [out] Pointer to an empty \c PulsarSpins array to store the deserialized instance */ ) { /* set up local variables */ CHAR *nodeContent = NULL; CHAR *nodeContentWorker = NULL; int arraySize = 0; int i; /* sanity check */ if(!xmlDocument) { XLALPrintError("Invalid input parameters: xmlDocument\n"); XLAL_ERROR(XLAL_EINVAL); } if(!paramName) { XLALPrintError("Invalid input parameters: paramName\n"); XLAL_ERROR(XLAL_EINVAL); } if(!spins) { XLALPrintError("Invalid input parameters: spins\n"); XLAL_ERROR(XLAL_EINVAL); } /* retrieve arraysize (number of pulsar spins) */ nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, resourcePath, paramName, VOT_PARAM, VOT_ARRAYSIZE ); if(!nodeContent || sscanf( nodeContent, "%i", &arraySize) == EOF || arraySize == 0) { if(nodeContent) XLALFree(nodeContent); XLALPrintError("Invalid node content encountered: %s.%s.arraysize\n", resourcePath, paramName); XLAL_ERROR(XLAL_EDATA); } XLALFree(nodeContent); /* retrieve pulsar spin array (string) */ nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, resourcePath, paramName, VOT_PARAM, VOT_VALUE ); if(!nodeContent) { XLALPrintError("Invalid node content encountered: %s.%s\n", resourcePath, paramName); XLAL_ERROR(XLAL_EDATA); } /* finally, parse and store individual spin values */ nodeContentWorker = strtok(nodeContent, " "); for(i = 0; i < arraySize; i++ ) { /* scan current item */ if(sscanf((char*)nodeContentWorker, "%lf", &spins[i]) == EOF) { XLALFree(nodeContent); XLALPrintError("Invalid node content encountered: %s.%s[%i]\n", resourcePath, paramName, i); XLAL_ERROR(XLAL_EDATA); } /* advance to next item */ nodeContentWorker = strtok(NULL, " "); } /* for i < arraySize */ /* sanity check */ if(i != arraySize) { XLALFree(nodeContent); XLALPrintError("Invalid node content encountered: %s.%s (found %i of %i items)\n", resourcePath, paramName, i, arraySize); XLAL_ERROR(XLAL_EDATA); } /* clean up*/ XLALFree(nodeContent); return XLAL_SUCCESS; } /* XLALVOTDoc2PulsarSpinsByName() */
/** * Function that *truncates the PSD in place* to the requested frequency-bin interval [firstBin, lastBin] for the given multiPSDVector. * Now also truncates the original SFT vector, as necessary for correct computation of normalized SFT power. */ int XLALCropMultiPSDandSFTVectors ( MultiPSDVector *multiPSDVect, MultiSFTVector *multiSFTVect, UINT4 firstBin, UINT4 lastBin ) { /* check user input */ if ( !multiPSDVect ) { XLALPrintError ("%s: invalid NULL input 'multiPSDVect'\n", __func__ ); XLAL_ERROR ( XLAL_EINVAL ); } if ( !multiSFTVect ) { XLALPrintError ("%s: invalid NULL input 'multiSFTVect'\n", __func__ ); XLAL_ERROR ( XLAL_EINVAL ); } if ( lastBin < firstBin ) { XLALPrintError ("%s: empty bin interval requested [%d, %d]\n", __func__, firstBin, lastBin ); XLAL_ERROR ( XLAL_EDOM ); } UINT4 numIFOs = multiPSDVect->length; UINT4 numBins = multiPSDVect->data[0]->data[0].data->length; if ( numIFOs != multiSFTVect->length ) { XLALPrintError ("%s: inconsistent number of IFOs between PSD (%d) and SFT (%d) vectors.\n", __func__, numIFOs, multiSFTVect->length ); XLAL_ERROR ( XLAL_EDOM ); } if ( numBins != multiSFTVect->data[0]->data[0].data->length ) { XLALPrintError ("%s: inconsistent number of bins between PSD (%d bins) and SFT (%d bins) vectors.\n", __func__, numBins, multiSFTVect->data[0]->data[0].data->length ); XLAL_ERROR ( XLAL_EDOM ); } if ( (firstBin >= numBins) || (lastBin >= numBins ) ) { XLALPrintError ("%s: requested bin-interval [%d, %d] outside of PSD bins [0, %d]\n", __func__, firstBin, lastBin, numBins - 1 ); XLAL_ERROR ( XLAL_EDOM ); } /* ----- check if there's anything to do at all? ----- */ if ( (firstBin == 0) && (lastBin == numBins - 1) ) return XLAL_SUCCESS; /* ----- loop over detectors, timestamps, then crop each PSD ----- */ UINT4 X; for ( X=0; X < numIFOs; X ++ ) { PSDVector *thisPSDVect = multiPSDVect->data[X]; SFTVector *thisSFTVect = multiSFTVect->data[X]; UINT4 numTS = thisPSDVect->length; UINT4 iTS; for ( iTS = 0; iTS < numTS; iTS ++ ) { REAL8FrequencySeries *thisPSD = &thisPSDVect->data[iTS]; COMPLEX8FrequencySeries *thisSFT = &thisSFTVect->data[iTS]; if ( numBins != thisPSD->data->length ) { XLALPrintError ("%s: inconsistent number of frequency-bins across multiPSDVector: X=%d, iTS=%d: numBins = %d != %d\n", __func__, X, iTS, numBins, thisPSD->data->length ); XLAL_ERROR ( XLAL_EDOM ); } if ( numBins != thisSFT->data->length ) { XLALPrintError ("%s: inconsistent number of frequency-bins across multiSFTVector: X=%d, iTS=%d: numBins = %d != %d\n", __func__, X, iTS, numBins, thisSFT->data->length ); XLAL_ERROR ( XLAL_EDOM ); } UINT4 numNewBins = lastBin - firstBin + 1; /* crop PSD */ XLAL_CHECK(XLALResizeREAL8FrequencySeries(thisPSD, firstBin, numNewBins) != NULL, XLAL_EFUNC); /* crop SFT */ XLAL_CHECK(XLALResizeCOMPLEX8FrequencySeries(thisSFT, firstBin, numNewBins) != NULL, XLAL_EFUNC); } /* for iTS < numTS */ } /* for X < numIFOs */ /* that should be all ... */ return XLAL_SUCCESS; } /* XLALCropMultiPSDandSFTVectors() */
/** * \brief Serializes a \c PulsarDopplerParams structure into a VOTable XML %node * * This function takes a \c PulsarDopplerParams structure and serializes it into a VOTable * \c RESOURCE %node identified by the given name. The returned \c xmlNode can then be * embedded into an existing %node hierarchy or turned into a full VOTable document. * * \param pdp [in] Pointer to the \c PulsarDopplerParams structure to be serialized * \param name [in] Unique identifier of this particular \c PulsarDopplerParams structure instance * * \return A pointer to a \c xmlNode that holds the VOTable fragment that represents * the \c PulsarDopplerParams structure. * In case of an error, a null-pointer is returned.\n * \b Important: the caller is responsible to free the allocated memory (when the * fragment isn't needed anymore) using \c xmlFreeNode. Alternatively, \c xmlFreeDoc * can be used later on when the returned fragment has been embedded in a XML document. * * \sa XLALCreateVOTParamNode * \sa XLALCreateVOTResourceNode * \sa XLALCreateVOTDocumentFromTree * * \author Oliver Bock\n * Albert-Einstein-Institute Hannover, Germany */ xmlNodePtr XLALPulsarDopplerParams2VOTNode(const PulsarDopplerParams *const pdp, const char *name) { /* set up local variables */ xmlNodePtr xmlParentNode = NULL; xmlNodePtr xmlChildNode = NULL; xmlNodePtr xmlChildNodeList = NULL; xmlNodePtr xmlCurrentChildNode = NULL; /* check and convert input parameters */ XLAL_CHECK_NULL ( pdp != NULL, XLAL_EINVAL ); CHAR Alpha[REAL8STR_MAXLEN] = {0}; if( snprintf(Alpha, REAL8STR_MAXLEN, "%g", pdp->Alpha) < 0) { XLALPrintError("Invalid input parameter: PulsarDopplerParams->Alpha\n"); XLAL_ERROR_NULL(XLAL_EINVAL); } CHAR Delta[REAL8STR_MAXLEN] = {0}; if( snprintf(Delta, REAL8STR_MAXLEN, "%g", pdp->Delta) < 0) { XLALPrintError("Invalid input parameter: PulsarDopplerParams->Delta\n"); XLAL_ERROR_NULL(XLAL_EINVAL); } CHAR argp[REAL8STR_MAXLEN] = {0}; if( snprintf(argp, REAL8STR_MAXLEN, "%g", pdp->argp) < 0) { XLALPrintError("Invalid input parameter: PulsarDopplerParams->argp\n"); XLAL_ERROR_NULL(XLAL_EINVAL); } CHAR asini[REAL8STR_MAXLEN] = {0}; if( snprintf(asini, REAL8STR_MAXLEN, "%g", pdp->asini) < 0) { XLALPrintError("Invalid input parameter: PulsarDopplerParams->asini\n"); XLAL_ERROR_NULL(XLAL_EINVAL); } CHAR ecc[REAL8STR_MAXLEN] = {0}; if( snprintf(ecc, REAL8STR_MAXLEN, "%g", pdp->ecc) < 0) { XLALPrintError("Invalid input parameter: PulsarDopplerParams->ecc\n"); XLAL_ERROR_NULL(XLAL_EINVAL); } CHAR period[REAL8STR_MAXLEN] = {0}; if( snprintf(period, REAL8STR_MAXLEN, "%g", pdp->period) < 0) { XLALPrintError("Invalid input parameter: PulsarDopplerParams->period\n"); XLAL_ERROR_NULL(XLAL_EINVAL); } if(!name || strlen(name) <= 0) { XLALPrintError("Invalid input parameter: name\n"); XLAL_ERROR_NULL(XLAL_EINVAL); } /* ----- set up PARAM node (Alpha) */ xmlChildNode = XLALCreateVOTParamNode("Alpha", "rad", VOT_REAL8, NULL, Alpha); if(!xmlChildNode) { XLALPrintError("Couldn't create PARAM node: %s.Alpha\n", name); XLAL_ERROR_NULL(XLAL_EFAILED); } /* initialize child node list with first child */ xmlChildNodeList = xmlChildNode; xmlCurrentChildNode = xmlChildNodeList; /* ----- set up PARAM node (Delta) */ xmlChildNode = XLALCreateVOTParamNode("Delta", "rad", VOT_REAL8, NULL, Delta); if(!xmlChildNode) { /* clean up */ xmlFreeNodeList(xmlChildNodeList); XLALPrintError("Couldn't create PARAM node: %s.Delta\n", name); XLAL_ERROR_NULL(XLAL_EFAILED); } /* add child as next sibling to child node list */ xmlCurrentChildNode->next = xmlChildNode; xmlCurrentChildNode = xmlCurrentChildNode->next; /* ----- set up PARAM node (fkdot) */ xmlChildNode = XLALPulsarSpins2VOTNode(&pdp->fkdot, "fkdot"); if(!xmlChildNode) { /* clean up */ xmlFreeNodeList(xmlChildNodeList); XLALPrintError("Couldn't create PARAM node: %s.fkdot\n", name); XLAL_ERROR_NULL(XLAL_EFAILED); } /* add child as next sibling to child node list */ xmlCurrentChildNode->next = xmlChildNode; xmlCurrentChildNode = xmlCurrentChildNode->next; // ---------- handle binary-orbital parameters ---------- /* ----- set up PARAM node (argp) */ xmlChildNode = XLALCreateVOTParamNode("argp", "rad", VOT_REAL8, NULL, argp); if(!xmlChildNode) { /* clean up */ xmlFreeNodeList(xmlChildNodeList); XLALPrintError("Couldn't create PARAM node: %s.argp\n", name); XLAL_ERROR_NULL(XLAL_EFAILED); } /* add child as next sibling to child node list */ xmlCurrentChildNode->next = xmlChildNode; xmlCurrentChildNode = xmlCurrentChildNode->next; /* ----- set up PARAM node (asini) */ xmlChildNode = XLALCreateVOTParamNode("asini", "s", VOT_REAL8, NULL, asini); if(!xmlChildNode) { /* clean up */ xmlFreeNodeList(xmlChildNodeList); XLALPrintError("Couldn't create PARAM node: %s.asini\n", name); XLAL_ERROR_NULL(XLAL_EFAILED); } /* add child as next sibling to child node list */ xmlCurrentChildNode->next = xmlChildNode; xmlCurrentChildNode = xmlCurrentChildNode->next; /* ----- set up PARAM node (ecc) */ xmlChildNode = XLALCreateVOTParamNode("ecc", NULL, VOT_REAL8, NULL, ecc); if(!xmlChildNode) { /* clean up */ xmlFreeNodeList(xmlChildNodeList); XLALPrintError("Couldn't create PARAM node: %s.ecc\n", name); XLAL_ERROR_NULL(XLAL_EFAILED); } /* add child as next sibling to child node list */ xmlCurrentChildNode->next = xmlChildNode; xmlCurrentChildNode = xmlCurrentChildNode->next; /* ----- set up PARAM node (period) */ xmlChildNode = XLALCreateVOTParamNode("period", "s", VOT_REAL8, NULL, period); if(!xmlChildNode) { /* clean up */ xmlFreeNodeList(xmlChildNodeList); XLALPrintError("Couldn't create PARAM node: %s.period\n", name); XLAL_ERROR_NULL(XLAL_EFAILED); } /* add child as next sibling to child node list */ xmlCurrentChildNode->next = xmlChildNode; xmlCurrentChildNode = xmlCurrentChildNode->next; /* ----- set up RESOURCE node (refTime)*/ xmlChildNode = XLALLIGOTimeGPS2VOTNode(&pdp->refTime, "refTime" ); if(!xmlChildNode) { /* clean up */ xmlFreeNodeList(xmlChildNodeList); XLALPrintError("Couldn't create RESOURCE node: %s.refTime\n", name ); XLAL_ERROR_NULL(XLAL_EFAILED); } /* add child as next sibling to child node list */ xmlCurrentChildNode->next = xmlChildNode; xmlCurrentChildNode = xmlCurrentChildNode->next; /* ----- set up RESOURCE node (tp)*/ xmlChildNode = XLALLIGOTimeGPS2VOTNode(&pdp->tp, "tp"); if(!xmlChildNode) { /* clean up */ xmlFreeNodeList(xmlChildNodeList); XLALPrintError("Couldn't create RESOURCE node: tp\n"); XLAL_ERROR_NULL(XLAL_EFAILED); } /* add child as next sibling to child node list */ xmlCurrentChildNode->next = xmlChildNode; xmlCurrentChildNode = xmlCurrentChildNode->next; // ---------- END: binary-orbital parameters ---------- /* set up parent RESOURCE node*/ xmlParentNode = XLALCreateVOTResourceNode("PulsarDopplerParams", name, xmlChildNodeList); if(!xmlParentNode) { /* clean up */ xmlFreeNodeList(xmlChildNodeList); XLALPrintError("Couldn't create RESOURCE node: %s\n", name); XLAL_ERROR_NULL(XLAL_EFAILED); } /* return RESOURCE node (needs to be xmlFreeNode'd or xmlFreeDoc'd by caller!!!) */ return xmlParentNode; } // XLALPulsarDopplerParams2VOTNode()
/*============================================================ * FUNCTION definitions *============================================================*/ int main(int argc, char *argv[]) { static LALStatus status; /* LALStatus pointer */ UserVariables_t XLAL_INIT_DECL(uvar); ConfigVariables_t XLAL_INIT_DECL(cfg); UINT4 k, numBins, numIFOs, maxNumSFTs, X, alpha; REAL8 Freq0, dFreq, normPSD; UINT4 finalBinSize, finalBinStep, finalNumBins; REAL8Vector *overSFTs = NULL; /* one frequency bin over SFTs */ REAL8Vector *overIFOs = NULL; /* one frequency bin over IFOs */ REAL8Vector *finalPSD = NULL; /* math. operation PSD over SFTs and IFOs */ REAL8Vector *finalNormSFT = NULL; /* normalised SFT power */ vrbflg = 1; /* verbose error-messages */ /* set LAL error-handler */ lal_errhandler = LAL_ERR_EXIT; /* register and read user variables */ if (initUserVars(argc, argv, &uvar) != XLAL_SUCCESS) return EXIT_FAILURE; MultiSFTVector *inputSFTs = NULL; if ( ( inputSFTs = XLALReadSFTs ( &cfg, &uvar ) ) == NULL ) { XLALPrintError ("Call to XLALReadSFTs() failed with xlalErrno = %d\n", xlalErrno ); return EXIT_FAILURE; } /* clean sfts if required */ if ( XLALUserVarWasSet( &uvar.linefiles ) ) { RandomParams *randPar=NULL; FILE *fpRand=NULL; INT4 seed, ranCount; if ( (fpRand = fopen("/dev/urandom", "r")) == NULL ) { fprintf(stderr,"Error in opening /dev/urandom" ); return EXIT_FAILURE; } if ( (ranCount = fread(&seed, sizeof(seed), 1, fpRand)) != 1 ) { fprintf(stderr,"Error in getting random seed" ); return EXIT_FAILURE; } LAL_CALL ( LALCreateRandomParams (&status, &randPar, seed), &status ); LAL_CALL( LALRemoveKnownLinesInMultiSFTVector ( &status, inputSFTs, uvar.maxBinsClean, uvar.blocksRngMed, uvar.linefiles, randPar), &status); LAL_CALL ( LALDestroyRandomParams (&status, &randPar), &status); fclose(fpRand); } /* end cleaning */ LogPrintf (LOG_DEBUG, "Computing spectrogram and PSD ... "); /* get power running-median rngmed[ |data|^2 ] from SFTs */ MultiPSDVector *multiPSD = NULL; XLAL_CHECK_MAIN( ( multiPSD = XLALNormalizeMultiSFTVect ( inputSFTs, uvar.blocksRngMed, NULL ) ) != NULL, XLAL_EFUNC); /* restrict this PSD to just the "physical" band if requested using {--Freq, --FreqBand} */ if ( ( XLALCropMultiPSDandSFTVectors ( multiPSD, inputSFTs, cfg.firstBin, cfg.lastBin )) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALCropMultiPSDandSFTVectors (inputPSD, inputSFTs, %d, %d) failed with xlalErrno = %d\n", __func__, cfg.firstBin, cfg.lastBin, xlalErrno ); return EXIT_FAILURE; } /* start frequency and frequency spacing */ Freq0 = multiPSD->data[0]->data[0].f0; dFreq = multiPSD->data[0]->data[0].deltaF; /* number of raw bins in final PSD */ numBins = multiPSD->data[0]->data[0].data->length; if ( (finalPSD = XLALCreateREAL8Vector ( numBins )) == NULL ) { LogPrintf (LOG_CRITICAL, "Out of memory!\n"); return EXIT_FAILURE; } /* number of IFOs */ numIFOs = multiPSD->length; if ( (overIFOs = XLALCreateREAL8Vector ( numIFOs )) == NULL ) { LogPrintf (LOG_CRITICAL, "Out of memory!\n"); return EXIT_FAILURE; } /* maximum number of SFTs */ maxNumSFTs = 0; for (X = 0; X < numIFOs; ++X) { maxNumSFTs = GSL_MAX(maxNumSFTs, multiPSD->data[X]->length); } if ( (overSFTs = XLALCreateREAL8Vector ( maxNumSFTs )) == NULL ) { LogPrintf (LOG_CRITICAL, "Out of memory!\n"); return EXIT_FAILURE; } /* normalize rngmd(power) to get proper *single-sided* PSD: Sn = (2/Tsft) rngmed[|data|^2]] */ normPSD = 2.0 * dFreq; /* loop over frequency bins in final PSD */ for (k = 0; k < numBins; ++k) { /* loop over IFOs */ for (X = 0; X < numIFOs; ++X) { /* number of SFTs for this IFO */ UINT4 numSFTs = multiPSD->data[X]->length; /* copy PSD frequency bins and normalise multiPSD for later use */ for (alpha = 0; alpha < numSFTs; ++alpha) { multiPSD->data[X]->data[alpha].data->data[k] *= normPSD; overSFTs->data[alpha] = multiPSD->data[X]->data[alpha].data->data[k]; } /* compute math. operation over SFTs for this IFO */ overIFOs->data[X] = math_op(overSFTs->data, numSFTs, uvar.PSDmthopSFTs); if ( isnan( overIFOs->data[X] ) ) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in overIFOs->data[X=%d] = NAN ... exiting\n", X ); } /* for IFOs X */ /* compute math. operation over IFOs for this frequency */ finalPSD->data[k] = math_op(overIFOs->data, numIFOs, uvar.PSDmthopIFOs); if ( isnan ( finalPSD->data[k] ) ) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in finalPSD->data[k=%d] = NAN ... exiting\n", k ); } /* for freq bins k */ LogPrintfVerbatim ( LOG_DEBUG, "done.\n"); /* compute normalised SFT power */ if (uvar.outputNormSFT) { LogPrintf (LOG_DEBUG, "Computing normalised SFT power ... "); if ( (finalNormSFT = XLALCreateREAL8Vector ( numBins )) == NULL ) { LogPrintf (LOG_CRITICAL, "Out of memory!\n"); return EXIT_FAILURE; } /* loop over frequency bins in SFTs */ for (k = 0; k < numBins; ++k) { /* loop over IFOs */ for (X = 0; X < numIFOs; ++X) { /* number of SFTs for this IFO */ UINT4 numSFTs = inputSFTs->data[X]->length; /* compute SFT power */ for (alpha = 0; alpha < numSFTs; ++alpha) { COMPLEX8 bin = inputSFTs->data[X]->data[alpha].data->data[k]; overSFTs->data[alpha] = crealf(bin)*crealf(bin) + cimagf(bin)*cimagf(bin); } /* compute math. operation over SFTs for this IFO */ overIFOs->data[X] = math_op(overSFTs->data, numSFTs, uvar.nSFTmthopSFTs); if ( isnan ( overIFOs->data[X] )) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in overIFOs->data[X=%d] = NAN ... exiting\n", X ); } /* over IFOs */ /* compute math. operation over IFOs for this frequency */ finalNormSFT->data[k] = math_op(overIFOs->data, numIFOs, uvar.nSFTmthopIFOs); if ( isnan( finalNormSFT->data[k] ) ) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in bin finalNormSFT->data[k=%d] = NAN ... exiting\n", k ); } /* over freq bins */ LogPrintfVerbatim ( LOG_DEBUG, "done.\n"); } /* output spectrograms */ if ( uvar.outputSpectBname ) { LAL_CALL ( LALfwriteSpectrograms ( &status, uvar.outputSpectBname, multiPSD ), &status ); } /* ---------- if user requested it, output complete MultiPSDVector over IFOs X, timestamps and freq-bins into ASCI file(s) */ if ( uvar.dumpMultiPSDVector ) { if ( XLALDumpMultiPSDVector ( uvar.outputPSD, multiPSD ) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALDumpMultiPSDVector() failed, xlalErrnor = %d\n", __func__, xlalErrno ); return EXIT_FAILURE; } } /* if uvar.dumpMultiPSDVector */ /* ----- if requested, compute data-quality factor 'Q' -------------------- */ if ( uvar.outputQ ) { REAL8FrequencySeries *Q; if ( (Q = XLALComputeSegmentDataQ ( multiPSD, cfg.dataSegment )) == NULL ) { XLALPrintError ("%s: XLALComputeSegmentDataQ() failed with xlalErrno = %d\n", __func__, xlalErrno ); return EXIT_FAILURE; } if ( XLAL_SUCCESS != XLALWriteREAL8FrequencySeries_to_file ( Q, uvar.outputQ ) ) { return EXIT_FAILURE; } XLALDestroyREAL8FrequencySeries ( Q ); } /* if outputQ */ /* ---------- BINNING if requested ---------- */ /* work out bin size */ if (XLALUserVarWasSet(&uvar.binSize)) { finalBinSize = uvar.binSize; } else if (XLALUserVarWasSet(&uvar.binSizeHz)) { finalBinSize = (UINT4)floor(uvar.binSizeHz / dFreq + 0.5); /* round to nearest bin */ } else { finalBinSize = 1; } /* work out bin step */ if (XLALUserVarWasSet(&uvar.binStep)) { finalBinStep = uvar.binStep; } else if (XLALUserVarWasSet(&uvar.binStepHz)) { finalBinStep = (UINT4)floor(uvar.binStepHz / dFreq + 0.5); /* round to nearest bin */ } else { finalBinStep = finalBinSize; } /* work out total number of bins */ finalNumBins = (UINT4)floor((numBins - finalBinSize) / finalBinStep) + 1; /* write final PSD to file */ if (XLALUserVarWasSet(&uvar.outputPSD)) { FILE *fpOut = NULL; if ((fpOut = fopen(uvar.outputPSD, "wb")) == NULL) { LogPrintf ( LOG_CRITICAL, "Unable to open output file %s for writing...exiting \n", uvar.outputPSD ); return EXIT_FAILURE; } /* write header info in comments */ if ( XLAL_SUCCESS != XLALOutputVersionString ( fpOut, 0 ) ) XLAL_ERROR ( XLAL_EFUNC ); /* write the command-line */ for (int a = 0; a < argc; a++) fprintf(fpOut,"%%%% argv[%d]: '%s'\n", a, argv[a]); /* write column headings */ fprintf(fpOut,"%%%% columns:\n%%%% FreqBinStart"); if (uvar.outFreqBinEnd) fprintf(fpOut," FreqBinEnd"); fprintf(fpOut," PSD"); if (uvar.outputNormSFT) fprintf(fpOut," normSFTpower"); fprintf(fpOut,"\n"); LogPrintf(LOG_DEBUG, "Printing PSD to file ... "); for (k = 0; k < finalNumBins; ++k) { UINT4 b = k * finalBinStep; REAL8 f0 = Freq0 + b * dFreq; REAL8 f1 = f0 + finalBinStep * dFreq; fprintf(fpOut, "%f", f0); if (uvar.outFreqBinEnd) fprintf(fpOut, " %f", f1); REAL8 psd = math_op(&(finalPSD->data[b]), finalBinSize, uvar.PSDmthopBins); if ( isnan ( psd )) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in psd[k=%d] = NAN ... exiting\n", k ); fprintf(fpOut, " %e", psd); if (uvar.outputNormSFT) { REAL8 nsft = math_op(&(finalNormSFT->data[b]), finalBinSize, uvar.nSFTmthopBins); if ( isnan ( nsft )) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in nsft[k=%d] = NAN ... exiting\n", k ); fprintf(fpOut, " %f", nsft); } fprintf(fpOut, "\n"); } // k < finalNumBins LogPrintfVerbatim ( LOG_DEBUG, "done.\n"); fclose(fpOut); } /* we are now done with the psd */ XLALDestroyMultiPSDVector ( multiPSD); XLALDestroyMultiSFTVector ( inputSFTs); XLALDestroyUserVars(); XLALDestroyREAL8Vector ( overSFTs ); XLALDestroyREAL8Vector ( overIFOs ); XLALDestroyREAL8Vector ( finalPSD ); XLALDestroyREAL8Vector ( finalNormSFT ); LALCheckMemoryLeaks(); return EXIT_SUCCESS; } /* main() */
/** * Function to step through the full template grid point by point. * Normal return = 0, * errors return -1, * end of scan is signalled by return = 1 */ int XLALNextDopplerPos(PulsarDopplerParams *pos, DopplerFullScanState *scan) { /* This traps coding errors in the calling routine. */ if ( pos == NULL || scan == NULL ) { XLAL_ERROR ( XLAL_EINVAL ); } if ( scan->state == STATE_IDLE ) { XLALPrintError ("\nCalled XLALNextDopplerPos() on un-initialized DopplerFullScanState !\n\n"); XLAL_ERROR ( XLAL_EINVAL ); } /* is this search finished? then return '1' */ if ( scan->state == STATE_FINISHED ) return 1; // set refTime in returned template to the refTime of the grid pos->refTime = scan->spinRange.refTime; /* ----- step foward one template in full grid ----- */ /* Which "class" of template grid are we dealing with: factored, or full-multidim ? */ switch ( scan->gridType ) { /* emulate old 'factored' grids 'sky x f0dot x f1dot x f2dot x f3dot': */ case GRID_FLAT: case GRID_ISOTROPIC: case GRID_METRIC: case GRID_FILE_SKYGRID: case GRID_METRIC_SKYFILE: /* backwards-compatibility mode */ nextPointInFactoredGrid ( pos, scan ); break; case GRID_FILE_FULLGRID: XLAL_INIT_MEM(pos->fkdot); pos->fkdot[0] = scan->thisGridPoint->entry.data[0]; pos->Alpha = scan->thisGridPoint->entry.data[1]; pos->Delta = scan->thisGridPoint->entry.data[2]; pos->fkdot[1] = scan->thisGridPoint->entry.data[3]; pos->fkdot[2] = scan->thisGridPoint->entry.data[4]; pos->fkdot[3] = scan->thisGridPoint->entry.data[5]; pos->asini = 0; // isolated pulsar /* advance to next grid point */ if ( ( scan->thisGridPoint = scan->thisGridPoint->next ) == NULL ) scan->state = STATE_FINISHED; break; /* case GRID_METRIC_LATTICE: */ /* if ( XLALgetCurrentDopplerPos ( pos, scan->latticeScan, COORDINATESYSTEM_EQUATORIAL ) ) { */ /* XLAL_ERROR ( XLAL_EFUNC ); */ /* } */ /* /\* advance to next point *\/ */ /* ret = XLALadvanceLatticeIndex ( scan->latticeScan ); */ /* if ( ret < 0 ) { */ /* XLAL_ERROR ( XLAL_EFUNC ); */ /* } */ /* else if ( ret == 1 ) */ /* { */ /* XLALPrintError ( "\n\nXLALadvanceLatticeIndex(): this was the last lattice points!\n\n"); */ /* scan->state = STATE_FINISHED; */ /* } */ /* #if 0 */ /* { /\* debugging *\/ */ /* gsl_vector_int *lal_index = NULL; */ /* XLALgetCurrentLatticeIndex ( &lal)index, scan->latticeScan ); */ /* XLALfprintfGSLvector_int ( stderr, "%d", lal_index ); */ /* gsl_vector_int_free ( lal_index ); */ /* } */ /* #endif */ break; case GRID_SPINDOWN_SQUARE: /* square parameter space */ case GRID_SPINDOWN_AGEBRK: /* age-braking index parameter space */ { /* Advance to next tile */ int retn = XLALNextLatticeTilingPoint(scan->spindownTilingItr, scan->spindownTilingPoint); if (retn < 0) { XLALPrintError("\nGRID_SPINDOWN_{SQUARE,AGEBRK}: XLALNextLatticeTilingPoint() failed\n"); return -1; } if (retn > 0) { /* Found a point */ pos->Alpha = gsl_vector_get(scan->spindownTilingPoint, 0); pos->Delta = gsl_vector_get(scan->spindownTilingPoint, 1); pos->fkdot[0] = gsl_vector_get(scan->spindownTilingPoint, 2); for (size_t i = 1; i < PULSAR_MAX_SPINS; ++i) { pos->fkdot[i] = gsl_vector_get(scan->spindownTilingPoint, i + 2); } return 0; } else { /* No more points */ scan->state = STATE_FINISHED; return 1; } } break; default: XLALPrintError("\nInvalid grid type '%d'\n\n", scan->gridType ); xlalErrno = XLAL_EINVAL; return -1; break; } /* switch gridType */ return 0; } /* XLALNextDopplerPos() */