27 #include <lal/LALHeap.h>
28 #include <lal/LALHashTbl.h>
29 #include <lal/LALBitset.h>
32 #define COMPARE_BY( x, y ) do { if ( (x) < (y) ) return -1; if ( (x) > (y) ) return +1; } while(0)
146 static int cache_max_semi_bbox_sample_dim0(
const WeaveCache *
cache,
const LatticeTiling *coh_tiling,
const size_t i, gsl_vector *coh_bbox_sample, gsl_vector *semi_bbox_sample,
double *max_semi_bbox_sample_dim0 );
217 const WeaveCache *
cache,
218 const LatticeTiling *coh_tiling,
220 gsl_vector *coh_bbox_sample,
221 gsl_vector *semi_bbox_sample,
222 double *max_semi_bbox_sample_dim0
226 if ( i < cache->ndim ) {
233 const double coh_bbox_sample_i = gsl_vector_get( coh_bbox_sample,
i );
236 for (
int step = -1; step <= 1; ++ step ) {
237 gsl_vector_set( coh_bbox_sample,
i, coh_bbox_sample_i - step * 0.5 * coh_bbox_i );
242 gsl_vector_set( coh_bbox_sample,
i, coh_bbox_sample_i );
250 *max_semi_bbox_sample_dim0 = GSL_MAX( *max_semi_bbox_sample_dim0, gsl_vector_get( semi_bbox_sample,
cache->dim0 ) );
262 const UINT4 semi_nfreqs,
263 const UINT4 nfreq_partitions,
264 const UINT4 freq_partition_index,
271 const UINT4 min_part_nfreqs = semi_nfreqs / nfreq_partitions;
274 INT4 excess_nfreqs = semi_nfreqs - nfreq_partitions * min_part_nfreqs;
278 INT4 part_nfreqs = min_part_nfreqs;
279 if ( excess_nfreqs > 0 ) {
287 for (
size_t i = 0;
i < freq_partition_index; ++
i ) {
288 *left_offset += part_nfreqs;
290 if ( excess_nfreqs == 0 ) {
294 *right_offset = *left_offset + part_nfreqs - semi_nfreqs;
306 const LatticeTiling *semi_tiling,
307 const SuperskyTransformData *semi_rssky_transf,
309 const UINT4 nqueries,
310 const UINT4 nfreq_partitions
321 WeaveCacheQueries *queries =
XLALCalloc( 1,
sizeof( *queries ) );
323 queries->coh_part_left_offset =
XLALCalloc( nfreq_partitions,
sizeof( *queries->coh_part_left_offset ) );
325 queries->coh_part_right_offset =
XLALCalloc( nfreq_partitions,
sizeof( *queries->coh_part_right_offset ) );
327 queries->coh_index =
XLALCalloc( nqueries,
sizeof( *queries->coh_index ) );
329 queries->coh_phys =
XLALCalloc( nqueries,
sizeof( *queries->coh_phys ) );
331 queries->coh_left =
XLALCalloc( nqueries,
sizeof( *queries->coh_left ) );
333 queries->coh_right =
XLALCalloc( nqueries,
sizeof( *queries->coh_right ) );
335 queries->coh_relevance =
XLALCalloc( nqueries,
sizeof( *queries->coh_relevance ) );
337 queries->coh_nres =
XLALCalloc( nqueries,
sizeof( *queries->coh_nres ) );
339 queries->coh_ntmpl =
XLALCalloc( nqueries,
sizeof( *queries->coh_ntmpl ) );
343 queries->semi_rssky_transf = semi_rssky_transf;
344 queries->dfreq =
dfreq;
345 queries->nqueries = nqueries;
346 queries->nfreq_partitions = nfreq_partitions;
372 for (
size_t i = 0;
i < queries->nfreq_partitions; ++
i ) {
384 WeaveCacheQueries *queries
387 if ( queries != NULL ) {
388 XLALFree( queries->coh_part_left_offset );
389 XLALFree( queries->coh_part_right_offset );
405 WeaveCacheQueries *queries,
406 const UINT8 semi_index,
407 const gsl_vector *semi_rssky,
408 const INT4 semi_left,
409 const INT4 semi_right,
410 const UINT4 freq_partition_index
420 memset( queries->coh_index, 0, queries->nqueries *
sizeof( queries->coh_index[0] ) );
423 queries->semi_index = semi_index;
426 queries->semi_rssky_dim0 = gsl_vector_get( semi_rssky, queries->dim0 );
432 queries->semi_left = semi_left;
433 queries->semi_right = semi_right;
436 queries->freq_partition_index = freq_partition_index;
440 queries->semi_relevance = gsl_vector_get( semi_rssky, queries->dim0 ) + queries->semi_relevance_offset;
450 const WeaveCache *
cache,
451 WeaveCacheQueries *queries,
452 const UINT4 query_index
464 double coh_point_array[
cache->ndim];
465 gsl_vector_view coh_point_view = gsl_vector_view_array( coh_point_array,
cache->ndim );
469 double coh_near_point_array[
cache->ndim];
470 gsl_vector_view coh_near_point_view = gsl_vector_view_array( coh_near_point_array,
cache->ndim );
471 gsl_vector_memcpy( &coh_near_point_view.vector, &coh_point_view.vector );
474 queries->coh_index[query_index] = queries->semi_index;
475 queries->coh_left[query_index] = queries->semi_left;
476 queries->coh_right[query_index] = queries->semi_right;
483 if (
cache->coh_locator != NULL ) {
487 XLAL_CHECK( queries->coh_left[query_index] <= queries->semi_left && queries->semi_right <= queries->coh_right[query_index],
XLAL_EFAILED,
"Range of coherent tiling [%i,%i] does not contain semicoherent tiling [%i,%i] at semicoherent index %"LAL_UINT8_FORMAT", query index %u", queries->coh_left[query_index], queries->coh_right[query_index], queries->semi_left, queries->semi_right, queries->semi_index, query_index );
491 ++queries->coh_index[query_index];
501 double semi_near_point_array[
cache->ndim];
502 gsl_vector_view semi_near_point_view = gsl_vector_view_array( semi_near_point_array,
cache->ndim );
504 const double semi_near_point_dim0 = gsl_vector_get( &semi_near_point_view.vector,
cache->dim0 );
505 queries->coh_relevance[query_index] = GSL_MAX( semi_near_point_dim0, queries->semi_rssky_dim0 ) +
cache->coh_relevance_offset;
516 WeaveCacheQueries *queries,
528 for (
size_t i = 0;
i < queries->nqueries; ++
i ) {
533 *semi_nfreqs = queries->semi_right - queries->semi_left + 1;
536 INT4 semi_part_left_offset = 0, semi_part_right_offset = 0;
538 XLAL_CHECK( queries->coh_part_left_offset[queries->freq_partition_index] <= semi_part_left_offset && semi_part_right_offset <= queries->coh_part_right_offset[queries->freq_partition_index],
XLAL_EFAILED );
545 queries->semi_left += semi_part_left_offset;
546 queries->semi_right += semi_part_right_offset;
547 if ( queries->semi_right < queries->semi_left ) {
553 *semi_nfreqs = queries->semi_right - queries->semi_left + 1;
556 for (
size_t i = 0;
i < queries->nqueries; ++
i ) {
557 queries->coh_left[
i] += queries->coh_part_left_offset[queries->freq_partition_index];
558 queries->coh_right[
i] += queries->coh_part_right_offset[queries->freq_partition_index];
562 queries->semi_phys.fkdot[0] += queries->dfreq * queries->semi_left;
563 for (
size_t i = 0;
i < queries->nqueries; ++
i ) {
564 queries->coh_phys[
i].fkdot[0] += queries->dfreq * queries->coh_left[
i];
568 *semi_phys = queries->semi_phys;
571 queries->semi_ntmpl += *semi_nfreqs;
581 const WeaveCacheQueries *queries,
596 for (
size_t i = 0;
i < queries->nqueries; ++
i ) {
597 *coh_nres += queries->coh_nres[
i];
602 for (
size_t i = 0;
i < queries->nqueries; ++
i ) {
603 *coh_ntmpl += queries->coh_ntmpl[
i];
607 *semi_ntmpl = queries->semi_ntmpl;
617 const LatticeTiling *coh_tiling,
619 const SuperskyTransformData *coh_rssky_transf,
620 const SuperskyTransformData *semi_rssky_transf,
621 WeaveCohInput *coh_input,
622 const UINT4 max_size,
636 cache->coh_rssky_transf = coh_rssky_transf;
637 cache->semi_rssky_transf = semi_rssky_transf;
638 cache->coh_input = coh_input;
639 cache->generation = 0;
646 cache->any_gc = ( max_size == 0 );
647 cache->all_gc = all_gc;
667 double coh_origin_array[
cache->ndim];
668 gsl_vector_view coh_origin_view = gsl_vector_view_array( coh_origin_array,
cache->ndim );
670 double semi_origin_array[
cache->ndim];
671 gsl_vector_view semi_origin_view = gsl_vector_view_array( semi_origin_array,
cache->ndim );
673 const double semi_origin_dim0 = gsl_vector_get( &semi_origin_view.vector,
cache->dim0 );
676 double coh_bbox_sample_array[
cache->ndim];
677 gsl_vector_view coh_bbox_sample_view = gsl_vector_view_array( coh_bbox_sample_array,
cache->ndim );
678 gsl_vector_memcpy( &coh_bbox_sample_view.vector, &coh_origin_view.vector );
679 double semi_bbox_sample_array[
cache->ndim];
680 gsl_vector_view semi_bbox_sample_view = gsl_vector_view_array( semi_bbox_sample_array,
cache->ndim );
681 double max_semi_bbox_sample_dim0 = semi_origin_dim0;
685 cache->coh_relevance_offset = max_semi_bbox_sample_dim0 - semi_origin_dim0;
690 if ( interpolation ) {
770 if (
cache != NULL ) {
784 REAL4 *cache_mean_max_size,
786 WeaveCache *
const *
cache
796 *cache_mean_max_size = 0;
797 for (
size_t i = 0;
i < ncache; ++
i ) {
798 *cache_mean_max_size +=
cache[
i]->heap_max_size;
800 *cache_mean_max_size /= ncache;
812 WeaveCache *
const *
cache
822 REAL4 cache_mean_max_size = 0;
865 cache->generation = 0;
876 const WeaveCacheQueries *queries,
877 const UINT4 query_index,
878 const WeaveCohResults **coh_res,
881 WeaveSearchTiming *tim
897 if ( find_item == NULL ) {
900 if (
cache->saved_item == NULL ) {
905 find_item = new_item;
912 new_item->
relevance = queries->coh_relevance[query_index];
915 const UINT4 coh_nfreqs = queries->coh_right[query_index] - queries->coh_left[query_index] + 1;
940 while (
cache->all_gc ) {
947 if ( least_relevant_item != NULL && least_relevant_item != new_item &&
cache_item_compare_by_relevance( least_relevant_item, &relevance_threshold ) < 0 ) {
970 if (
cache->saved_item != NULL ) {
978 if (
cache->heap_max_size < heap_size ) {
979 cache->heap_max_size = heap_size;
983 queries->coh_nres[query_index] += coh_nfreqs;
986 const UINT8 coh_bitset_index = queries->freq_partition_index *
cache->coh_max_index + find_key.
coh_index;
992 queries->coh_ntmpl[query_index] += coh_nfreqs;
1002 *coh_res = find_item->
coh_res;
1008 *coh_offset = queries->semi_left - queries->coh_left[query_index];
static int cache_item_compare_by_coh_index(const void *x, const void *y)
Compare cache items by generation, then locator index.
void XLALWeaveCacheQueriesDestroy(WeaveCacheQueries *queries)
Destroy storage for a series of cache queries.
int XLALWeaveCacheQuery(const WeaveCache *cache, WeaveCacheQueries *queries, const UINT4 query_index)
Query a cache for the results nearest to a given coherent point.
int XLALWeaveCacheQueriesFinal(WeaveCacheQueries *queries, PulsarDopplerParams *semi_phys, UINT4 *semi_nfreqs)
Finalise a series of cache queries.
int XLALWeaveCacheQueriesInit(WeaveCacheQueries *queries, const UINT8 semi_index, const gsl_vector *semi_rssky, const INT4 semi_left, const INT4 semi_right, const UINT4 freq_partition_index)
Initialise a series of cache queries.
int XLALWeaveCacheExpire(WeaveCache *cache)
Expire all items in the cache.
int XLALWeaveGetCacheMeanMaxSize(REAL4 *cache_mean_max_size, const size_t ncache, WeaveCache *const *cache)
Determine the mean maximum size obtained by caches.
static int cache_left_right_offsets(const UINT4 semi_nfreqs, const UINT4 nfreq_partitions, const UINT4 freq_partition_index, INT4 *left_offset, INT4 *right_offset)
Compute left/right-most index offsets to select a given partition.
WeaveCache * XLALWeaveCacheCreate(const LatticeTiling *coh_tiling, const BOOLEAN interpolation, const SuperskyTransformData *coh_rssky_transf, const SuperskyTransformData *semi_rssky_transf, WeaveCohInput *coh_input, const UINT4 max_size, const BOOLEAN all_gc)
Create a cache.
void XLALWeaveCacheDestroy(WeaveCache *cache)
Destroy a cache.
int XLALWeaveCacheRetrieve(WeaveCache *cache, const WeaveCacheQueries *queries, const UINT4 query_index, const WeaveCohResults **coh_res, UINT8 *coh_index, UINT4 *coh_offset, WeaveSearchTiming *tim)
Retrieve coherent results for a given query, or compute new coherent results if not found.
int XLALWeaveCacheQueriesGetCounts(const WeaveCacheQueries *queries, UINT8 *coh_nres, UINT8 *coh_ntmpl, UINT8 *semi_ntmpl)
Get number of computed coherent results, and number of coherent and semicoherent templates.
int XLALWeaveCacheClear(WeaveCache *cache)
Clear all items in the cache from memory.
static void cache_item_destroy(void *x)
Destroy a cache item.
WeaveCacheQueries * XLALWeaveCacheQueriesCreate(const LatticeTiling *semi_tiling, const SuperskyTransformData *semi_rssky_transf, const double dfreq, const UINT4 nqueries, const UINT4 nfreq_partitions)
Create storage for a series of cache queries.
static int cache_item_compare_by_relevance(const void *x, const void *y)
Compare cache items by generation, then relevance.
int XLALWeaveCacheWriteInfo(FITSFile *file, const size_t ncache, WeaveCache *const *cache)
Write various information from caches to a FITS file.
static UINT8 cache_item_hash(const void *x)
Hash cache items by generation and locator index.
static int cache_max_semi_bbox_sample_dim0(const WeaveCache *cache, const LatticeTiling *coh_tiling, const size_t i, gsl_vector *coh_bbox_sample, gsl_vector *semi_bbox_sample, double *max_semi_bbox_sample_dim0)
Sample points on surface of coherent bounding box, convert to semicoherent supersky coordinates,...
Module which caches computed coherent results.
void XLALWeaveCohResultsDestroy(WeaveCohResults *coh_res)
Destroy coherent results.
int XLALWeaveCohResultsCompute(WeaveCohResults **coh_res, WeaveCohInput *coh_input, const PulsarDopplerParams *coh_phys, const UINT4 coh_nfreqs, WeaveSearchTiming *tim)
Create and compute coherent results.
int XLALFITSHeaderWriteREAL4(FITSFile UNUSED *file, const CHAR UNUSED *key, const REAL4 UNUSED value, const CHAR UNUSED *comment)
struct tagFITSFile FITSFile
Representation of a FITS file.
LALBitset * XLALBitsetCreate(void)
void XLALBitsetDestroy(LALBitset *bs)
int XLALBitsetGet(const LALBitset *bs, const UINT8 idx, BOOLEAN *is_set)
int XLALBitsetSet(LALBitset *bs, const UINT8 idx, const BOOLEAN is_set)
int XLALPearsonHash(void *hval, const size_t hval_len, const void *data, const size_t data_len)
int XLALHashTblFind(const LALHashTbl *ht, const void *x, const void **y)
LALHashTbl * XLALHashTblCreate(LALHashTblDtorFcn dtor, LALHashTblHashFcn hash, LALHashTblCmpFcn cmp)
int XLALHashTblAdd(LALHashTbl *ht, void *x)
int XLALHashTblRemove(LALHashTbl *ht, const void *x)
void XLALHashTblDestroy(LALHashTbl *ht)
int XLALHashTblClear(LALHashTbl *ht)
const void * XLALHeapRoot(const LALHeap *h)
int XLALHeapAdd(LALHeap *h, void **x)
int XLALHeapSize(const LALHeap *h)
int XLALHeapExchangeRoot(LALHeap *h, void **x)
int XLALHeapRemoveRoot(LALHeap *h)
int XLALHeapClear(LALHeap *h)
LALHeap * XLALHeapCreate(LALHeapDtorFcn dtor, int max_size, int min_or_max_heap, LALHeapCmpFcn cmp)
void XLALHeapDestroy(LALHeap *h)
void * XLALCalloc(size_t m, size_t n)
size_t XLALTotalLatticeTilingDimensions(const LatticeTiling *tiling)
Return the total number of dimensions of the lattice tiling.
const LatticeTilingStats * XLALLatticeTilingStatistics(const LatticeTiling *tiling, const size_t dim)
Return statistics related to the number/value of lattice tiling points in a dimension.
int XLALNearestLatticeTilingBlock(const LatticeTilingLocator *loc, const gsl_vector *point, const size_t dim, gsl_vector *nearest_point, UINT8 *nearest_index, INT4 *nearest_left, INT4 *nearest_right)
Locate the nearest block in a lattice tiling to a given point.
void XLALDestroyLatticeTilingLocator(LatticeTilingLocator *loc)
Destroy a lattice tiling locator.
size_t XLALTiledLatticeTilingDimensions(const LatticeTiling *tiling)
Return the number of tiled dimensions of the lattice tiling.
size_t XLALLatticeTilingTiledDimension(const LatticeTiling *tiling, const size_t tiled_dim)
Return the dimension of the tiled lattice tiling dimension indexed by 'tiled_dim'.
LatticeTilingLocator * XLALCreateLatticeTilingLocator(const LatticeTiling *tiling)
Create a new lattice tiling locator.
REAL8 XLALLatticeTilingBoundingBox(const LatticeTiling *tiling, const size_t dim)
Return the bounding box extent of the lattice tiling in a given dimension, or 0 for non-tiled dimensi...
int XLALSetPhysicalPointSuperskyRefTime(PulsarDopplerParams *out_phys, const SuperskyTransformData *rssky_transf)
Set the reference time of a physical point to that of the reduced supersky coordinates.
int XLALConvertPhysicalToSuperskyPoint(gsl_vector *out_rssky, const PulsarDopplerParams *in_phys, const SuperskyTransformData *rssky_transf)
Convert a point from physical to supersky coordinates.
int XLALConvertSuperskyToPhysicalPoint(PulsarDopplerParams *out_phys, const gsl_vector *in_rssky, const gsl_vector *ref_rssky, const SuperskyTransformData *rssky_transf)
Convert a point from supersky to physical coordinates.
int XLALConvertSuperskyToSuperskyPoint(gsl_vector *out_rssky, const SuperskyTransformData *out_rssky_transf, const gsl_vector *in_rssky, const gsl_vector *ref_rssky, const SuperskyTransformData *in_rssky_transf)
Convert a point between supersky coordinates.
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_NULL(assertion,...)
Statistics related to the number/value of lattice tiling points in a dimension.
UINT4 min_points
Minimum number of points in this dimension.
UINT8 total_points
Total number of points up to this dimension.
Type containing the 'Doppler-parameters' affecting the time-evolution of the phase.
REAL8 Alpha
Sky position: RA (longitude) in equatorial coords and radians.
Item stored in the cache.
REAL4 relevance
Relevance, used to decide how long to keep items.
UINT8 coh_index
Coherent locator index, used to find items in cache.
UINT4 generation
Generation, used both to find items in cache and to decide how long to keep items.
WeaveCohResults * coh_res
Results of a coherent computation on a single segment.
Cache used to store coherent results.
UINT8 coh_max_index
Maximum value of index from coherent locator.
double coh_relevance_offset
Offset used in computation of coherent point relevance.
size_t ndim
Number of parameter-space dimensions.
size_t dim0
Lowest tiled parameter-space dimension.
LatticeTilingLocator * coh_locator
Coherent parameter-space tiling locator.
WeaveCohInput * coh_input
Input data required for computing coherent results.
UINT4 generation
Current generation of cache items.
LALHashTbl * coh_index_hash
Hash table which looks up cache items by index.
BOOLEAN all_gc
Whether garbage collection should remove as many results as possible.
LALBitset * coh_computed_bitset
Bitset which records whether an item has ever been computed.
const SuperskyTransformData * semi_rssky_transf
Reduced supersky transform data for semicoherent lattice.
UINT4 heap_max_size
Maximum size obtained by relevance heap.
cache_item * saved_item
Save an no-longer-used cache item for re-use.
const SuperskyTransformData * coh_rssky_transf
Reduced supersky transform data for coherent lattice.
BOOLEAN any_gc
Whether any garbage collection of results should be used.
LALHeap * relevance_heap
Heap which ranks cache items by relevance.
Container for a series of cache queries.
UINT4 freq_partition_index
Index to current partition of semicoherent frequency block.
UINT8 semi_index
Sequential index for the current semicoherent frequency block.
INT4 * coh_part_right_offset
Offset to apply to coherent right-most index to enclose a frequency partition.
REAL4 semi_relevance
Relevance of the current semicoherent frequency block.
UINT8 * coh_nres
Number of computed coherent results (per query)
UINT8 semi_ntmpl
Number of semicoherent templates (over all queries)
PulsarDopplerParams * coh_phys
Physical points of each queried coherent frequency block.
size_t dim0
Lowest tiled parameter-space dimension.
UINT4 nfreq_partitions
Number of partitions to divide semicoherent frequency block into.
INT4 * coh_right
Indexes of right-most point in queried coherent frequency block.
UINT4 nqueries
Number of queries for which space is allocated.
INT4 semi_right
Index of right-most point in current semicoherent frequency block.
UINT8 * coh_ntmpl
Number of coherent templates (per query)
size_t ndim
Number of parameter-space dimensions.
const SuperskyTransformData * semi_rssky_transf
Reduced supersky transform data for semicoherent lattice.
INT4 * coh_part_left_offset
Offset to apply to coherent left-most index to enclose a frequency partition.
double semi_relevance_offset
Offset used in computation of semicoherent point relevance.
UINT8 * coh_index
Sequential indexes for each queried coherent frequency block.
PulsarDopplerParams semi_phys
Physical coordinates of the current semicoherent frequency block.
INT4 * coh_left
Indexes of left-most point in queried coherent frequency block.
REAL4 * coh_relevance
Relevance of each queried coherent frequency block.
INT4 semi_left
Index of left-most point in current semicoherent frequency block.