def test_single_epoch_weak_transient(self): """ A weak (barely detected in blind extraction) transient appears at field centre in one image, then disappears entirely. Because it is a weak extraction, it will not be immediately marked as transient, but it will get flagged up after forced-fitting due to the variability search. """ im_params = self.im_params transient_src = db_subs.MockSource( template_extractedsource=db_subs.example_extractedsource_tuple( ra=im_params[0]['centre_ra'], dec=im_params[0]['centre_decl'], ), lightcurve={im_params[2]['taustart_ts'] : self.barely_detectable_flux} ) inserted_sources = [] for img_pars in im_params[:3]: image, _,forced_fits = insert_image_and_simulated_sources( self.dataset,img_pars,[transient_src], self.new_source_sigma_margin) self.assertEqual(forced_fits, []) newsources = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(newsources), 0) transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id, **self.search_params) #No variability yet self.assertEqual(len(transients), 0) #Now, the final, empty image: image, blind_extractions, forced_fits = insert_image_and_simulated_sources( self.dataset,im_params[3],[transient_src], self.new_source_sigma_margin) self.assertEqual(len(blind_extractions),0) self.assertEqual(len(forced_fits), 1) #No changes to newsource table newsources = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(newsources), 0) #But it now has high variability transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id, **self.search_params) self.assertEqual(len(transients), 1) transient_properties = transients[0] # Check that the bands for the images are the same as the transient's band freq_bands = self.dataset.frequency_bands() self.assertEqual(len(freq_bands), 1) self.assertEqual(freq_bands[0], transient_properties['band']) #Sanity check that the runcat is correctly matched runcats = self.dataset.runcat_entries() self.assertEqual(len(runcats), 1) self.assertEqual(runcats[0]['runcat'], transient_properties['runcat_id'])
def test_steady_source(self): """ Sanity check: Ensure we get no newsource table entries for a steady source. """ im_params = self.im_params steady_src = db_subs.MockSource( template_extractedsource=db_subs.example_extractedsource_tuple( ra=im_params[0]['centre_ra'], dec=im_params[0]['centre_decl'], ), lightcurve=defaultdict(lambda : self.reliably_detectable_flux) ) inserted_sources = [] for img_pars in im_params: image, _,forced_fits = insert_image_and_simulated_sources( self.dataset,img_pars,[steady_src], self.new_source_sigma_margin) #should not have any nulldetections self.assertEqual(len(forced_fits), 0) transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id, **self.search_params) newsources = get_newsources_for_dataset(self.dataset.id) #or newsources, high variability sources self.assertEqual(len(transients), 0) self.assertEqual(len(newsources), 0)
def test_probably_not_a_transient(self): """ No source at 250MHz, but we detect a source at 50MHz. Not necessarily a transient. Should trivially ignore 250MHz data when looking at a new 50MHz source. """ img_params = self.img_params img0 = img_params[0] # This time around, we just manually exclude the steady src from # the first image detections. steady_low_freq_src = MockSource( example_extractedsource_tuple(ra=img_params[0]['centre_ra'], dec=img_params[0]['centre_decl']), lightcurve=defaultdict(lambda: self.always_detectable_flux)) # Insert first image, no sources. tkp.db.Image(data=img_params[0], dataset=self.dataset) # Now set up second image. img1 = tkp.db.Image(data=img_params[1], dataset=self.dataset) xtr = steady_low_freq_src.simulate_extraction(img1, extraction_type='blind') insert_extracted_sources(img1._id, [xtr], 'blind') associate_extracted_sources(img1._id, deRuiter_r, self.new_source_sigma_margin) transients = get_newsources_for_dataset(self.dataset.id) # Should have no marked transients self.assertEqual(len(transients), 0)
def test_probably_not_a_transient(self): """ No source at 250MHz, but we detect a source at 50MHz. Not necessarily a transient. Should trivially ignore 250MHz data when looking at a new 50MHz source. """ img_params = self.img_params img0 = img_params[0] # This time around, we just manually exclude the steady src from # the first image detections. steady_low_freq_src = MockSource( example_extractedsource_tuple(ra=img_params[0]['centre_ra'], dec=img_params[0]['centre_decl'] ), lightcurve=defaultdict(lambda :self.always_detectable_flux) ) # Insert first image, no sources. tkp.db.Image(data=img_params[0],dataset=self.dataset) # Now set up second image. img1 = tkp.db.Image(data=img_params[1],dataset=self.dataset) xtr = steady_low_freq_src.simulate_extraction(img1, extraction_type='blind') insert_extracted_sources(img1._id, [xtr], 'blind') associate_extracted_sources(img1._id, deRuiter_r, self.new_source_sigma_margin) transients = get_newsources_for_dataset(self.dataset.id) # Should have no marked transients self.assertEqual(len(transients), 0)
def test_marginal_transient(self): """ ( flux1 > (rms_min0*(det0 + margin) ) but ( flux1 < (rms_max0*(det0 + margin) ) --> Possible transient If it was in a region of rms_min, we would (almost certainly) have seen it in the first image. So new source --> Possible transient. But if it was in a region of rms_max, then perhaps we would have missed it. In which case, new source --> Just seeing deeper. Note that if we are tiling overlapping images, then the first time a field is processed with image-centre at the edge of the old field, we may get a bunch of unhelpful 'possible transients'. Furthermore, this will pick up fluctuating sources near the image-margins even with a fixed field of view. But without a more complex store of image-rms-per-position, we cannot do better. Hopefully we can use a 'distance from centre' feature to separate out the good and bad candidates in this case. """ img_params = self.img_params #Must pick flux value carefully to fire correct logic branch: marginal_transient_flux = self.reliably_detected_at_image_centre_flux marginal_transient = MockSource( example_extractedsource_tuple(ra=img_params[0]['centre_ra'], dec=img_params[0]['centre_decl']), lightcurve={img_params[1]['taustart_ts'] : marginal_transient_flux} ) #First, check that we've set up the test correctly: rms_min0 = img_params[0]['rms_min'] rms_max0 = img_params[0]['rms_max'] det0 = img_params[0]['detection_thresh'] self.assertTrue(marginal_transient_flux < rms_max0*(det0 + self.new_source_sigma_margin ) ) self.assertTrue(marginal_transient_flux > rms_min0*(det0 + self.new_source_sigma_margin ) ) for pars in self.img_params: img = tkp.db.Image(data=pars,dataset=self.dataset) xtr = marginal_transient.simulate_extraction(img, extraction_type='blind') if xtr is not None: img.insert_extracted_sources([xtr],'blind') img.associate_extracted_sources(deRuiter_r, self.new_source_sigma_margin) newsources = get_newsources_for_dataset(self.dataset.id) #Should have one 'possible' transient self.assertEqual(len(newsources),1) self.assertTrue( newsources[0]['low_thresh_sigma'] > self.new_source_sigma_margin) self.assertTrue( newsources[0]['high_thresh_sigma'] < self.new_source_sigma_margin)
def test_steady_source(self): """ Sanity check: Ensure we get no newsource table entries for a steady source. """ im_params = self.im_params steady_src = db_subs.MockSource( template_extractedsource=db_subs.example_extractedsource_tuple( ra=im_params[0]['centre_ra'], dec=im_params[0]['centre_decl'], ), lightcurve=defaultdict(lambda: self.reliably_detectable_flux)) inserted_sources = [] for img_pars in im_params: image, _, forced_fits = insert_image_and_simulated_sources( self.dataset, img_pars, [steady_src], self.new_source_sigma_margin) #should not have any nulldetections self.assertEqual(len(forced_fits), 0) transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id, **self.search_params) newsources = get_newsources_for_dataset(self.dataset.id) #or newsources, high variability sources self.assertEqual(len(transients), 0) self.assertEqual(len(newsources), 0)
def test_null_detection_business_as_usual(self): """ If we do not blindly extract a steady source due to increased RMS, then we expect a null-detection forced-fit to be triggered. However, if the source properties are steady, this should not result in the source being identified as transient. """ img0 = self.img_params[0] steady_src_flux = self.barely_detectable_flux steady_src = MockSource( example_extractedsource_tuple(ra=img0['centre_ra'], dec=img0['centre_decl'] ), lightcurve=defaultdict(lambda :steady_src_flux) ) image, blind_xtr,forced_fits = insert_image_and_simulated_sources( self.dataset,self.img_params[0],[steady_src], self.new_source_sigma_margin) self.assertEqual(len(blind_xtr),1) self.assertEqual(len(forced_fits),0) image, blind_xtr,forced_fits = insert_image_and_simulated_sources( self.dataset,self.img_params[1],[steady_src], self.new_source_sigma_margin) self.assertEqual(len(blind_xtr),0) self.assertEqual(len(forced_fits),1) get_sources_filtered_by_final_variability(dataset_id=self.dataset.id, **self.search_params) transients=get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(transients),0)
def test_null_detection_business_as_usual(self): """ If we do not blindly extract a steady source due to increased RMS, then we expect a null-detection forced-fit to be triggered. However, if the source properties are steady, this should not result in the source being identified as transient. """ img0 = self.img_params[0] steady_src_flux = self.barely_detectable_flux steady_src = MockSource( example_extractedsource_tuple(ra=img0['centre_ra'], dec=img0['centre_decl']), lightcurve=defaultdict(lambda: steady_src_flux)) image, blind_xtr, forced_fits = insert_image_and_simulated_sources( self.dataset, self.img_params[0], [steady_src], self.new_source_sigma_margin) self.assertEqual(len(blind_xtr), 1) self.assertEqual(len(forced_fits), 0) image, blind_xtr, forced_fits = insert_image_and_simulated_sources( self.dataset, self.img_params[1], [steady_src], self.new_source_sigma_margin) self.assertEqual(len(blind_xtr), 0) self.assertEqual(len(forced_fits), 1) get_sources_filtered_by_final_variability(dataset_id=self.dataset.id, **self.search_params) transients = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(transients), 0)
def test_probably_not_a_transient(self): """ ( flux1 < (rms_min0*(det0 + margin) ) --> Probably not a transient NB even if avg_source_flux == rms_min0*det0 + epsilon we might not detect it in the first image, due to noise fluctuations. So we provide the user-tunable marginal_detection_thresh, to ignore these 'noise' transients. """ img_params = self.img_params img0 = img_params[0] marginal_steady_src_flux = self.barely_detectable_flux # This time around, we just manually exclude the steady src from # the first image detections. marginal_steady_src = MockSource( example_extractedsource_tuple(ra=img_params[0]['centre_ra'], dec=img_params[0]['centre_decl'] ), lightcurve=defaultdict(lambda :marginal_steady_src_flux) ) # First, check that we've set up the test correctly rms_min0 = img_params[0]['rms_min'] det0 = img_params[0]['detection_thresh'] self.assertTrue(marginal_steady_src_flux < rms_min0 * (det0 + self.new_source_sigma_margin)) # Insert first image, no sources. tkp.db.Image(data=img_params[0], dataset=self.dataset) # Now set up second image. img1 = tkp.db.Image(data=img_params[1], dataset=self.dataset) xtr = marginal_steady_src.simulate_extraction(img1, extraction_type='blind') insert_extracted_sources(img1._id, [xtr], 'blind') associate_extracted_sources(img1._id, deRuiter_r, self.new_source_sigma_margin) newsources = get_newsources_for_dataset(self.dataset.id) # Should have no flagged new sources self.assertEqual(len(newsources), 0)
def test_probably_not_a_transient(self): """ ( flux1 < (rms_min0*(det0 + margin) ) --> Probably not a transient NB even if avg_source_flux == rms_min0*det0 + epsilon we might not detect it in the first image, due to noise fluctuations. So we provide the user-tunable marginal_detection_thresh, to ignore these 'noise' transients. """ img_params = self.img_params img0 = img_params[0] marginal_steady_src_flux = self.barely_detectable_flux # This time around, we just manually exclude the steady src from # the first image detections. marginal_steady_src = MockSource( example_extractedsource_tuple(ra=img_params[0]['centre_ra'], dec=img_params[0]['centre_decl'] ), lightcurve=defaultdict(lambda :marginal_steady_src_flux) ) #First, check that we've set up the test correctly: rms_min0 = img_params[0]['rms_min'] det0 = img_params[0]['detection_thresh'] self.assertTrue(marginal_steady_src_flux < rms_min0*(det0 + self.new_source_sigma_margin ) ) #Insert first image, no sources. tkp.db.Image(data=img_params[0],dataset=self.dataset) #Now set up second image. img1 = tkp.db.Image(data=img_params[1],dataset=self.dataset) xtr = marginal_steady_src.simulate_extraction(img1, extraction_type='blind') img1.insert_extracted_sources([xtr],'blind') img1.associate_extracted_sources(deRuiter_r, self.new_source_sigma_margin) newsources = get_newsources_for_dataset(self.dataset.id) #Should have no flagged new sources self.assertEqual(len(newsources),0)
def test_full_transient_search_routine(self): inserted_imgs = [] for img_idx in xrange(self.n_images): image, _,_ = insert_image_and_simulated_sources( self.dataset,self.img_params[img_idx],self.all_mock_sources, self.new_source_sigma_margin) inserted_imgs.append(image) transients = get_sources_filtered_by_final_variability(dataset_id=self.dataset.id, **self.search_params) newsources = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(transients), self.n_transients_after_image[img_idx]) #Sanity check that everything went into one band bands = frequency_bands(self.dataset._id) self.assertEqual(len(bands), 1) all_transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id, **self.search_params) # for t in all_transients: # print "V_int:", t['v_int'], " eta_int:", t['eta_int'] #Now test thresholding: more_highly_variable = sum(t['v_int'] > 2.0 for t in all_transients) very_non_flat = sum(t['eta_int'] > 100.0 for t in all_transients) high_v_transients = get_sources_filtered_by_final_variability( eta_min=1.1, v_min=2.0, dataset_id=self.dataset.id, # minpoints=1 ) self.assertEqual(len(high_v_transients), more_highly_variable) high_eta_transients = get_sources_filtered_by_final_variability( eta_min=100, v_min=0.01, dataset_id=self.dataset.id, # minpoints=1 ) self.assertEqual(len(high_eta_transients), very_non_flat)
def test_full_transient_search_routine(self): inserted_imgs = [] for img_idx in xrange(self.n_images): image, _,_ = insert_image_and_simulated_sources( self.dataset,self.img_params[img_idx],self.all_mock_sources, self.new_source_sigma_margin) inserted_imgs.append(image) transients = get_sources_filtered_by_final_variability(dataset_id=self.dataset.id, **self.search_params) newsources = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(transients), self.n_transients_after_image[img_idx]) #Sanity check that everything went into one band bands = self.dataset.frequency_bands() self.assertEqual(len(bands), 1) all_transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id, **self.search_params) # for t in all_transients: # print "V_int:", t['v_int'], " eta_int:", t['eta_int'] #Now test thresholding: more_highly_variable = sum(t['v_int'] > 2.0 for t in all_transients) very_non_flat = sum(t['eta_int'] > 100.0 for t in all_transients) high_v_transients = get_sources_filtered_by_final_variability( eta_min=1.1, v_min=2.0, dataset_id=self.dataset.id, # minpoints=1 ) self.assertEqual(len(high_v_transients), more_highly_variable) high_eta_transients = get_sources_filtered_by_final_variability( eta_min=100, v_min=0.01, dataset_id=self.dataset.id, # minpoints=1 ) self.assertEqual(len(high_eta_transients), very_non_flat)
def test_certain_transient(self): """ flux1 > (rms_max0*(det0+margin) --> Definite transient Nice and bright, must be new - mark it definite transient. """ img_params = self.img_params bright_transient = MockSource(example_extractedsource_tuple( ra=img_params[0]['centre_ra'], dec=img_params[0]['centre_decl']), lightcurve={ img_params[1]['taustart_ts']: self.always_detectable_flux }) #First, check that we've set up the test correctly: rms_max0 = img_params[0]['rms_max'] det0 = img_params[0]['detection_thresh'] self.assertTrue(bright_transient.lightcurve.values()[0] > rms_max0 * (det0 + self.new_source_sigma_margin)) for pars in self.img_params: img = tkp.db.Image(data=pars, dataset=self.dataset) xtr = bright_transient.simulate_extraction(img, extraction_type='blind') if xtr is not None: insert_extracted_sources(img._id, [xtr], 'blind') associate_extracted_sources(img._id, deRuiter_r, self.new_source_sigma_margin) newsources = get_newsources_for_dataset(self.dataset.id) #Should have one 'definite' transient self.assertEqual(len(newsources), 1) self.assertTrue( newsources[0]['low_thresh_sigma'] > self.new_source_sigma_margin) self.assertTrue( newsources[0]['high_thresh_sigma'] > self.new_source_sigma_margin) self.assertTrue(newsources[0]['low_thresh_sigma'] > newsources[0] ['high_thresh_sigma'])
def test_certain_transient(self): """ flux1 > (rms_max0*(det0+margin) --> Definite transient Nice and bright, must be new - mark it definite transient. """ img_params = self.img_params bright_transient = MockSource( example_extractedsource_tuple(ra=img_params[0]['centre_ra'], dec=img_params[0]['centre_decl']), lightcurve={img_params[1]['taustart_ts']: self.always_detectable_flux} ) #First, check that we've set up the test correctly: rms_max0 = img_params[0]['rms_max'] det0 = img_params[0]['detection_thresh'] self.assertTrue(bright_transient.lightcurve.values()[0] > rms_max0*(det0 + self.new_source_sigma_margin ) ) for pars in self.img_params: img = tkp.db.Image(data=pars,dataset=self.dataset) xtr = bright_transient.simulate_extraction(img, extraction_type='blind') if xtr is not None: insert_extracted_sources(img._id, [xtr], 'blind') associate_extracted_sources(img._id, deRuiter_r, self.new_source_sigma_margin) newsources = get_newsources_for_dataset(self.dataset.id) #Should have one 'definite' transient self.assertEqual(len(newsources),1) self.assertTrue( newsources[0]['low_thresh_sigma'] > self.new_source_sigma_margin) self.assertTrue( newsources[0]['high_thresh_sigma'] > self.new_source_sigma_margin) self.assertTrue( newsources[0]['low_thresh_sigma'] > newsources[0]['high_thresh_sigma'])
def test_previous_image_id(self): img_params = self.img_params mock_sources = [] mock_sources.append( MockSource(example_extractedsource_tuple( ra=img_params[0]['centre_ra'], dec=img_params[0]['centre_decl']), lightcurve={ img_params[-1]['taustart_ts']: self.always_detectable_flux })) mock_sources.append( MockSource(example_extractedsource_tuple( ra=img_params[0]['centre_ra'] + 1, dec=img_params[0]['centre_decl']), lightcurve={ img_params[-1]['taustart_ts']: self.always_detectable_flux })) image_ids = {} for img_idx in xrange(self.n_images): image, _, _ = insert_image_and_simulated_sources( self.dataset, self.img_params[img_idx], mock_sources, self.new_source_sigma_margin) image_ids[img_idx] = image.id newsources = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(newsources), len(mock_sources)) newsource_properties = newsources[0] print "Image IDs:", image_ids self.assertEqual(newsource_properties['previous_limits_image'], image_ids[4])
def test_previous_image_id(self): img_params = self.img_params mock_sources=[] mock_sources.append( MockSource( example_extractedsource_tuple(ra=img_params[0]['centre_ra'], dec=img_params[0]['centre_decl']), lightcurve={img_params[-1]['taustart_ts']: self.always_detectable_flux} )) mock_sources.append( MockSource( example_extractedsource_tuple(ra=img_params[0]['centre_ra']+1, dec=img_params[0]['centre_decl']), lightcurve={img_params[-1]['taustart_ts']: self.always_detectable_flux} )) image_ids={} for img_idx in xrange(self.n_images): image, _,_ = insert_image_and_simulated_sources( self.dataset,self.img_params[img_idx],mock_sources, self.new_source_sigma_margin) image_ids[img_idx]=image.id newsources = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(newsources),len(mock_sources)) newsource_properties = newsources[0] print "Image IDs:", image_ids self.assertEqual(newsource_properties['previous_limits_image'], image_ids[4])
def test_single_epoch_bright_transient(self): """A bright transient appears at field centre in one image.""" im_params = self.im_params transient_src = db_subs.MockSource( template_extractedsource=db_subs.example_extractedsource_tuple( ra=im_params[0]['centre_ra'], dec=im_params[0]['centre_decl'], ), lightcurve={ im_params[2]['taustart_ts']: self.reliably_detectable_flux }) for img_pars in im_params[:3]: image, _, forced_fits = insert_image_and_simulated_sources( self.dataset, img_pars, [transient_src], self.new_source_sigma_margin) self.assertEqual(len(forced_fits), 0) # Check the number of detected transients transients = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(transients), 1) newsrc_properties = transients[0] # Check that the bands for the images are the same as the transient's band freq_bands = frequency_bands(self.dataset._id) self.assertEqual(len(freq_bands), 1) self.assertEqual(freq_bands[0], newsrc_properties['band']) # Sanity check that the runcat is correctly matched runcats = runcat_entries(self.dataset._id) self.assertEqual(len(runcats), 1) self.assertEqual(runcats[0]['runcat'], newsrc_properties['runcat_id']) # Since it is a single-epoch source, variability indices default to 0: self.assertEqual(newsrc_properties['v_int'], 0) self.assertEqual(newsrc_properties['eta_int'], 0) # Bright 'new-source' / single-epoch transient; should have high sigmas: self.assertTrue(newsrc_properties['low_thresh_sigma'] > self.new_source_sigma_margin) self.assertEqual(newsrc_properties['low_thresh_sigma'], newsrc_properties['high_thresh_sigma']) # Check the correct trigger xtrsrc was identified: self.assertEqual(newsrc_properties['taustart_ts'], transient_src.lightcurve.keys()[0]) # Ok, now add the last image and check that we get a correct forced-fit # request: image, _, forced_fits = insert_image_and_simulated_sources( self.dataset, im_params[3], [transient_src], self.new_source_sigma_margin) self.assertEqual(len(forced_fits), 1) transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id, **self.search_params) self.assertEqual(len(transients), 1) transient_properties = transients[0] # And now we should have a non-zero variability value self.assertNotAlmostEqual(transient_properties['v_int'], 0) self.assertNotAlmostEqual(transient_properties['eta_int'], 0)
def test_multi_epoch_source_flare_and_fade(self): """ A steady source (i.e. detected in first image) flares up, then fades and finally disappears. """ im_params = self.im_params transient_src = db_subs.MockSource( template_extractedsource=db_subs.example_extractedsource_tuple( ra=im_params[0]['centre_ra'], dec=im_params[0]['centre_decl'], ), lightcurve={ im_params[0]['taustart_ts'] : self.barely_detectable_flux, im_params[1]['taustart_ts'] : 2*self.barely_detectable_flux, im_params[2]['taustart_ts'] : self.barely_detectable_flux, } ) inserted_sources = [] for img_pars in im_params[:2]: image, blind_xtr,forced_fits = insert_image_and_simulated_sources( self.dataset,img_pars,[transient_src], self.new_source_sigma_margin) self.assertEqual(len(forced_fits), 0) inserted_sources.extend(blind_xtr) #This should always be 0: newsources = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(newsources), 0) transients = get_sources_filtered_by_final_variability(dataset_id=self.dataset.id, **self.search_params) #We've seen a flare: self.assertEqual(len(transients), 1) transient_properties = transients[0] # Check that the bands for the images are the same as the transient's band freq_bands = frequency_bands(self.dataset._id) self.assertEqual(len(freq_bands), 1) self.assertEqual(freq_bands[0], transient_properties['band']) #Sanity check that the runcat is correctly matched runcats = runcat_entries(self.dataset._id) self.assertEqual(len(runcats), 1) self.assertEqual(runcats[0]['runcat'], transient_properties['runcat_id']) #Check we have sensible variability indices # print "\n",transient_properties metrics = db_subs.lightcurve_metrics(inserted_sources) # print "\nAfter two images:" for metric_name in 'v_int', 'eta_int': # print metric_name, transient_properties[metric_name] self.assertAlmostEqual(transient_properties[metric_name], metrics[-1][metric_name]) #Add 3rd image (another blind detection), check everything is sane image, blind_xtr,forced_fits = insert_image_and_simulated_sources( self.dataset,im_params[2],[transient_src], self.new_source_sigma_margin) self.assertEqual(len(forced_fits), 0) inserted_sources.extend(blind_xtr) self.assertEqual(len(get_newsources_for_dataset(self.dataset.id)),0) # Ok, now add the last image and check that we get a correct forced-fit # request: image, blind_xtr,forced_fits = insert_image_and_simulated_sources( self.dataset,im_params[3],[transient_src], self.new_source_sigma_margin) self.assertEqual(len(blind_xtr),0) self.assertEqual(len(forced_fits),1) inserted_sources.extend(forced_fits) self.assertEqual(len(get_newsources_for_dataset(self.dataset.id)),0) transients = get_sources_filtered_by_final_variability(dataset_id=self.dataset.id, **self.search_params) # Variability indices should take non-detections into account self.assertEqual(len(transients), 1) transient_properties = transients[0] metrics = db_subs.lightcurve_metrics(inserted_sources) # print "\nAfter four images:" for metric_name in 'v_int', 'eta_int': # print metric_name, transient_properties[metric_name] self.assertAlmostEqual(transient_properties[metric_name], metrics[-1][metric_name])
def test_single_epoch_bright_transient(self): """A bright transient appears at field centre in one image.""" im_params = self.im_params transient_src = db_subs.MockSource( template_extractedsource=db_subs.example_extractedsource_tuple( ra=im_params[0]['centre_ra'], dec=im_params[0]['centre_decl'], ), lightcurve={im_params[2]['taustart_ts'] : self.reliably_detectable_flux} ) for img_pars in im_params[:3]: image, _,forced_fits = insert_image_and_simulated_sources( self.dataset,img_pars,[transient_src], self.new_source_sigma_margin) self.assertEqual(len(forced_fits), 0) # Check the number of detected transients transients = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(transients), 1) newsrc_properties = transients[0] # Check that the bands for the images are the same as the transient's band freq_bands = frequency_bands(self.dataset._id) self.assertEqual(len(freq_bands), 1) self.assertEqual(freq_bands[0], newsrc_properties['band']) # Sanity check that the runcat is correctly matched runcats = runcat_entries(self.dataset._id) self.assertEqual(len(runcats), 1) self.assertEqual(runcats[0]['runcat'], newsrc_properties['runcat_id']) # Since it is a single-epoch source, variability indices default to 0: self.assertEqual(newsrc_properties['v_int'],0) self.assertEqual(newsrc_properties['eta_int'],0) # Bright 'new-source' / single-epoch transient; should have high sigmas: self.assertTrue( newsrc_properties['low_thresh_sigma']> self.new_source_sigma_margin) self.assertEqual(newsrc_properties['low_thresh_sigma'], newsrc_properties['high_thresh_sigma']) # Check the correct trigger xtrsrc was identified: self.assertEqual(newsrc_properties['taustart_ts'], transient_src.lightcurve.keys()[0]) # Ok, now add the last image and check that we get a correct forced-fit # request: image, _,forced_fits = insert_image_and_simulated_sources( self.dataset,im_params[3],[transient_src], self.new_source_sigma_margin) self.assertEqual(len(forced_fits),1) transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id,**self.search_params) self.assertEqual(len(transients), 1) transient_properties = transients[0] # And now we should have a non-zero variability value self.assertNotAlmostEqual(transient_properties['v_int'], 0) self.assertNotAlmostEqual(transient_properties['eta_int'], 0)
def test_multi_epoch_source_flare_and_fade(self): """ A steady source (i.e. detected in first image) flares up, then fades and finally disappears. """ im_params = self.im_params transient_src = db_subs.MockSource( template_extractedsource=db_subs.example_extractedsource_tuple( ra=im_params[0]['centre_ra'], dec=im_params[0]['centre_decl'], ), lightcurve={ im_params[0]['taustart_ts']: self.barely_detectable_flux, im_params[1]['taustart_ts']: 2 * self.barely_detectable_flux, im_params[2]['taustart_ts']: self.barely_detectable_flux, }) inserted_sources = [] for img_pars in im_params[:2]: image, blind_xtr, forced_fits = insert_image_and_simulated_sources( self.dataset, img_pars, [transient_src], self.new_source_sigma_margin) self.assertEqual(len(forced_fits), 0) inserted_sources.extend(blind_xtr) #This should always be 0: newsources = get_newsources_for_dataset(self.dataset.id) self.assertEqual(len(newsources), 0) transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id, **self.search_params) #We've seen a flare: self.assertEqual(len(transients), 1) transient_properties = transients[0] # Check that the bands for the images are the same as the transient's band freq_bands = frequency_bands(self.dataset._id) self.assertEqual(len(freq_bands), 1) self.assertEqual(freq_bands[0], transient_properties['band']) #Sanity check that the runcat is correctly matched runcats = runcat_entries(self.dataset._id) self.assertEqual(len(runcats), 1) self.assertEqual(runcats[0]['runcat'], transient_properties['runcat_id']) #Check we have sensible variability indices # print "\n",transient_properties metrics = db_subs.lightcurve_metrics(inserted_sources) # print "\nAfter two images:" for metric_name in 'v_int', 'eta_int': # print metric_name, transient_properties[metric_name] self.assertAlmostEqual(transient_properties[metric_name], metrics[-1][metric_name]) #Add 3rd image (another blind detection), check everything is sane image, blind_xtr, forced_fits = insert_image_and_simulated_sources( self.dataset, im_params[2], [transient_src], self.new_source_sigma_margin) self.assertEqual(len(forced_fits), 0) inserted_sources.extend(blind_xtr) self.assertEqual(len(get_newsources_for_dataset(self.dataset.id)), 0) # Ok, now add the last image and check that we get a correct forced-fit # request: image, blind_xtr, forced_fits = insert_image_and_simulated_sources( self.dataset, im_params[3], [transient_src], self.new_source_sigma_margin) self.assertEqual(len(blind_xtr), 0) self.assertEqual(len(forced_fits), 1) inserted_sources.extend(forced_fits) self.assertEqual(len(get_newsources_for_dataset(self.dataset.id)), 0) transients = get_sources_filtered_by_final_variability( dataset_id=self.dataset.id, **self.search_params) # Variability indices should take non-detections into account self.assertEqual(len(transients), 1) transient_properties = transients[0] metrics = db_subs.lightcurve_metrics(inserted_sources) # print "\nAfter four images:" for metric_name in 'v_int', 'eta_int': # print metric_name, transient_properties[metric_name] self.assertAlmostEqual(transient_properties[metric_name], metrics[-1][metric_name])