20Compute the F-statistic for a piecewise model template.
29from tqdm
import trange
34from .
import basis_functions
as bf
35from .
import gte_and_other_methods
as gom
36from .
import semicoherent_metric_methods
as scmm
37from .
import tbank_estimates
as tbe
53 Fstat_opt_args = lp.FstatOptionalArgs(lp.FstatOptionalArgsDefaults)
54 Fstat_opt_args.FstatMethod = lp.FMETHOD_DEMOD_BEST
55 Fstat_opt_args.sourceDeltaT = finputdata.sourceDeltaT
57 logging.info(f
"SFT path: {sft_path}")
61 for elem
in inject_params:
65 logging.debug(inject_params)
66 logging.debug(all_minus_one)
67 logging.debug(
not inject_params == []
and not all_minus_one)
70 if inject_params != []
and not all_minus_one:
71 Tdata = timeint[-1] - timeint[0]
74 cosi = finputdata.cosi
76 phi0 = finputdata.phi0
77 tref = timeint[0] + Tdata * finputdata.trefsegfrac
78 Alpha = finputdata.Alpha
79 Delta = finputdata.Delta
82 Fstat_signal = lp.CreatePulsarParamsVector(1)
83 Fstat_signal.data[0].Amp.aPlus = 0.5 * h0 * (1.0 + cosi * cosi)
84 Fstat_signal.data[0].Amp.aCross = h0 * cosi
85 Fstat_signal.data[0].Amp.psi = psi
86 Fstat_signal.data[0].Amp.phi0 = phi0
87 Fstat_signal.data[0].Doppler.refTime = tref
88 Fstat_signal.data[0].Doppler.Alpha = Alpha
89 Fstat_signal.data[0].Doppler.Delta = Delta
91 logging.info(f
"Injecting parameters: {inject_params} with h0: {h0}")
94 for i
in range(len(inject_params)):
95 Fstat_signal.data[0].Doppler.fkdot[i] = inject_params[i]
97 Fstat_opt_args.injectSources = Fstat_signal
99 dfreq = finputdata.dfreq
100 emphdata = lp.InitBarycenter(
"earth00-40-DE405.dat.gz",
"sun00-40-DE405.dat.gz")
102 constraints = lp.SFTConstraints()
104 constraints.minStartTime = lal.LIGOTimeGPS(timeint[0])
105 constraints.maxStartTime = lal.LIGOTimeGPS(timeint[1])
107 if len(detectors) == 0:
108 catalogue = lp.SFTdataFind(sft_path +
"*.sft", constraints)
110 sft_path_master = sft_path +
"*.sft"
112 elif len(detectors) == 1:
114 det1_path = sft_path + detectors[0] +
"/*.sft"
116 catalogue = lp.SFTdataFind(det1_path, constraints)
118 sft_path_master = det1_path
120 elif len(detectors) == 2:
122 det1_path = sft_path + detectors[0] +
"/*.sft"
123 det2_path = sft_path + detectors[1] +
"/*.sft"
125 sft_path_master = det1_path +
";" + det2_path
127 catalogue = lp.SFTdataFind(sft_path_master, constraints)
129 elif len(detectors) == 3:
131 det1_path = sft_path + detectors[0] +
"/*.sft"
132 det2_path = sft_path + detectors[1] +
"/*.sft"
133 det2_path = sft_path + detectors[3] +
"/*.sft"
135 sft_path_master = det1_path +
";" + det2_path +
";" + det3_path
137 catalogue = lp.SFTdataFind(sft_path_master, constraints)
139 logging.debug(
"Heya!")
141 logging.info(f
"Path to SFT's being used: {sft_path_master}")
143 fstat = lp.CreateFstatInput(
144 catalogue, SFTfmin, SFTfmax, dfreq, emphdata, Fstat_opt_args
153 num_det = finputdata.detectors.length
154 Tsft = finputdata.Tsft
156 sft_ts = lp.MakeMultiTimestamps(tstart, Tdata, Tsft, 0, num_det)
157 sft_catalog = lp.MultiAddToFakeSFTCatalog(
None, finputdata.detectors, sft_ts)
173 Tdata = timeint[1] - timeint[0]
174 dfreq = finputdata.dfreq
176 Fstat_opt_args = lp.FstatOptionalArgs(lp.FstatOptionalArgsDefaults)
177 Fstat_opt_args.FstatMethod = lp.FMETHOD_DEMOD_BEST
178 Fstat_opt_args.sourceDeltaT = finputdata.sourceDeltaT
181 cosi = finputdata.cosi
183 phi0 = finputdata.phi0
184 tref = timeint[0] + Tdata * trefsegfrac
185 Alpha = finputdata.Alpha
186 Delta = finputdata.Delta
189 Fstat_signal = lp.CreatePulsarParamsVector(1)
190 Fstat_signal.data[0].Amp.aPlus = 0.5 * h0 * (1.0 + cosi * cosi)
191 Fstat_signal.data[0].Amp.aCross = h0 * cosi
192 Fstat_signal.data[0].Amp.psi = psi
193 Fstat_signal.data[0].Amp.phi0 = phi0
194 Fstat_signal.data[0].Doppler.refTime = tref
195 Fstat_signal.data[0].Doppler.Alpha = Alpha
196 Fstat_signal.data[0].Doppler.Delta = Delta
198 logging.debug(f
"Injecting parameters: {inject_params} with h0: {h0}")
201 for i
in range(len(inject_params)):
202 Fstat_signal.data[0].Doppler.fkdot[i] = inject_params[i]
204 Fstat_opt_args.injectSources = Fstat_signal
206 Fstat_injection_noise = lp.MultiNoiseFloor()
207 Fstat_injection_noise.length = finputdata.detectors.length
210 for i, noise
in enumerate(finputdata.noise_sqrt_Sh):
211 Fstat_injection_noise.sqrtSn[i] = noise
213 Fstat_opt_args.injectSqrtSX = Fstat_injection_noise
215 ephemerides = lp.InitBarycenter(
"earth00-19-DE405.dat.gz",
"sun00-19-DE405.dat.gz")
218 Fstat_input = lp.CreateFstatInput(
219 sft_catalog, SFTfmin, SFTfmax, dfreq, ephemerides, Fstat_opt_args
235 s =
int(len(transformmatrices[0]) / 2)
237 segs =
int(len(template) / s - 1)
239 dopparams = lp.PulsarDopplerParams()
240 dopparams.Alpha = finputdata.Alpha
241 dopparams.Delta = finputdata.Delta
247 for seg
in range(segs):
249 segtemp = template[seg * s : (seg + 2) * s]
253 + (bf.knotslist[seg + 1] - bf.knotslist[seg]) * trefsegfrac
255 dopparams.refTime = tref
257 p0 = bf.knotslist[seg]
258 p1 = bf.knotslist[seg + 1]
260 fstatin = fstatinputarray[seg]
262 tstart = bf.knotslist[0]
263 dopplerparams = np.matmul(transformmatrices[seg], segtemp)
270 dopparams.fkdot[0 : len(dopplerparams)] = dopplerparams
273 whatToCompute = lp.FSTATQ_2F_PER_DET + lp.FSTATQ_2F
274 fstatresults = lp.FstatResults()
275 fstatresults = lp.ComputeFstat(
276 fstatresults, fstatin, dopparams, numFreqBins, whatToCompute
279 fstat_res_array.append(fstatresults)
281 return fstat_res_array
285 with open(filename,
"a+")
as reader:
287 for elem
in fstat_res_heap:
294 fstat_res_array = elem[4]
296 fstats_on_segs = [fstat_res.twoF[0]
for fstat_res
in fstat_res_array]
297 fstat = sum(fstats_on_segs) / len(fstats_on_segs)
300 twoF_on_segs_on_detectors = []
302 numdets = fstat_res_array[0].numDetectors
304 for i
in range(numdets):
306 fstat_res.twoFPerDet(i)[0]
for fstat_res
in fstat_res_array
308 twoF_on_segs_on_detectors.append(two_F_on_segs)
312 for detector_2Fs
in twoF_on_segs_on_detectors:
313 this_det_2F = sum(detector_2Fs) / len(detector_2Fs)
315 two_F_per_det.append(this_det_2F)
318 templateline =
" ".join(
"{:20.12E}".
format(x)
for x
in template)
320 fstat_line =
"{:20.10f}".
format(fstat) +
" "
322 for twoF
in two_F_per_det:
323 fstat_line +=
"{:20.10f}".
format(twoF) +
" "
325 mismatch_line =
"{:20.10f}".
format(mismatch) +
" "
328 line = fstat_line + mismatch_line + templateline +
"\n"
330 line = mismatch_line + fstat_line + templateline +
"\n"
341 elif 50 <= fstat < 500:
346 lower_round =
int(fstat - fstat % base)
348 if lower_round
in dic:
349 dic[lower_round] += 1
355 with open(filename,
"a+")
as reader:
357 for k, v
in dic.items():
358 line =
str(k) +
", " +
str(v) +
"\n"
383 Fstat_mismatch=False,
388 segs = len(bf.knotslist) - 1
389 logging.info(
"Knots: %s",
str(bf.knotslist))
391 finalknot = len(bf.knotslist)
397 tiling = lp.CreateLatticeTiling(s * finalknot)
399 logging.debug(
"Doing metric")
400 metric = scmm.PreCompMetric(s)
402 logging.debug(
"Doing Bounds")
403 tbe.setbounds(tiling, tbank)
405 logging.debug(
"Setting tiling lattice and metric")
408 lp.SetTilingLatticeAndMetric(
409 tiling, lp.TILING_LATTICE_ANSTAR, metric, tbank.maxmismatch
412 signalpoint = lal.gsl_vector(s * finalknot)
413 signalpoint.data = signalparams
415 nearestpoint = lal.gsl_vector(s * finalknot)
417 nearestpoint.data = signalpoint.data
418 nearesttemp = nearestpoint.data
422 for i
in range(len(nearesttemp)):
423 diffvec.append(nearesttemp[i] - signalparams[i])
429 iterator = lp.CreateLatticeTilingIterator(tiling, s * finalknot)
431 for i
in range(s * finalknot):
432 stats = lp.LatticeTilingStatistics(tiling, i)
433 logging.info(f
"Total points in dim={i}: {stats.total_points}")
434 logging.info(f
"Minimum points in dim={i}: {stats.min_points}")
435 logging.info(f
"Maximum points in dim={i}: {stats.max_points}")
438 transformmatrices = []
440 logging.info(
"Setting up Fstatistic input and transformation matrices")
442 for seg
in range(segs):
443 logging.debug(f
"Doing seg: {seg}")
444 p0 = bf.knotslist[seg]
445 p1 = bf.knotslist[seg + 1]
446 tref = p0 + (p1 - p0) * trefsegfrac
447 tstart = bf.knotslist[0]
451 signalparamsseg = signalparams[seg * s : (seg + 2) * s]
452 inject_params = gom.PWParamstoTrefParams(
453 signalparamsseg, p0 - tstart, p1 - tstart, tref - tstart, s
456 transformmatrices.append(gom.ParamTransformationMatrix(p0, p1, tref, s))
458 if SFTFiles
or finputdata.inject_data:
464 sft_path=SFTdirectory,
465 detectors=finputdata.detectors.data,
466 inject_params=inject_params,
469 sft_catalog =
SFTCatalog(p0, p1 - p0, finputdata)
477 trefsegfrac=trefsegfrac,
479 fstatinputarray.append(finput)
481 logging.info(
"Finputs done")
491 trefsegfrac=trefsegfrac,
495 all_sig_twoFs = [elem.twoF[0]
for elem
in sigfstat]
496 sigtwoF = sum(all_sig_twoFs) / (len(all_sig_twoFs))
498 sig_fstat_heap = [[sigtwoF, -1, -1, signalparams, sigfstat]]
501 out_directory +
"/" + filename, sig_fstat_heap, fstats_first=
True
504 mismatchfilename =
"Mismatch_" + filename[:-4] +
".txt"
508 out_directory +
"/" + mismatchfilename, sig_fstat_heap, fstats_first=
False
515 template = lal.gsl_vector(s * finalknot)
517 starttime = time.time()
519 logging.info(
"Counting templates ...")
520 tempcount = lp.TotalLatticeTilingPoints(iterator)
521 logging.info(f
"... finished: number of templates = {tempcount}")
523 if mode ==
"template_count":
524 return 0, 0, 0, tempcount
526 lowest_mismatch_metric = 1000000000000000000000000
527 lowest_mismatch_fstat = 1000000000000000000000000
529 tqdm_file = open(filename[:-4] +
"_tqdm_Output.txt",
"w+")
533 if mode ==
"mis_hist" and not Fstat_mismatch:
535 for counter
in trange(tempcount, file=tqdm_file):
536 fin = lp.NextLatticeTilingPoint(iterator, template)
537 thistemp = copy.copy(template.data)
540 signalparams[i] - thistemp[i]
for i
in range(len(signalparams))
543 tempmismatch = np.dot(tempdiffvec, np.dot(metric, tempdiffvec))
545 if tempmismatch < lowest_mismatch_metric:
546 lowest_mismatch_metric = tempmismatch
548 return lowest_mismatch_metric, 0, 0, tempcount
551 mismatch_fstat_res_heap = []
554 lowest_mismatch = 100000000000
560 for counter
in trange(tempcount, file=tqdm_file):
561 fin = lp.NextLatticeTilingPoint(iterator, template)
562 thistemp = copy.copy(template.data)
569 trefsegfrac=trefsegfrac,
573 all_twoFs = [res.twoF[0]
for res
in fstat]
575 twoF = sum(all_twoFs) / len(all_twoFs)
580 tempdiffvec = [signalparams[i] - thistemp[i]
for i
in range(len(signalparams))]
582 temp_mismatch_metric = np.dot(tempdiffvec, np.dot(metric, tempdiffvec))
583 temp_mismatch_fstat = (sigtwoF - twoF) / (sigtwoF - 4)
585 if temp_mismatch_metric < lowest_mismatch_metric:
586 lowest_mismatch_metric = temp_mismatch_metric
588 if temp_mismatch_fstat < lowest_mismatch_fstat:
589 lowest_mismatch_fstat = temp_mismatch_fstat
592 this_mismatch = temp_mismatch_fstat
594 this_mismatch = temp_mismatch_metric
596 if this_mismatch < lowest_mismatch:
597 lowest_mismatch = this_mismatch
601 if counter < tempsperfile:
602 hq.heappush(fstat_res_heap, (twoF, this_mismatch, counter, thistemp, fstat))
604 mismatch_fstat_res_heap,
605 (-this_mismatch, twoF, counter, thistemp, fstat),
609 fstat_res_heap, (twoF, this_mismatch, counter, thistemp, fstat)
612 mismatch_fstat_res_heap,
613 (-this_mismatch, twoF, counter, thistemp, fstat),
620 fstat_hist_file_name = out_directory +
"/" +
"Fstat_hist_" + filename
625 for i, elem
in enumerate(mismatch_fstat_res_heap):
626 new_mismatch = -1 * elem[0]
627 mismatch_fstat_res_heap[i] = (new_mismatch, elem[1], elem[2], elem[3], elem[4])
630 mismatch_fstat_res_heap.sort()
631 fstat_res_heap.sort(reverse=
True)
634 fin = lp.NextLatticeTilingPoint(iterator, template)
636 raise RuntimeError(
"end of template bank has not been reached")
639 logging.info(f
"Length of tempheap: {len(fstat_res_heap)}")
640 logging.info(f
"Templates per file is: {tempsperfile}")
641 logging.info(f
"Templates counted: {counter}")
642 logging.info(f
"Time Elapsed: {time.time() - starttime}")
643 logging.info(f
"Templates per second: {counter / (time.time() - starttime)}")
646 logging.info(f
"Sig f-stat: {sigtwoF}")
647 logging.info(
"Running maximum f-stat: %s",
str(fstatmax))
648 logging.info(
"Heap maximum f-stat: %s",
str(fstat_res_heap[0][0]))
649 logging.info(f
"Running lowest mismatch: {lowest_mismatch}")
650 logging.info(f
"Heap lowest mismatch: {mismatch_fstat_res_heap[0][0]}")
654 out_directory +
"/" + filename, fstat_res_heap, fstats_first=
True
657 out_directory +
"/" + mismatchfilename,
658 mismatch_fstat_res_heap,
662 return lowest_mismatch_metric, lowest_mismatch_fstat, fstatmax, tempcount
679 segs = len(bf.knotslist) - 1
680 logging.info(
"Knots: %s",
str(bf.knotslist))
682 finalknot = len(bf.knotslist)
688 tiling = lp.CreateLatticeTiling(s * finalknot)
690 logging.debug(
"Doing metric")
691 metric = scmm.PreCompMetric(s)
693 logging.debug(
"Doing Bounds")
694 tbe.setbounds(tiling, tbank)
696 logging.debug(
"Setting tiling lattice and metric")
699 lp.SetTilingLatticeAndMetric(
700 tiling, lp.TILING_LATTICE_ANSTAR, metric, tbank.maxmismatch
704 iterator = lp.CreateLatticeTilingIterator(tiling, s * finalknot)
706 for i
in range(s * finalknot):
707 stats = lp.LatticeTilingStatistics(tiling, i)
708 logging.info(f
"Total points in dim={i}: {stats.total_points}")
709 logging.info(f
"Minimum points in dim={i}: {stats.min_points}")
710 logging.info(f
"Maximum points in dim={i}: {stats.max_points}")
713 transformmatrices = []
715 logging.info(
"Setting up Fstatistic input and transformation matrices")
717 for seg
in range(segs):
718 logging.debug(f
"Doing seg: {seg}")
719 p0 = bf.knotslist[seg]
720 p1 = bf.knotslist[seg + 1]
721 tref = p0 + (p1 - p0) * trefsegfrac
722 tstart = bf.knotslist[0]
724 transformmatrices.append(gom.ParamTransformationMatrix(p0, p1, tref, s))
730 sft_path = SFTdirectory
738 detectors=tbank.detectors,
741 fstatinputarray.append(finput)
743 logging.info(
"Finputs done")
751 template = lal.gsl_vector(s * finalknot)
753 starttime = time.time()
755 logging.info(
"Counting templates ...")
756 tempcount = lp.TotalLatticeTilingPoints(iterator)
757 logging.info(f
"... finished: number of templates = {tempcount}")
759 tqdm_file = open(filename[:-4] +
"_tqdm_Output.txt",
"w+")
763 for counter
in trange(tempcount, file=tqdm_file):
764 fin = lp.NextLatticeTilingPoint(iterator, template)
765 thistemp = copy.copy(template.data)
772 trefsegfrac=trefsegfrac,
776 all_twoFs = [res.twoF[0]
for res
in fstat]
778 twoF = sum(all_twoFs) / len(all_twoFs)
785 if counter <= tempsperfile:
786 hq.heappush(fstat_res_heap, (twoF, 0, counter, thistemp, fstat))
788 hq.heappushpop(fstat_res_heap, (twoF, 0, counter, thistemp, fstat))
793 fin = lp.NextLatticeTilingPoint(iterator, template)
795 raise RuntimeError(
"end of template bank has not been reached")
798 logging.info(f
"Length of tempheap: {len(fstat_res_heap)}")
799 logging.info(f
"Templates per file is: {tempsperfile}")
800 logging.info(f
"Templates counted: {counter}")
801 logging.info(f
"Time Elapsed: {time.time() - starttime}")
802 logging.info(f
"Templates per second: {counter / (time.time() - starttime)}")
805 logging.info(
"Running maximum f-stat: %s",
str(fstatmax))
806 logging.info(
"Heap maximum f-stat: %s",
str(fstat_res_heap[-1][0]))
808 fstat_res_heap.sort(reverse=
True)
813 return 0, 0, fstatmax, tempcount
def dic_to_file(filename, dic)
def fstatinputfromSFTFiles(SFTfmin, SFTfmax, finputdata, timeint=[-1, -2], sft_path=".", detectors=[], inject_params=[])
def semifstatcatalogue(SFTfmin, SFTfmax, tbank, finputdata, signalparams, filename, out_directory=".", SFTdirectory=".", trefsegfrac=0.0, rtnsum=False, SFTFiles=False, tempsperfile=1000, Fstat_mismatch=False, fstat_hist=False, mode="search")
def pw_fstat_search_catalogue(SFTfmin, SFTfmax, tbank, finputdata, filename, tbankdirectory=".", SFTdirectory=".", trefsegfrac=0.0, rtnsum=False, tempsperfile=1000)
def fstat_res_heap_to_file(filename, fstat_res_heap, fstats_first=True)
def SFTCatalog(tstart, Tdata, finputdata)
def computefstat(template, finputdata, fstatinputarray, transformmatrices, trefsegfrac=0.0, rtnsum=False)
def add_fstat_to_dic(fstat, dic)
def fstatinput(SFTfmin, SFTfmax, sft_catalog, finputdata, inject_params, timeint=[-1, -2], trefsegfrac=0.0)
An "SFT-catalogue": a vector of SFTdescriptors, as returned by XLALSFTdataFind()