/** 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; }
/** 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 */ ) { toplist TL; /* the results toplist */ Template *bintemp = NULL; /* the binary parameter space template */ Template fdots; /* 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; /* 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); } /* allocate memory for the results toplist */ TL.n = ntoplist; if ((TL.data = (REAL8 *)XLALCalloc(TL.n,sizeof(REAL8))) == 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.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); } fdots.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 *); INT4 newmax = bingrid->max; ParameterSpace *temppspace = NULL; if (bingrid->Nr>0) { getnext = &XLALGetNextRandomBinaryTemplate; newmax = bingrid->Nr; temppspace = pspace; } else getnext = &XLALGetNextTemplate; /* single loop over binary templates */ while (getnext(&bintemp,bingrid,temppspace,r)) { REAL8 logLratiosum = 0.0; /* initialise likelihood ratio */ /** loop over segments **********************************************************************************/ for (i=0;i<power->length;i++) { REAL4DemodulatedPower *currentpower = power->segment[i]; GridParameters *fdotgrid = fgrid->segment[i]; REAL8 tmid = XLALGPSGetREAL8(&(power->segment[i]->epoch)) + 0.5*pspace->tseg; /* REAL8 norm = (REAL8)background->data[i]; */ INT4 idx = 0; /* compute instantaneous frequency derivitives corresponding to the current template for this segment */ XLALComputeBinaryFreqDerivitives(&fdots,bintemp,tmid); /* find indices corresponding to the spin derivitive values for the segment power */ for (j=0;j<fdots.ndim;j++) { UINT4 tempidx = 0.5 + (fdots.x[j] - fdotgrid->grid[j].min)*fdotgrid->grid[j].oneoverdelta; idx += tempidx*fdotgrid->prod[j]; } /* define the power at this location in this segment */ logLratiosum += currentpower->data->data[idx]; /* /norm; */ } /* end loop over segments */ /*************************************************************************************/ /* output semi-coherent statistic for this template if it exceeds the threshold*/ logLratiosum *= 2.0; /* make it a true chi-squared variable */ mean += logLratiosum; var += logLratiosum*logLratiosum; 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 (floor(100.0*(REAL8)bintemp->currentidx/(REAL8)newmax) > (REAL8)percent) { percent = (UINT4)floor(100*(REAL8)bintemp->currentidx/(REAL8)newmax); LogPrintf(LOG_DEBUG,"%s : completed %d%% (%d/%d)\n",__func__,percent,bintemp->currentidx,newmax); } } /* end loop over templates */ /*************************************************************************************/ /* compute mean and variance of results */ mean = mean/(REAL8)newmax; var = var/(REAL8)(newmax-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 */ XLALFree(fdots.x); XLALFree(TL.data); for (i=0;i<(UINT4)TL.n;i++) XLALFree(TL.params[i]); XLALFree(TL.params); LogPrintf(LOG_DEBUG,"%s : leaving.\n",__func__); return XLAL_SUCCESS; }