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

Crossmatch #338

Merged
merged 5 commits into from
Oct 22, 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
13 changes: 11 additions & 2 deletions lightcurve/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ RUN \
chmod +x tailwindcss && \
./tailwindcss -i /lightcurve/src/probability_api/templates/probability.css -o /compiled/probability.css


FROM node:22-alpine as tailwindcss_crossmatch
COPY ./lightcurve/ /lightcurve/
WORKDIR /lightcurve
RUN \
wget -nc https://github.com/tailwindlabs/tailwindcss/releases/download/v3.4.13/tailwindcss-linux-x64 -O tailwindcss && \
chmod +x tailwindcss && \
./tailwindcss -i /lightcurve/src/crossmatch_api/templates/crossmatch.css -o /compiled/crossmatch.css

FROM python:3.11-slim as production
RUN pip install poetry
COPY --from=builder /app /app
Expand All @@ -63,6 +72,6 @@ COPY --from=tailwindcss_lightcurve /compiled/main.css /app/src/api/static
COPY --from=tailwindcss_magstats /compiled/magstats.css /app/src/magstats_api/static
COPY --from=tailwindcss_object /compiled/object.css /app/src/object_api/static
COPY --from=tailwindcss_probability /compiled/probability.css /app/src/probability_api/static
# COPY --from=tailwindcss_crossmatch /compiled/crossmatch.css /app/src/crossmatch_api/static
COPY --from=tailwindcss_crossmatch /compiled/crossmatch.css /app/src/crossmatch_api/static
RUN poetry install --only-root
CMD ["bash", "scripts/entrypoint.sh"]
CMD ["bash", "scripts/entrypoint.sh"]
14 changes: 13 additions & 1 deletion lightcurve/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,16 @@ services:
- variables.env
environment:
SERVICE: probability_api
API_URL: http://localhost:8004
API_URL: http://localhost:8004

crossmatch:
build:
context: ../
dockerfile: lightcurve/Dockerfile
ports:
- 8005:8000
env_file:
- variables.env
environment:
SERVICE: crossmatch_api
API_URL: http://localhost:8005
11 changes: 11 additions & 0 deletions lightcurve/scripts/run_crossmatch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import os

import uvicorn


def run():
port = os.getenv("PORT", default=8000)
uvicorn.run("crossmatch_api.api:app", port=int(port), reload=True, reload_dirs=[".", "../libs"])

if __name__ == "__main__":
run()
7 changes: 7 additions & 0 deletions lightcurve/scripts/run_dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,17 @@ def run_object():
port = int(os.getenv("PORT", default=8000))
asyncio.run(run_service("object_api", port))


def run_crossmatch():
port = int(os.getenv("PORT", default=8000))
asyncio.run(run_service("crossmatch_api", port))


def run_probability():
port = int(os.getenv("PORT", default=8000))
asyncio.run(run_service("probability_api", port))


async def run_services(services, port):
tasks = []
for i, service in enumerate(services):
Expand Down
Empty file.
33 changes: 33 additions & 0 deletions lightcurve/src/crossmatch_api/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from prometheus_fastapi_instrumentator import Instrumentator

from .routes import htmx, rest
from database.mongo import connect as connect_mongo
from database.sql import connect as connect_sql, session_wrapper

app = FastAPI(openapi_url="/v2/object/openapi.json")
app.state.mongo_db = None
psql_engine = connect_sql()
app.state.psql_session = session_wrapper(psql_engine)
instrumentator = Instrumentator().instrument(app).expose(app)

app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)


app.include_router(rest.router)
app.include_router(prefix="/htmx", router=htmx.router)

app.mount("/static", StaticFiles(directory="src/crossmatch_api/static"), name="static")


@app.get("/openapi.json")
def custom_swagger_route():
return app.openapi()
47 changes: 47 additions & 0 deletions lightcurve/src/crossmatch_api/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import re


def update_config_dict(config_dict):
config_dict["FILTERS_MAP"] = {
"filter_atlas_detections": filter_atlas_detection_non_detection,
"filter_atlas_non_detections": filter_atlas_detection_non_detection,
"filter_atlas_lightcurve": filter_atlas_lightcurve,
"filter_atlas_forced_photometry": filter_atlas_detection_non_detection,
}


def get_filters_map():
return {
"filter_atlas_detections": filter_atlas_detection_non_detection,
"filter_atlas_non_detections": filter_atlas_detection_non_detection,
"filter_atlas_lightcurve": filter_atlas_lightcurve,
"filter_atlas_forced_photometry": filter_atlas_detection_non_detection,
}


