# 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 =