27#include <lal/LALNoiseModels.h>
28#include <lal/LALStdio.h>
29#include <lal/LALgetopt.h>
30#include <lal/LALStdlib.h>
31#include <lal/LIGOLwXML.h>
32#include <lal/LIGOLwXMLRead.h>
34#include <lal/FindChirp.h>
36#include <lal/FrequencySeries.h>
37#include <lal/TimeSeries.h>
38#include <lal/TimeFreqFFT.h>
39#include <lal/InspiralInjectionParams.h>
40#include <lal/VectorOps.h>
41#include <lal/LALFrStream.h>
42#include <lal/LALDetectors.h>
43#include <lal/LALFrameIO.h>
45#define PROGRAM_NAME "coinj"
48"lalpps_coinj [options]\n\
49--help display this message \n\
50--input <injection.xml> Specify input SimInspiralTable xml file\n\
51--output-path OUTPUTPATH directory path where frames are going to be written to\n\
52--skip-ascii-output skip generation of ASCII txt output file\n\
53--response-type TYPE TYPE of injection, [ strain | etmx | etmy ]\n\
54--frames Create h(t) frame files\n\n\
55[--maxSNR snrhigh --minSNR snrlow Adjust injections to have combined SNR between snrlow and snrhigh in the H1H2L1V1 network]\n\
56[--SNR snr adjust distance to get precisely this snr]\n\
57[--GPSstart A --GPSend B Only generate waveforms for injection between GPS seconds A and B (int)]\n\
58[--max-chirp-dist DIST Set the maximum chirp distance in H, L or V to DIST]\n\
59lalapps_coinj: create coherent injection files for LIGO and VIRGO\n"
62#define UNUSED __attribute__ ((unused))
78typedef struct actuationparameters
95 if(!inj) {printf(
"Null pointer passed to chirpDist!\n"); exit(1);}
103 default: {printf(
"ERROR: Unknown IFO code %c\n",
ifo);}
105 return( eff_dist*pow(1.218/inj->
mchirp , (5./6.)));
108int main(
int argc,
char *argv[])
111 CHAR inputfile[FILENAME_MAX];
112 CHAR outputpath[1000];
118 REAL8 injLength=100.0;
119 REAL8 LeadupTime=95.0;
123 UINT4 Nsamples,det_idx,
i,inj_num=0;
129 CHAR outfilename[FILENAME_MAX];
132 const LALUnit strainPerCount={0,{0,0,0,0,0,1,-1},{0,0,0,0,0,0,0}};
133 const LALUnit countPerStrain={0,{0,0,0,0,0,-1,1},{0,0,0,0,0,0,0}};
143 double max_chirp_dist=0.0;
152 CHAR VirgoParsSource[100];
153 CHAR VirgoParsInfo[100];
154 REAL8 NetworkSNR=0.0;
157 INT4 skipASCIIoutput=0;
160 REAL4FFTPlan *fwd_plan;
162 REAL8 UNUSED maxRatio=1.0, UNUSED minRatio=1.0;
164 INT4 GPSstart=0,GPSend=2147483647;
174 {
"skip-ascii-output",
no_argument,&skipASCIIoutput,
'A'},
234 strncpy(inputfile,
LALoptarg,FILENAME_MAX-1);
243 else {
fprintf(stderr,
"Invalid argument to response-type: %s\nResponse type must be strain, etmy or etmx\n", \
262 fprintf(stderr,
"Target SNR = %lf\n",targetSNR);
266 fprintf(stderr,
"Using maximum chirp distance of %lf\n",max_chirp_dist);
272 fprintf(stderr,
"Error: minSNR must be less than maxSNR\n");
274 if(targetSNR!=0.0 && (targetSNR<minSNR || targetSNR>
maxSNR)){
275 fprintf(stderr,
"Target SNR %lf is not in range %lf to %lf, ignoring min and max\n",targetSNR,
minSNR,
maxSNR);
288 this_injection.
next=NULL;
314 default:
fprintf(stderr,
"Unknown IFO\n"); exit(1);
break;
328 actuationTimeSeries=NULL;
329 goto calcSNRandwriteFrames;
337 switch(injectionResponse){
339 sprintf(injtype,
"STRAIN");
343 sprintf(injtype,
"ETMX");
347 sprintf(injtype,
"ETMY");
351 fprintf(stderr,
"Must specify response function: strain, etmy or etmx\n"); exit(1);
364 actuationTimeSeries =
XLALRespFilt(actuationTimeSeries,transfer);
369 else actuationTimeSeries=TimeSeries;
376 if(this_injection.
mass1<2.0 && this_injection.
mass2<2.0) sprintf(massBin,
"BNS");
377 else if(this_injection.
mass1<2.0 || this_injection.
mass2<2.0) sprintf(massBin,
"NSBH");
378 else sprintf(massBin,
"BBH");
380 if (!(skipASCIIoutput)){
381 result = snprintf(outfilename,
sizeof(outfilename),
"%s%s%i_CBC_%s_%i_%s_%s.txt",outputpath,
"/",inj_epoch.
gpsSeconds,massBin,inj_num,injtype,det_name);
382 if (result < 0 || (
size_t)result >
sizeof(outfilename) - 1)
384 fprintf(stderr,
"ERROR: file name too long: '%s'\n", outfilename);
387 outfile=fopen(outfilename,
"w");
388 fprintf(stdout,
"Injected signal %i for %s into file %s\n",inj_num,det_name,outfilename);
393 calcSNRandwriteFrames:
405 REAL8 sim_psd_value=0;
409 (sim_psd_value*PSDscale);
411 (sim_psd_value*PSDscale);
413 mySNRsq *= 4.0*fftData->
deltaF;
417 fprintf(stdout,
"SNR in design %s of injection %i = %lf\n",det_name,inj_num,mySNR);
422 NetworkSNR+=mySNR*mySNR;
425 sprintf(VirgoParsSource,
"%s-INSP%i",det_name,inj_num);
426 VirgoOutPars.source=VirgoParsSource;
427 sprintf(VirgoParsInfo,
"HWINJ-STRAIN");
428 VirgoOutPars.description=VirgoParsInfo;
430 VirgoOutPars.nframes=(
UINT4)injLength;
431 VirgoOutPars.frame=0;
433 fprintf(stdout,
"Generating frame file for %s-%s-%i\n",VirgoParsSource,VirgoParsInfo,TimeSeries->
epoch.
gpsSeconds);
436 frame =
XLALFrameNew( &TimeSeries->
epoch, injLength,
"HWINJ-STRAIN", 0, 1, detectorFlags );
440 result = snprintf(
fname,
sizeof(
fname),
"%s%s%s-INSP%i_HWINJ_STRAIN-%i-%i.gwf",outputpath,
"/",det_name, inj_num, inj_epoch.
gpsSeconds, (
UINT4)injLength);
441 if (result < 0 || (
size_t)result >
sizeof(
fname) - 1)
443 fprintf( stderr,
"ERROR: file name too long: '%s'\n",
fname );
449 fprintf( stderr,
"ERROR: Cannot save frame file: '%s'\n",
fname );
467 NetworkSNR=sqrt(NetworkSNR);
469 if(targetSNR!=0.0 && repeatLoop==0 && hitTarget==0) {
476 rewriteXML=1; repeatLoop=1; hitTarget=1;}
477 else {repeatLoop=0; hitTarget=0;}
478 if(targetSNR==0.0 &&
minSNR>NetworkSNR) {
485 rewriteXML=1; repeatLoop=1;}
487 if(targetSNR==0.0 &&
maxSNR!=0.0 &&
maxSNR<NetworkSNR) {
497 fprintf(stderr,
"Multiplying by %lf to get from %lf to target\n",1.01*(NetworkSNR/
maxSNR),NetworkSNR);}
502 double second_max=0.0;
504 for(
int cidx=0;cidx<3;cidx++)
506 if(this_max<
chirpDist(injTable,ifostr[cidx])) this_max=
chirpDist(injTable,ifostr[cidx]);
508 for(
int cidx=0;cidx<3;cidx++)
509 if(second_max<
chirpDist(injTable,ifostr[cidx]) &&
chirpDist(injTable,ifostr[cidx])<this_max) second_max=
chirpDist(injTable,ifostr[cidx]);
510 if(second_max>max_chirp_dist){
511 injTable->
distance*=0.95*(max_chirp_dist/second_max);
512 injTable->
eff_dist_h*=0.95*max_chirp_dist/second_max;
513 injTable->
eff_dist_l*=0.95*max_chirp_dist/second_max;
514 injTable->
eff_dist_v*=0.95*max_chirp_dist/second_max;
515 injTable->
eff_dist_t*=0.95*max_chirp_dist/second_max;
516 injTable->
eff_dist_g*=0.95*max_chirp_dist/second_max;
517 rewriteXML=1; repeatLoop=1;
518 fprintf(stderr,
"MCD: Multiplying distance by %lf to get from %lf to target\n",0.95*max_chirp_dist/second_max,second_max);
521 if(repeatLoop==1)
fprintf(stderr,
"Reinjecting with new distance %f for desired SNR\n\n",injTable->
distance);
524 fprintf(stderr,
"\nNetwork SNR of %i = %lf\n",inj_num,NetworkSNR);
525 injTable=injTable->
next;
530 }
while(injTable!=NULL);
534 fprintf(stderr,
"Overwriting %s with adjusted distances\n",inputfile);
535 inputfile[strlen(inputfile)-4] = 0;
536 strncat(inputfile,
"_adj.xml",FILENAME_MAX-1);
538 if(
xmlfp==NULL)
fprintf(stderr,
"Error! Cannot open %s for writing\n",inputfile);
void LALFindChirpInjectSignals(LALStatus *status, REAL4TimeSeries *chan, SimInspiralTable *events, COMPLEX8FrequencySeries *resp)
#define LAL_CALL(function, statusptr)
int LALgetopt_long_only(int argc, char *const *argv, const char *options, const struct LALoption *long_options, int *opt_index)
#define required_argument
int XLALCloseLIGOLwXMLFile(LIGOLwXMLStream *xml)
LIGOLwXMLStream * XLALOpenLIGOLwXMLFile(const char *path)
int XLALWriteLIGOLwXMLSimInspiralTable(LIGOLwXMLStream *, const SimInspiralTable *)
SimInspiralTable * XLALSimInspiralTableFromLIGOLw(const char *fileName)
ActuationParameters actuationParams[LAL_NUM_IFO]
int main(int argc, char *argv[])
double chirpDist(SimInspiralTable *inj, char ifo)
int vrbflg
defined in lal/lib/std/LALError.c
void() NoiseFunc(LALStatus *status, REAL8 *psd, REAL8 f)
static LALUnit strainPerCount
REAL4TimeSeries * XLALRespFilt(REAL4TimeSeries *strain, COMPLEX8FrequencySeries *transfer)
void XLALDestroyCOMPLEX8FrequencySeries(COMPLEX8FrequencySeries *series)
COMPLEX8FrequencySeries * XLALCreateCOMPLEX8FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
COMPLEX8FrequencySeries * generateActuation(COMPLEX8FrequencySeries *resp, REAL4 ETMcal, REAL4 pendF, REAL4 pendQ)
#define XLAL_INIT_DECL(var,...)
#define LAL_GEO_600_DETECTOR_BIT
#define LAL_LLO_4K_DETECTOR_BIT
#define LAL_TAMA_300_DETECTOR_BIT
#define LAL_VIRGO_DETECTOR_BIT
#define LAL_LHO_2K_DETECTOR_BIT
#define LAL_LHO_4K_DETECTOR_BIT
LALFrameUFrameH LALFrameH
int XLALFrameWrite(LALFrameH *frame, const char *fname)
int XLALFrameAddREAL4TimeSeriesSimData(LALFrameH *frame, const REAL4TimeSeries *series)
LALFrameH * XLALFrameNew(const LIGOTimeGPS *epoch, double duration, const char *project, int run, int frnum, INT8 detectorFlags)
void XLALFrameFree(LALFrameH *frame)
void LALTAMAPsd(LALStatus *status, REAL8 *shf, REAL8 x)
void LALGEOPsd(LALStatus UNUSED *status, REAL8 *psd, REAL8 f)
void LALLIGOIPsd(LALStatus UNUSED *status, REAL8 *psd, REAL8 f)
void LALVIRGOPsd(LALStatus *status, REAL8 *shf, REAL8 x)
REAL4FFTPlan * XLALCreateForwardREAL4FFTPlan(UINT4 size, int measurelvl)
void XLALDestroyREAL4FFTPlan(REAL4FFTPlan *plan)
int XLALREAL4TimeFreqFFT(COMPLEX8FrequencySeries *freq, const REAL4TimeSeries *tser, const REAL4FFTPlan *plan)
REAL4TimeSeries * XLALCreateREAL4TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL4TimeSeries(REAL4TimeSeries *series)
const LALUnit lalADCCountUnit
const LALUnit lalDimensionlessUnit
COMPLEX8Vector * XLALCreateCOMPLEX8Vector(UINT4 length)
void XLALDestroyCOMPLEX8Vector(COMPLEX8Vector *vector)
COMPLEX8Vector * XLALCCVectorDivide(COMPLEX8Vector *out, const COMPLEX8Vector *in1, const COMPLEX8Vector *in2)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
LIGOTimeGPS geocent_end_time
struct tagSimInspiralTable * next