/* parse command line arguments using LALgetopt_long to get ring params */ int coh_PTF_parse_options(struct coh_PTF_params *params,int argc,char **argv ) { CHAR ifo[LIGOMETA_IFO_MAX]; UINT4 ifoNumber; static struct coh_PTF_params localparams; memset( &localparams.haveTrig, 0, LAL_NUM_IFO * sizeof(int) ); struct LALoption long_options[] = { { "verbose", no_argument, &vrbflg, 1 }, { "strain-data", no_argument, &localparams.strainData, 1 }, { "zero-data", no_argument, &localparams.zeroData, 1 }, { "theoretical-spectrum", no_argument, &localparams.whiteSpectrum, 1 }, { "write-raw-data", no_argument, &localparams.writeRawData, 1 }, { "write-data", no_argument, &localparams.writeProcessedData, 1 }, { "write-inv-spectrum", no_argument, &localparams.writeInvSpectrum, 1 }, { "write-segment", no_argument, &localparams.writeSegment, 1 }, { "write-filter-output",no_argument, &localparams.writeFilterOutput, 1 }, { "analyze-inj-segs-only",no_argument, &localparams.analyzeInjSegsOnly, 1 }, { "do-null-stream", no_argument, &localparams.doNullStream, 1 }, { "do-trace-snr", no_argument, &localparams.doTraceSNR, 1 }, { "do-bank-veto", no_argument, &localparams.doBankVeto, 1 }, { "do-auto-veto", no_argument, &localparams.doAutoVeto, 1 }, { "do-chi-square", no_argument, &localparams.doChiSquare, 1 }, { "do-sngl-chi-tests", no_argument, &localparams.doSnglChiSquared, 1}, { "do-clustering", no_argument, &localparams.clusterFlag, 1}, /* {"g1-data", no_argument, &(haveTrig[LAL_IFO_G1]), 1 },*/ {"h1-data", no_argument, &(localparams.haveTrig[LAL_IFO_H1]),1}, {"h2-data", no_argument, &(localparams.haveTrig[LAL_IFO_H2]),1}, {"l1-data", no_argument, &(localparams.haveTrig[LAL_IFO_L1]),1}, /* {"t1-data", no_argument, &(haveTrig[LAL_IFO_T1]), 1 },*/ {"v1-data", no_argument, &(localparams.haveTrig[LAL_IFO_V1]),1}, {"face-on-analysis", no_argument, &(localparams.faceOnAnalysis),1}, {"face-away-analysis", no_argument, &(localparams.faceAwayAnalysis),1}, {"dynamic-template-length",no_argument, &(localparams.dynTempLength),1}, {"store-amplitude-params",no_argument, &(localparams.storeAmpParams),1}, {"analyse-segment-end", no_argument, &(localparams.analSegmentEnd),1}, {"do-short-slides", no_argument, &(localparams.doShortSlides),1}, { "write-sngl-inspiral-table", no_argument, &(localparams.writeSnglInspiralTable),1}, { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { "simulated-data", required_argument, 0, '6' }, { "gps-start-time", required_argument, 0, 'a' }, { "gps-start-time-ns", required_argument, 0, 'A' }, { "gps-end-time", required_argument, 0, 'b' }, { "gps-end-time-ns", required_argument, 0, 'B' }, { "trigger-time", required_argument, 0, '<' }, { "trigger-time-ns", required_argument, 0, '>' }, { "h1-channel-name", required_argument, 0, 'c' }, { "h1-frame-cache", required_argument, 0, 'D' }, { "h2-channel-name", required_argument, 0, 'x' }, { "h2-frame-cache", required_argument, 0, 'X' }, { "l1-channel-name", required_argument, 0, 'y' }, { "l1-frame-cache", required_argument, 0, 'Y' }, { "v1-channel-name", required_argument, 0, 'z' }, { "v1-frame-cache", required_argument, 0, 'Z' }, { "low-template-freq", required_argument, 0, 'e' }, { "low-filter-freq", required_argument, 0, 'H' }, { "high-filter-freq", required_argument, 0, 'I' }, { "highpass-frequency", required_argument, 0, 'E' }, { "injection-file", required_argument, 0, 'i' }, { "snr-threshold", required_argument, 0, 'j' }, { "spin-snr-threshold", required_argument, 0, '2' }, { "sngl-snr-threshold", required_argument, 0, '1' }, { "trig-time-window", required_argument, 0, 'J' }, { "user-tag", required_argument, 0, 'k' }, { "ifo-tag", required_argument, 0, 'K' }, { "non-spin-snr2-threshold", required_argument, 0, 'l' }, { "spin-snr2-threshold", required_argument, 0, 'L' }, { "spin-bank", required_argument, 0, 'm' }, { "non-spin-bank", required_argument, 0, 'M' }, { "only-segment-numbers", required_argument, 0, 'n' }, { "only-template-numbers", required_argument, 0, 'N' }, { "output-file", required_argument, 0, 'o' }, { "bank-file", required_argument, 0, 'O' }, { "num-auto-chisq-points", required_argument, 0, 'p' }, { "auto-veto-time-step", required_argument, 0, 'P' }, { "num-chi-square-bins", required_argument, 0, 'q' }, { "chi-square-threshold", required_argument, 0, 'Q' }, { "random-seed", required_argument, 0, 'r' }, { "dynamic-range-factor", required_argument, 0, 'R' }, { "sample-rate", required_argument, 0, 's' }, { "segment-duration", required_argument, 0, 'S' }, { "psd-segment-duration", required_argument, 0, '9' }, { "bank-veto-templates", required_argument, 0, 't' }, { "inverse-spec-length", required_argument, 0, 'T' }, { "trig-start-time", required_argument, 0, 'u' }, { "trig-end-time", required_argument, 0, 'U' }, { "block-duration", required_argument, 0, 'w' }, { "pad-data", required_argument, 0, 'W' }, { "right-ascension", required_argument, 0, 'f' }, { "declination", required_argument, 0, 'F' }, { "sky-error", required_argument, 0, 'g' }, { "timing-accuracy", required_argument, 0, 'G' }, { "approximant", required_argument, 0, 'C' }, { "order", required_argument, 0, 'v' }, { "h1-slide-segment", required_argument, 0, '!' }, { "h2-slide-segment", required_argument, 0, '&' }, { "l1-slide-segment", required_argument, 0, '(' }, { "v1-slide-segment", required_argument, 0, ')' }, { "sky-positions-file", required_argument, 0, '#' }, { "fft-level", required_argument, 0, '|' }, { "cluster-window", required_argument, 0, '4' }, { "inj-search-window", required_argument, 0, '3' }, { "inj-mchirp-window", required_argument, 0, '5' }, { "ligo-calibrated-data", required_argument, 0, '7' }, { "virgo-calibrated-data", required_argument, 0, '8' }, { "short-slide-offset", required_argument, 0, '@' }, { 0, 0, 0, 0 } }; char args[] = "a:A:b:B:c:C:D:e:E:f:F:g:G:h:H:i:I:j:J:k:K:l:L:m:M:n:N:o:O:p:P:q:Q:r:R:s:S:t:T:u:U:v:V:w:W:x:X:y:Y:z:Z:1:2:3:4:5:6:7:8:9:<:>:!:&:(:):#:|:@"; char *program = argv[0]; /* set default values for parameters before parsing arguments */ coh_PTF_default_params( &localparams ); while ( 1 ) { int option_index = 0; int c; c = LALgetopt_long_only( argc, argv, args, long_options, &option_index ); if ( c == -1 ) /* end of options */ break; switch ( c ) { case 0: /* if option set a flag, nothing else to do */ if ( long_options[option_index].flag ) break; else error( "error parsing option %s with argument %s\n", long_options[option_index].name, LALoptarg ); case 'a': /* gps-start-time */ localparams.startTime.gpsSeconds = atol( LALoptarg ); break; case 'A': /* gps-start-time-ns */ localparams.startTime.gpsNanoSeconds = atol( LALoptarg ); break; case 'b': /* gps-end-time */ localparams.endTime.gpsSeconds = atol( LALoptarg ); break; case 'B': /* gps-end-time-ns */ localparams.endTime.gpsNanoSeconds = atol( LALoptarg ); break; case '<': /* trigger-time */ localparams.trigTime.gpsSeconds = atol( LALoptarg ); break; case '>': /* trigger-time-ns */ localparams.trigTime.gpsNanoSeconds = atol( LALoptarg ); break; case 'c': /* h1 channel-name */ localparams.channel[LAL_IFO_H1] = LALoptarg; break; case 'D': /* h1 frame-cache */ localparams.dataCache[LAL_IFO_H1] = LALoptarg; break; case 'y': /* l1 channel-name */ localparams.channel[LAL_IFO_L1] = LALoptarg; break; case 'Y': /* l1 frame-cache */ localparams.dataCache[LAL_IFO_L1] = LALoptarg; break; case 'z': /* v1 channel-name */ localparams.channel[LAL_IFO_V1] = LALoptarg; break; case 'Z': /* v1 frame-cache */ localparams.dataCache[LAL_IFO_V1] = LALoptarg; break; case 'x': /* h2 channel-name */ localparams.channel[LAL_IFO_H2] = LALoptarg; break; case 'X': /* h2 frame-cache */ localparams.dataCache[LAL_IFO_H2] = LALoptarg; break; case 'e': /* start frequency of template generation */ localparams.lowTemplateFrequency = atof( LALoptarg ); break; case 'H': /* start frequency of matched filter */ localparams.lowFilterFrequency = atof( LALoptarg ); break; case 'I': /* End frequency of matched filter */ localparams.highFilterFrequency = atof( LALoptarg ); break; case 'E': /* highpass-frequency */ localparams.highpassFrequency = atof( LALoptarg ); break; case 'C': /* waveform approximant */ /* This will directly fail if the approximant is not a valid one. However the user may get to a call to FindChirpTDTemplate and find out only then that the approximant is not supported in there. */ localparams.approximant = XLALSimInspiralGetApproximantFromString(LALoptarg); break; case '6': /* Simulated data option */ localparams.simData = 1; if ( ! strcmp( "WhiteNoise",LALoptarg)) { localparams.simDataType = WHITE_PSD; } else if ( ! strcmp( "ILIGONoise",LALoptarg)) { localparams.simDataType = ILIGO_PSD; } else if ( ! strcmp( "ALIGONoise",LALoptarg)) { localparams.simDataType = ALIGO_PSD; } else { fprintf( stderr, "invalid argument to --%s:\n" "unknown data type specified:" "%s valid options are WhiteNoise, ILIGONoise or ALIGONoise", long_options[option_index].name, LALoptarg ); exit(1); } break; case 'v': /* PN order of waveform */ if ( ! strcmp( "twoPN", LALoptarg ) ) { localparams.order = LAL_PNORDER_TWO; } else if ( ! strcmp( "twoPointFivePN", LALoptarg ) ) { localparams.order = LAL_PNORDER_TWO_POINT_FIVE; } else if ( ! strcmp( "threePN", LALoptarg ) ) { localparams.order = LAL_PNORDER_THREE; } else if ( ! strcmp( "threePointFivePN", LALoptarg ) ) { localparams.order = LAL_PNORDER_THREE_POINT_FIVE; } else if ( ! strcmp( "pseudoFourPN", LALoptarg ) ) { localparams.order = LAL_PNORDER_PSEUDO_FOUR; } else { fprintf( stderr, "invalid argument to --%s:\n" "unknown order specified: " "%s (must be one of twoPN, twoPointFivePN, threePN, threePointFivePN, pseudoFourPN)\n", long_options[option_index].name, LALoptarg ); exit( 1 ); } break; case 'f': /* right-ascension */ localparams.rightAscension = atof( LALoptarg ) * LAL_PI_180; break; case 'F': /* Declination */ localparams.declination = atof( LALoptarg ) * LAL_PI_180; break; case 'g': /* Error in declination */ localparams.skyError = atof( LALoptarg ) * LAL_PI_180; break; case 'G': /* timing accuracy of network */ localparams.timingAccuracy = atof( LALoptarg ); break; case 'h': /* help */ coh_PTF_usage( program ); exit( 0 ); case 'i': /* injection-file */ localparams.injectFile = LALoptarg; break; case 'j': localparams.threshold = atof(LALoptarg); break; case '2': localparams.spinThreshold = atof(LALoptarg); break; case '1': localparams.snglSNRThreshold = atof(LALoptarg); break; case 'J': localparams.timeWindow = atof(LALoptarg); break; case 'k': /* user-tag */ strncpy( localparams.userTag, LALoptarg, sizeof( localparams.userTag ) - 1 ); break; case 'K': /* ifo-tag */ strncpy( localparams.ifoTag, LALoptarg, sizeof( localparams.ifoTag ) - 1 ); break; case 'l': localparams.nonspinSNR2threshold = atof(LALoptarg); break; case 'L': localparams.spinSNR2threshold = atof(LALoptarg); break; case 'm': /* spin bank */ localparams.spinBank = 1; strncpy( localparams.spinBankName, LALoptarg, sizeof( localparams.spinBankName ) - 1 ); break; case 'M': /* non spin bank */ localparams.noSpinBank = 1; strncpy( localparams.noSpinBankName, LALoptarg, sizeof( localparams.noSpinBankName ) - 1 ); break; case 'n': /* only-segment-numbers */ localparams.segmentsToDoList = LALoptarg; break; case 'N': /* only-template-number */ localparams.templatesToDoList = LALoptarg; break; case 'o': /* output-file */ strncpy( localparams.outputFile, LALoptarg, sizeof( localparams.outputFile ) - 1 ); break; case 'O': /* bank-file */ localparams.bankFile = LALoptarg; break; case 'p': /* num auto chisq points */ localparams.numAutoPoints = atoi( LALoptarg ); break; case 'P': /* Auto veto time step */ localparams.autoVetoTimeStep = atof( LALoptarg ); break; case 'q': /* num chi square bins */ localparams.numChiSquareBins = atoi( LALoptarg ); break; case 'Q': localparams.chiSquareCalcThreshold = atof( LALoptarg ); break; case 'r': /* random seed */ localparams.randomSeed = atoi( LALoptarg ); break; case 'R': /* dynamic range factor */ localparams.dynRangeFac = atof( LALoptarg ); break; case 's': /* sample rate */ localparams.sampleRate = atof( LALoptarg ); break; case 'S': /* segment-duration */ localparams.segmentDuration = atof( LALoptarg ); break; case '9': /* PSD segment-duration */ localparams.psdSegmentDuration = atof( LALoptarg ); break; case 't': /* bank veto template bank */ localparams.bankVetoBankName = LALoptarg; break; case 'T': /* inverse-spec-length */ localparams.truncateDuration = atof( LALoptarg ); break; case 'u': /* trig-start-time */ localparams.trigStartTimeNS = (INT8) atol( LALoptarg ) * LAL_INT8_C(1000000000); break; case 'U': /* trig-end-time */ localparams.trigEndTimeNS = (INT8) atol( LALoptarg ) * LAL_INT8_C(1000000000); break; case 'w': /* block-duration */ localparams.duration = atof( LALoptarg ); break; case 'W': /* pad-data */ localparams.padData = atof( LALoptarg ); break; case '!': /* h1-slide-segment */ localparams.slideSegments[LAL_IFO_H1] = atoi( LALoptarg ); break; case '&': /* h2-slide-segments */ localparams.slideSegments[LAL_IFO_H2] = atoi( LALoptarg ); break; case '(': /* l1-slide-segments */ localparams.slideSegments[LAL_IFO_L1] = atoi( LALoptarg ); break; case ')': /* v1-slide-segments */ localparams.slideSegments[LAL_IFO_V1] = atoi( LALoptarg ); break; case '@': /* Short slide offset time */ localparams.shortSlideOffset = atoi( LALoptarg ); break; case 'V': /* version */ XLALOutputVersionString(stderr, 0); exit( 0 ); case '#': /* sky grid file */ localparams.skyPositionsFile = LALoptarg; break; case '|': /* FFT-level for plans */ localparams.fftLevel = atoi( LALoptarg ); break; case '4': /* Cluster window */ localparams.clusterWindow = atof(LALoptarg); break; case '3': /* Injection search window */ localparams.injSearchWindow = atof( LALoptarg ); break; case '5': /* Injection search window */ localparams.injMchirpWindow = atof( LALoptarg ); break; case '7': if (!strcmp("real_4", LALoptarg)) { localparams.ligoDoubleData = 0; } else if (!strcmp("real_8", LALoptarg)) { localparams.ligoDoubleData = 1; } else { fprintf(stderr, "invalid argument to --%s:\n" "unknown data type specified;\n" "%s (must be one of: real_4, real_8)\n", long_options[option_index].name, LALoptarg); } break; case '8': if (!strcmp("real_4", LALoptarg)) { localparams.virgoDoubleData = 0; } else if (!strcmp("real_8", LALoptarg)) { localparams.virgoDoubleData = 1; } else { fprintf(stderr, "invalid argument to --%s:\n" "unknown data type specified;\n" "%s (must be one of: real_4, real_8)\n", long_options[option_index].name, LALoptarg); } break; case '?': error( "unknown error while parsing options\n" ); default: error( "unknown error while parsing options\n" ); } } if ( LALoptind < argc ) { fprintf( stderr, "extraneous command line arguments:\n" ); while ( LALoptind < argc ) fprintf( stderr, "%s\n", argv[LALoptind++] ); exit( 1 ); } /* set number of ifos */ localparams.numIFO = 0; for ( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++ ) { if ( localparams.haveTrig[ifoNumber] ) { XLALReturnIFO(ifo,ifoNumber); snprintf( localparams.ifoName[localparams.numIFO], LIGOMETA_IFO_MAX,\ "%s", ifo ); localparams.numIFO++; } } /* check for H1H2 */ if (localparams.numIFO == 2) { if (! strcmp(localparams.ifoName[0],"H1")) { if (! strcmp(localparams.ifoName[1],"H2")) { localparams.singlePolFlag = 1; } } } /* Set the faceOn-faceAway flag */ /* Otherwise it takes default value of 0 */ if (localparams.faceOnAnalysis) { localparams.faceOnStatistic = 1; } else if (localparams.faceAwayAnalysis) { localparams.faceOnStatistic = 2; } /* Set the number of points in the time arrays */ localparams.numTimePoints = floor(\ localparams.segmentDuration * localparams.sampleRate + 0.5); /* Set the number of points in the frequency arrays */ localparams.numFreqPoints = localparams.numTimePoints / 2 + 1; /* For now we stick to only analysing half of each segment */ localparams.strideDuration = 0.5 * localparams.segmentDuration; /* FIXME: Hardcoded to 1s */ localparams.numBufferPoints = floor(localparams.sampleRate + 0.5); /* Choose the start and end point of each segment for analysis */ if (localparams.analSegmentEnd) { /* Want to analyse from the end of the segment */ /* Start from the end */ localparams.analEndPoint = localparams.numTimePoints; /* Remove the spectrum truncation */ localparams.analEndPoint -= floor(\ 0.5 * localparams.truncateDuration * localparams.sampleRate + 0.5); /* Remove the buffer points */ localparams.analEndPoint -= localparams.numBufferPoints; /* And set the start point */ localparams.analStartPoint = localparams.analEndPoint - \ 0.5*localparams.numTimePoints; } else { /* DEFAULT: Analyse the middle of the segment */ localparams.analStartPoint = 1*localparams.numTimePoints/4; localparams.analEndPoint = (3*localparams.numTimePoints)/4; } localparams.analStartTime = localparams.analStartPoint / \ localparams.sampleRate; localparams.analStartPointBuf = localparams.analStartPoint\ - localparams.numBufferPoints; localparams.analEndTime = localparams.analEndPoint / \ localparams.sampleRate; localparams.analEndPointBuf = localparams.analEndPoint\ + localparams.numBufferPoints; localparams.numAnalPoints = localparams.analEndPoint\ - localparams.analStartPoint; localparams.numAnalPointsBuf = localparams.analEndPointBuf\ - localparams.analStartPointBuf; /* Max template length is start length minus PSD truncation */ localparams.maxTempLength = localparams.analStartTime; localparams.maxTempLength -= localparams.truncateDuration/2.; /* Determine the number of short slides */ if (localparams.doShortSlides) { localparams.numShortSlides = 1 + localparams.numIFO * (int) floor( \ localparams.strideDuration / \ (localparams.shortSlideOffset * (localparams.numIFO-1)) ); } else { localparams.numShortSlides = 1; } /* Set the template correction factor */ if ( localparams.approximant == FindChirpSP) { /* Most of this gets stored in fcTmplt->fcTmpltNorm which is computed on * the fly. This is the correction needed to that. */ /* First need to add ( (df)**-7./6. )**2 */ localparams.tempCorrFac = pow(localparams.segmentDuration,14./6.); /* For some reason FindChirp multiplies by a dt factor, take this out */ localparams.tempCorrFac *= pow(localparams.sampleRate,2./6.); } else { /* Sigmasq factors are not yet available for all approximants */ /* Set values to 1 (so this factor has no effect) and warn user */ verbose("warning: Sigmasq correction factor is not yet available for this approximant: setting it to 1.\n"); localparams.tempCorrFac = 1.0; } *params = localparams; return 0; }
static struct options parse_command_line(int *argc, char **argv[], const ProcessTable *process, ProcessParamsTable **paramaddpoint) { struct options options = options_defaults(); int c; int option_index; struct LALoption long_options[] = { {"gps-end-time", required_argument, NULL, 'A'}, {"gps-start-time", required_argument, NULL, 'B'}, {"help", no_argument, NULL, 'C'}, {"max-amplitude", required_argument, NULL, 'D'}, {"min-amplitude", required_argument, NULL, 'E'}, {"max-bandwidth", required_argument, NULL, 'F'}, {"min-bandwidth", required_argument, NULL, 'G'}, {"max-duration", required_argument, NULL, 'H'}, {"min-duration", required_argument, NULL, 'I'}, {"max-e-over-r2", required_argument, NULL, 'S'}, {"min-e-over-r2", required_argument, NULL, 'T'}, {"max-frequency", required_argument, NULL, 'J'}, {"min-frequency", required_argument, NULL, 'K'}, {"max-hrss", required_argument, NULL, 'L'}, {"min-hrss", required_argument, NULL, 'M'}, {"output", required_argument, NULL, 'V'}, {"population", required_argument, NULL, 'N'}, {"q", required_argument, NULL, 'O'}, {"ra-dec", required_argument, NULL, 'U'}, {"seed", required_argument, NULL, 'P'}, {"time-step", required_argument, NULL, 'Q'}, {"time-slide-file", required_argument, NULL, 'W'}, {"jitter", required_argument, NULL, 'X'}, {"user-tag", required_argument, NULL, 'R'}, {NULL, 0, NULL, 0} }; do switch(c = LALgetopt_long(*argc, *argv, "", long_options, &option_index)) { case 'A': XLALClearErrno(); { LIGOTimeGPS tmp; XLALStrToGPS(&tmp, LALoptarg, NULL); options.gps_end_time = XLALGPSToINT8NS(&tmp); } if(xlalErrno) { fprintf(stderr, "invalid --%s (%s specified)\n", long_options[option_index].name, LALoptarg); exit(1); } ADD_PROCESS_PARAM(process, "lstring"); break; case 'B': XLALClearErrno(); { LIGOTimeGPS tmp; XLALStrToGPS(&tmp, LALoptarg, NULL); options.gps_start_time = XLALGPSToINT8NS(&tmp); } if(xlalErrno) { fprintf(stderr, "invalid --%s (%s specified)\n", long_options[option_index].name, LALoptarg); exit(1); } ADD_PROCESS_PARAM(process, "lstring"); break; case 'C': print_usage(); exit(0); case 'D': options.maxA = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'E': options.minA = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'F': options.maxbandwidth = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'G': options.minbandwidth = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'H': options.maxduration = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'I': options.minduration = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'J': options.maxf = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'K': options.minf = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'L': options.maxhrss = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'M': options.minhrss = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'N': if(!strcmp(LALoptarg, "targeted")) options.population = POPULATION_TARGETED; else if(!strcmp(LALoptarg, "string_cusp")) options.population = POPULATION_STRING_CUSP; else if(!strcmp(LALoptarg, "all_sky_sinegaussian")) options.population = POPULATION_ALL_SKY_SINEGAUSSIAN; else if(!strcmp(LALoptarg, "all_sky_btlwnb")) options.population = POPULATION_ALL_SKY_BTLWNB; else { fprintf(stderr, "error: unrecognized population \"%s\"", LALoptarg); exit(1); } ADD_PROCESS_PARAM(process, "lstring"); break; case 'O': options.q = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'P': options.seed = atol(LALoptarg); ADD_PROCESS_PARAM(process, "int_8u"); break; case 'Q': options.time_step = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'R': options.user_tag = LALoptarg; ADD_PROCESS_PARAM(process, "lstring"); break; case 'S': options.maxEoverr2 = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'T': options.minEoverr2 = atof(LALoptarg); ADD_PROCESS_PARAM(process, "real_8"); break; case 'U': { char *end; options.ra = strtod(LALoptarg, &end); while(isspace(*end)) end++; if(*end != ',') { fprintf(stderr, "error: cannot parse --ra-dec \"%s\"\n", LALoptarg); exit(1); } options.dec = strtod(end + 1, &end); while(isspace(*end)) end++; if(*end != '\0') { fprintf(stderr, "error: cannot parse --ra-dec \"%s\"\n", LALoptarg); exit(1); } } ADD_PROCESS_PARAM(process, "lstring"); break; case 'V': options.output = LALoptarg; break; case 'W': options.time_slide_file = LALoptarg; ADD_PROCESS_PARAM(process, "lstring"); break; case 'X': options.jitter = atof(LALoptarg); ADD_PROCESS_PARAM(process, "lstring"); break; case 0: /* option sets a flag */ break; case -1: /* end of arguments */ break; case '?': /* unrecognized option */ print_usage(); exit(1); case ':': /* missing argument for an option */ print_usage(); exit(1); } while(c != -1); /* check some of the input parameters for consistency */ if(options.maxA < options.minA) { fprintf(stderr, "error: --max-amplitude < --min-amplitude\n"); exit(1); } if(options.maxbandwidth < options.minbandwidth) { fprintf(stderr, "error: --max-bandwidth < --min-bandwidth\n"); exit(1); } if(options.maxduration < options.minduration) { fprintf(stderr, "error: --max-duration < --min-duration\n"); exit(1); } if(options.maxf < options.minf) { fprintf(stderr, "error: --max-frequency < --min-frequency\n"); exit(1); } if(options.maxhrss < options.minhrss) { fprintf(stderr, "error: --max-hrss < --min-hrss\n"); exit(1); } if(options.gps_start_time == -1 || options.gps_end_time == -1) { fprintf(stderr, "--gps-start-time and --gps-end-time are both required\n"); exit(1); } if(options.gps_end_time < options.gps_start_time) { fprintf(stderr, "error: --gps-end-time < --gps-start-time\n"); exit(1); } if(!options.time_slide_file) { fprintf(stderr, "--time-slide-file is required\n"); exit(1); } switch(options.population) { case POPULATION_TARGETED: case POPULATION_ALL_SKY_SINEGAUSSIAN: case POPULATION_ALL_SKY_BTLWNB: case POPULATION_STRING_CUSP: break; default: fprintf(stderr, "error: --population is required\n"); exit(1); } if(!options.output) { int max_length = 100; /* ARGH: ugly */ options.output = calloc(max_length + 1, sizeof(*options.output)); if(options.user_tag) snprintf(options.output, max_length, "HL-INJECTIONS_%s-%d-%d.xml", options.user_tag, (int) (options.gps_start_time / LAL_INT8_C(1000000000)), (int) ((options.gps_end_time - options.gps_start_time) / LAL_INT8_C(1000000000))); else snprintf(options.output, max_length, "HL-INJECTIONS-%d-%d.xml", (int) (options.gps_start_time / LAL_INT8_C(1000000000)), (int) ((options.gps_end_time - options.gps_start_time) / LAL_INT8_C(1000000000))); } return options; }
/* Internal function to parse integer strings into UINT8 magnitudes plus a sign. */ static UINT8 LALStringToU8AndSign(INT2 * sign, const CHAR * string, CHAR ** endptr) { union { char *s; const char *cs; } bad; /* there is a REASON for warnings... */ const CHAR *here = string; /* current position in string */ CHAR c; /* current character in string */ UINT4 n = LAL_UINT8_MAXDIGITS - 1; /* number of worry-free digits */ UINT8 value; /* current converted value */ /* Skip leading space, and read sign character, if any. */ *sign = 1; while (isspace(*here)) here++; if (*here == '+') here++; else if (*here == '-') { *sign = -1; here++; } /* Read first digit. Abort if it's not a digit. */ if (isdigit((int) (c = *here))) { value = (UINT8) (c - '0'); here++; } else { bad.cs = string; /* ... and this avoids the warnings... BAD! */ *endptr = bad.s; return 0; } /* Otherwise, start reading number. Stop if we get close to overflowing. */ while (isdigit((int) (c = *here)) && --n) { value *= LAL_INT8_C(10); value += (UINT8) (c - '0'); here++; } /* Proceed with caution near overflow. At this point, if n==0, then c = *here is the (LAL_UINT8_MAXDIGITS)th digit read, but value does not yet incorporate it. */ if (!n) { here++; if (isdigit((int) (*here))) { value = LAL_UINT8_MAX; do here++; while (isdigit((int) (*here))); } else if (value > LAL_UINT8_MAX / LAL_INT8_C(10)) { value = LAL_UINT8_MAX; } else { UINT8 increment = (UINT8) (c - '0'); value *= 10; if (value > LAL_UINT8_MAX - increment) value = LAL_UINT8_MAX; else value += increment; } } /* Return appropriate values. */ bad.cs = here; /* ... and this avoids the warnings... BAD! */ *endptr = bad.s; return value; }
int main( int argc, char *argv[] ) { /* lal initialization variables */ LALStatus status = blank_status; /* program option variables */ CHAR *userTag = NULL; CHAR comment[LIGOMETA_COMMENT_MAX]; char *ifoName = NULL; char *inputGlob = NULL; char *inputFileName = NULL; char *outputFileName = NULL; char *tamaFileName = NULL; char *summFileName = NULL; REAL4 snrStar = -1; SnglInspiralClusterChoice clusterchoice = none; INT8 cluster_dt = -1; char *injectFileName = NULL; INT8 inject_dt = -1; char *missedFileName = NULL; INT4 hardware = 0; int enableTrigStartTime = 1; int j; FILE *fp = NULL; glob_t globbedFiles; int numInFiles = 0; char **inFileNameList; char line[MAX_PATH]; int errnum; UINT8 triggerInputTimeNS = 0; MetadataTable proctable; MetadataTable procparams; ProcessParamsTable *this_proc_param; UINT4 numSimEvents = 0; UINT4 numSimInData = 0; UINT4 numSimFound = 0; UINT4 numSimMissed = 0; UINT4 numSimDiscard = 0; UINT4 numSimProcessed = 0; SimRingdownTable *simEventHead = NULL; SimRingdownTable *thisSimEvent = NULL; SimRingdownTable *missedSimHead = NULL; SimRingdownTable *thisMissedSim = NULL; SimRingdownTable *tmpSimEvent = NULL; SimRingdownTable *prevSimEvent = NULL; SearchSummaryTable *searchSummaryTable = NULL; UINT4 numEvents = 0; UINT4 numEventsKept = 0; UINT4 numEventsInIFO = 0; UINT4 numEventsCoinc = 0; UINT4 numEventsDiscard = 0; UINT4 numEventsProcessed = 0; UINT4 numClusteredEvents = 0; SnglRingdownTable **eventHandle = NULL; SnglRingdownTable *eventHead = NULL; SnglRingdownTable *thisEvent = NULL; SnglRingdownTable *tmpEvent = NULL; SnglRingdownTable *prevEvent = NULL; LIGOLwXMLStream xmlStream; MetadataTable outputTable; /* * * initialization * */ /* set up inital debugging values */ lal_errhandler = LAL_ERR_EXIT; /* create the process and process params tables */ proctable.processTable = (ProcessTable *) calloc( 1, sizeof(ProcessTable) ); XLALGPSTimeNow(&(proctable.processTable->start_time)); XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME, lalAppsVCSIdentId, lalAppsVCSIdentStatus, lalAppsVCSIdentDate, 0); this_proc_param = procparams.processParamsTable = (ProcessParamsTable *) calloc( 1, sizeof(ProcessParamsTable) ); memset( comment, 0, LIGOMETA_COMMENT_MAX * sizeof(CHAR) ); /* * * parse command line arguments * */ while (1) { /* LALgetopt arguments */ static struct LALoption long_options[] = { {"verbose", no_argument, &vrbflg, 1 }, {"sort-triggers", no_argument, &sortTriggers, 1 }, {"help", no_argument, 0, 'h'}, {"user-tag", required_argument, 0, 'Z'}, {"userTag", required_argument, 0, 'Z'}, {"comment", required_argument, 0, 'c'}, {"version", no_argument, 0, 'V'}, {"glob", required_argument, 0, 'g'}, {"input", required_argument, 0, 'i'}, {"output", required_argument, 0, 'o'}, {"data-type", required_argument, 0, 'k'}, {"tama-output", required_argument, 0, 'j'}, {"summary-file", required_argument, 0, 'S'}, {"snr-threshold", required_argument, 0, 's'}, {"cluster-algorithm", required_argument, 0, 'C'}, {"cluster-time", required_argument, 0, 't'}, {"ifo-cut", required_argument, 0, 'd'}, {"injection-file", required_argument, 0, 'I'}, {"injection-coincidence", required_argument, 0, 'T'}, {"missed-injections", required_argument, 0, 'm'}, {"hardware-injections", required_argument, 0, 'H'}, {"disable-trig-start-time", no_argument, 0, 'D'}, {0, 0, 0, 0} }; int c; /* LALgetopt_long stores the option index here. */ int option_index = 0; size_t LALoptarg_len; c = LALgetopt_long_only ( argc, argv, "hZ:c:d:g:i:o:j:S:s:C:Vt:I:T:m:H:D", long_options, &option_index ); /* detect the end of the options */ if ( c == - 1 ) break; switch ( c ) { case 0: /* if this option set a flag, do nothing else now */ if ( long_options[option_index].flag != 0 ) { break; } else { fprintf( stderr, "error parsing option %s with argument %s\n", long_options[option_index].name, LALoptarg ); exit( 1 ); } break; case 'h': fprintf( stdout, USAGE ); exit( 0 ); break; case 'Z': /* create storage for the usertag */ LALoptarg_len = strlen( LALoptarg ) + 1; userTag = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR) ); memcpy( userTag, LALoptarg, LALoptarg_len ); this_proc_param = this_proc_param->next = (ProcessParamsTable *) calloc( 1, sizeof(ProcessParamsTable) ); snprintf( this_proc_param->program, LIGOMETA_PROGRAM_MAX, "%s", PROGRAM_NAME ); snprintf( this_proc_param->param, LIGOMETA_PARAM_MAX, "-userTag" ); snprintf( this_proc_param->type, LIGOMETA_TYPE_MAX, "string" ); snprintf( this_proc_param->value, LIGOMETA_VALUE_MAX, "%s", LALoptarg ); break; case 'c': if ( strlen( LALoptarg ) > LIGOMETA_COMMENT_MAX - 1 ) { fprintf( stderr, "invalid argument to --%s:\n" "comment must be less than %d characters\n", long_options[option_index].name, LIGOMETA_COMMENT_MAX ); exit( 1 ); } else { snprintf( comment, LIGOMETA_COMMENT_MAX, "%s", LALoptarg); } break; case 'V': fprintf( stdout, "Single Ringdown Reader and Injection Analysis\n" "Patrick Brady, Duncan Brown and Steve Fairhurst\n"); XLALOutputVersionString(stderr, 0); exit( 0 ); break; case 'g': /* create storage for the input file glob */ LALoptarg_len = strlen( LALoptarg ) + 1; inputGlob = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR)); memcpy( inputGlob, LALoptarg, LALoptarg_len ); ADD_PROCESS_PARAM( "string", "'%s'", LALoptarg ); break; case 'i': /* create storage for the input file name */ LALoptarg_len = strlen( LALoptarg ) + 1; inputFileName = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR)); memcpy( inputFileName, LALoptarg, LALoptarg_len ); ADD_PROCESS_PARAM( "string", "%s", LALoptarg ); break; case 'o': /* create storage for the output file name */ LALoptarg_len = strlen( LALoptarg ) + 1; outputFileName = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR)); memcpy( outputFileName, LALoptarg, LALoptarg_len ); ADD_PROCESS_PARAM( "string", "%s", LALoptarg ); break; case 'j': /* create storage of the TAMA file name */ LALoptarg_len = strlen( LALoptarg ) + 1; tamaFileName = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR)); memcpy( tamaFileName, LALoptarg, LALoptarg_len ); ADD_PROCESS_PARAM( "string", "%s", LALoptarg ); break; case 'S': /* create storage for the summ file name */ LALoptarg_len = strlen( LALoptarg ) + 1; summFileName = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR)); memcpy( summFileName, LALoptarg, LALoptarg_len ); ADD_PROCESS_PARAM( "string", "%s", LALoptarg ); break; case 's': snrStar = (REAL4) atof( LALoptarg ); if ( snrStar < 0 ) { fprintf( stdout, "invalid argument to --%s:\n" "threshold must be >= 0: " "(%f specified)\n", long_options[option_index].name, snrStar ); exit( 1 ); } ADD_PROCESS_PARAM( "float", "%e", snrStar ); break; case 'k': /* type of data to analyze */ if ( ! strcmp( "playground_only", LALoptarg ) ) { dataType = playground_only; } else if ( ! strcmp( "exclude_play", LALoptarg ) ) { dataType = exclude_play; } else if ( ! strcmp( "all_data", LALoptarg ) ) { dataType = all_data; } else { fprintf( stderr, "invalid argument to --%s:\n" "unknown data type, %s, specified: " "(must be playground_only, exclude_play or all_data)\n", long_options[option_index].name, LALoptarg ); exit( 1 ); } ADD_PROCESS_PARAM( "string", "%s", LALoptarg ); break; case 'C': /* choose the clustering algorithm */ { if ( ! strcmp( "snr_and_chisq", LALoptarg ) ) { clusterchoice = snr_and_chisq; } else if ( ! strcmp( "snrsq_over_chisq", LALoptarg) ) { clusterchoice = snrsq_over_chisq; } else if ( ! strcmp( "snr", LALoptarg) ) { clusterchoice = snr; } else { fprintf( stderr, "invalid argument to --%s:\n" "unknown clustering specified:\n " "%s (must be one of: snr_and_chisq, \n" " snrsq_over_chisq or snr)\n", long_options[option_index].name, LALoptarg); exit( 1 ); } ADD_PROCESS_PARAM( "string", "%s", LALoptarg ); } break; case 't': /* cluster time is specified on command line in ms */ cluster_dt = (INT8) atoi( LALoptarg ); if ( cluster_dt <= 0 ) { fprintf( stdout, "invalid argument to --%s:\n" "custer window must be > 0: " "(%" LAL_INT8_FORMAT " specified)\n", long_options[option_index].name, cluster_dt ); exit( 1 ); } ADD_PROCESS_PARAM( "int", "%" LAL_INT8_FORMAT "", cluster_dt ); /* convert cluster time from ms to ns */ cluster_dt *= LAL_INT8_C(1000000); break; case 'I': /* create storage for the injection file name */ LALoptarg_len = strlen( LALoptarg ) + 1; injectFileName = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR)); memcpy( injectFileName, LALoptarg, LALoptarg_len ); ADD_PROCESS_PARAM( "string", "%s", LALoptarg ); break; case 'd': LALoptarg_len = strlen( LALoptarg ) + 1; ifoName = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR)); memcpy( ifoName, LALoptarg, LALoptarg_len ); ADD_PROCESS_PARAM( "string", "%s", LALoptarg ); break; case 'T': /* injection coincidence time is specified on command line in ms */ inject_dt = (INT8) atoi( LALoptarg ); if ( inject_dt < 0 ) { fprintf( stdout, "invalid argument to --%s:\n" "injection coincidence window must be >= 0: " "(%" LAL_INT8_FORMAT " specified)\n", long_options[option_index].name, inject_dt ); exit( 1 ); } ADD_PROCESS_PARAM( "int", "%" LAL_INT8_FORMAT " ", inject_dt ); /* convert inject time from ms to ns */ inject_dt *= LAL_INT8_C(1000000); break; case 'm': /* create storage for the missed injection file name */ LALoptarg_len = strlen( LALoptarg ) + 1; missedFileName = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR)); memcpy( missedFileName, LALoptarg, LALoptarg_len ); ADD_PROCESS_PARAM( "string", "%s", LALoptarg ); break; case 'H': hardware = (INT4) atoi( LALoptarg ); if ( hardware <= 0 ) { fprintf( stdout, "invalid argument to --%s:\n" "GPS start time of hardware injections must be > 0: " "(%d specified)\n", long_options[option_index].name, hardware ); exit( 1 ); } ADD_PROCESS_PARAM( "int", "%" LAL_INT4_FORMAT " ", hardware ); break; case 'D': enableTrigStartTime = 0; ADD_PROCESS_PARAM( "string", "%s", " " ); break; case '?': exit( 1 ); break; default: fprintf( stderr, "unknown error while parsing options\n" ); exit( 1 ); } } if ( LALoptind < argc ) { fprintf( stderr, "extraneous command line arguments:\n" ); while ( LALoptind < argc ) { fprintf ( stderr, "%s\n", argv[LALoptind++] ); } exit( 1 ); } /* * * can use LALCalloc() / LALMalloc() from here * */ /* don't buffer stdout if we are in verbose mode */ if ( vrbflg ) setvbuf( stdout, NULL, _IONBF, 0 ); /* fill the comment, if a user has specified it, or leave it blank */ if ( ! *comment ) { snprintf( proctable.processTable->comment, LIGOMETA_COMMENT_MAX, " " ); } else { snprintf( proctable.processTable->comment, LIGOMETA_COMMENT_MAX, "%s", comment ); } /* check that the input and output file names have been specified */ if ( (! inputGlob && ! inputFileName) || (inputGlob && inputFileName) ) { fprintf( stderr, "exactly one of --glob or --input must be specified\n" ); exit( 1 ); } if ( ! outputFileName ) { fprintf( stderr, "--output must be specified\n" ); exit( 1 ); } /* check that Data Type has been specified */ if ( dataType == unspecified_data_type ) { fprintf( stderr, "Error: --data-type must be specified\n"); exit(1); } /* check that if clustering is being done that we have all the options */ if ( clusterchoice && cluster_dt < 0 ) { fprintf( stderr, "--cluster-time must be specified if --cluster-algorithm " "is given\n" ); exit( 1 ); } else if ( ! clusterchoice && cluster_dt >= 0 ) { fprintf( stderr, "--cluster-algorithm must be specified if --cluster-time " "is given\n" ); exit( 1 ); } /* check that we have all the options to do injections */ if ( injectFileName && inject_dt < 0 ) { fprintf( stderr, "--injection-coincidence must be specified if " "--injection-file is given\n" ); exit( 1 ); } else if ( ! injectFileName && inject_dt >= 0 ) { fprintf( stderr, "--injection-file must be specified if " "--injection-coincidence is given\n" ); exit( 1 ); } /* save the sort triggers flag */ if ( sortTriggers ) { this_proc_param = this_proc_param->next = (ProcessParamsTable *) calloc( 1, sizeof(ProcessParamsTable) ); snprintf( this_proc_param->program, LIGOMETA_PROGRAM_MAX, "%s", PROGRAM_NAME ); snprintf( this_proc_param->param, LIGOMETA_PARAM_MAX, "--sort-triggers" ); snprintf( this_proc_param->type, LIGOMETA_TYPE_MAX, "string" ); snprintf( this_proc_param->value, LIGOMETA_VALUE_MAX, " " ); } switch ( dataType ) { case playground_only: if ( vrbflg ) fprintf( stdout, "using data from playground times only\n" ); snprintf( procparams.processParamsTable->program, LIGOMETA_PROGRAM_MAX, "%s", PROGRAM_NAME ); snprintf( procparams.processParamsTable->param, LIGOMETA_PARAM_MAX, "--playground-only" ); snprintf( procparams.processParamsTable->type, LIGOMETA_TYPE_MAX, "string" ); snprintf( procparams.processParamsTable->value, LIGOMETA_TYPE_MAX, " " ); break; case exclude_play: if ( vrbflg ) fprintf( stdout, "excluding all triggers in playground times\n" ); snprintf( procparams.processParamsTable->program, LIGOMETA_PROGRAM_MAX, "%s", PROGRAM_NAME ); snprintf( procparams.processParamsTable->param, LIGOMETA_PARAM_MAX, "--exclude-play" ); snprintf( procparams.processParamsTable->type, LIGOMETA_TYPE_MAX, "string" ); snprintf( procparams.processParamsTable->value, LIGOMETA_TYPE_MAX, " " ); break; case all_data: if ( vrbflg ) fprintf( stdout, "using all input data\n" ); snprintf( procparams.processParamsTable->program, LIGOMETA_PROGRAM_MAX, "%s", PROGRAM_NAME ); snprintf( procparams.processParamsTable->param, LIGOMETA_PARAM_MAX, "--all-data" ); snprintf( procparams.processParamsTable->type, LIGOMETA_TYPE_MAX, "string" ); snprintf( procparams.processParamsTable->value, LIGOMETA_TYPE_MAX, " " ); break; default: fprintf( stderr, "data set not defined\n" ); exit( 1 ); } /* * * read in the injection XML file, if we are doing an injection analysis * */ if ( injectFileName ) { if ( vrbflg ) fprintf( stdout, "reading injections from %s... ", injectFileName ); simEventHead = XLALSimRingdownTableFromLIGOLw( injectFileName, 0, 0 ); if ( vrbflg ) fprintf( stdout, "got %d injections\n", numSimEvents ); if ( ! simEventHead ) { fprintf( stderr, "error: unable to read sim_ringdown table from %s\n", injectFileName ); exit( 1 ); } /* if we are doing hardware injections, increment all the start times */ if ( hardware ) { if ( vrbflg ) fprintf( stdout, "incrementing GPS times of injections by %d seconds\n", hardware ); for ( thisSimEvent = simEventHead; thisSimEvent; thisSimEvent = thisSimEvent->next ) { thisSimEvent->geocent_start_time.gpsSeconds += hardware; thisSimEvent->h_start_time.gpsSeconds += hardware; thisSimEvent->l_start_time.gpsSeconds += hardware; } } /* discard all injection events that are not in the data we want */ if ( dataType != all_data ) { numSimDiscard = 0; thisSimEvent = simEventHead; simEventHead = NULL; prevSimEvent = NULL; if ( vrbflg ) fprintf( stdout, "discarding injections not in data\n" ); while ( thisSimEvent ) { INT4 isPlayground = XLALINT8NanoSecIsPlayground(XLALGPSToINT8NS(&(thisSimEvent->geocent_start_time))); if ( (dataType == playground_only && isPlayground) || (dataType == exclude_play && ! isPlayground) ) { /* store the head of the linked list */ if ( ! simEventHead ) simEventHead = thisSimEvent; /* keep this event */ prevSimEvent = thisSimEvent; thisSimEvent = thisSimEvent->next; ++numSimInData; if ( vrbflg ) fprintf( stdout, "+" ); } else { /* throw this event away */ tmpSimEvent = thisSimEvent; if ( prevSimEvent ) prevSimEvent->next = thisSimEvent->next; thisSimEvent = thisSimEvent->next; LALFree( tmpSimEvent ); ++numSimDiscard; if ( vrbflg ) fprintf( stdout, "-" ); } } if ( vrbflg ) fprintf( stdout, "\nusing %d (discarded %d) of %d injections\n", numSimInData, numSimDiscard, numSimEvents ); } else { if ( vrbflg ) fprintf( stdout, "using all %d injections\n", numSimInData ); numSimInData = numSimEvents; } } /* * * read in the input triggers from the xml files * */ if ( inputGlob ) { /* use glob() to get a list of the input file names */ if ( glob( inputGlob, GLOB_ERR, NULL, &globbedFiles ) ) { fprintf( stderr, "error globbing files from %s\n", inputGlob ); perror( "error:" ); exit( 1 ); } numInFiles = globbedFiles.gl_pathc; inFileNameList = (char **) LALCalloc( numInFiles, sizeof(char *) ); for ( j = 0; j < numInFiles; ++j ) { inFileNameList[j] = globbedFiles.gl_pathv[j]; } } else if ( inputFileName ) { /* read the list of input filenames from a file */ fp = fopen( inputFileName, "r" ); if ( ! fp ) { fprintf( stderr, "could not open file containing list of xml files\n" ); perror( "error:" ); exit( 1 ); } /* count the number of lines in the file */ while ( get_next_line( line, sizeof(line), fp ) ) { ++numInFiles; } rewind( fp ); /* allocate memory to store the input file names */ inFileNameList = (char **) LALCalloc( numInFiles, sizeof(char *) ); /* read in the input file names */ for ( j = 0; j < numInFiles; ++j ) { inFileNameList[j] = (char *) LALCalloc( MAX_PATH, sizeof(char) ); get_next_line( line, sizeof(line), fp ); strncpy( inFileNameList[j], line, strlen(line) - 1); } fclose( fp ); } else { fprintf( stderr, "no input file mechanism specified\n" ); exit( 1 ); } if ( vrbflg ) { fprintf( stdout, "reading input triggers from:\n" ); for ( j = 0; j < numInFiles; ++j ) { fprintf( stdout, "%s\n", inFileNameList[j] ); } } /* * * read in the triggers from the input xml files * */ if ( injectFileName ) { thisSimEvent = simEventHead; simEventHead = NULL; prevSimEvent = NULL; numSimDiscard = 0; numSimInData = 0; if ( vrbflg ) fprintf( stdout, "discarding injections not in input data\n" ); } for ( j = 0; j < numInFiles; ++j ) { LIGOTimeGPS inPlay, outPlay; UINT8 outPlayNS, outStartNS, outEndNS, triggerTimeNS; INT4 trigStartTimeArg = 0; searchSummaryTable = XLALSearchSummaryTableFromLIGOLw( inFileNameList[j] ); if ( ( ! searchSummaryTable ) || searchSummaryTable->next ) { fprintf( stderr, "error: zero or multiple search_summary tables in %s\n", inFileNameList[j] ); exit( 1 ); } if ( enableTrigStartTime ) { /* override the value of out_start_time if there is a non-zero */ /* --trig-start-time option in the process_params table */ /* this is necessary to get round a bug in early versions of */ /* the ringdown code */ int mioStatus; int pParParam; int pParValue; struct MetaioParseEnvironment parseEnv; const MetaioParseEnv env = &parseEnv; /* open the procress_params table from the input file */ mioStatus = MetaioOpenTable( env, inFileNameList[j], "process_params" ); if ( mioStatus ) { fprintf( stderr, "error opening process_params table from file %s\n", inFileNameList[j] ); exit( 1 ); } /* figure out where the param and value columns are */ if ( (pParParam = MetaioFindColumn( env, "param" )) < 0 ) { fprintf( stderr, "unable to find column param in process_params\n" ); MetaioClose(env); exit( 1 ); } if ( (pParValue = MetaioFindColumn( env, "value" )) < 0 ) { fprintf( stderr, "unable to find column value in process_params\n" ); MetaioClose(env); exit( 1 ); } /* get the trigger start time from the process params */ while ( (mioStatus = MetaioGetRow(env)) == 1 ) { if ( ! strcmp( env->ligo_lw.table.elt[pParParam].data.lstring.data, "--trig-start-time" ) ) { trigStartTimeArg = (INT4) atoi( env->ligo_lw.table.elt[pParValue].data.lstring.data ); } } MetaioClose( env ); if ( trigStartTimeArg ) { searchSummaryTable->out_start_time.gpsSeconds = trigStartTimeArg; searchSummaryTable->out_start_time.gpsNanoSeconds = 0; if ( vrbflg ) fprintf( stdout, "file %s has --trig-start-time %d\n", inFileNameList[j], trigStartTimeArg ); } } /* compute the out time from the search summary table */ outStartNS = XLALGPSToINT8NS ( &(searchSummaryTable->out_start_time) ); outEndNS = XLALGPSToINT8NS ( &(searchSummaryTable->out_end_time) ); triggerTimeNS = outEndNS - outStartNS; /* check for events and playground */ if ( dataType != all_data ) { LAL_CALL( LALPlaygroundInSearchSummary( &status, searchSummaryTable, &inPlay, &outPlay ), &status ); outPlayNS = XLALGPSToINT8NS ( &outPlay ); if ( dataType == playground_only ) { if ( outPlayNS ) { /* increment the total trigger time by the amount of playground */ triggerInputTimeNS += outPlayNS; } else { /* skip this file as it does not contain any playground data */ if ( vrbflg ) { fprintf( stdout, "file %s not in playground, continuing\n", inFileNameList[j] ); } LALFree( searchSummaryTable ); searchSummaryTable = NULL; continue; } } else if ( dataType == exclude_play ) { /* increment the total trigger time by the out time minus */ /* the time that is in the playground */ triggerInputTimeNS += triggerTimeNS - outPlayNS; } } else { /* increment the total trigger time by the out time minus */ triggerInputTimeNS += triggerTimeNS; } if ( injectFileName ) { if ( vrbflg ) fprintf( stdout, "discarding injections not in file: " ); /* throw away injections that are outside analyzed times */ while ( thisSimEvent && thisSimEvent->geocent_start_time.gpsSeconds < searchSummaryTable->out_end_time.gpsSeconds ) { /* check if injection is before file start time */ if ( thisSimEvent->geocent_start_time.gpsSeconds < searchSummaryTable->out_start_time.gpsSeconds ) { /* discard the current injection */ if ( prevSimEvent ) prevSimEvent->next = thisSimEvent->next; tmpSimEvent = thisSimEvent; thisSimEvent = thisSimEvent->next; LALFree( tmpSimEvent ); ++numSimDiscard; if ( vrbflg ) fprintf( stdout, "-" ); } else { /* store the head of the linked list */ if ( ! simEventHead ) simEventHead = thisSimEvent; /* keep this injection */ prevSimEvent = thisSimEvent; thisSimEvent = thisSimEvent->next; ++numSimInData; if ( vrbflg ) fprintf( stdout, "+" ); } } if ( vrbflg ) fprintf( stdout, "\n" ); } /* * * if there are any events in the file, read them in * */ if ( searchSummaryTable->nevents ) { INT4 isPlay; if ( vrbflg ) fprintf( stdout, "file %s contains %d events, processing\n", inFileNameList[j], searchSummaryTable->nevents ); if ( ! prevEvent ) { eventHandle = &thisEvent; } else { eventHandle = &(prevEvent->next); } /* read the events from the file into a temporary list */ XLAL_TRY( *eventHandle = XLALSnglRingdownTableFromLIGOLw( inFileNameList[j] ), errnum); if ( ! *eventHandle ) switch ( errnum ) { case XLAL_EDATA: XLALPrintError("Unable to read sngl_ringdown table from %s\n", inFileNameList[j] ); /*LALFree(thisInputFile);*/ XLALClearErrno(); break; default: XLALSetErrno( errnum ); XLAL_ERROR(XLAL_EFUNC ); } /* only keep triggers from the data that we want to analyze */ thisEvent = *eventHandle; while ( thisEvent ) { numEvents++; isPlay = XLALINT8NanoSecIsPlayground( XLALGPSToINT8NS( &(thisEvent->start_time) ) ); if ( (dataType == all_data || (dataType == playground_only && isPlay) || (dataType == exclude_play && ! isPlay)) && ( snrStar < 0 || thisEvent->snr > snrStar) ) { /* keep the trigger and increment the count of triggers */ if ( ! eventHead ) eventHead = thisEvent; prevEvent = thisEvent; thisEvent = thisEvent->next; ++numEventsKept; } else { /* discard the trigger and move to the next one */ if ( prevEvent ) prevEvent->next = thisEvent->next; tmpEvent = thisEvent; thisEvent = thisEvent->next; LAL_CALL ( LALFreeSnglRingdown ( &status, &tmpEvent ), &status); } } /* make sure that the linked list is properly terminated */ if ( prevEvent && prevEvent->next ) prevEvent->next->next = NULL; } else { if ( vrbflg ) fprintf( stdout, "file %s contains no events, skipping\n", inFileNameList[j] ); } LALFree( searchSummaryTable ); searchSummaryTable = NULL; } /* discard the remaining injections which occured after the last file */ if ( injectFileName ) { if ( vrbflg ) fprintf( stdout, "kept %d injections, discarded %d\n", numSimInData, numSimDiscard ); if ( prevSimEvent ) prevSimEvent->next = NULL; numSimDiscard = 0; while ( thisSimEvent ) { tmpSimEvent = thisSimEvent; thisSimEvent = thisSimEvent->next; LALFree( tmpSimEvent ); ++numSimDiscard; if ( vrbflg ) fprintf( stdout, "-" ); } if ( vrbflg ) fprintf( stdout, "\ndiscarded %d injections at end of list\n", numSimDiscard ); } /* * * sort the ringdown events by time * */ if ( injectFileName || sortTriggers ) { if ( vrbflg ) fprintf( stdout, "sorting ringdown trigger list..." ); LAL_CALL( LALSortSnglRingdown( &status, &eventHead, *LALCompareSnglRingdownByTime ), &status ); if ( vrbflg ) fprintf( stdout, "done\n" ); } /* * * keep only event from requested ifo * */ if ( ifoName ) { if ( vrbflg ) fprintf( stdout, "keeping only triggers from %s, discarding others...", ifoName ); LAL_CALL( LALIfoCutSingleRingdown( &status, &eventHead, ifoName ), &status ); LALIfoCountSingleRingdown( &status, &numEventsInIFO, eventHead, XLALIFONumber(ifoName) ); if ( vrbflg ) fprintf( stdout, "done\n" ); } /* * * check for events that are coincident with injections * */ if ( injectFileName ) { int coincidence = 0; UINT8 simTime, ringdownTime; if ( vrbflg ) fprintf( stdout, "checking for events that are coincident with injections\n" ); /* Note: we are assuming that both the ringdown and */ /* injection events are time sorted */ thisSimEvent = simEventHead; thisEvent = eventHead; simEventHead = NULL; eventHead = NULL; prevSimEvent = NULL; prevEvent = NULL; numSimFound = 0; numSimDiscard = 0; numEventsDiscard = 0; numEventsCoinc = 0; if ( ! thisEvent ) { /* no triggers in the input data, so all injections are missed */ if ( vrbflg ) fprintf( stdout, "no triggers in input data\n" ); thisMissedSim = missedSimHead = thisSimEvent; while ( thisMissedSim ) { /* count the number of injections just stuck in the missed list */ if ( vrbflg ) fprintf( stdout, "M" ); ++numSimMissed; ++numSimProcessed; thisMissedSim = thisMissedSim->next; } } else { /* begin loop over the sim_ringdown events */ while ( thisSimEvent ) { /* compute the end time in nanosec for the injection */ /* at the relevant detector */ if ( ! strcmp( "L1", thisEvent->ifo ) ) { simTime = XLALGPSToINT8NS ( &(thisSimEvent->l_start_time) ); } else if ( ! strcmp( "H1", thisEvent->ifo ) || ! strcmp( "H2", thisEvent->ifo ) ) { simTime = XLALGPSToINT8NS ( &(thisSimEvent->h_start_time) ); } else { fprintf( stderr, "unknown detector found in event list: %s\n", thisEvent->ifo ); fprintf( stderr, "Detector must be one of (G1|H1|H2|L1|T1|V1)\n"); exit( 1 ); } /* find the first ringdown event after the current sim event */ while ( thisEvent ) { coincidence = 0; /* compute the time in nanosec for the ringdown */ ringdownTime = XLALGPSToINT8NS ( &(thisEvent->start_time) ); if ( ringdownTime < (simTime - inject_dt) ) { /* discard this event and move on to the next one */ if ( prevEvent ) prevEvent->next = thisEvent->next; tmpEvent = thisEvent; thisEvent = thisEvent->next; LAL_CALL ( LALFreeSnglRingdown ( &status, &tmpEvent ), &status); ++numEventsProcessed; ++numEventsDiscard; if ( vrbflg ) fprintf( stdout, "-" ); } else { /* we have reached the negative coincincidence window */ break; } } while ( thisEvent ) { /* compute the time in nanosec for the ringdown */ ringdownTime = XLALGPSToINT8NS ( &(thisEvent->start_time) ); if ( ringdownTime < (simTime + inject_dt) ) { /* this event is within the coincidence window */ /* store this event and move on to the next one */ if ( ! eventHead ) eventHead = thisEvent; prevEvent = thisEvent; thisEvent = thisEvent->next; coincidence = 1; ++numEventsProcessed; ++numEventsCoinc; if ( vrbflg ) fprintf( stdout, "+" ); } else { /* we have reached the end of the positive coincincidence window */ break; } } if ( coincidence ) { /* keep this event in the list and move to the next sim event */ if ( ! simEventHead ) simEventHead = thisSimEvent; prevSimEvent = thisSimEvent; ++numSimFound; ++numSimProcessed; thisSimEvent = thisSimEvent->next; if ( vrbflg ) fprintf( stdout, "F" ); } else { /* save this sim event in the list of missed events... */ if ( ! missedSimHead ) { missedSimHead = thisMissedSim = thisSimEvent; } else { thisMissedSim = thisMissedSim->next = thisSimEvent; } /* ...and remove it from the list of found events */ if ( prevSimEvent ) prevSimEvent->next = thisSimEvent->next; ++numSimMissed; if ( vrbflg ) fprintf( stdout, "M" ); /* move to the next sim in the list */ ++numSimProcessed; thisSimEvent = thisSimEvent->next; /* make sure the missed sim list is terminated */ thisMissedSim->next = NULL; } if ( ! thisEvent ) { /* these are no more events to process so all the rest of the */ /* injections must be put in the missed injections list */ if ( ! missedSimHead ) { /* this and any subsequent events are in the missed sim list */ if ( thisSimEvent ) thisMissedSim = missedSimHead = thisSimEvent; } else { if ( thisSimEvent ) { /* append the rest of the list to the list of missed injections */ thisMissedSim = thisMissedSim->next = thisSimEvent; } else { /* there are no injections after this one */ thisMissedSim = thisMissedSim->next = NULL; } } /* terminate the list of found injections correctly */ if ( prevSimEvent ) prevSimEvent->next = NULL; while ( thisMissedSim ) { /* count the number of injections just stuck in the missed list */ if ( vrbflg ) fprintf( stdout, "M" ); ++numSimMissed; ++numSimProcessed; thisMissedSim = thisMissedSim->next; } thisSimEvent = NULL; break; } } if ( thisEvent ) { /* discard any remaining ringdown triggers -- including thisEvent */ /* as we have run out of injections */ tmpEvent = thisEvent; if ( prevEvent ) prevEvent->next = NULL; while ( tmpEvent ) { thisEvent = tmpEvent; tmpEvent = tmpEvent->next; LAL_CALL ( LALFreeSnglRingdown ( &status, &thisEvent ), &status); ++numEventsDiscard; ++numEventsProcessed; if ( vrbflg ) fprintf( stdout, "-" ); } } } if ( vrbflg ) { fprintf( stdout, "\nfound %d injections, missed %d injections " "(%d injections processed)\n", numSimFound, numSimMissed, numSimProcessed ); fprintf( stdout, "found %d coincident events, %d events discarded " "(%d events processed)\n", numEventsCoinc, numEventsDiscard, numEventsProcessed ); } } /* end if ( injectFileName ) */ /* * * cluster the remaining events * */ if ( eventHead && clusterchoice ) { if ( vrbflg ) fprintf( stdout, "clustering remaining triggers... " ); LAL_CALL( LALClusterSnglRingdownTable( &status, eventHead, cluster_dt, clusterchoice ), &status ); if ( vrbflg ) fprintf( stdout, "done\n" ); /* count the number of triggers surviving the clustering */ thisEvent = eventHead; numClusteredEvents = 0; while ( thisEvent ) { ++numClusteredEvents; thisEvent = thisEvent->next; } } /* * * write output data * */ /* write the main output file containing found injections */ if ( vrbflg ) fprintf( stdout, "writing output xml files... " ); memset( &xmlStream, 0, sizeof(LIGOLwXMLStream) ); LAL_CALL( LALOpenLIGOLwXMLFile( &status, &xmlStream, outputFileName ), &status ); /* write out the process and process params tables */ if ( vrbflg ) fprintf( stdout, "process... " ); XLALGPSTimeNow(&(proctable.processTable->start_time)); LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, process_table ), &status ); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, proctable, process_table ), &status ); LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status ); free( proctable.processTable ); /* write the process params table */ if ( vrbflg ) fprintf( stdout, "process_params... " ); LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, process_params_table ), &status ); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, procparams, process_params_table ), &status ); LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status ); /* Write the found injections to the sim table */ if ( simEventHead ) { if ( vrbflg ) fprintf( stdout, "sim_ringdown... " ); outputTable.simRingdownTable = simEventHead; LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, sim_ringdown_table ), &status ); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, sim_ringdown_table ), &status ); LAL_CALL( LALEndLIGOLwXMLTable( &status, &xmlStream ), &status ); } /* Write the results to the ringdown table */ if ( eventHead ) { if ( vrbflg ) fprintf( stdout, "sngl_ringdown... " ); outputTable.snglRingdownTable = eventHead; LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, sngl_ringdown_table ), &status ); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, sngl_ringdown_table ), &status ); LAL_CALL( LALEndLIGOLwXMLTable( &status, &xmlStream ), &status); } /* close the output file */ LAL_CALL( LALCloseLIGOLwXMLFile(&status, &xmlStream), &status); if ( vrbflg ) fprintf( stdout, "done\n" ); /* write out the TAMA file if it is requested */ if ( tamaFileName ) { /* FIXME */ REAL8 UNUSED trigtime; fp = fopen( tamaFileName, "w" ); if ( ! fp ) { perror( "TAMA file" ); exit( 1 ); } fprintf( fp, "IFO trigger time snr chisq " " total mass eta eff dist (kpc)\n" ); for ( thisEvent = eventHead; thisEvent; thisEvent = thisEvent->next ) { trigtime = XLALGPSGetREAL8(&(thisEvent->start_time)); } fclose( fp ); } if ( missedFileName ) { /* open the missed injections file and write the missed injections to it */ if ( vrbflg ) fprintf( stdout, "writing missed injections... " ); memset( &xmlStream, 0, sizeof(LIGOLwXMLStream) ); LAL_CALL( LALOpenLIGOLwXMLFile( &status, &xmlStream, missedFileName ), &status ); if ( missedSimHead ) { outputTable.simRingdownTable = missedSimHead; LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, sim_ringdown_table ), &status ); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, sim_ringdown_table ), &status ); LAL_CALL( LALEndLIGOLwXMLTable( &status, &xmlStream ), &status ); } LAL_CALL( LALCloseLIGOLwXMLFile( &status, &xmlStream ), &status ); if ( vrbflg ) fprintf( stdout, "done\n" ); } if ( summFileName ) { LIGOTimeGPS triggerTime; /* write out a summary file */ fp = fopen( summFileName, "w" ); switch ( dataType ) { case playground_only: fprintf( fp, "using data from playground times only\n" ); break; case exclude_play: fprintf( fp, "excluding all triggers in playground times\n" ); break; case all_data: fprintf( fp, "using all input data\n" ); break; default: fprintf( stderr, "data set not defined\n" ); exit( 1 ); } fprintf( fp, "read triggers from %d files\n", numInFiles ); fprintf( fp, "number of triggers in input files: %d \n", numEvents ); if ( snrStar >= 0 ) { fprintf( fp, "number of triggers in input data with snr above %f: %d \n", snrStar, numEventsKept ); } else { fprintf( fp, "number of triggers in input data %d \n", numEventsKept ); } if ( ifoName ) { fprintf( fp, "number of triggers from %s ifo %d \n", ifoName, numEventsInIFO ); } XLALINT8NSToGPS( &triggerTime, triggerInputTimeNS ); fprintf( fp, "amount of time analysed for triggers %d sec %d ns\n", triggerTime.gpsSeconds, triggerTime.gpsNanoSeconds ); if ( injectFileName ) { fprintf( fp, "read %d injections from file %s\n", numSimEvents, injectFileName ); fprintf( fp, "number of injections in input data: %d\n", numSimInData ); fprintf( fp, "number of injections found in input data: %d\n", numSimFound ); fprintf( fp, "number of triggers found within %" LAL_INT8_FORMAT "msec of injection: %d\n", (inject_dt / LAL_INT8_C(1000000) ), numEventsCoinc ); fprintf( fp, "efficiency: %f \n", (REAL4) numSimFound / (REAL4) numSimInData ); } if ( clusterchoice ) { fprintf( fp, "number of event clusters with %" LAL_INT8_FORMAT " msec window: %d\n", cluster_dt/ LAL_INT8_C(1000000), numClusteredEvents ); } fclose( fp ); } /* * * free memory and exit * */ /* free the ringdown events we saved */ while ( eventHead ) { thisEvent = eventHead; eventHead = eventHead->next; LAL_CALL ( LALFreeSnglRingdown ( &status, &thisEvent ), &status); } /* free the process params */ while( procparams.processParamsTable ) { this_proc_param = procparams.processParamsTable; procparams.processParamsTable = this_proc_param->next; free( this_proc_param ); } /* free the found injections */ while ( simEventHead ) { thisSimEvent = simEventHead; simEventHead = simEventHead->next; LALFree( thisSimEvent ); } /* free the temporary memory containing the missed injections */ while ( missedSimHead ) { tmpSimEvent = missedSimHead; missedSimHead = missedSimHead->next; LALFree( tmpSimEvent ); } /* free the input file name data */ if ( inputGlob ) { LALFree( inFileNameList ); globfree( &globbedFiles ); } else { for ( j = 0; j < numInFiles; ++j ) { LALFree( inFileNameList[j] ); } LALFree( inFileNameList ); } if ( vrbflg ) fprintf( stdout, "checking memory leaks and exiting\n" ); LALCheckMemoryLeaks(); exit( 0 ); }