diff --git a/docs/brokers/create_dataservice.rst b/docs/brokers/create_dataservice.rst index d50d81c0b..05c3557b3 100644 --- a/docs/brokers/create_dataservice.rst +++ b/docs/brokers/create_dataservice.rst @@ -51,7 +51,7 @@ First the actual query class: """ return self.query_parameters - def query_service(self, data, **kwargs): + def query_service(self, query_parameters, **kwargs): """ This is where you actually make the call to the Data Service. Return the results. @@ -209,12 +209,16 @@ At this point you should be seeing a list of Targets showing up in your TOM afte Continuing with our ``target`` example, we need to be able to ``create_target_from_query`` in order to actually save the target object resulting from a successful result for ``query_target`` above. This function expects a single instance with the same format as the list of dictionaries created by ``query_targets`` and converts that dictionary into a Target Object -returning that object. +returning that unsaved object. .. code-block:: python :caption: my_dataservice.MyDataService :linenos: + from tom_targets.models import Target + + ... + def create_target_from_query(self, target_result, **kwargs): """Create a new target from the query results :returns: target object diff --git a/tom_dataservices/apps.py b/tom_dataservices/apps.py index 91a0c1d23..7e9bdbdbd 100644 --- a/tom_dataservices/apps.py +++ b/tom_dataservices/apps.py @@ -34,5 +34,6 @@ def data_services(self): data_services = [ {'class': f'{self.name}.data_services.simbad.SimbadDataService'}, {'class': f'{self.name}.data_services.tns.TNSDataService'}, + {'class': f'{self.name}.data_services.ned.NEDDataService'}, ] return data_services diff --git a/tom_dataservices/data_services/ned.py b/tom_dataservices/data_services/ned.py new file mode 100644 index 000000000..68dfd2b62 --- /dev/null +++ b/tom_dataservices/data_services/ned.py @@ -0,0 +1,85 @@ +from typing import List, Dict + +from django import forms +from astroquery.ned import Ned +from astroquery.exceptions import RemoteServiceError + +from tom_dataservices.dataservices import DataService +from tom_dataservices.forms import BaseQueryForm +from tom_targets.models import Target + + +class NEDDataService(DataService): + """ + This the NED dataservice responsible for querying NED for an object ID. + Uses astroquery.ned. + """ + name = 'NED' + info_url = 'https://ned.ipac.caltech.edu/' + + @classmethod + def get_form_class(cls): + """ + Points to the form class discussed below. + """ + return NEDForm + + def build_query_parameters(self, parameters: Dict, **kwargs) -> Dict: + """ + Use this function to convert the form results into the query parameters understood + by the Data Service. + """ + query_parameters = { + 'object_id': parameters.get('object_id') + } + + self.query_parameters = query_parameters + return query_parameters + + def query_service(self, query_parameters: Dict, **kwargs): + """ + This is where you actually make the call to the Data Service. + Return the results. + """ + try: + query_results = Ned.query_object(query_parameters.get('object_id')) + except RemoteServiceError: + query_results = {} + self.query_results = query_results + return self.query_results + + def query_targets(self, query_parameters: Dict, **kwargs) -> List[Dict]: + """ + This code calls `query_service` and returns a list of dicts containing target results. + This call and the results should be tailored towards describing targets. + """ + query_results = self.query_service(query_parameters) + # Convert astropy table to list of dictionaries + targets = [dict(zip(query_results.colnames, row)) for row in query_results] + # Make primary name searched term. Add NED name as alias. + if query_parameters.get('object_id'): + for target_result in targets: + if target_result['Object Name'] != query_parameters['object_id']: + target_result['aliases'] = [target_result['Object Name']] + target_result['Object Name'] = query_parameters['object_id'] + return targets + + def create_target_from_query(self, target_result: Dict, **kwargs): + """Create a new target from the query results + :returns: target object + :rtype: `Target` + """ + + target = Target( + name=target_result['Object Name'], + type='SIDEREAL', + ra=target_result['RA'], + dec=target_result['DEC'], + ) + return target + + +class NEDForm(BaseQueryForm): + object_id = forms.CharField(required=False, + label='Object ID', + help_text='Extragalactic Source Name (i.e. "NGC 224" or "M31")')