/** * @brief Read a two-column data file. * @details Read a data file containing two whitespace separated columns * of data and create two arrays containing the data in each column. * If any line begins with the character '#' then it is ignored. * @param[out] xdat The x-data stored in the first column. * @param[out] ydat The y-data stored in the second column. * @param fp Pointer to a LALFILE structure opened for input. * @return The number of data points read or <0 if an error occurs. */ size_t XLALSimReadDataFile2Col(double **xdat, double **ydat, LALFILE * fp) { char line[LINE_MAX]; size_t size = PAGESIZE; size_t lnum = 0; size_t npts; *xdat = XLALMalloc(size * sizeof(**xdat)); *ydat = XLALMalloc(size * sizeof(**ydat)); npts = 0; while (XLALFileGets(line, sizeof(line), fp)) { ++lnum; if (strchr(line, '\n') == NULL) { /* line too long */ XLALFree(*xdat); XLALFree(*ydat); XLAL_ERROR(XLAL_EIO, "Line %zd too long\n", lnum); } if (*line == '#') /* ignore lines beginning with a '#' */ continue; if (sscanf(line, "%lf %lf", *xdat + npts, *ydat + npts) != 2) { XLALFree(*xdat); XLALFree(*ydat); XLAL_ERROR(XLAL_EIO, "Line %zd malformed\n", lnum); } if (++npts == size) { size += PAGESIZE; *xdat = XLALRealloc(*xdat, size * sizeof(**xdat)); *ydat = XLALRealloc(*ydat, size * sizeof(**ydat)); } } *xdat = XLALRealloc(*xdat, npts * sizeof(**xdat)); *ydat = XLALRealloc(*ydat, npts * sizeof(**ydat)); return npts; }
/** * Append the given PulsarParamsVector 'add' to the vector 'list' ( which can be NULL), return resulting list * with new elements 'add' appended at the end of 'list'. */ PulsarParamsVector * XLALPulsarParamsVectorAppend ( PulsarParamsVector *list, const PulsarParamsVector *add ) { XLAL_CHECK_NULL ( add != NULL, XLAL_EINVAL ); PulsarParamsVector *ret; if ( list == NULL ) { XLAL_CHECK_NULL ( (ret = XLALCalloc ( 1, sizeof(*ret))) != NULL, XLAL_ENOMEM ); } else { ret = list; } UINT4 oldlen = ret->length; UINT4 addlen = add->length; UINT4 newlen = oldlen + addlen; ret->length = newlen; XLAL_CHECK_NULL ( (ret->data = XLALRealloc ( ret->data, newlen * sizeof(ret->data[0]) )) != NULL, XLAL_ENOMEM ); memcpy ( ret->data + oldlen, add->data, addlen * sizeof(ret->data[0]) ); // we have to properly copy the 'name' string fields for ( UINT4 i = 0; i < addlen; i ++ ) { XLAL_CHECK_NULL ( (ret->data[oldlen + i].name = XLALStringDuplicate ( add->data[i].name )) != NULL, XLAL_EFUNC ); } return ret; } // XLALPulsarParamsVectorAppend()
xmlNodePtr LALInferenceVariableItem2VOTParamNode(LALInferenceVariableItem *const varitem) { VOTABLE_DATATYPE vo_type; CHAR *unitName={0}; UINT4 bufsize=1024; UINT4 required_size=0; CHAR *valString=XLALCalloc(bufsize,sizeof(CHAR)); CHAR arraysize[32]=""; switch(varitem->type) { /* Special case for matrix */ case LALINFERENCE_gslMatrix_t: return(XLALgsl_matrix2VOTNode(*(gsl_matrix **)varitem->value, varitem->name, unitName)); break; /* Special case for string */ case LALINFERENCE_string_t: return(XLALCreateVOTParamNode(varitem->name,unitName,VOT_CHAR,"*",*(char **)varitem->value)); break; case LALINFERENCE_REAL8Vector_t: { REAL8Vector *vec=*(REAL8Vector **)varitem->value; snprintf(arraysize,32,"%i",vec->length); vo_type=VOT_REAL8; break; } case LALINFERENCE_INT4Vector_t: { INT4Vector *vec=*(INT4Vector **)varitem->value; snprintf(arraysize,32,"%i",vec->length); vo_type=VOT_INT4; break; } default: /* Check the type of the item */ vo_type=LALInferenceVariableType2VOT(varitem->type); } if(vo_type>=VOT_DATATYPE_LAST){ XLALPrintError("%s: Unsupported LALInferenceVariableType %i\n",__func__,(int)varitem->type); return NULL; } required_size=LALInferencePrintNVariableItem(valString, bufsize, varitem); if(required_size>bufsize){ bufsize=required_size; valString=XLALRealloc(valString,bufsize*sizeof(CHAR)); required_size=LALInferencePrintNVariableItem(valString, bufsize, varitem); } xmlNodePtr node = XLALCreateVOTParamNode(varitem->name,unitName,vo_type,arraysize,valString); XLALFree(valString); return(node); }
/** * Resize a candidateVector * \param [in] vector Pointer of vector to resize * \param [in] length New length of candidateVector * \return Pointer to resized vector */ candidateVector * resize_candidateVector(candidateVector *vector, UINT4 length) { if (vector==NULL) return new_candidateVector(length); if (length==0) { free_candidateVector(vector); return NULL; } XLAL_CHECK_NULL( (vector->data = XLALRealloc(vector->data, length*sizeof(*vector->data))) != NULL, XLAL_ENOMEM ); vector->length = length; return vector; } /* resize_candidateVector() */
/** * Resize an UpperLimitVector * \param [in,out] vector Pointer to UpperLimitVector to resize * \param [in] length New length of the vector * \return Pointer to reallocated UpperLimitVector */ UpperLimitVector * resize_UpperLimitVector(UpperLimitVector *vector, UINT4 length) { if (vector==NULL) return new_UpperLimitVector(length); if (length==0) { free_UpperLimitVector(vector); return NULL; } UINT4 oldlength = vector->length; XLAL_CHECK_NULL( (vector->data = XLALRealloc(vector->data, length*sizeof(*vector->data))) != NULL, XLAL_ENOMEM ); vector->length = length; for (UINT4 ii=oldlength; ii<length; ii++) reset_UpperLimitStruct(&(vector->data[ii])); return vector; } /* resize_UpperLimitVector() */
/** The main function of binary2sft.c * */ int main( int argc, char *argv[] ) { UserInput_t uvar = empty_UserInput; /* user input variables */ INT4 i,j; /* counter */ SFTVector *SFTvect = NULL; char *noisestr = XLALCalloc(1,sizeof(char)); /**********************************************************************************/ /* 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; } LogPrintf(LOG_DEBUG,"%s : read in uservars\n",__func__); /**********************************************************************************/ /* read in the cache 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; while (fscanf(cachefp,"%*s %*d %*d")!=EOF) i++; INT4 Nfiles = i; fclose(cachefp); LogPrintf(LOG_DEBUG,"%s : counted %d files listed in the cache file.\n",__func__,Nfiles); /* allocate memory */ char **filenames = LALCalloc(Nfiles,sizeof(char*)); LIGOTimeGPSVector fileStart; fileStart.data = LALCalloc(Nfiles,sizeof(LIGOTimeGPS)); for (i=0;i<Nfiles;i++) filenames[i] = LALCalloc(512,sizeof(char)); if ((cachefp = fopen(uvar.cachefile,"r")) == NULL) { LogPrintf(LOG_CRITICAL,"%s : failed to open binary input file %s\n",__func__,uvar.cachefile); return 1; } for (i=0;i<Nfiles;i++) { fscanf(cachefp,"%s %d %d %*d",filenames[i],&(fileStart.data[i].gpsSeconds),&(fileStart.data[i].gpsNanoSeconds)); } fclose(cachefp); /* initialise the random number generator */ gsl_rng * r; if (XLALInitgslrand(&r,uvar.seed)) { LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_EFAULT); } /* setup the binaryToSFT parameters */ BinaryToSFTparams par; par.tsft = uvar.tsft; par.freq = uvar.freq; par.freqband = uvar.freqband; par.tsamp = uvar.tsamp; par.highpassf = uvar.highpassf; par.amp_inj = uvar.amp_inj; par.f_inj = uvar.f_inj; par.asini_inj = uvar.asini_inj; XLALGPSSetREAL8(&(par.tasc_inj),uvar.tasc_inj); par.tref = fileStart.data[0]; par.P_inj = uvar.P_inj; par.phi_inj = uvar.phi_inj; par.r = r; /**********************************************************************************/ /* loop over the input files */ long int ntot = 0; for (j=0;j<Nfiles;j++) { UINT4 k = 0; INT8Vector *np = NULL; REAL8Vector *R = NULL; par.tstart = fileStart.data[j]; REAL8 norm1 = par.tsamp/par.tsft; REAL8 norm2 = 1.0/(par.tsamp*par.tsft); UINT4 oldlen; if (SFTvect==NULL) oldlen = 0; else oldlen = SFTvect->length; LogPrintf(LOG_DEBUG,"%s : working on file %s\n",__func__,filenames[j]); if (XLALBinaryToSFTVector(&SFTvect,filenames[j],&(fileStart.data[j]),&par,&np,&R)) { LogPrintf(LOG_CRITICAL,"%s : failed to convert binary input file %s to sfts\n",__func__,filenames[j]); return 1; } if ((np!=NULL) && (R!=NULL)) { for (k=0;k<np->length;k++) { ntot += np->data[k]; char temp[64]; sprintf(temp,"%d %e %e\n",SFTvect->data[oldlen+k].epoch.gpsSeconds,(REAL8)np->data[k]*norm1,R->data[k]*norm2); noisestr = (char *)XLALRealloc(noisestr,sizeof(char)*(1+strlen(noisestr)+strlen(temp))); strcat(noisestr,temp); } XLALDestroyINT8Vector(np); XLALDestroyREAL8Vector(R); } } /* end loop over input files */ /**********************************************************************************/ /* create a noise string */ /**********************************************************************************/ /* generate comment string */ char *VCSInfoString = XLALGetVersionString(0); XLAL_CHECK ( VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" ); CHAR *logstr; size_t len; XLAL_CHECK ( (logstr = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) != NULL, XLAL_EFUNC ); char *comment = XLALCalloc ( 1, len = strlen ( logstr ) + strlen(VCSInfoString) + strlen(noisestr) + 512 ); XLAL_CHECK ( comment != NULL, XLAL_ENOMEM, "XLALCalloc(1,%zd) failed.\n", len ); sprintf ( comment, "Generated by:\n%s\n%s\nTotal number of photons = %ld\n%s\n", logstr, VCSInfoString, ntot, noisestr ); /**********************************************************************************/ /* either write whole SFT-vector to single concatenated file */ if ( uvar.outSingleSFT ) { XLAL_CHECK ( XLALWriteSFTVector2File( SFTvect, uvar.outputdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { /* or as individual SFT-files */ XLAL_CHECK ( XLALWriteSFTVector2Dir( SFTvect, uvar.outputdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC ); } /**********************************************************************************/ /* free memory */ XLALDestroySFTVector(SFTvect); XLALFree(logstr); XLALFree(comment); XLALFree(noisestr); LALCheckMemoryLeaks(); return 0; }
/** * \brief Serializes an array of \c LALInferenceVariables into a VOTable XML %node * * This function takes a \c LALInferenceVariables structure and serializes it into a VOTable * \c RESOURCE %node identified by the given name. The returned \c xmlNode can then be * embedded into an existing %node hierarchy or turned into a full VOTable document. * A VOTable Table element is returned, with fixed variables as PARAMs and the varying ones as FIELDs. * * \param varsArray [in] Pointer to an array of \c LALInferenceVariables structures to be serialized * \param N [in] Number of items in the array * \param tablename UNDOCUMENTED * * \return A pointer to a \c xmlNode that holds the VOTable fragment that represents * the \c LALInferenceVariables array. * In case of an error, a null-pointer is returned.\n * \b Important: the caller is responsible to free the allocated memory (when the * fragment isn't needed anymore) using \c xmlFreeNode. Alternatively, \c xmlFreeDoc * can be used later on when the returned fragment has been embedded in a XML document. * * \sa XLALCreateVOTParamNode * \sa XLALCreateVOTResourceNode * * \author John Veitch * */ xmlNodePtr XLALInferenceVariablesArray2VOTTable(LALInferenceVariables * const *const varsArray, UINT4 N, const char *tablename) { xmlNodePtr fieldNodeList=NULL; xmlNodePtr paramNodeList=NULL; xmlNodePtr xmlTABLEDATAnode=NULL; xmlNodePtr VOTtableNode=NULL; xmlNodePtr tmpNode=NULL; xmlNodePtr field_ptr,param_ptr; LALInferenceVariableItem *varitem=NULL; UINT4 Nfields=0; UINT4 bufsize=1024; int err; /* Sanity check input */ if(!varsArray) { XLALPrintError("Received null varsArray pointer"); XLAL_ERROR_NULL(XLAL_EFAULT); } if(N==0) return(NULL); field_ptr=fieldNodeList; param_ptr=paramNodeList; char *field_names[varsArray[0]->dimension]; /* Build a list of PARAM and FIELD elements */ for(varitem=varsArray[0]->head;varitem;varitem=varitem->next) { tmpNode=NULL; switch(varitem->vary){ case LALINFERENCE_PARAM_LINEAR: case LALINFERENCE_PARAM_CIRCULAR: case LALINFERENCE_PARAM_OUTPUT: { tmpNode=LALInferenceVariableItem2VOTFieldNode(varitem); if(!tmpNode) { XLALPrintWarning ("%s: xmlAddNextSibling() failed to add field node for %s.\n", __func__, varitem->name ); //XLAL_ERROR_NULL(XLAL_EFAILED); continue; } if(field_ptr) field_ptr=xmlAddNextSibling(field_ptr,tmpNode); else {field_ptr=tmpNode; fieldNodeList=field_ptr;} field_names[Nfields]=varitem->name; Nfields++; break; } case LALINFERENCE_PARAM_FIXED: { tmpNode=LALInferenceVariableItem2VOTParamNode(varitem); if(!tmpNode) { XLALPrintWarning ("%s: xmlAddNextSibling() failed to add param node for %s.\n", __func__, varitem->name ); //XLAL_ERROR_NULL(XLAL_EFAILED); continue; } if(param_ptr) param_ptr=xmlAddNextSibling(param_ptr,tmpNode); else {param_ptr=tmpNode; paramNodeList=param_ptr;} break; } default: { XLALPrintWarning("Unknown param vary type"); } } } if(Nfields>0) { UINT4 row,col; /* create TABLEDATA node */ if ( ( xmlTABLEDATAnode = xmlNewNode ( NULL, CAST_CONST_XMLCHAR("TABLEDATA") ))== NULL ) { XLALPrintError ("%s: xmlNewNode() failed to create 'TABLEDATA' node.\n", __func__ ); err = XLAL_ENOMEM; goto failed; } /* ---------- loop over data-arrays and generate each table-row */ for ( row = 0; row < N; row ++ ) { /* create TR node */ xmlNodePtr xmlThisRowNode = NULL; if ( (xmlThisRowNode = xmlNewNode ( NULL, CAST_CONST_XMLCHAR("TR") )) == NULL ) { XLALPrintError ("%s: xmlNewNode() failed to create new 'TR' node.\n", __func__ ); err = XLAL_EFAILED; goto failed; } if ( xmlAddChild(xmlTABLEDATAnode, xmlThisRowNode ) == NULL ) { XLALPrintError ("%s: failed to insert 'TR' node into 'TABLEDATA' node.\n", __func__ ); err = XLAL_EFAILED; goto failed; } /* ----- loop over columns and generate each table element */ for ( col = 0; col < Nfields; col ++ ) { /* create TD node */ xmlNodePtr xmlThisEntryNode = NULL; if ( (xmlThisEntryNode = xmlNewNode ( NULL, CAST_CONST_XMLCHAR("TD") )) == NULL ) { XLALPrintError ("%s: xmlNewNode() failed to create new 'TD' node.\n", __func__ ); err = XLAL_EFAILED; goto failed; } if ( xmlAddChild(xmlThisRowNode, xmlThisEntryNode ) == NULL ) { XLALPrintError ("%s: failed to insert 'TD' node into 'TR' node.\n", __func__ ); err = XLAL_EFAILED; goto failed; } char *valuestr=XLALCalloc(bufsize,sizeof(char)); varitem = LALInferenceGetItem(varsArray[row],field_names[col]); UINT4 required_size=LALInferencePrintNVariableItem(valuestr,bufsize,varitem); if(required_size>bufsize) { bufsize=required_size; valuestr=XLALRealloc(valuestr,required_size*sizeof(char)); required_size=LALInferencePrintNVariableItem(valuestr,bufsize,varitem); } xmlNodePtr xmlTextNode= xmlNewText (CAST_CONST_XMLCHAR(valuestr) ); if ( xmlTextNode == NULL ) { XLALPrintError("%s: xmlNewText() failed to turn text '%s' into node\n", __func__, valuestr ); err = XLAL_EFAILED; XLALFree(valuestr); goto failed; } if ( xmlAddChild(xmlThisEntryNode, xmlTextNode ) == NULL ) { XLALPrintError ("%s: failed to insert text-node node into 'TD' node.\n", __func__ ); err = XLAL_EFAILED; XLALFree(valuestr); goto failed; } XLALFree(valuestr); } /* for col < numFields */ } /* for row < numRows */ } /* Create a TABLE from the FIELDs, PARAMs, and TABLEDATA nodes */ VOTtableNode= XLALCreateVOTTableNode (tablename, fieldNodeList, paramNodeList, xmlTABLEDATAnode ); return(VOTtableNode); failed: XLAL_ERROR_NULL ( err ); return(NULL); }
/** Compute the semi-coherent statistics * * This function computes the semi-coherent s. * */ int XLALComputeSemiCoherentStat(FILE *fp, /**< [in] the output file pointer */ REAL4DemodulatedPowerVector *power, /**< [in] the input data in the form of power */ ParameterSpace *pspace, /**< [in] the parameter space */ GridParametersVector *fgrid, /**< UNDOCUMENTED */ GridParameters *bingrid, /**< [in] the grid parameters */ INT4 ntoplist, /**< UNDOCUMENTED */ BOOLEAN with_xbins /**< enable fast summing of extra bins */ ) { toplist TL; /* the results toplist */ Template *bintemp = NULL; /* the binary parameter space template */ Template *fdots = NULL; /* the freq derivitive template for each segment */ UINT4 i,j; /* counters */ UINT4 percent = 0; /* counter for status update */ REAL8 mean = 0.0; REAL8 var = 0.0; UINT4 Ntemp = 0; /* validate input parameters */ /* if ((*SemiCo) != NULL) { */ /* LogPrintf(LOG_CRITICAL,"%s: Invalid input, output BayesianProducts structure != NULL.\n",__func__); */ /* XLAL_ERROR(XLAL_EINVAL); */ /* } */ if (power == NULL) { LogPrintf(LOG_CRITICAL,"%s: Invalid input, input REAL4DemodulatedPowerVector structure = NULL.\n",__func__); XLAL_ERROR(XLAL_EINVAL); } if (pspace == NULL) { LogPrintf(LOG_CRITICAL,"%s: Invalid input, input GridParameters structure = NULL.\n",__func__); XLAL_ERROR(XLAL_EINVAL); } if (fgrid == NULL) { LogPrintf(LOG_CRITICAL,"%s: Invalid input, input GridParametersVector structure = NULL.\n",__func__); XLAL_ERROR(XLAL_EINVAL); } if (bingrid == NULL) { LogPrintf(LOG_CRITICAL,"%s: Invalid input, input GridParameters structure = NULL.\n",__func__); XLAL_ERROR(XLAL_EINVAL); } /* check for same frequency spacing */ const REAL8 dfreq = fgrid->segment[0]->grid[0].delta; for (i=0;i<power->length;i++) { if ( dfreq != fgrid->segment[i]->grid[0].delta ) { LogPrintf(LOG_CRITICAL,"%s : inconsistent frequency spacing in segment %u, %.10g != %.10g\n",__func__,i,fgrid->segment[i]->grid[0].delta,dfreq); XLAL_ERROR(XLAL_EINVAL); } } /* check that coherent grids step by 1 in frequency */ for (i=0;i<power->length;i++) { GridParameters *fdotgrid = fgrid->segment[i]; if ( fdotgrid->prod[0] != 1 ) { LogPrintf(LOG_CRITICAL,"%s : coherent grid step in segment %u does not equal 1\n",__func__,i); XLAL_ERROR(XLAL_EINVAL); } } /* allocate memory for the results toplist */ TL.n = ntoplist; if ((TL.data = (REAL4 *)XLALCalloc(TL.n,sizeof(REAL4))) == NULL) { LogPrintf(LOG_CRITICAL,"%s : XLALCalloc() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_ENOMEM); } if ((TL.params = (REAL8 **)XLALCalloc(TL.n,sizeof(REAL8 *))) == NULL) { LogPrintf(LOG_CRITICAL,"%s : XLALCalloc() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_ENOMEM); } for (i=0;i<(UINT4)TL.n;i++) { TL.params[i] = NULL; if ((TL.params[i] = (REAL8 *)XLALCalloc(bingrid->ndim,sizeof(REAL8))) == NULL) { LogPrintf(LOG_CRITICAL,"%s : XLALCalloc() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_ENOMEM); } } TL.idx = 0; /* allocate memory for the fdots */ if ((fdots = XLALCalloc(power->length, sizeof(*fdots))) == NULL) { LogPrintf(LOG_CRITICAL,"%s : XLALCalloc() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_ENOMEM); } for (i=0;i<power->length;i++) { if ((fdots[i].x = XLALCalloc(fgrid->segment[0]->ndim,sizeof(REAL8))) == NULL) { LogPrintf(LOG_CRITICAL,"%s : XLALCalloc() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_ENOMEM); } if ((fdots[i].idx = XLALCalloc(fgrid->segment[0]->ndim,sizeof(INT4))) == NULL) { LogPrintf(LOG_CRITICAL,"%s : XLALCalloc() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_ENOMEM); } fdots[i].ndim = fgrid->segment[0]->ndim; } /* define the chi-squared threshold */ /* REAL8 thr = gsl_cdf_chisq_Qinv(frac,2*power->length); LogPrintf(LOG_DEBUG,"%s : computed the threshold as %f\n",__func__,thr); */ int (*getnext)(Template **temp,GridParameters *gridparams, ParameterSpace *space,void *); UINT8 newmax = bingrid->max; ParameterSpace *temppspace = NULL; if (bingrid->coverage>0) { getnext = &XLALGetNextRandomBinaryTemplate; newmax = bingrid->Nr; temppspace = pspace; } else getnext = &XLALGetNextTemplate; REAL4 *logLratiosumvec = NULL; /* single loop over binary templates */ double fine_deriv_t = 0; UINT8 num_fine_deriv = 0; double fine_sum_t = 0; UINT8 num_fine_sum = 0; INT4 max_tot_xbins = 0; while (getnext(&bintemp,bingrid,temppspace,r)) { const REAL8 asini = bintemp->x[1]; /* define asini */ const REAL8 omega = bintemp->x[3]; /* define omega */ /* maximum extra bins to sum in frequency at this template, while keeping correct derivative bins (minus 10% for safety) */ const INT4 xbins = !with_xbins ? 0 : (INT4) floor( 0.45 * dfreq / ( asini * omega ) ); XLAL_CHECK( xbins >= 0, XLAL_EDOM, "Invalid xbins=%d\n", xbins ); INT4 left_xbins = xbins, right_xbins = xbins; /** loop over segments **********************************************************************************/ const double fine_deriv_t0 = XLALGetCPUTime(); for (i=0;i<power->length;i++) { REAL8 tmid = XLALGPSGetREAL8(&(power->segment[i]->epoch)) + 0.5*pspace->tseg; GridParameters *fdotgrid = fgrid->segment[i]; /* REAL8 norm = (REAL8)background->data[i]; */ /* compute instantaneous frequency derivitives corresponding to the current template for this segment */ XLALComputeBinaryFreqDerivitives(&fdots[i],bintemp,tmid); /* find ndim-D indices corresponding to the spin derivitive values for the segment power */ for (j=0;j<fdots[i].ndim;j++) { fdots[i].idx[j] = lround( (fdots[i].x[j] - fdotgrid->grid[j].min)*fdotgrid->grid[j].oneoverdelta ); /* check that index is in range */ if ( fdots[i].idx[j] < 0 || fdots[i].idx[j] >= (INT4)fdotgrid->grid[j].length ) { LogPrintf(LOG_CRITICAL,"%s: stepped outside grid in segment %d, nu=%g, asini=%g, tasc=%g, omega=%g, fdots[%d] = [%g <= %g <= %g, 0 <= %d < %d]\n", __func__, i, bintemp->x[0], bintemp->x[1], bintemp->x[2], bintemp->x[3], j, fdotgrid->grid[j].min, fdots[i].x[j], fdotgrid->grid[j].min + fdotgrid->grid[j].delta*fdotgrid->grid[j].length, fdots[i].idx[j], fdotgrid->grid[j].length); XLAL_ERROR(XLAL_EDOM); } } /* ensure number of extra frequency bins do not go out of range of coherent grids */ left_xbins = GSL_MIN( left_xbins, (INT4)( fdots[i].idx[0] ) ); right_xbins = GSL_MIN( right_xbins, (INT4)( fdotgrid->grid[0].length - fdots[i].idx[0] - 1 ) ); XLAL_CHECK( left_xbins >= 0, XLAL_EDOM, "Invalid left_xbins=%d\n", left_xbins ); XLAL_CHECK( right_xbins >= 0, XLAL_EDOM, "Invalid right_xbins=%d\n", right_xbins ); } /* end loop over segments */ fine_deriv_t += XLALGetCPUTime() - fine_deriv_t0; num_fine_deriv += power->length; /*************************************************************************************/ const INT4 tot_xbins = 1 + left_xbins + right_xbins; if ( max_tot_xbins < tot_xbins ) { max_tot_xbins = tot_xbins; /* reallocate logLratiosumvec */ logLratiosumvec = XLALRealloc( logLratiosumvec, max_tot_xbins * sizeof( *logLratiosumvec ) ); XLAL_CHECK( logLratiosumvec != NULL, XLAL_ENOMEM ); } /** loop over segments **********************************************************************************/ const double fine_sum_t0 = XLALGetCPUTime(); for (i=0;i<power->length;i++) { REAL4DemodulatedPower *currentpower = power->segment[i]; GridParameters *fdotgrid = fgrid->segment[i]; /* find starting 1-D index corresponding to the spin derivitive values for the segment power */ INT4 idx0 = fdots[i].idx[0] - left_xbins; for (j=1;j<fdots[i].ndim;j++) { idx0 += fdots[i].idx[j] * fdotgrid->prod[j]; } /* define the power at this location in this segment */ if (i==0) { memcpy( logLratiosumvec, ¤tpower->data->data[idx0], tot_xbins * sizeof( *logLratiosumvec ) ); } else { XLAL_CHECK( XLALVectorAddREAL4( logLratiosumvec, logLratiosumvec, ¤tpower->data->data[idx0], tot_xbins ) == XLAL_SUCCESS, XLAL_EFUNC ); } } /* end loop over segments */ fine_sum_t += XLALGetCPUTime() - fine_sum_t0; num_fine_sum += ( power->length - 1 ) * tot_xbins; /*************************************************************************************/ /* make it a true chi-squared variable */ XLAL_CHECK( XLALVectorScaleREAL4( logLratiosumvec, 2.0, logLratiosumvec, tot_xbins ) == XLAL_SUCCESS, XLAL_EFUNC ); /* save central binary template frequency */ const REAL8 nu0 = bintemp->x[0]; for (INT4 x = -left_xbins; x <= right_xbins; ++x) { /* set binary template frequency */ bintemp->x[0] = nu0 + dfreq*x; /* output semi-coherent statistic for this template if it exceeds the threshold*/ const REAL4 logLratiosum = logLratiosumvec[x + left_xbins]; mean += logLratiosum; var += logLratiosum*logLratiosum; ++Ntemp; XLALtoplist(logLratiosum,bintemp,&TL); } /* if (logLratiosum>thr) { for (j=0;j<bingrid->ndim;j++) fprintf(fp,"%6.12f\t",bintemp->x[j]); fprintf(fp,"%6.12e\n",logLratiosum); } */ /* output status to screen */ if ( (bintemp->currentidx == 0) || (floor(100.0*(REAL8)bintemp->currentidx/(REAL8)newmax) > (REAL8)percent) ) { percent = (UINT4)floor(100*(REAL8)bintemp->currentidx/(REAL8)newmax); LogPrintf(LOG_NORMAL,"%s : completed %d%% (%"LAL_UINT8_FORMAT"/%"LAL_UINT8_FORMAT")\n",__func__,percent,bintemp->currentidx,newmax); } /* we've computed this number of extra templates */ bintemp->currentidx += left_xbins + right_xbins; } /* end loop over templates */ LogPrintf(LOG_NORMAL,"%s : time to compute fine grid derivatives = %0.12e\n",__func__, fine_deriv_t); LogPrintf(LOG_NORMAL,"%s : number of fine grid derivatives = %"LAL_UINT8_FORMAT"\n",__func__, num_fine_deriv); LogPrintf(LOG_NORMAL,"%s : time to compute fine summations = %0.12e\n",__func__, fine_sum_t); LogPrintf(LOG_NORMAL,"%s : number of fine grid summations = %"LAL_UINT8_FORMAT"\n",__func__, num_fine_sum); LogPrintf(LOG_NORMAL,"%s : summed up to %d frequency bins at a time\n", __func__, max_tot_xbins); /*************************************************************************************/ /* compute mean and variance of results */ mean = mean/(REAL8)Ntemp; var = var/(REAL8)(Ntemp-1); var = (var - mean*mean); /* modify toplist to have correct mean and variance */ for (i=0;i<(UINT4)TL.n;i++) TL.data[i] = (TL.data[i] - mean)*sqrt(4.0*power->length)/sqrt(var) + 2.0*power->length; /* output toplist to file */ for (i=0;i<(UINT4)TL.n;i++) { for (j=0;j<bingrid->ndim;j++) fprintf(fp,"%6.12f\t",TL.params[i][j]); fprintf(fp,"%6.12e\n",TL.data[i]); } /* free template memory */ for (i=0;i<power->length;i++) { XLALFree(fdots[i].x); XLALFree(fdots[i].idx); } XLALFree(fdots); XLALFree(TL.data); for (i=0;i<(UINT4)TL.n;i++) XLALFree(TL.params[i]); XLALFree(TL.params); XLALFree(logLratiosumvec); LogPrintf(LOG_DEBUG,"%s : leaving.\n",__func__); return XLAL_SUCCESS; }
/** Read in input user arguments * */ int XLALReadUserVars(int argc, /**< [in] the command line argument counter */ char *argv[], /**< [in] the command line arguments */ UserInput_t *uvar, /**< [out] the user input structure */ CHAR **clargs /**< [out] the command line args string */ ) { INT4 i; /* initialise user variables */ uvar->sftbasename = NULL; uvar->comment = NULL; uvar->gpsstart = -1; uvar->gpsend = -1; uvar->mismatch = 0.2; uvar->ntoplist = 10; uvar->coverage = -1; uvar->blocksize = 100; uvar->ndim = -1; uvar->bins_factor = BINS_FACTOR; uvar->tsft = 256; uvar->seed = 1; uvar->tempdir = NULL; uvar->with_xbins = 1; /* initialise all parameter space ranges to zero */ uvar->freqband = 0; uvar->minorbperiod = 0.0; uvar->maxorbperiod = 0.0; uvar->minasini = 0.0; uvar->maxasini = 0.0; uvar->tasc = -1.0; uvar->deltaorbphase = 2.0*LAL_PI; /* ---------- register all user-variables ---------- */ XLALRegisterUvarMember(sftbasename, STRING, 'i', REQUIRED, "The basename of the input SFT files"); XLALRegisterUvarMember(outputdir, STRING, 'o', REQUIRED, "The output directory name"); XLALRegisterUvarMember(comment, STRING, 'C', REQUIRED, "An analysis descriptor string"); XLALRegisterUvarMember(tempdir, STRING, 'z', OPTIONAL, "A temporary directory"); XLALRegisterUvarMember(freq, REAL8, 'f', REQUIRED, "The starting frequency (Hz)"); XLALRegisterUvarMember(freqband, REAL8, 'b', OPTIONAL, "The frequency band (Hz)"); XLALRegisterUvarMember(minorbperiod, REAL8, 'p', REQUIRED, "The minimum orbital period value (sec)"); XLALRegisterUvarMember(maxorbperiod, REAL8, 'P', OPTIONAL, "The maximum orbital period value (sec)"); XLALRegisterUvarMember(minasini, REAL8, 'a', REQUIRED, "The minimum orbital semi-major axis (sec)"); XLALRegisterUvarMember(maxasini, REAL8, 'A', OPTIONAL, "The maximum orbital semi-major axis (sec)"); XLALRegisterUvarMember(tasc, REAL8, 't', REQUIRED, "The best guess orbital time of ascension (rads)"); XLALRegisterUvarMember(deltaorbphase, REAL8, 'T', OPTIONAL, "The orbital phase uncertainty (cycles)"); XLALRegisterUvarMember(mismatch, REAL8, 'm', OPTIONAL, "The grid mismatch (0->1)"); XLALRegisterUvarMember(coverage, REAL8, 'c', OPTIONAL, "The random template coverage (0->1)"); XLALRegisterUvarMember(blocksize, INT4, 'r', OPTIONAL, "The running median block size"); XLALRegisterUvarMember(ndim, INT4, 'n', OPTIONAL, "The number of spin derivitive dimensions required (default: automatic)"); XLALRegisterUvarMember(bins_factor, REAL8, 'R', OPTIONAL, "The percentage of bins to add to each side of the fft for safety"); XLALRegisterUvarMember(tsft, REAL8, 'S', OPTIONAL, "The length of the input SFTs in seconds"); XLALRegisterUvarMember(ntoplist, INT4, 'x', OPTIONAL, "output the top N results"); XLALRegisterUvarMember(seed, INT4, 'X', OPTIONAL, "The random number seed (0 = clock)"); XLALRegisterUvarMember(gpsstart, INT4, 's', OPTIONAL, "The minimum start time (GPS sec)"); XLALRegisterUvarMember(gpsend, INT4, 'e', OPTIONAL, "The maximum end time (GPS sec)"); XLALRegisterUvarMember(with_xbins, BOOLEAN, 0, DEVELOPER, "Enable fast summing of extra bins"); /* do ALL cmdline and cfgfile handling */ BOOLEAN should_exit = 0; if (XLALUserVarReadAllInput(&should_exit, argc, argv, lalAppsVCSInfoList)) { LogPrintf(LOG_CRITICAL,"%s : XLALUserVarReadAllInput failed with error = %d\n",__func__,xlalErrno); return XLAL_EFAULT; } if (should_exit) exit(1); /* put clargs into string */ *clargs = XLALCalloc(1,sizeof(CHAR)); for (i=0;i<argc;i++) { INT4 len = 2 + strlen(argv[i]) + strlen(*clargs); *clargs = XLALRealloc(*clargs,len*sizeof(CHAR)); strcat(*clargs,argv[i]); strcat(*clargs," "); } LogPrintf(LOG_DEBUG,"%s : leaving.\n",__func__); return XLAL_SUCCESS; }
/** * Turn the given multi-IFO SFTvectors into one long Fourier transform (LFT) over the total observation time */ SFTtype * XLALSFTVectorToLFT ( SFTVector *sfts, /**< input SFT vector (gets modified!) */ REAL8 upsampling /**< upsampling factor >= 1 */ ) { XLAL_CHECK_NULL ( (sfts != NULL) && (sfts->length > 0), XLAL_EINVAL ); XLAL_CHECK_NULL ( upsampling >= 1, XLAL_EDOM, "Upsampling factor (%f) must be >= 1 \n", upsampling ); // ----- some useful SFT infos SFTtype *firstSFT = &(sfts->data[0]); UINT4 numBinsSFT = firstSFT->data->length; REAL8 dfSFT = firstSFT->deltaF; REAL8 Tsft = 1.0 / dfSFT; REAL8 f0SFT = firstSFT->f0; // ----- turn input SFTs into a complex (heterodyned) timeseries COMPLEX8TimeSeries *lTS; XLAL_CHECK_NULL ( (lTS = XLALSFTVectorToCOMPLEX8TimeSeries ( sfts )) != NULL, XLAL_EFUNC ); REAL8 dt = lTS->deltaT; UINT4 numSamples0 = lTS->data->length; REAL8 Tspan0 = numSamples0 * dt; // ---------- determine time-span of upsampled time-series /* NOTE: Tspan MUST be an integer multiple of Tsft, * in order for the frequency bins of the final FFT * to be commensurate with the SFT bins. * This is required so that fHet is an exact * frequency-bin in both cases */ UINT4 numSFTsFit = lround ( (Tspan0 * upsampling) / Tsft ); REAL8 Tspan = numSFTsFit * Tsft; UINT4 numSamples = lround ( Tspan / dt ); // ----- enlarge TimeSeries container for zero-padding if neccessary if ( numSamples > numSamples0 ) { XLAL_CHECK_NULL ( (lTS->data->data = XLALRealloc ( lTS->data->data, numSamples * sizeof(lTS->data->data[0]) )) != NULL, XLAL_ENOMEM ); lTS->data->length = numSamples; memset ( lTS->data->data + numSamples0, 0, (numSamples - numSamples0) * sizeof(lTS->data->data[0])); /* set all new time-samples to zero */ } /* translate this back into fmin for the LFT (counting down from DC==fHet) */ /* fHet = DC of our internal DFTs */ UINT4 NnegSFT = NhalfNeg ( numBinsSFT ); REAL8 fHet = f0SFT + 1.0 * NnegSFT * dfSFT; UINT4 NnegLFT = NhalfNeg ( numSamples ); REAL8 f0LFT = fHet - NnegLFT / Tspan; // ----- prepare output LFT ---------- SFTtype *outputLFT; XLAL_CHECK_NULL ( (outputLFT = XLALCreateSFT ( numSamples )) != NULL, XLAL_EFUNC ); // prepare LFT header strcpy ( outputLFT->name, firstSFT->name ); strncat ( outputLFT->name, ":long Fourier transform", sizeof(outputLFT->name) - 1 - strlen(outputLFT->name)); outputLFT->epoch = firstSFT->epoch; outputLFT->f0 = f0LFT; outputLFT->deltaF = 1.0 / Tspan; outputLFT->sampleUnits = firstSFT->sampleUnits; // ---------- FFT the long timeseries ---------- COMPLEX8FFTPlan *LFTplan; XLAL_CHECK_NULL ( (LFTplan = XLALCreateForwardCOMPLEX8FFTPlan( numSamples, 0 )) != NULL, XLAL_EFUNC ); XLAL_CHECK_NULL ( XLALCOMPLEX8VectorFFT( outputLFT->data, lTS->data, LFTplan ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK_NULL ( XLALReorderFFTWtoSFT (outputLFT->data) == XLAL_SUCCESS, XLAL_EFUNC ); // apply proper normalization 'dt' for ( UINT4 k = 0; k < outputLFT->data->length; k ++ ) { outputLFT->data->data[k] *= dt; } /* cleanup memory */ XLALDestroyCOMPLEX8TimeSeries ( lTS ); XLALDestroyCOMPLEX8FFTPlan ( LFTplan ); return outputLFT; } // XLALSFTVectorToLFT()
/** * @brief Read a multi-column data file. * @details Read a data file containing multiple whitespace separated columns * of data and create an array containing the data. * If any line begins with the character '#' then it is ignored. * The data is stored in the array in row-major format so that the data * sample on row @c i (beginning with zero) and column @c j (beginning with * zero) is found as the element <tt>[i * ncol + j]</tt> where @c ncol is the * number of columns. * @param[out] data The data stored in row-major order. * @param[out] ncol The number of columns in the data file. * @param fp Pointer to a LALFILE structure opened for input. * @return The number of rows read or (size_t)(-1) if an error occurs. */ size_t XLALSimReadDataFileNCol(double **data, size_t *ncol, LALFILE *fp) { char line[LINE_MAX]; size_t page = PAGESIZE; size_t size = 0; size_t lnum = 0; size_t nrow = 0; *data = NULL; *ncol = 0; while (XLALFileGets(line, sizeof(line), fp)) { char *s; char *endp; size_t col; ++lnum; if (strchr(line, '\n') == NULL) { /* line too long */ XLALFree(*data); XLAL_ERROR(XLAL_EIO, "Line %zd too long\n", lnum); } if (*line == '#') /* ignore lines beginning with '#' */ continue; if (*ncol == 0) { /* count columns on first line */ endp = line; while (1) { s = endp; /* work around bug in glibc < 2.16 * http://sourceware.org/bugzilla/show_bug.cgi?id=13970 */ double v = strtod(s, &endp); (void)v; if (s == endp || *endp == '\0') break; ++*ncol; } if (*ncol == 0) { XLALFree(*data); XLAL_ERROR(XLAL_EIO, "Line %zd malformed\n", lnum); } } if (nrow == size) { /* allocate more memory for data */ size += page; *data = XLALRealloc(*data, *ncol * page * sizeof(**data)); } /* scan line for data values in each column */ endp = line; for (col = 0; col < *ncol; ++col) { s = endp; (*data)[*ncol * nrow + col] = strtod(s, &endp); if (s == endp || *endp == '\0') { XLALFree(*data); XLAL_ERROR(XLAL_EIO, "Line %zd malformed\n", lnum); } } ++nrow; } *data = XLALRealloc(*data, *ncol * nrow * sizeof(**data)); return nrow; }
/// /// Parse a string containing a list of comma-separated values (CSV) into a StringVector. /// \note surrounding whitespace and quotes (\' or \") are removed from the individual list entries. /// /// \note The output string-vector (*strVect) must be NULL /// int XLALParseStringValueAsSTRINGVector ( LALStringVector **strVect, ///< [out] allocated string vector const CHAR *valString ///< [in] input string value ) { XLAL_CHECK ( valString != NULL, XLAL_EINVAL ); XLAL_CHECK ( (strVect != NULL) && (*strVect == NULL) , XLAL_EINVAL ); LALStringVector *ret; XLAL_CHECK ( (ret = XLALCalloc ( 1, sizeof(*ret))) != NULL, XLAL_ENOMEM ); const char *start = valString; const char *tmp; do { // create space for the next string-vector entry ret->length ++; XLAL_CHECK ( (ret->data = XLALRealloc ( ret->data, ret->length * sizeof(ret->data[0]) )) != NULL, XLAL_ENOMEM ); // determine length of next CSV string value, taking account of quotes size_t len; CHAR inQuotes = 0; tmp = start; do { // simple comma outside of quotes if ( !inQuotes && ((*tmp) == ',') ) { break; // found a separator-comma } // handle quotes if ( (*tmp) == '\'' || (*tmp) == '\"' ) // found quotes { if ( !inQuotes ) { inQuotes = (*tmp); // we've intered quotes } else if ( inQuotes == (*tmp) ) { inQuotes = 0; // we've left quotes, only if closing quotes match opening ones } } // end: if quotes found tmp ++; } while ( (*tmp) != 0 ); if ( (*tmp) == 0 ) { len = strlen ( start ); } else { len = tmp - start; } // copy this string value with surrounding whitespace removed char *deblanked; XLAL_CHECK ( (deblanked = XLALDeblankString ( start, len ) ) != NULL, XLAL_EFUNC ); ret->data[ret->length-1] = NULL; XLAL_CHECK ( XLALParseStringValueAsSTRING ( &(ret->data[ret->length-1]), deblanked ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALFree ( deblanked ); } while ( ( (*tmp) != 0) && ( *(start = tmp + 1) != 0 ) ); (*strVect) = ret; return XLAL_SUCCESS; } // XLALParseStringValueAsSTRINGVector()
/** Read in input user arguments * */ int XLALReadUserVars(int argc, /**< [in] the command line argument counter */ char *argv[], /**< [in] the command line arguments */ UserInput_t *uvar, /**< [out] the user input structure */ CHAR **clargs /**< [out] the command line args string */ ) { CHAR *version_string; INT4 i; /* initialise user variables */ uvar->sftbasename = NULL; uvar->comment = NULL; uvar->gpsstart = -1; uvar->gpsend = -1; uvar->mismatch = 0.2; uvar->ntoplist = 10; uvar->coverage = -1; uvar->blocksize = 100; uvar->tsft = 256; uvar->seed = 1; uvar->tempdir = NULL; /* initialise all parameter space ranges to zero */ uvar->freqband = 0; uvar->minorbperiod = 0.0; uvar->maxorbperiod = 0.0; uvar->minasini = 0.0; uvar->maxasini = 0.0; uvar->tasc = -1.0; uvar->deltaorbphase = 2.0*LAL_PI; /* ---------- register all user-variables ---------- */ XLALRegisterUvarMember(sftbasename, STRING, 'i', REQUIRED, "The basename of the input SFT files"); XLALRegisterUvarMember(outputdir, STRING, 'o', REQUIRED, "The output directory name"); XLALRegisterUvarMember(comment, STRING, 'C', REQUIRED, "An analysis descriptor string"); XLALRegisterUvarMember(tempdir, STRING, 'z', OPTIONAL, "A temporary directory"); XLALRegisterUvarMember(freq, REAL8, 'f', REQUIRED, "The starting frequency (Hz)"); XLALRegisterUvarMember(freqband, REAL8, 'b', OPTIONAL, "The frequency band (Hz)"); XLALRegisterUvarMember(minorbperiod, REAL8, 'p', REQUIRED, "The minimum orbital period value (sec)"); XLALRegisterUvarMember(maxorbperiod, REAL8, 'P', OPTIONAL, "The maximum orbital period value (sec)"); XLALRegisterUvarMember(minasini, REAL8, 'a', REQUIRED, "The minimum orbital semi-major axis (sec)"); XLALRegisterUvarMember(maxasini, REAL8, 'A', OPTIONAL, "The maximum orbital semi-major axis (sec)"); XLALRegisterUvarMember(tasc, REAL8, 't', REQUIRED, "The best guess orbital time of ascension (rads)"); XLALRegisterUvarMember(deltaorbphase, REAL8, 'T', OPTIONAL, "The orbital phase uncertainty (cycles)"); XLALRegisterUvarMember(mismatch, REAL8, 'm', OPTIONAL, "The grid mismatch (0->1)"); XLALRegisterUvarMember(coverage, REAL8, 'c', OPTIONAL, "The random template coverage (0->1)"); XLALRegisterUvarMember(blocksize, INT4, 'r', OPTIONAL, "The running median block size"); XLALRegisterUvarMember(tsft, INT4, 'S', OPTIONAL, "The length of the input SFTs in seconds"); XLALRegisterUvarMember(ntoplist, INT4, 'x', OPTIONAL, "output the top N results"); XLALRegisterUvarMember(seed, INT4, 'X', OPTIONAL, "The random number seed (0 = clock)"); XLALRegisterUvarMember(gpsstart, INT4, 's', OPTIONAL, "The minimum start time (GPS sec)"); XLALRegisterUvarMember(gpsend, INT4, 'e', OPTIONAL, "The maximum end time (GPS sec)"); XLALRegisterUvarMember(version, BOOLEAN, 'V', SPECIAL, "Output code version"); /* do ALL cmdline and cfgfile handling */ BOOLEAN should_exit = 0; if (XLALUserVarReadAllInput(&should_exit, argc, argv)) { LogPrintf(LOG_CRITICAL,"%s : XLALUserVarReadAllInput failed with error = %d\n",__func__,xlalErrno); return XLAL_EFAULT; } if (should_exit) exit(1); if ((version_string = XLALGetVersionString(0)) == NULL) { XLALPrintError("XLALGetVersionString(0) failed.\n"); exit(1); } if (uvar->version) { printf("%s\n",version_string); exit(0); } XLALFree(version_string); /* put clargs into string */ *clargs = XLALCalloc(1,sizeof(CHAR)); for (i=0;i<argc;i++) { INT4 len = 2 + strlen(argv[i]) + strlen(*clargs); *clargs = XLALRealloc(*clargs,len*sizeof(CHAR)); strcat(*clargs,argv[i]); strcat(*clargs," "); } LogPrintf(LOG_DEBUG,"%s : leaving.\n",__func__); return XLAL_SUCCESS; }