int main(int argc, char *argv[]) { FILE *fp = NULL; BarycenterInput XLAL_INIT_DECL(baryinput); INT4 leap0,leap; LIGOTimeGPS epoch; LIGOTimeGPS TstartSSB, TendSSB, TendGPS; INT4 n; LIGOTimeGPS *TSSB = NULL; MJDTime TstartUTCMJD; LIGOTimeGPS TDET; REAL8 temp; INT4 i; MJDTime tempTOA; REAL8 dt; LIGOTimeGPS TstartGPS; MJDTime *TOA = NULL; CHAR tempstr[18]; CHAR *tempstr2; CHAR TstartMJDstr[20],TfinishMJDstr[20],TOAstr[22]; PulsarSignalParams pulsarparams; CHAR parfile[256]; CHAR timfile[256]; CHAR detcode[16]; REAL8 TstartUTCMJDtest; REAL8 diff; MJDTime MJDdiff, MJDtest; MJDTime TrefTDBMJD; LIGOTimeGPS TrefSSB_TDB_GPS; // ---------------------------------------------------------------------- UserVariables_t XLAL_INIT_DECL(uvar); XLAL_CHECK ( initUserVars (argc, argv, &uvar) == XLAL_SUCCESS, XLAL_EFUNC ); if (uvar.help) { /* exit if help was required */ exit(0); } unsigned int seed = uvar.randSeed; if ( uvar.randSeed == 0 ) { seed = clock(); } srand ( seed ); // ----- sky position: random or user-specified ---------- REAL8 alpha, delta; CHAR *RAJ = NULL, *DECJ = NULL; BOOLEAN have_RAJ = XLALUserVarWasSet ( &uvar.RAJ ); BOOLEAN have_DECJ = XLALUserVarWasSet ( &uvar.DECJ ); if ( have_RAJ ) { XLAL_CHECK ( XLALTranslateHMStoRAD ( &alpha, uvar.RAJ ) == XLAL_SUCCESS, XLAL_EFUNC ); RAJ = XLALStringDuplicate ( uvar.RAJ ); } else { // pick randomly alpha = LAL_TWOPI * (1.0 * rand() / ( RAND_MAX + 1.0 ) ); // alpha uniform in [0, 2pi) XLAL_CHECK ( (RAJ = XLALTranslateRADtoHMS ( alpha )) != NULL, XLAL_EFUNC ); } if ( have_DECJ ) { XLAL_CHECK ( XLALTranslateDMStoRAD ( &delta, uvar.DECJ ) == XLAL_SUCCESS, XLAL_EFUNC ); DECJ = XLALStringDuplicate ( uvar.DECJ ); } else { // pick randomly delta = LAL_PI_2 - acos ( 1 - 2.0 * rand()/RAND_MAX ); // sin(delta) uniform in [-1,1] XLAL_CHECK ( (DECJ = XLALTranslateRADtoDMS ( delta )) != NULL, XLAL_EFUNC ); } /* define start time in an MJD structure */ REAL8toMJD ( &TstartUTCMJD, uvar.TstartUTCMJD ); XLALPrintInfo ( "TstartUTCMJD=%f converted to MJD days = %d fracdays = %6.12f\n", uvar.TstartUTCMJD, TstartUTCMJD.days, TstartUTCMJD.fracdays ); /* convert back to test conversions */ TstartUTCMJDtest = MJDtoREAL8 (TstartUTCMJD); diff = uvar.TstartUTCMJD - TstartUTCMJDtest; if ( fabs(diff) > 1e-9) { fprintf(stderr,"ERROR : Time conversion gives discrepancy of %e sec. Exiting.\n",diff); return(-1); } XLALPrintInfo ( "MJD conversion gives discrepancies of %e sec\n", diff); /* use start time to define an epoch for the leap seconds */ /* Note that epochs are defined in TDB !!! but here we only need to be rough to get a leap second value */ TDBMJDtoGPS(&epoch,TstartUTCMJD); XLALPrintInfo ( "leap second epoch = %d %d\n",epoch.gpsSeconds,epoch.gpsNanoSeconds); /* deal with ephemeris files and compute leap seconds */ EphemerisData *edat; XLAL_CHECK ( (edat = XLALInitBarycenter( uvar.ephemEarth, uvar.ephemSun )) != NULL, XLAL_EFUNC ); leap0 = XLALGPSLeapSeconds (epoch.gpsSeconds); XLALPrintInfo ( "leap seconds = %d\n",leap0); /* select detector location */ if (strcmp(uvar.Observatory,"GBT")==0) { baryinput.site.location[0] = GBT_LOCATION_X; baryinput.site.location[1] = GBT_LOCATION_Y; baryinput.site.location[2] = GBT_LOCATION_Z; sprintf(detcode,"gbt"); } else if (strcmp(uvar.Observatory,"NARRABRI")==0) { baryinput.site.location[0] = NARRABRI_LOCATION_X; baryinput.site.location[1] = NARRABRI_LOCATION_Y; baryinput.site.location[2] = NARRABRI_LOCATION_Z; sprintf(detcode,"atca"); } else if (strcmp(uvar.Observatory,"ARECIBO")==0) { baryinput.site.location[0] = ARECIBO_LOCATION_X; baryinput.site.location[1] = ARECIBO_LOCATION_Y; baryinput.site.location[2] = ARECIBO_LOCATION_Z; sprintf(detcode,"ao"); } else if (strcmp(uvar.Observatory,"NANSHAN")==0) { baryinput.site.location[0] = NANSHAN_LOCATION_X; baryinput.site.location[1] = NANSHAN_LOCATION_Y; baryinput.site.location[2] = NANSHAN_LOCATION_Z; sprintf(detcode,"nanshan"); } else if (strcmp(uvar.Observatory,"DSS_43")==0) { baryinput.site.location[0] = DSS_43_LOCATION_X; baryinput.site.location[1] = DSS_43_LOCATION_Y; baryinput.site.location[2] = DSS_43_LOCATION_Z; sprintf(detcode,"tid43"); } else if (strcmp(uvar.Observatory,"PARKES")==0) { baryinput.site.location[0] = PARKES_LOCATION_X; baryinput.site.location[1] = PARKES_LOCATION_Y; baryinput.site.location[2] = PARKES_LOCATION_Z; sprintf(detcode,"pks"); } else if (strcmp(uvar.Observatory,"JODRELL")==0) { baryinput.site.location[0] = JODRELL_LOCATION_X; baryinput.site.location[1] = JODRELL_LOCATION_Y; baryinput.site.location[2] = JODRELL_LOCATION_Z; sprintf(detcode,"jb"); } else if (strcmp(uvar.Observatory,"VLA")==0) { baryinput.site.location[0] = VLA_LOCATION_X; baryinput.site.location[1] = VLA_LOCATION_Y; baryinput.site.location[2] = VLA_LOCATION_Z; sprintf(detcode,"vla"); } else if (strcmp(uvar.Observatory,"NANCAY")==0) { baryinput.site.location[0] = NANCAY_LOCATION_X; baryinput.site.location[1] = NANCAY_LOCATION_Y; baryinput.site.location[2] = NANCAY_LOCATION_Z; sprintf(detcode,"ncy"); } else if (strcmp(uvar.Observatory,"EFFELSBERG")==0) { baryinput.site.location[0] = EFFELSBERG_LOCATION_X; baryinput.site.location[1] = EFFELSBERG_LOCATION_Y; baryinput.site.location[2] = EFFELSBERG_LOCATION_Z; sprintf(detcode,"eff"); } else if (strcmp(uvar.Observatory,"JODRELLM4")==0) { baryinput.site.location[0] = JODRELLM4_LOCATION_X; baryinput.site.location[1] = JODRELLM4_LOCATION_Y; baryinput.site.location[2] = JODRELLM4_LOCATION_Z; sprintf(detcode,"jbm4"); } else if (strcmp(uvar.Observatory,"GB300")==0) { baryinput.site.location[0] = GB300_LOCATION_X; baryinput.site.location[1] = GB300_LOCATION_Y; baryinput.site.location[2] = GB300_LOCATION_Z; sprintf(detcode,"gb300"); } else if (strcmp(uvar.Observatory,"GB140")==0) { baryinput.site.location[0] = GB140_LOCATION_X; baryinput.site.location[1] = GB140_LOCATION_Y; baryinput.site.location[2] = GB140_LOCATION_Z; sprintf(detcode,"gb140"); } else if (strcmp(uvar.Observatory,"GB853")==0) { baryinput.site.location[0] = GB853_LOCATION_X; baryinput.site.location[1] = GB853_LOCATION_Y; baryinput.site.location[2] = GB853_LOCATION_Z; sprintf(detcode,"gb853"); } else if (strcmp(uvar.Observatory,"LA_PALMA")==0) { baryinput.site.location[0] = LA_PALMA_LOCATION_X; baryinput.site.location[1] = LA_PALMA_LOCATION_Y; baryinput.site.location[2] = LA_PALMA_LOCATION_Z; sprintf(detcode,"lap"); } else if (strcmp(uvar.Observatory,"Hobart")==0) { baryinput.site.location[0] = Hobart_LOCATION_X; baryinput.site.location[1] = Hobart_LOCATION_Y; baryinput.site.location[2] = Hobart_LOCATION_Z; sprintf(detcode,"hob"); } else if (strcmp(uvar.Observatory,"Hartebeesthoek")==0) { baryinput.site.location[0] = Hartebeesthoek_LOCATION_X; baryinput.site.location[1] = Hartebeesthoek_LOCATION_Y; baryinput.site.location[2] = Hartebeesthoek_LOCATION_Z; sprintf(detcode,"hart"); } else if (strcmp(uvar.Observatory,"WSRT")==0) { baryinput.site.location[0] = WSRT_LOCATION_X; baryinput.site.location[1] = WSRT_LOCATION_Y; baryinput.site.location[2] = WSRT_LOCATION_Z; sprintf(detcode,"wsrt"); } else if (strcmp(uvar.Observatory,"COE")==0) { baryinput.site.location[0] = COE_LOCATION_X; baryinput.site.location[1] = COE_LOCATION_Y; baryinput.site.location[2] = COE_LOCATION_Z; sprintf(detcode,"coe"); } else if (strcmp(uvar.Observatory,"SSB")!=0) { fprintf(stderr,"ERROR. Unknown Observatory %s. Exiting.\n",uvar.Observatory); return(-1); } XLALPrintInfo ( "selected observatory %s - observatoryt code = %s\n",uvar.Observatory,detcode); XLALPrintInfo ( "baryinput location = %6.12f %6.12f %6.12f\n",baryinput.site.location[0],baryinput.site.location[1],baryinput.site.location[2]); /* convert start time to UTC GPS */ UTCMJDtoGPS(&TstartGPS, TstartUTCMJD, leap0); XLALPrintInfo ( "TstartGPS = %d %d\n",TstartGPS.gpsSeconds,TstartGPS.gpsNanoSeconds); /* convert back to test conversion */ UTCGPStoMJD(&MJDtest,&TstartGPS,leap0); deltaMJD ( &MJDdiff, &MJDtest, &TstartUTCMJD ); diff = (MJDdiff.days+MJDdiff.fracdays)*86400; if ( fabs(diff) > 1e-9) { fprintf(stderr,"ERROR : Time conversion gives discrepancy of %e sec. Exiting.\n",diff); return(-1); } XLALPrintInfo ( "MJD conversion gives discrepancies of %e sec\n",diff); /* define reference time in an MJD structure */ REAL8toMJD ( &TrefTDBMJD, uvar.TrefTDBMJD ); XLALPrintInfo ( "TrefTDBMJD converted to MJD days = %d fracdays = %6.12f\n",TrefTDBMJD.days,TrefTDBMJD.fracdays); /* convert reference time to TDB GPS */ TDBMJDtoGPS(&TrefSSB_TDB_GPS,TrefTDBMJD); XLALPrintInfo ( "TrefSSB_TDB_GPS = %d %d\n",TrefSSB_TDB_GPS.gpsSeconds,TrefSSB_TDB_GPS.gpsNanoSeconds); /* convert back to test conversion */ TDBGPStoMJD ( &MJDtest, TrefSSB_TDB_GPS, leap0 ); deltaMJD ( &MJDdiff, &MJDtest, &TrefTDBMJD ); diff = (MJDdiff.days+MJDdiff.fracdays)*86400; if ( fabs(diff) > 1e-9) { fprintf(stderr,"ERROR : Time conversion gives discrepancy of %e sec. Exiting.\n",diff); return(-1); } XLALPrintInfo ( "MJD conversion gives discrepancies of %e sec\n",diff); /* fill in required pulsar params structure for Barycentering */ LALDetector *site = NULL; site = (LALDetector *)LALMalloc(sizeof(LALDetector)); site->location[0] = baryinput.site.location[0]; site->location[1] = baryinput.site.location[1]; site->location[2] = baryinput.site.location[2]; pulsarparams.site = site; pulsarparams.pulsar.position.longitude = alpha; pulsarparams.pulsar.position.latitude = delta; pulsarparams.pulsar.position.system = COORDINATESYSTEM_EQUATORIAL; pulsarparams.ephemerides = edat; /* generate SSB initial TOA in GPS */ XLALConvertGPS2SSB ( &TstartSSB, TstartGPS, &pulsarparams); XLALPrintInfo ( "TstartSSB = %d %d\n",TstartSSB.gpsSeconds,TstartSSB.gpsNanoSeconds); /* define TOA end time in GPS */ temp = uvar.DurationMJD*86400.0; TendGPS = TstartGPS; XLALGPSAdd(&TendGPS, temp); XLALPrintInfo ( "GPS end time of TOAs = %d %d\n",TendGPS.gpsSeconds,TendGPS.gpsNanoSeconds); /* generate SSB end time in GPS (force integer seconds) */ XLALConvertGPS2SSB (&TendSSB,TendGPS,&pulsarparams); XLALPrintInfo ( "TendSSB = %d %d\n",TendSSB.gpsSeconds,TendSSB.gpsNanoSeconds); /* define TOA seperation in the SSB */ dt = uvar.DeltaTMJD*86400.0; n = (INT4)ceil(uvar.DurationMJD/uvar.DeltaTMJD); XLALPrintInfo ( "TOA seperation at SSB = %g sec\n",dt); XLALPrintInfo ( "number of TOAs to generate = %d\n",n); /* allocate memory for artificial SSB TOAs */ TSSB = (LIGOTimeGPS *)LALMalloc(n*sizeof(LIGOTimeGPS)); TOA = (MJDTime *)LALMalloc(n*sizeof(MJDTime)); /* generate artificial SSB TOAs given the phase model phi = 2*pi*(f0*(t-tref) + 0.5*fdot*(t-tref)^2) */ for (i=0;i<n;i++) { REAL8 dtref,fnow,cyclefrac,dtcor; LIGOTimeGPS tnow; /* define current interval */ XLALPrintInfo ( "current (t-tstart) = %g sec\n", i * dt); /* define current t */ tnow = TstartSSB; XLALGPSAdd(&tnow, i * dt); XLALPrintInfo ( "current t = %d %d\n",tnow.gpsSeconds,tnow.gpsNanoSeconds); /* define current t-tref */ dtref = XLALGPSDiff(&tnow,&TrefSSB_TDB_GPS); XLALPrintInfo ( "current (t - tref) = %9.12f\n",dtref); dtcor = 1; while (dtcor>1e-9) { /* define actual cycle fraction at requested time */ cyclefrac = fmod(uvar.f0*dtref + 0.5*uvar.fdot*dtref*dtref,1.0); XLALPrintInfo ( "cyclefrac = %9.12f\n",cyclefrac); /* define instantaneous frequency */ fnow = uvar.f0 + uvar.fdot*dtref; XLALPrintInfo ( "instananeous frequency = %9.12f\n",fnow); /* add correction to time */ dtcor = cyclefrac/fnow; dtref -= dtcor; XLALPrintInfo ( "timing correction = %9.12f\n",dtcor); XLALPrintInfo ( "corrected dtref to = %9.12f\n",dtref); } // while dtcor>1e-9 /* define time of zero phase */ TSSB[i] = TrefSSB_TDB_GPS; XLALGPSAdd(&TSSB[i], dtref); XLALPrintInfo ( "TSSB[%d] = %d %d\n",i,TSSB[i].gpsSeconds,TSSB[i].gpsNanoSeconds); } // for i < n /* loop over SSB time of arrivals and compute detector time of arrivals */ for (i=0;i<n;i++) { LIGOTimeGPS TSSBtest; LIGOTimeGPS GPStest; /* convert SSB to Detector time */ int ret = XLALConvertSSB2GPS ( &TDET, TSSB[i], &pulsarparams); if ( ret != XLAL_SUCCESS ) { XLALPrintError ("XLALConvertSSB2GPS() failed with xlalErrno = %d\n", xlalErrno ); return(-1); } XLALPrintInfo ( "converted SSB TOA %d %d -> Detector TOA %d %d\n",TSSB[i].gpsSeconds,TSSB[i].gpsNanoSeconds,TDET.gpsSeconds,TDET.gpsNanoSeconds); /* convert back for testing conversion */ XLALConvertGPS2SSB (&TSSBtest,TDET,&pulsarparams); diff = XLALGPSDiff(&TSSBtest,&TSSB[i]); if ( fabs(diff) > 1e-9) { fprintf(stderr,"ERROR : Time conversion gives discrepancy of %e sec. Exiting.\n",diff); return(-1); } XLALPrintInfo ( "SSB -> detector conversion gives discrepancies of %e sec\n",diff); /* recompute leap seconds incase they've changed */ leap = XLALGPSLeapSeconds (TDET.gpsSeconds); /* must now convert to an MJD time for TEMPO */ /* Using UTC conversion as used by Matt in his successful comparison */ UTCGPStoMJD (&tempTOA,&TDET,leap); XLALPrintInfo ( "output MJD time = %d %6.12f\n",tempTOA.days,tempTOA.fracdays); /* convert back to test conversion */ UTCMJDtoGPS ( &GPStest, tempTOA, leap ); diff = XLALGPSDiff(&TDET,&GPStest); if ( fabs(diff) > 1e-9) { fprintf(stderr,"ERROR. Time conversion gives discrepancy of %e sec. Exiting.\n",diff); return(-1); } XLALPrintInfo ( "MJD time conversion gives discrepancies of %e sec\n",diff); /* fill in results */ TOA[i].days = tempTOA.days; TOA[i].fracdays = tempTOA.fracdays; } // for i < n snprintf(tempstr,15,"%1.13f",TOA[0].fracdays); tempstr2 = tempstr+2; snprintf(TstartMJDstr,19,"%d.%s",TOA[0].days,tempstr2); XLALPrintInfo ( "Converted initial TOA MJD %d %6.12f to the string %s\n",TOA[0].days,TOA[0].fracdays,TstartMJDstr); snprintf(tempstr,15,"%1.13f",TOA[n-1].fracdays); tempstr2 = tempstr+2; snprintf(TfinishMJDstr,19,"%d.%s",TOA[n-1].days,tempstr2); XLALPrintInfo ( "*** Converted MJD to a string %s\n",TfinishMJDstr); XLALPrintInfo ( "Converted final TOA MJD %d %6.12f to the string %s\n",TOA[n-1].days,TOA[n-1].fracdays,TfinishMJDstr); /* define output file names */ sprintf(parfile,"%s.par",uvar.PSRJ); sprintf(timfile,"%s.tim",uvar.PSRJ); /* output to par file in format required by TEMPO 2 */ if ((fp = fopen(parfile,"w")) == NULL) { fprintf(stderr,"ERROR. Could not open file %s. Exiting.\n",parfile); return(-1); } fprintf(fp,"PSRJ\t%s\n",uvar.PSRJ); fprintf(fp,"RAJ\t%s\t1\n",RAJ); fprintf(fp,"DECJ\t%s\t1\n",DECJ); fprintf(fp,"PEPOCH\t%6.12f\n",uvar.TrefTDBMJD); fprintf(fp,"POSEPOCH\t%6.12f\n",uvar.TrefTDBMJD); fprintf(fp,"DMEPOCH\t%6.12f\n",uvar.TrefTDBMJD); fprintf(fp,"DM\t0.0\n"); fprintf(fp,"F0\t%6.16f\t1\n",uvar.f0); fprintf(fp,"F1\t%6.16f\t0\n",uvar.fdot); fprintf(fp,"START\t%s\n",TstartMJDstr); fprintf(fp,"FINISH\t%s\n",TfinishMJDstr); fprintf(fp,"TZRSITE\t%s\n",detcode); fprintf(fp,"CLK\tUTC(NIST)\n"); fprintf(fp,"EPHEM\tDE405\n"); fprintf(fp,"UNITS\tTDB\n"); fprintf(fp,"MODE\t0\n"); /* close par file */ fclose(fp); /* output to tim file in format required by TEMPO 2 */ if ((fp = fopen(timfile,"w")) == NULL) { fprintf(stderr,"ERROR. Could not open file %s. Exiting.\n",timfile); return(-1); } fprintf(fp,"FORMAT 1\n"); for (i=0;i<n;i++) { /* convert each TOA to a string for output */ snprintf(tempstr,18,"%1.16f",TOA[i].fracdays); tempstr2 = tempstr+2; snprintf(TOAstr,22,"%d.%s",TOA[i].days,tempstr2); fprintf(fp,"blank.dat\t1000.0\t%s\t1.0\t%s\n",TOAstr,detcode); XLALPrintInfo ( "Converting MJD time %d %6.16f to string %s\n",TOA[i].days,TOA[i].fracdays,TOAstr); } // for i < n /* close tim file */ fclose(fp); /* free memory */ XLALFree ( TSSB ); XLALFree ( TOA ); XLALFree ( site ); XLALDestroyEphemerisData ( edat ); XLALDestroyUserVars (); LALCheckMemoryLeaks(); return XLAL_SUCCESS; } /* main() */
/** * @brief Seeks a LALFrStream stream to data at a given time * @details * The position of a LALFrStream is set so that the net read will * be at the specified time. #LAL_FR_STREAM_END and #LAL_FR_STREAM_GAP * bits are turned off in the #LALFrStreamState state. If the time is before * the beginning of the stream, the stream position is set to the beginning of * the stream and the routine returns with code 1. If the time is after the * end of the stream, the #LAL_FR_STREAM_END bit is set in the * #LALFrStreamState state, and the routine returns with code 2. If the time * is in a gap in the data, the #LAL_FR_STREAM_GAP bit is set in the * #LALFrStreamState state, the position is advanced to the next data, and the * routine returns with code 3. If, however, the * #LAL_FR_STREAM_IGNORETIME_MODE bit is not set in the LALFrStreamMode mode * then these conditions result in an error. * @param stream Pointer to a #LALFrStream structure. * @param epoch The LIGOTimeGPS time of the next data to read. * @retval 3 Time requested is in a gap in the data. * @retval 2 Time requested is after the end of the stream. * @retval 1 Time requested is before the beginning of the stream. * @retval 0 Normal success. * @retval <0 Failure. */ int XLALFrStreamSeek(LALFrStream * stream, const LIGOTimeGPS * epoch) { double twant = XLALGPSGetREAL8(epoch); LALCacheEntry *entry; /* close file if one is open */ XLALFrStreamFileClose(stream); /* clear EOF or GAP states; preserve ERR state */ if (stream->state & LAL_FR_STREAM_ERR) stream->state = LAL_FR_STREAM_ERR; else stream->state = LAL_FR_STREAM_OK; /* is epoch before first file? */ if (epoch->gpsSeconds < stream->cache->list->t0) { XLALFrStreamRewind(stream); stream->state |= LAL_FR_STREAM_GAP; /* is this reported as an error? */ if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) { /* FIXME: if this is an error, should the stream state say so? */ /* stream->state |= LAL_FR_STREAM_ERR; */ XLAL_ERROR(XLAL_ETIME); } if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE) XLAL_PRINT_WARNING("Requested time %d before first frame", epoch->gpsSeconds); return 1; /* before first file code */ } /* seek for the time in the cache */ entry = XLALCacheEntrySeek(stream->cache, twant); if (!entry) { /* seek failed: only happens if time is past end of cache */ stream->fnum = stream->cache->length; stream->epoch = *epoch; stream->state |= LAL_FR_STREAM_END; /* is this reported as an error? */ if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) { /* FIXME: if this is an error, should the stream state say so? */ /* stream->state |= LAL_FR_STREAM_ERR; */ XLAL_ERROR(XLAL_ETIME); } if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE) XLAL_PRINT_WARNING("Requested time %d after last frame", epoch->gpsSeconds); return 2; /* after last file code */ } /* now we must find the position within the frame file */ for (stream->fnum = entry - stream->cache->list; stream->fnum < stream->cache->length; ++stream->fnum) { /* check the file contents to determine the position that matches */ size_t nFrame; if (XLALFrStreamFileOpen(stream, stream->fnum) < 0) XLAL_ERROR(XLAL_EFUNC); if (epoch->gpsSeconds < stream->cache->list[stream->fnum].t0) { /* detect a gap between files */ stream->state |= LAL_FR_STREAM_GAP; break; } nFrame = XLALFrFileQueryNFrame(stream->file); for (stream->pos = 0; stream->pos < (int)nFrame; ++stream->pos) { LIGOTimeGPS start; int cmp; XLALFrFileQueryGTime(&start, stream->file, stream->pos); cmp = XLALGPSCmp(epoch, &start); if (cmp >= 0 && XLALGPSDiff(epoch, &start) < XLALFrFileQueryDt(stream->file, stream->pos)) break; /* this is the frame! */ if (cmp < 0) { /* detect a gap between frames within a file */ stream->state |= LAL_FR_STREAM_GAP; break; } } if (stream->pos < (int)nFrame) /* we've found the frame */ break; /* oops... not in this frame file, go on to the next one */ /* probably the frame file was mis-named.... */ XLALFrStreamFileClose(stream); } if (stream->fnum >= stream->cache->length) { /* we've gone right to the end without finding it! */ stream->fnum = stream->cache->length; stream->epoch = *epoch; stream->state |= LAL_FR_STREAM_END; /* is this reported as an error? */ if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) { /* FIXME: if this is an error, should the stream state say so? */ /* stream->state |= LAL_FR_STREAM_ERR; */ XLAL_ERROR(XLAL_ETIME); } if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE) XLAL_PRINT_WARNING("Requested time %d after last frame", epoch->gpsSeconds); return 2; /* after last file code */ } /* set the time of the stream */ if (stream->state & LAL_FR_STREAM_GAP) { XLALFrFileQueryGTime(&stream->epoch, stream->file, stream->pos); if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE) XLAL_PRINT_WARNING("Requested time %.6f in gap in frame data", twant); if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) XLAL_ERROR(XLAL_ETIME); return 3; /* in a gap code */ } stream->epoch = *epoch; return 0; }
/** The main function of Intermittent.c * */ int main( int argc, char *argv[] ) { UserInput_t uvar = empty_UserInput; /* user input variables */ INT4 i,k,m; /* counter */ CHAR newtemp[LONGSTRINGLENGTH]; FILE *ifp = NULL; CHAR *clargs = NULL; /* store the command line args */ /**********************************************************************************/ /* register and read all user-variables */ if (XLALReadUserVars(argc,argv,&uvar)) { LogPrintf(LOG_CRITICAL,"%s : XLALReadUserVars() failed with error = %d\n",__func__,xlalErrno); return 1; } if (uvar.verbose) fprintf(stdout,"%s : read in uservars\n",__func__); /**********************************************************************************/ /* make temporary directory */ if (uvar.tempdir) { /* initialise the random number generator - use the clock */ gsl_rng * q; if (XLALInitgslrand(&q,0)) { LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_EFAULT); } INT4 id = (INT4)(1e9*gsl_rng_uniform(q)); sprintf(newtemp,"%s/%09d",uvar.tempdir,id); fprintf(stdout,"temp dir = %s\n",newtemp); if (mkdir(newtemp,0755)) { if (uvar.verbose) fprintf(stdout,"%s : Unable to make temporary directory %s. Might be a problem.\n",__func__,newtemp); return 1; } } /**********************************************************************************/ /* read in the cache file and find the correct entry for the binary file */ FILE *cachefp = NULL; if ((cachefp = fopen(uvar.cachefile,"r")) == NULL) { LogPrintf(LOG_CRITICAL,"%s : failed to open binary input file %s\n",__func__,uvar.cachefile); return 1; } i = 0; INT4 idx = -1; CHAR filename[LONGSTRINGLENGTH]; CHAR dummy[LONGSTRINGLENGTH]; LIGOTimeGPS fileStart; INT4 dummysec = 0; INT4 dummynan = 0; while (fscanf(cachefp,"%s %d %d",dummy,&dummysec,&dummynan)!=EOF) { if (strstr(dummy,uvar.binfile)) { idx = i; strcpy(filename,dummy); fileStart.gpsSeconds = dummysec; fileStart.gpsNanoSeconds = (INT4)1e9*(floor(1e-9*dummynan/uvar.tsamp + 0.5)*uvar.tsamp); /* round to make sure we get samples at GPS seconds */ } i++; } if (idx < 0) { LogPrintf(LOG_CRITICAL,"%s : failed to find binary input file %s in cache file %s\n",__func__,filename,uvar.cachefile); return 1; } fclose(cachefp); if (uvar.verbose) fprintf(stdout,"%s : found the requested binary file entry in the cache file.\n",__func__); /***********************************************************************************/ /* setup the fixed binaryToSFT parameters */ BinaryToSFTparams par; par.tsamp = uvar.tsamp; par.highpassf = uvar.highpassf; par.amp_inj = 0.0; par.f_inj = 0.0; par.asini_inj = 0.0; XLALGPSSetREAL8(&(par.tasc_inj),0); par.tref = fileStart; par.P_inj = 0; par.phi_inj = 0; par.r = NULL; /* setup the gridding over coherent times - which we make sure are integers */ INT4 dummyT = uvar.Tmin; INT4 NT = 0; while (dummyT<uvar.Tmax) { dummyT = (INT4)((REAL8)dummyT*(1.0 + uvar.mismatch)); NT++; } if (uvar.verbose) fprintf(stdout,"%s : Going to do %d different coherent lengths.\n",__func__,NT); /**********************************************************************************/ /* OPEN INTERMEDIATE RESULTS FILE */ /**********************************************************************************/ CHAR intname[LONGSTRINGLENGTH]; if (XLALOpenIntermittentResultsFile(&ifp,intname,newtemp,clargs,&uvar,&fileStart)) { LogPrintf(LOG_CRITICAL,"%s : XLALOpenCoherentResultsFile() failed with error = %d\n",__func__,xlalErrno); return 1; } if (uvar.verbose) fprintf(stdout,"%s : opened coherent results file %s.\n",__func__,intname); /**********************************************************************************/ /* loop over the different coherent lengths */ INT4 currentT = uvar.Tmin; for (i=0;i<NT;i++) { if (uvar.verbose) fprintf(stdout,"%s : working on segment length %d/%d using a segment time of %d sec\n",__func__,i,NT,currentT); /* define SFT frequency bounds */ REAL8 wings = LAL_TWOPI*uvar.maxasini/uvar.minorbperiod; REAL8 fmin_read = MINBAND*floor((uvar.freq - WINGS_FACTOR*uvar.freq*wings - (REAL8)uvar.blocksize/(REAL8)uvar.Tmin)/MINBAND); REAL8 fmax_read = MINBAND*ceil((uvar.freq + (REAL8)uvar.blocksize/(REAL8)uvar.Tmin + uvar.freqband + WINGS_FACTOR*(uvar.freq + uvar.freqband)*wings)/MINBAND); REAL8 fband_read = fmax_read - fmin_read; if (uvar.verbose) fprintf(stdout,"%s : reading in SFT frequency band [%f -> %f]\n",__func__,fmin_read,fmax_read); /* define the number of different start times */ INT4 Ns = ceil(1.0/uvar.mismatch); INT4 Tstep = (INT4)floor(currentT/(REAL8)Ns); if (Tstep == 0) Ns = 1; else Ns = (INT4)ceil((REAL8)currentT/(REAL8)Tstep); if (uvar.verbose) fprintf(stdout,"%s : number of start times is %d and time step is %d sec\n",__func__,Ns,Tstep); par.tsft = currentT; par.freq = fmin_read; par.freqband = fband_read; /* loop over different start times - make sure they are integer GPS time for simplicity */ LIGOTimeGPS currentStart; currentStart.gpsSeconds = (INT4)ceil((REAL8)fileStart.gpsSeconds + 1e-9*(REAL8)fileStart.gpsNanoSeconds); currentStart.gpsNanoSeconds = 0; for (k=0;k<Ns;k++) { if (uvar.verbose) fprintf(stdout,"%s : working on offset start %d/%d using a start time of %d %d sec\n",__func__,k,Ns,currentStart.gpsSeconds,currentStart.gpsNanoSeconds); memcpy(&(par.tstart),¤tStart,sizeof(LIGOTimeGPS)); ParameterSpace pspace = empty_ParameterSpace; /* the search parameter space */ COMPLEX8TimeSeriesArray *dstimevec = NULL; /* contains the downsampled inverse FFT'd SFTs */ REAL4DemodulatedPowerVector *dmpower = NULL; /* contains the demodulated power for all SFTs */ GridParametersVector *freqgridparams = NULL; /* the coherent grid on the frequency derivitive parameter space */ SFTVector *sftvec = NULL; INT8Vector *np = NULL; REAL8Vector *R = NULL; /**********************************************************************************/ /* GENERATE SFTS FROM BINARY INPUT FILE */ /**********************************************************************************/ /* converts a binary input file into sfts */ if (XLALBinaryToSFTVector(&sftvec,filename,&fileStart,&par,&np,&R)) { LogPrintf(LOG_CRITICAL,"%s : failed to convert binary input file %s to sfts\n",__func__,uvar.binfile); return 1; } XLALDestroyINT8Vector(np); XLALDestroyREAL8Vector(R); if (uvar.verbose) fprintf(stdout,"%s : generated SFTs for file %s\n",__func__,filename); /* if we have any SFTs */ if (sftvec->length>0) { /* define SFT length and the start and span of the observations plus the definitive segment time */ pspace.tseg = 1.0/sftvec->data[0].deltaF; memcpy(&(pspace.epoch),&(sftvec->data[0].epoch),sizeof(LIGOTimeGPS)); pspace.span = XLALGPSDiff(&(sftvec->data[sftvec->length-1].epoch),&(sftvec->data[0].epoch)) + pspace.tseg; if (uvar.verbose) { fprintf(stdout,"%s : SFT length = %f seconds\n",__func__,pspace.tseg); fprintf(stdout,"%s : entire dataset starts at GPS time %d contains %d SFTS and spans %.0f seconds\n",__func__,pspace.epoch.gpsSeconds,sftvec->length,pspace.span); } /**********************************************************************************/ /* NORMALISE THE SFTS */ /**********************************************************************************/ /* compute the background noise using the sfts - this routine uses the running median at the edges to normalise the wings */ if (XLALNormalizeSFTVect(sftvec,uvar.blocksize, 0)) { LogPrintf(LOG_CRITICAL,"%s : XLALNormaliseSFTVect() failed with error = %d\n",__func__,xlalErrno); return 1; } if (uvar.verbose) fprintf(stdout,"%s : normalised the SFTs\n",__func__); /**********************************************************************************/ /* DEFINE THE BINARY PARAMETER SPACE */ /**********************************************************************************/ /* define the binary parameter space */ if (XLALDefineBinaryParameterSpace(&(pspace.space),pspace.epoch,pspace.span,&uvar)) { LogPrintf(LOG_CRITICAL,"%s : XLALDefineBinaryParameterSpace() failed with error = %d\n",__func__,xlalErrno); return 1; } if (uvar.verbose) fprintf(stdout,"%s : defined binary parameter prior space\n",__func__); /**********************************************************************************/ /* COMPUTE THE COARSE GRID ON FREQUENCY DERIVITIVES */ /**********************************************************************************/ /* compute the grid parameters for all SFTs */ if (XLALComputeFreqGridParamsVector(&freqgridparams,pspace.space,sftvec,uvar.mismatch)) { LogPrintf(LOG_CRITICAL,"%s : XLALComputeFreqGridParams() failed with error = %d\n",__func__,xlalErrno); return 1; } if (uvar.verbose) fprintf(stdout,"%s : computed the grid parameters for the sfts\n",__func__); /**********************************************************************************/ /* CONVERT ALL SFTS TO DOWNSAMPLED TIMESERIES */ /**********************************************************************************/ if (XLALSFTVectorToCOMPLEX8TimeSeriesArray(&dstimevec,sftvec)) { LogPrintf(LOG_CRITICAL,"%s : XLALSFTVectorToCOMPLEX8TimeSeriesArray() failed with error = %d\n",__func__,xlalErrno); return 1; } if (uvar.verbose) fprintf(stdout,"%s : converted SFTs to downsampled timeseries\n",__func__); /**********************************************************************************/ /* COMPUTE THE STATISTICS ON THE COARSE GRID */ /**********************************************************************************/ /* compute the demodulated power on the frequency derivitive grid */ if (XLALCOMPLEX8TimeSeriesArrayToDemodPowerVector(&dmpower,dstimevec,freqgridparams,ifp)) { LogPrintf(LOG_CRITICAL,"%s : XLALCOMPLEX8TimeSeriesArrayToDemodPowerVector() failed with error = %d\n",__func__,xlalErrno); return 1; } if (uvar.verbose) fprintf(stdout,"%s : computed the demodulated power\n",__func__); /**********************************************************************************/ /* FREE MEMORY */ /**********************************************************************************/ /* free memory inside the loop */ XLALFreeParameterSpace(&pspace); XLALFreeREAL4DemodulatedPowerVector(dmpower); for (m=0;m<(INT4)dstimevec->length;m++) { XLALDestroyCOMPLEX8TimeSeries(dstimevec->data[m]); } XLALFree(dstimevec->data); XLALFree(dstimevec); for (m=0;m<(INT4)freqgridparams->length;m++) { XLALFree(freqgridparams->segment[m]->grid); XLALFree(freqgridparams->segment[m]->prod); XLALFree(freqgridparams->segment[m]); } XLALFree(freqgridparams->segment); XLALFree(freqgridparams); if (uvar.verbose) fprintf(stdout,"%s : freed memory\n",__func__); XLALDestroySFTVector(sftvec); } /* end if statement on whether we have SFTs */ /* update the start time of the segment */ XLALGPSAdd(¤tStart,(REAL8)Tstep); } /* end loop over start times */ /* update segment length */ currentT = (INT4)((REAL8)currentT*(1.0 + uvar.mismatch)); } /* end loop over segment lengths */ /* move the temporary directory to the final location */ if (uvar.tempdir) { CHAR newoutputfile[LONGSTRINGLENGTH]; snprintf(newoutputfile,LONGSTRINGLENGTH,"%s/IntermittentResults-%s-%d.txt",uvar.outputdir,uvar.outLabel,fileStart.gpsSeconds); if (rename(intname,newoutputfile)) { LogPrintf(LOG_CRITICAL,"%s : unable to move final results file %s -> %s. Exiting.\n",__func__,intname,newoutputfile); return 1; } } /**********************************************************************************/ /* FREE MEMORY */ /**********************************************************************************/ fclose(ifp); LALCheckMemoryLeaks(); return 0; }
/** * Simulate a pulsar signal to best accuracy possible. * \author Reinhard Prix * \date 2005 * * The motivation for this function is to provide functions to * simulate pulsar signals <em>with the best possible accuracy</em>, * i.e. using no approximations, contrary to LALGeneratePulsarSignal(). * * Obviously this is not meant as a fast code to be used in a Monte-Carlo * simulation, but rather as a <em>reference</em> to compare other (faster) * functions agains, in order to be able to gauge the quality of a given * signal-generation routine. * * We want to calculate \f$h(t)\f$, given by * \f[ * h(t) = F_+(t)\, h_+(t) + F_\times(t) \,h_\times(t)\,, * \f] * where \f$F_+\f$ and \f$F_x\f$ are called the <em>beam-pattern</em> functions, * which depend of the wave polarization \f$\psi\f$, * the source position \f$\alpha\f$, \f$\delta\f$ and the detector position and * orientation (\f$\gamma\f$, \f$\lambda\f$, \f$L\f$ and \f$\xi\f$). The expressions for * the beam-pattern functions are given in \cite JKS98 , which we write as * \f{eqnarray}{ * F_+(t) = \sin \zeta \cos 2\psi \, a(t) + \sin \zeta \sin 2\psi \, b(t)\,,\\ * F_\times(t) = \sin\zeta \cos 2\psi \,b(t) - \sin\zeta \sin 2\psi \, a(t) \,, * \f} * where \f$\zeta\f$ is the angle between the interferometer arms, and * \f{eqnarray}{ * a(t) &=& a_1 \cos[ 2 (\alpha - T)) ] + a_2 \sin[ 2(\alpha - T)] * + a_3 \cos[ \alpha - T ] + a_4 \sin [ \alpha - T ] + a_5\,,\\ * b(t) &=& b_1 \cos[ 2(\alpha - T)] + b_2 \sin[ 2(\alpha - T) ] * + b_3 \cos[ \alpha - T ] + b_4 \sin[ \alpha - T]\,, * \f} * where \f$T\f$ is the local (mean) sidereal time of the detector, and the * time-independent coefficients \f$a_i\f$ and \f$b_i\f$ are given by * \f{eqnarray}{ * a_1 &=& \frac{1}{16} \sin 2\gamma \,(3- \cos 2\lambda)\,(3 - \cos 2\delta)\,,\\ * a_2 &=& -\frac{1}{4}\cos 2\gamma \,\sin \lambda \,(3 - \cos 2\delta) \,,\\ * a_3 &=& \frac{1}{4} \sin 2\gamma \,\sin 2\lambda \,\sin 2\delta \,\\ * a_4 &=& -\frac{1}{2} \cos 2\gamma \,\cos \lambda \,\sin 2 \delta\,,\\ * a_5 &=& \frac{3}{4} \sin 2\gamma \, \cos^2 \lambda \,\cos^2 \delta\,, * \f} * and * \f{eqnarray}{ * b_1 &=& \cos 2\gamma \,\sin \lambda \,\sin \delta\,,\\ * b_2 &=& \frac{1}{4} \sin 2\gamma \,(3-\cos 2\lambda)\, \sin \delta\,,\\ * b_3 &=& \cos 2\gamma \,\cos \lambda \,\cos\delta \,, \\ * b_4 &=& \frac{1}{2} \sin2\gamma \,\sin 2\lambda \,\cos\delta\,, * \f} * * The source model considered is a plane-wave * \f{eqnarray}{ * h_+(t) &=& A_+\, \cos \Psi(t)\,,\\ * h_\times(t) &=& A_\times \, \sin \Psi(t)\,, * \f} * where the wave-phase is \f$\Psi(t) = \Phi_0 + \Phi(t)\f$, and for an * isolated pulsar we have * \f{equation}{ * \Phi(t) = 2\pi \left[\sum_{s=0} \frac{f^{(s)}(\tau_\mathrm{ref})}{ * (s+1)!} \left( \tau(t) - \tau_\mathrm{ref} \right)^{s+1} \right]\,, * \f} * where \f$\tau_\mathrm{ref}\f$ is the "reference time" for the definition * of the pulsar-parameters \f$f^{(s)}\f$ in the solar-system barycenter * (SSB), and \f$\tau(t)\f$ is the SSB-time of the phase arriving at the * detector at UTC-time \f$t\f$, which depends on the source-position * (\f$\alpha\f$, \f$\delta\f$) and the detector-position, namely * \f{equation}{ * \tau (t) = t + \frac{ \vec{r}(t)\cdot\vec{n}}{c}\,, * \f} * where \f$\vec{r}(t)\f$ is the vector from SSB to the detector, and \f$\vec{n}\f$ * is the unit-vector pointing <em>to</em> the source. * * This is a standalone "clean-room" implementation using no other * outside-functions <em>except</em> for LALGPStoLMST1() to calculate * the local (mean) sidereal time at the detector for given GPS-time, * (which I double-checked with an independent Mathematica script), * and and XLALBarycenter() to calculate \f$\tau(t)\f$. * * NOTE: currently only isolated pulsars are supported * * NOTE2: we don't really use the highest possible accuracy right now, * as we blatently neglect all relativistic timing effects (i.e. using dT=v.n/c) * * NOTE3: no heterodyning is performed here, the time-series is generated and sampled * at the given rate, that's all! ==\> the caller needs to make sure about the * right sampling rate to use (-\>aliasing) and do the proper post-treatment... * */ REAL4TimeSeries * XLALSimulateExactPulsarSignal ( const PulsarSignalParams *params ) { XLAL_CHECK_NULL ( params != NULL, XLAL_EINVAL, "Invalid NULL input 'params'\n"); XLAL_CHECK_NULL ( params->samplingRate > 0, XLAL_EDOM, "Sampling rate must be positive, got samplingRate = %g\n", params->samplingRate ); /* don't accept heterodyning frequency */ XLAL_CHECK_NULL ( params->fHeterodyne == 0, XLAL_EINVAL, "Heterodyning frequency must be set to 0, got params->fHeterodyne = %g\n", params->fHeterodyne ); UINT4 numSpins = 3; /* get timestamps of timeseries plus detector-states */ REAL8 dt = 1.0 / params->samplingRate; LIGOTimeGPSVector *timestamps; XLAL_CHECK_NULL ( (timestamps = XLALMakeTimestamps ( params->startTimeGPS, params->duration, dt, 0 )) != NULL, XLAL_EFUNC ); UINT4 numSteps = timestamps->length; DetectorStateSeries *detStates = XLALGetDetectorStates ( timestamps, params->site, params->ephemerides, 0 ); XLAL_CHECK_NULL ( detStates != NULL, XLAL_EFUNC, "XLALGetDetectorStates() failed.\n"); XLALDestroyTimestampVector ( timestamps ); timestamps = NULL; AMCoeffs *amcoe = XLALComputeAMCoeffs ( detStates, params->pulsar.position ); XLAL_CHECK_NULL ( amcoe != NULL, XLAL_EFUNC, "XLALComputeAMCoeffs() failed.\n"); /* create output timeseries (FIXME: should really know *detector* here, not just site!!) */ const LALFrDetector *site = &(params->site->frDetector); CHAR *channel = XLALGetChannelPrefix ( site->name ); XLAL_CHECK_NULL ( channel != NULL, XLAL_EFUNC, "XLALGetChannelPrefix( %s ) failed.\n", site->name ); REAL4TimeSeries *ts = XLALCreateREAL4TimeSeries ( channel, &(detStates->data[0].tGPS), 0, dt, &emptyUnit, numSteps ); XLAL_CHECK_NULL ( ts != NULL, XLAL_EFUNC, "XLALCreateREAL4TimeSeries() failed.\n"); XLALFree ( channel ); channel = NULL; /* orientation of detector arms */ REAL8 xAzi = site->xArmAzimuthRadians; REAL8 yAzi = site->yArmAzimuthRadians; REAL8 Zeta = xAzi - yAzi; if (Zeta < 0) { Zeta = -Zeta; } if ( params->site->type == LALDETECTORTYPE_CYLBAR ) { Zeta = LAL_PI_2; } REAL8 sinZeta = sin(Zeta); /* get source skyposition */ REAL8 Alpha = params->pulsar.position.longitude; REAL8 Delta = params->pulsar.position.latitude; REAL8 vn[3]; vn[0] = cos(Delta) * cos(Alpha); vn[1] = cos(Delta) * sin(Alpha); vn[2] = sin(Delta); /* get spin-parameters (restricted to maximally 3 spindowns right now) */ REAL8 phi0 = params->pulsar.phi0; REAL8 f0 = params->pulsar.f0; REAL8 f1dot = 0, f2dot = 0, f3dot = 0; if ( params->pulsar.spindown && (params->pulsar.spindown->length > numSpins) ) { XLAL_ERROR_NULL ( XLAL_EDOM, "Currently only supports up to %d spindowns!\n", numSpins ); } if ( params->pulsar.spindown && (params->pulsar.spindown->length >= 3 ) ) { f3dot = params->pulsar.spindown->data[2]; } if ( params->pulsar.spindown && (params->pulsar.spindown->length >= 2 ) ) { f2dot = params->pulsar.spindown->data[1]; } if ( params->pulsar.spindown && (params->pulsar.spindown->length >= 1 ) ) { f1dot = params->pulsar.spindown->data[0]; } /* internally we always work with refTime = startTime->SSB, therefore * we need to translate the pulsar spin-params and initial phase to the * startTime */ REAL8 startTimeSSB = XLALGPSGetREAL8 ( &(detStates->data[0].tGPS) ) + SCALAR ( vn, detStates->data[0].rDetector ); REAL8 refTime; if ( params->pulsar.refTime.gpsSeconds != 0 ) { REAL8 refTime0 = XLALGPSGetREAL8 ( &(params->pulsar.refTime) ); REAL8 deltaRef = startTimeSSB - refTime0; LIGOTimeGPS newEpoch; PulsarSpins fkdotNew; XLALGPSSetREAL8( &newEpoch, startTimeSSB ); PulsarSpins XLAL_INIT_DECL(fkdotOld); fkdotOld[0] = f0; fkdotOld[1] = f1dot; fkdotOld[2] = f2dot; fkdotOld[3] = f3dot; REAL8 DeltaTau = XLALGPSDiff ( &newEpoch, &(params->pulsar.refTime) ); int ret = XLALExtrapolatePulsarSpins ( fkdotNew, fkdotOld, DeltaTau ); XLAL_CHECK_NULL ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALExtrapolatePulsarSpins() failed.\n"); /* Finally, need to propagate phase */ phi0 += LAL_TWOPI * ( f0 * deltaRef + (1.0/2.0) * f1dot * deltaRef * deltaRef + (1.0/6.0) * f2dot * deltaRef * deltaRef * deltaRef + (1.0/24.0)* f3dot * deltaRef * deltaRef * deltaRef * deltaRef ); f0 = fkdotNew[0]; f1dot = fkdotNew[1]; f2dot = fkdotNew[2]; f3dot = fkdotNew[3]; refTime = startTimeSSB; } /* if refTime given */ else { /* if not given: use startTime -> SSB */ refTime = startTimeSSB; } /* get 4 amplitudes A_\mu */ REAL8 aPlus = sinZeta * params->pulsar.aPlus; REAL8 aCross = sinZeta * params->pulsar.aCross; REAL8 twopsi = 2.0 * params->pulsar.psi; REAL8 A1 = aPlus * cos(phi0) * cos(twopsi) - aCross * sin(phi0) * sin(twopsi); REAL8 A2 = aPlus * cos(phi0) * sin(twopsi) + aCross * sin(phi0) * cos(twopsi); REAL8 A3 = -aPlus * sin(phi0) * cos(twopsi) - aCross * cos(phi0) * sin(twopsi); REAL8 A4 = -aPlus * sin(phi0) * sin(twopsi) + aCross * cos(phi0) * cos(twopsi); /* main loop: generate time-series */ for ( UINT4 i = 0; i < numSteps; i++) { LIGOTimeGPS *tiGPS = &(detStates->data[i].tGPS); REAL8 ti = XLALGPSGetREAL8 ( tiGPS ); REAL8 deltati = ti - refTime; REAL8 dT = SCALAR(vn, detStates->data[i].rDetector ); REAL8 taui = deltati + dT; REAL8 phi_i = LAL_TWOPI * ( f0 * taui + (1.0/2.0) * f1dot * taui*taui + (1.0/6.0) * f2dot * taui*taui*taui + (1.0/24.0)* f3dot * taui*taui*taui*taui ); REAL8 cosphi_i = cos(phi_i); REAL8 sinphi_i = sin(phi_i); REAL8 ai = amcoe->a->data[i]; REAL8 bi = amcoe->b->data[i]; REAL8 hi = A1 * ai * cosphi_i + A2 * bi * cosphi_i + A3 * ai * sinphi_i + A4 * bi * sinphi_i; ts->data->data[i] = (REAL4)hi; } /* for i < numSteps */ XLALDestroyDetectorStateSeries( detStates ); XLALDestroyAMCoeffs ( amcoe ); return ts; } /* XLALSimulateExactPulsarSignal() */
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 = " ); 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 = " ); 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 = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, gDN_ij ); gsl_matrix_free ( gDN_ij ); } /* ----- output F-metric (and related matrices ---------- */ if ( Fmetric != NULL ) { fprintf ( fp, "\ngF_ij = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->gF_ij ); fprintf ( fp, "\ngFav_ij = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->gFav_ij ); fprintf ( fp, "\nm1_ij = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->m1_ij ); fprintf ( fp, "\nm2_ij = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->m2_ij ); fprintf ( fp, "\nm3_ij = " ); 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 = " ); 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() */
/** * basic initializations: set-up 'ConfigVariables' */ int XLALInitCode ( ConfigVariables *cfg, const UserVariables_t *uvar, const char *app_name) { if ( !cfg || !uvar || !app_name ) { LogPrintf (LOG_CRITICAL, "%s: illegal NULL pointer input.\n\n", __func__ ); XLAL_ERROR (XLAL_EINVAL ); } /* Init ephemerides */ XLAL_CHECK ( (cfg->edat = XLALInitBarycenter ( uvar->ephemEarth, uvar->ephemSun )) != NULL, XLAL_EFUNC ); // ----- figure out which segments to use BOOLEAN manualSegments = XLALUserVarWasSet(&uvar->duration) || XLALUserVarWasSet(&uvar->startTime) || XLALUserVarWasSet(&uvar->Nseg); if ( manualSegments && uvar->segmentList ) { XLAL_ERROR ( XLAL_EDOM, "Can specify EITHER {--startTime, --duration, --Nseg} OR --segmentList\n"); } LIGOTimeGPS startTimeGPS; REAL8 duration; if ( uvar->segmentList == NULL ) { XLAL_CHECK ( uvar->Nseg >= 1, XLAL_EDOM, "Invalid input --Nseg=%d: number of segments must be >= 1\n", uvar->Nseg ); XLAL_CHECK ( uvar->duration >= 1, XLAL_EDOM, "Invalid input --duration=%f: duration must be >= 1 s\n", uvar->duration ); startTimeGPS = uvar->startTime; int ret = XLALSegListInitSimpleSegments ( &cfg->segmentList, startTimeGPS, uvar->Nseg, uvar->duration / uvar->Nseg ); XLAL_CHECK ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALSegListInitSimpleSegments() failed with xlalErrno = %d\n", xlalErrno ); duration = uvar->duration; } else { LALSegList *segList = XLALReadSegmentsFromFile ( uvar->segmentList ); XLAL_CHECK ( segList != NULL, XLAL_EIO, "XLALReadSegmentsFromFile() failed to load segment list from file '%s', xlalErrno = %d\n", uvar->segmentList, xlalErrno ); cfg->segmentList = (*segList); // copy *contents* XLALFree ( segList ); startTimeGPS = cfg->segmentList.segs[0].start; UINT4 Nseg = cfg->segmentList.length; LIGOTimeGPS endTimeGPS = cfg->segmentList.segs[Nseg-1].end; duration = XLALGPSDiff( &endTimeGPS, &startTimeGPS ); } /* ----- figure out reference time */ LIGOTimeGPS refTimeGPS; /* treat special values first */ if ( uvar->refTime.gpsSeconds == 0 ) /* 0 = use startTime */ { refTimeGPS = uvar->startTime; } else if ( !XLALUserVarWasSet ( &uvar->refTime ) ) /* default = use mid-time of observation */ { refTimeGPS = startTimeGPS; XLALGPSAdd( &refTimeGPS, duration / 2.0 ); } else { refTimeGPS = uvar->refTime; } /* ----- get parameter-space point from user-input) */ cfg->signalParams.Amp.h0 = uvar->h0; cfg->signalParams.Amp.cosi = uvar->cosi; cfg->signalParams.Amp.psi = uvar->psi; cfg->signalParams.Amp.phi0 = uvar->phi0; { PulsarDopplerParams *dop = &(cfg->signalParams.Doppler); XLAL_INIT_MEM((*dop)); dop->refTime = refTimeGPS; dop->Alpha = uvar->Alpha; dop->Delta = uvar->Delta; dop->fkdot[0] = uvar->Freq; dop->fkdot[1] = uvar->f1dot; dop->fkdot[2] = uvar->f2dot; dop->fkdot[3] = uvar->f3dot; dop->asini = uvar->orbitasini; dop->period = uvar->orbitPeriod; dop->tp = uvar->orbitTp; dop->ecc = uvar->orbitEcc; dop->argp = uvar->orbitArgp; } /* ----- initialize IFOs and (Multi-)DetectorStateSeries ----- */ XLAL_CHECK ( XLALParseMultiLALDetector ( &cfg->multiIFO, uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC ); UINT4 numDet = cfg->multiIFO.length; XLAL_CHECK ( numDet >= 1, XLAL_EINVAL ); if ( uvar->sqrtSX ) { XLAL_CHECK ( XLALParseMultiNoiseFloor ( &cfg->multiNoiseFloor, uvar->sqrtSX, numDet ) == XLAL_SUCCESS, XLAL_EFUNC ); } /* ---------- translate coordinate system into internal representation ---------- */ if ( XLALDopplerCoordinateNames2System ( &cfg->coordSys, uvar->coords ) ) { LogPrintf (LOG_CRITICAL, "%s: Call to XLALDopplerCoordinateNames2System() failed. errno = %d\n\n", __func__, xlalErrno ); XLAL_ERROR ( XLAL_EFUNC ); } /* ---------- record full 'history' up to and including this application ---------- */ { CHAR *cmdline = NULL; CHAR *tmp; size_t len = strlen ( app_name ) + 1; if ( (cfg->history = XLALCalloc ( 1, sizeof(*cfg->history))) == NULL ) { LogPrintf (LOG_CRITICAL, "%s: XLALCalloc(1,%zu) failed.\n\n", __func__, sizeof(*cfg->history)); XLAL_ERROR ( XLAL_ENOMEM ); } if ( (tmp = XLALMalloc ( len )) == NULL ) { LogPrintf (LOG_CRITICAL, "%s: XLALMalloc (%zu) failed.\n\n", __func__, len ); XLAL_ERROR ( XLAL_ENOMEM ); } strcpy ( tmp, app_name ); cfg->history->app_name = tmp; /* get commandline describing search*/ if ( (cmdline = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) == NULL ) { LogPrintf (LOG_CRITICAL, "%s: XLALUserVarGetLog() failed with xlalErrno = %d.\n\n", __func__, xlalErrno ); XLAL_ERROR ( XLAL_EFUNC ); } cfg->history->cmdline = cmdline; } /* record history */ return XLAL_SUCCESS; } /* XLALInitCode() */
/** * 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; }