Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev to main #38

Merged
merged 6 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ TOMtoolkit module for reporting transients to the TNS
'c': 'Clear',
...
}, # Optional mapping from your reduced datum filter values to TNS filter options.
'instrument_mapping': {
'fa20': 'LCO1m - Sinistro',
...
}, # Optional mapping from your reduced datum instrument name to TNS instrument names
'default_authors': 'Foo Bar <[email protected]>, Rando Calrissian, et al.' # Optional default authors string to populate the author fields for tns submission. If not specified, defaults to saying "<logged in user> using <tom name>".
},
}
Expand All @@ -62,11 +66,16 @@ TOMtoolkit module for reporting transients to the TNS
'DEFAULT_AUTHORS': 'Foo Bar <[email protected]>, Rando Calrissian, et al.', # Optional default authors string to populate the author fields for tns submission. If not specified, defaults to saying "<logged in user> using <tom name>".
'USER_TOPICS': ['hermes.discovery', 'hermes.classification', ...] # This is a list of hermes topics you will be allowed to share on. hermes.discovery and hermes.classification are automatically used for TNS submissions of those types.
'TNS_GROUP_NAMES': ['bot_group', 'PI_group'], # Optional List. Include if you wish to use any affiliated Group Names when reporting to TNS.
'DATA_CONVERTER_CLASS': 'tom_dataproducts.alertstreams.hermes.HermesDataConverter', # Optional classpath to custom implementation of HermesDataConverter class, which is used to prefill TNS submission form fields with values stored in your TOM for your ReducedDatums.
'FILTER_MAPPING': {
'o': 'Other',
'c': 'Clear',
...
}, # Optional mapping from your reduced datum filter values to TNS filter options.
'INSTRUMENT_MAPPING': {
'fa20': 'LCO1m - Sinistro',
...
}, # Optional mapping from your reduced datum instrument name to TNS instrument names
'ENABLE_TNS': False # Set to True to enable TNS submissions through Hermes
},
}
Expand Down
32 changes: 24 additions & 8 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ packages = [{include = "tom_tns"}]

[tool.poetry.dependencies]
python = "^3.8.1,<3.12"
tomtoolkit = "^2.18"
tomtoolkit = ">=2.20.0"

[tool.poetry.group.lint.dependencies]
flake8 = ">=6.0,<7.2"
Expand Down
10 changes: 8 additions & 2 deletions tom_tns/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def is_set(self, field):
class TNSReportForm(BaseReportForm):
submitter = forms.CharField(required=True, widget=forms.HiddenInput())
object_name = forms.CharField(required=True, widget=forms.HiddenInput())
telescope = forms.CharField(required=False, widget=forms.HiddenInput())
ra = forms.FloatField(label='R.A.')
dec = forms.FloatField(label='Dec.')
reporting_group = forms.ChoiceField(choices=[])
Expand Down Expand Up @@ -107,7 +108,7 @@ def __init__(self, *args, **kwargs):

