177 lines
5.1 KiB
Python
177 lines
5.1 KiB
Python
# views.py
|
|
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
from rest_framework import status
|
|
|
|
from .models import GaiaSource
|
|
from .serializers import GaiaSourceSerializer
|
|
|
|
from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiParameter
|
|
|
|
import numpy as np
|
|
from astropy_healpix import HEALPix
|
|
from astropy.coordinates import SkyCoord
|
|
from astropy import units as u
|
|
|
|
|
|
|
|
|
|
class ConeSearchView(APIView):
|
|
|
|
@staticmethod
|
|
def get_healpix_indices(ra, dec, radius, nside, order):
|
|
|
|
# Create HEALPix object
|
|
healpix = HEALPix(nside=nside, order=order, frame='icrs')
|
|
|
|
# Convert the input coordinates to a SkyCoord object
|
|
center = SkyCoord(ra=ra*u.deg, dec=dec*u.deg, frame='icrs')
|
|
|
|
# Find the pixels within the given radius
|
|
indices = healpix.cone_search_skycoord(center, radius*u.deg)
|
|
return indices
|
|
|
|
serializer_class = GaiaSourceSerializer
|
|
|
|
@extend_schema(
|
|
|
|
description = "GAIA DR3 cone search using healpix indexation. ra, dec, radius in decimal degrees.",
|
|
|
|
summary = "GAIA DR3 cone search.",
|
|
|
|
responses = {
|
|
200: OpenApiResponse(response=GaiaSourceSerializer(many=True), description="Successful Response"),
|
|
400: OpenApiResponse(description="Bad Request"),
|
|
404: OpenApiResponse(description="Not Found")
|
|
},
|
|
|
|
# parameters=[
|
|
# OpenApiParameter(
|
|
# name='ra', description='Right Ascension in decimal degrees', required=True, type=float
|
|
# ),
|
|
# OpenApiParameter(
|
|
# name='dec', description='Declination in decimal degrees', required=True, type=float
|
|
# ),
|
|
# OpenApiParameter(
|
|
# name='radius', description='Search radius in decimal degrees', required=True, type=float
|
|
# )
|
|
# ],
|
|
tags=["GAIA"],
|
|
|
|
)
|
|
|
|
|
|
|
|
def get(self, request): # ra, dec, radius):
|
|
|
|
try:
|
|
ra = float(request.query_params.get('ra'))
|
|
dec = float(request.query_params.get('dec'))
|
|
radius = float(request.query_params.get('radius'))
|
|
order = str(request.query_params.get('order'))
|
|
except (TypeError, ValueError):
|
|
return Response({"error": "Invalid parameters"}, status=status.HTTP_400_BAD_REQUEST)
|
|
# radius = float(radius)
|
|
# ra = float(ra)
|
|
# dec = float(dec)
|
|
nside = 2048
|
|
|
|
#create skycoord for the center of search
|
|
center = SkyCoord(ra=ra*u.deg, dec=dec*u.deg, frame='icrs')
|
|
|
|
#fetch healpix indices in the specified disc
|
|
healpix_indices = self.get_healpix_indices(ra, dec, radius, nside, order)
|
|
#fetch all objects from those healpixes
|
|
if order == 'ring':
|
|
objects = GaiaSource.objects.filter(healpix_ring_index__in=healpix_indices)
|
|
elif order == 'nested':
|
|
objects = GaiaSource.objects.filter(healpix_nested_index__in=healpix_indices)
|
|
|
|
results = [] #initialize the results list
|
|
|
|
for obj in objects:
|
|
|
|
source_coordinates = SkyCoord(
|
|
ra=obj.ra*u.deg,
|
|
dec=obj.dec*u.deg,
|
|
frame='icrs'
|
|
)
|
|
|
|
separation = center.separation(source_coordinates)
|
|
|
|
if separation.degree <= radius:
|
|
|
|
results.append(obj)
|
|
|
|
serializer = GaiaSourceSerializer(results, many=True)
|
|
|
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BulkSearchView(APIView):
|
|
|
|
|
|
@staticmethod
|
|
def list_to_dict(queries): #turn a list of dicts into a dict of lists
|
|
transformed = {
|
|
'uuids': [],
|
|
'coordinates': [],
|
|
'radii': []
|
|
'orders': []
|
|
}
|
|
for query in queries:
|
|
transformed['uuids'].append(query['uuid'])
|
|
transformed['coordinates'].append(query['coordinates'])
|
|
transformed['radii'].append(query['radius'])
|
|
transformed['orders'].append(query['order'])
|
|
return transformed
|
|
|
|
@staticmethod
|
|
def process_coordinates(transformed, order):
|
|
results = []
|
|
for i, coords in enumerate(transformed['coordinates']):
|
|
|
|
ra, dec = coords
|
|
radius = transformed['radii'][i]
|
|
uuid = transformed['uuids'][i]
|
|
order = transformed['orders'][i]
|
|
|
|
# Call your function to get HEALPix indices
|
|
healpix_indices = ConeSearchView.get_healpix_indices(ra, dec, radius, 2048, order)
|
|
|
|
results.append({
|
|
'uuid': uuid,
|
|
'coordinates': coords,
|
|
'healpix_indices': healpix_indices
|
|
'orders': order
|
|
})
|
|
|
|
return results
|
|
|
|
|
|
|
|
def post(self, request):
|
|
|
|
serializer = BulkSearchSerializer(data=request.data['queries'], many=True)
|
|
|
|
if serializer.is_valid():
|
|
|
|
transformed = list_to_dict(serializer.validated_data)
|
|
|
|
processed_results = process_coordinates(transformed)
|
|
|
|
final_results =
|
|
|
|
|
|
|
|
|
|
|