def filter_atlas_detection_non_detection(lc_object):
pattern = re.compile("atlas*", re.IGNORECASE)
if pattern.match(lc_object["tid"]):
return False
return True


def filter_atlas_lightcurve(lc_object):
non_filtered_detections = []
non_filtered_non_detections = []
non_filtered_forced_photometry = []

for detection in lc_object["detections"]:
if filter_atlas_detection_non_detection(detection):
non_filtered_detections.append(detection)
for non_detecton in lc_object["non_detections"]:
if filter_atlas_detection_non_detection(non_detecton):
non_filtered_non_detections.append(non_detecton)
for forced_photometry in lc_object["forced_photometry"]:
if filter_atlas_detection_non_detection(forced_photometry):
non_filtered_forced_photometry.append(forced_photometry)

lc_object["detections"] = non_filtered_detections
lc_object["non_detections"] = non_filtered_non_detections
lc_object["forced_photometry"] = non_filtered_forced_photometry
return True
19 changes: 19 additions & 0 deletions lightcurve/src/crossmatch_api/get_crossmatch_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import requests

def get_alerce_data(ra, dec, radius):
base_url = "https://catshtm.alerce.online/crossmatch_all"

# Parameters for the API request
params = {
"ra": ra,
"dec": dec,
"radius": radius
}

try:
# Make the GET request
response = requests.get(base_url, params=params)
return response.json() # Return the JSON response

claudiomansillab marked this conversation as resolved.
Show resolved Hide resolved
except requests.RequestException as e:
return f"Error: {str(e)}"
37 changes: 37 additions & 0 deletions lightcurve/src/crossmatch_api/result_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import traceback
import logging

from fastapi import HTTPException

from core.exceptions import (
AtlasNonDetectionError,
DatabaseError,
ObjectNotFound,
SurveyIdError,
)


def handle_success(result):
return result


def _handle_client_error(err: BaseException, code=400):
raise HTTPException(status_code=code, detail=str(err))


def _handle_server_error(err: BaseException):
if err.__traceback__:
traceback.print_exception(err)
logging.error(err)
raise HTTPException(status_code=500, detail=str(err))


def handle_error(err: BaseException):
if isinstance(err, DatabaseError):
_handle_server_error(err)
if isinstance(err, SurveyIdError):
_handle_client_error(err)
if isinstance(err, AtlasNonDetectionError):
_handle_client_error(err)
if isinstance(err, ObjectNotFound):
_handle_client_error(err, code=404)
Empty file.
47 changes: 47 additions & 0 deletions lightcurve/src/crossmatch_api/routes/htmx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

import re
import os
from typing import Annotated
from fastapi import Query
import json

from core.services.object import get_object
from fastapi import APIRouter, Request, HTTPException
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
from ..result_handler import handle_error, handle_success
from ..get_crossmatch_data import get_alerce_data
router = APIRouter()
templates = Jinja2Templates(
directory="src/crossmatch_api/templates", autoescape=True, auto_reload=True
)
templates.env.globals["API_URL"] = os.getenv(
"API_URL", "http://localhost:8005"
)

@router.get("/crossmatch/{oid}", response_class=HTMLResponse)
async def object_mag_app(
request: Request,
oid: str,
):

object = get_object(oid,session_factory = request.app.state.psql_session)

cross = get_alerce_data(object.meanra, object.meandec, 50)

cross_keys_raw = []
for i in range(len(cross)):
cross_keys_raw.append(next(iter(cross[i].keys())))

cross_keys = []
for i in range(len(cross)):
if next(iter(cross[i].values()))['distance']['value'] <= 20:
cross_keys.append(next(iter(cross[i].keys())))

return templates.TemplateResponse(
name='crossmatch.html.jinja',
context={'request': request,
'cross': cross,
'crossKeys': cross_keys
},
)
22 changes: 22 additions & 0 deletions lightcurve/src/crossmatch_api/routes/rest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from fastapi import APIRouter, HTTPException, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

from core.exceptions import ObjectNotFound
from core.services.object import get_object
from ..get_crossmatch_data import get_alerce_data


router = APIRouter()
templates = Jinja2Templates(
directory="src/crossmatch_api/templates", autoescape=True, auto_reload=True
)

@router.get("/")
def root():
return "this is the crossmatch module"


@router.get("/healthcheck")
def healthcheck():
return "OK"
Loading
Loading