from rest_framework.views import APIView #from rest_framework.generics import GenericAPIView 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 import healpy as hp from astropy.coordinates import SkyCoord from astropy import units as u class ConeSearchView(APIView): 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')) 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) #fetch all objects from those healpixes objects = GaiaSource.objects.filter(healpix_ring_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) @staticmethod def get_healpix_indices(ra, dec, radius, nside): # Convert the input coordinates to a SkyCoord object center = SkyCoord(ra=ra*u.deg, dec=dec*u.deg, frame='icrs') # Convert the center coordinates to HEALPix vector vec = hp.ang2vec(center.ra.deg, center.dec.deg, lonlat=True) # Find the pixels within the given radius indices = hp.query_disc(nside, vec, np.radians(radius)) return indices