self.helper = FormHelper()
self.helper.layout = Layout(
'submitter', 'object_name',
'submitter', 'object_name', 'telescope',
Row(
Column('reporter', css_class='col-md-6'),
Column('reporting_group'),
Expand Down Expand Up @@ -226,6 +227,8 @@ def generate_hermes_report(self):
hermes_report['data']['photometry'][0]['observer'] = self.cleaned_data['observer']
if self.is_set('limiting_flux'):
hermes_report['data']['photometry'][0]['limiting_brightness'] = self.cleaned_data['limiting_flux']
if self.is_set('telescope'):
hermes_report['data']['photometry'][0]['telescope'] = self.cleaned_data['telescope']

if self.is_set('archive') and self.is_set('archival_remarks'):
discovery_info = hermes_report['data']['targets'][0]['discovery_info']
Expand Down Expand Up @@ -303,6 +306,7 @@ def generate_tns_report(self):

class TNSClassifyForm(BaseReportForm):
submitter = forms.CharField(required=False, widget=forms.HiddenInput())
telescope = forms.CharField(required=False, widget=forms.HiddenInput())
object_name = forms.CharField(required=False)
ra = forms.FloatField(required=False, widget=forms.HiddenInput())
dec = forms.FloatField(required=False, widget=forms.HiddenInput())
Expand Down Expand Up @@ -352,7 +356,7 @@ def __init__(self, *args, **kwargs):

self.helper = FormHelper()
self.helper.layout = Layout(
'submitter', 'ra', 'dec',
'submitter', 'ra', 'dec', 'telescope',
Row(
Column('classifier', css_class='col-md-8'),
Column('reporting_group'),
Expand Down Expand Up @@ -440,6 +444,8 @@ def generate_hermes_report(self):
},
}
files = [ascii_file]
if self.is_set('telescope'):
hermes_report['data']['spectroscopy'][0]['telescope'] = self.cleaned_data['telescope']
if self.is_set('redshift'):
hermes_report['data']['targets'][0]['redshift'] = self.cleaned_data['redshift']
if self.is_set('classification_remarks'):
Expand Down
87 changes: 71 additions & 16 deletions tom_tns/templatetags/tns_extras.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from django import template
from django.conf import settings

from tom_tns.tns_api import get_tns_values, map_filter_to_tns, default_authors
from tom_dataproducts.alertstreams.hermes import get_hermes_data_converter_class
from tom_tns.tns_api import (get_tns_values, map_filter_to_tns, map_instrument_to_tns,
default_authors)
from tom_tns.forms import TNSReportForm, TNSClassifyForm

register = template.Library()
Expand All @@ -11,6 +13,7 @@
TNS_FILTER_IDS = {name: fid for fid, name in get_tns_values('filters')}
TNS_INSTRUMENT_IDS = {name: iid for iid, name in get_tns_values('instruments')}
TNS_CLASSIFICATION_IDS = {name: cid for cid, name in get_tns_values('object_types')}
TNS_SPECTRUM_TYPE_IDS = {name: sid for sid, name in get_tns_values('spectra_types')}


@register.inclusion_tag('tom_tns/partials/tns_report_form.html', takes_context=True)
Expand All @@ -34,24 +37,47 @@ def report_to_tns(context):
initial['reporter'] = reporter

reduced_datum = None
if 'datum' in context:
if 'datum' in context and context['datum'].data_type == 'photometry':
reduced_datum = context['datum']
preset_datum = True
else:
# Get photometry if available
photometry = target.reduceddatum_set.filter(data_type='photometry')
if photometry.exists():
reduced_datum = photometry.latest()
preset_datum = False

if reduced_datum:
initial['observation_date'] = reduced_datum.timestamp
initial['flux'] = reduced_datum.value.get('magnitude')
initial['flux_error'] = reduced_datum.value.get('error')
filter_name = reduced_datum.value.get('filter')
mapped_filter = map_filter_to_tns(filter_name)
if mapped_filter in TNS_FILTER_IDS:
initial['filter'] = (TNS_FILTER_IDS[mapped_filter], mapped_filter)
instrument_name = reduced_datum.value.get('instrument')
if instrument_name in TNS_INSTRUMENT_IDS:
hermes_datum_converter = get_hermes_data_converter_class()(validate=False)
phot_data = hermes_datum_converter.get_hermes_photometry(reduced_datum)
initial['observation_date'] = phot_data['date_obs']
if phot_data.get('exposure_time'):
initial['exposure_time'] = phot_data['exposure_time']
instrument_name = map_instrument_to_tns(phot_data.get('instrument', ''))
if instrument_name and instrument_name in TNS_INSTRUMENT_IDS:
initial['instrument'] = (TNS_INSTRUMENT_IDS[instrument_name], instrument_name)
else:
# Try the hermes 'telescope' field if instrument is not present or doesn't match TNS
instrument_name = map_instrument_to_tns(phot_data.get('telescope', ''))
if instrument_name and instrument_name in TNS_INSTRUMENT_IDS:
initial['instrument'] = (TNS_INSTRUMENT_IDS[instrument_name], instrument_name)
if preset_datum and phot_data.get('telescope'):
# Only set the telescope if a preset datum was specified in loading the form
initial['telescope'] = phot_data['telescope']
mapped_filter = map_filter_to_tns(phot_data.get('bandpass', ''))
if mapped_filter and mapped_filter in TNS_FILTER_IDS:
initial['filter'] = (TNS_FILTER_IDS[mapped_filter], mapped_filter)
if phot_data.get('brightness'):
initial['flux'] = phot_data['brightness']
if phot_data.get('brightness_error'):
initial['flux_error'] = phot_data['brightness_error']
if phot_data.get('limiting_brightness'):
initial['limiting_flux'] = phot_data['limiting_brightness']
if phot_data.get('observer'):
initial['observer'] = phot_data['observer']
if phot_data.get('comments'):
initial['photometry_remarks'] = phot_data['comments']

tns_report_form = TNSReportForm(initial=initial)
return {'target': target,
'form': tns_report_form}
Expand Down Expand Up @@ -90,19 +116,48 @@ def classify_with_tns(context):

# Get the spectra details from the latest spectra reduced datum or one passed in
reduced_datum = None
if 'datum' in context:
if 'datum' in context and context['datum'].data_type == 'spectroscopy':
reduced_datum = context['datum']
preset_datum = True
else:
spectra = target.reduceddatum_set.filter(data_type='spectroscopy')
if spectra.exists():
reduced_datum = spectra.latest()
preset_datum = False
if reduced_datum:
initial['observation_date'] = reduced_datum.timestamp
hermes_datum_converter = get_hermes_data_converter_class()(validate=False)
spectra_data = hermes_datum_converter.get_hermes_spectroscopy(reduced_datum)
initial['observation_date'] = spectra_data['date_obs']
if spectra_data.get('exposure_time'):
initial['exposure_time'] = spectra_data['exposure_time']
instrument_name = map_instrument_to_tns(spectra_data.get('instrument', ''))
if instrument_name and instrument_name in TNS_INSTRUMENT_IDS:
initial['instrument'] = (TNS_INSTRUMENT_IDS[instrument_name], instrument_name)
else:
# Try the hermes 'telescope' field if instrument is not present or doesn't match TNS
instrument_name = map_instrument_to_tns(spectra_data.get('telescope', ''))
if instrument_name and instrument_name in TNS_INSTRUMENT_IDS:
initial['instrument'] = (TNS_INSTRUMENT_IDS[instrument_name], instrument_name)
if preset_datum and spectra_data.get('telescope'):
# Only set the telescope if a preset datum was specified in loading the form
initial['telescope'] = spectra_data['telescope']
if spectra_data.get('reducer'):
initial['reducer'] = spectra_data['reducer']
if spectra_data.get('observer'):
initial['observer'] = spectra_data['observer']
if spectra_data.get('classification', '') in TNS_CLASSIFICATION_IDS:
initial['classification'] = (
TNS_CLASSIFICATION_IDS[spectra_data['classification']], spectra_data['classification']
)
if spectra_data.get('spec_type') in TNS_SPECTRUM_TYPE_IDS:
initial['spectrum_type'] = (
TNS_SPECTRUM_TYPE_IDS[spectra_data['spec_type']], spectra_data['spec_type']
)
if spectra_data.get('comments'):
initial['spectrum_remarks'] = spectra_data['comments']

if reduced_datum.data_product and reduced_datum.data_product.get_file_extension().lower() in ['.ascii', '.txt']:
initial['ascii_file'] = (reduced_datum.data_product.pk, reduced_datum.data_product.get_file_name())
instrument_name = reduced_datum.value.get('instrument')
if instrument_name in TNS_INSTRUMENT_IDS:
initial['instrument'] = (TNS_INSTRUMENT_IDS[instrument_name], instrument_name)

tns_classify_form = TNSClassifyForm(initial=initial)
return {'target': target,
Expand Down
10 changes: 10 additions & 0 deletions tom_tns/tns_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ def map_filter_to_tns(filter):
return settings.BROKERS.get('TNS', {}).get('filter_mapping', {}).get(filter)


def map_instrument_to_tns(instrument):
""" Checks if a instrument mapping was set in the settings, and if so returns the
mapped value for the instrument passed in
"""
if submit_through_hermes():
return settings.DATA_SHARING.get('hermes', {}).get('INSTRUMENT_MAPPING', {}).get(instrument)
else:
return settings.BROKERS.get('TNS', {}).get('instrument_mapping', {}).get(instrument)


def default_authors():
""" Returns default authors if set in the settings, otherwise empty string.
"""
Expand Down
Loading