From ee9a38b0d1e2da00cfb63b3895c6167692ef7589 Mon Sep 17 00:00:00 2001 From: Rose Yemelyanova Date: Wed, 13 Jul 2022 08:40:14 +0000 Subject: [PATCH 1/2] added get operations to return the current state of the UB and Constraint objects in HklCalculation object. Modified tests for this, and also moved the UB calculation operation to hklCalc routes as it made most sense. Modified tests to reflect these changes. --- src/diffcalc_API/errors/HklCalculation.py | 19 +++++++++++++++- src/diffcalc_API/errors/UBCalculation.py | 18 +-------------- src/diffcalc_API/routes/Constraints.py | 12 ++++++++-- src/diffcalc_API/routes/HklCalculation.py | 24 +++++++++++++++++--- src/diffcalc_API/routes/UBCalculation.py | 27 +++++------------------ tests/test_hklcalc.py | 21 ++++++++++++++++++ tests/test_ubcalc.py | 20 ----------------- 7 files changed, 76 insertions(+), 65 deletions(-) diff --git a/src/diffcalc_API/errors/HklCalculation.py b/src/diffcalc_API/errors/HklCalculation.py index 5dd33f4..177fe66 100644 --- a/src/diffcalc_API/errors/HklCalculation.py +++ b/src/diffcalc_API/errors/HklCalculation.py @@ -1,6 +1,7 @@ -from typing import Tuple +from typing import Optional, Tuple, Union import numpy as np +from diffcalc.hkl.calc import HklCalculation from diffcalc_API.errorDefinitions import DiffcalcAPIException, ErrorCodes, allResponses @@ -8,6 +9,7 @@ class codes(ErrorCodes): check_valid_miller_indices = 400 check_valid_scan_bounds = 400 + calculate_UB_matrix = 400 responses = {code: allResponses[code] for code in np.unique(codes().all_codes())} @@ -32,3 +34,18 @@ def check_valid_scan_bounds(start: float, stop: float, inc: float): ), ) return + + +def calculate_UB_matrix( + hkl: HklCalculation, + firstTag: Optional[Union[int, str]], + secondTag: Optional[Union[int, str]], +) -> None: + try: + hkl.ubcalc.calc_ub(firstTag, secondTag) + except Exception as e: + raise DiffcalcAPIException( + status_code=codes.calculate_UB_matrix, + detail=f"Error calculating UB matrix: {e.__str__()}", + ) + return diff --git a/src/diffcalc_API/errors/UBCalculation.py b/src/diffcalc_API/errors/UBCalculation.py index c23ec99..2ec5860 100644 --- a/src/diffcalc_API/errors/UBCalculation.py +++ b/src/diffcalc_API/errors/UBCalculation.py @@ -1,4 +1,4 @@ -from typing import Optional, Union +from typing import Union import numpy as np from diffcalc.hkl.calc import HklCalculation @@ -14,7 +14,6 @@ class codes(ErrorCodes): get_reflection = 403 get_orientation = 403 check_property_is_valid = 400 - calculate_UB_matrix = 400 responses = {code: allResponses[code] for code in np.unique(codes().all_codes())} @@ -68,18 +67,3 @@ def check_property_is_valid(property: str) -> None: detail=f"invalid property. Choose one of: {VectorProperties}", ) return - - -def calculate_UB_matrix( - hkl: HklCalculation, - firstTag: Optional[Union[int, str]], - secondTag: Optional[Union[int, str]], -) -> None: - try: - hkl.ubcalc.calc_ub(firstTag, secondTag) - except Exception as e: - raise DiffcalcAPIException( - status_code=codes.calculate_UB_matrix, - detail=f"Error calculating UB matrix: {e.__str__()}", - ) - return diff --git a/src/diffcalc_API/routes/Constraints.py b/src/diffcalc_API/routes/Constraints.py index e2edf62..a4776b8 100644 --- a/src/diffcalc_API/routes/Constraints.py +++ b/src/diffcalc_API/routes/Constraints.py @@ -3,7 +3,7 @@ from diffcalc.hkl.calc import HklCalculation from diffcalc.hkl.constraints import Constraints -from fastapi import APIRouter, Body, Depends +from fastapi import APIRouter, Body, Depends, Response from diffcalc_API.config import constraintsWithNoValue from diffcalc_API.errors.Constraints import check_constraint_exists @@ -15,6 +15,15 @@ singleConstraintType = Union[Tuple[str, float], str] +@router.get("/{name}") +async def get_constraints_status( + name: str, hklCalc: HklCalculation = Depends(unpickleHkl) +): + return Response( + content=hklCalc.constraints.__str__(), media_type="application/text" + ) + + @router.put("/{name}/set") async def set_constraints( name: str, @@ -33,7 +42,6 @@ async def set_constraints( return {"message": f"constraints updated (replaced) for crystal {name}"} -# is patch the correct choice here? What about delete instead? @router.patch("/{name}/unconstrain/{property}") async def remove_constraint( name: str, diff --git a/src/diffcalc_API/routes/HklCalculation.py b/src/diffcalc_API/routes/HklCalculation.py index c8aeb50..e4bd964 100644 --- a/src/diffcalc_API/routes/HklCalculation.py +++ b/src/diffcalc_API/routes/HklCalculation.py @@ -1,16 +1,18 @@ from itertools import product -from typing import Dict, List, Tuple, Union +from pathlib import Path +from typing import Callable, Dict, List, Optional, Tuple, Union import numpy as np from diffcalc.hkl.calc import HklCalculation from diffcalc.hkl.geometry import Position -from fastapi import APIRouter, Depends, Query +from fastapi import APIRouter, Depends, Query, Response from diffcalc_API.errors.HklCalculation import ( + calculate_UB_matrix, check_valid_miller_indices, check_valid_scan_bounds, ) -from diffcalc_API.fileHandling import unpickleHkl +from diffcalc_API.fileHandling import supplyPersist, unpickleHkl router = APIRouter(prefix="/calculate", tags=["hkl"]) @@ -19,6 +21,22 @@ positionType = Tuple[float, float, float] +@router.get("/{name}/UB") +async def calculate_UB( + name: str, + firstTag: Optional[Union[int, str]] = Query(default=None, example="refl1"), + secondTag: Optional[Union[int, str]] = Query(default=None, example="plane"), + hklCalc: HklCalculation = Depends(unpickleHkl), + persist: Callable[[HklCalculation, str], Path] = Depends(supplyPersist), +): + calculate_UB_matrix(hklCalc, firstTag, secondTag) + + persist(hklCalc, name) + return Response( + content=np.round(hklCalc.ubcalc.UB, 6).__str__(), media_type="application/text" + ) + + @router.get("/{name}/position/lab") async def lab_position_from_miller_indices( name: str, diff --git a/src/diffcalc_API/routes/UBCalculation.py b/src/diffcalc_API/routes/UBCalculation.py index 7be25a4..609e7e2 100644 --- a/src/diffcalc_API/routes/UBCalculation.py +++ b/src/diffcalc_API/routes/UBCalculation.py @@ -1,14 +1,11 @@ -import json from pathlib import Path -from typing import Callable, Optional, Tuple, Union +from typing import Callable, Tuple, Union -import numpy as np from diffcalc.hkl.calc import HklCalculation from diffcalc.hkl.geometry import Position -from fastapi import APIRouter, Body, Depends, Query +from fastapi import APIRouter, Body, Depends, Response from diffcalc_API.errors.UBCalculation import ( - calculate_UB_matrix, check_params_not_empty, check_property_is_valid, get_orientation, @@ -26,9 +23,9 @@ router = APIRouter(prefix="/ub", tags=["ub"]) -@router.get("/") -async def read_main(): - return {"msg": "Hello World"} +@router.get("/{name}") +async def get_UB_status(name: str, hklCalc: HklCalculation = Depends(unpickleHkl)): + return Response(content=hklCalc.ubcalc.__str__(), media_type="application/text") @router.put("/{name}/reflection") @@ -172,20 +169,6 @@ async def modify_property( return {"message": f"{property} set for UB calculation of crystal {name}"} -@router.get("/{name}/UB") -async def calculate_UB( - name: str, - firstTag: Optional[Union[int, str]] = Query(default=None, example="refl1"), - secondTag: Optional[Union[int, str]] = Query(default=None, example="plane"), - hklCalc: HklCalculation = Depends(unpickleHkl), - persist: Callable[[HklCalculation, str], Path] = Depends(supplyPersist), -): - calculate_UB_matrix(hklCalc, firstTag, secondTag) - - persist(hklCalc, name) - return json.dumps(np.round(hklCalc.ubcalc.UB, 6).tolist()) - - @router.delete("/{name}/reflection") async def delete_reflection( name: str, diff --git a/tests/test_hklcalc.py b/tests/test_hklcalc.py index 13fee59..7448174 100644 --- a/tests/test_hklcalc.py +++ b/tests/test_hklcalc.py @@ -142,3 +142,24 @@ def test_invalid_scans(client: TestClient): ) assert invalidWavelengthScan.status_code == codes.check_valid_scan_bounds + + +def test_calculate_UB(client: TestClient): + response = client.get( + "/calculate/test/UB", params={"firstTag": "refl1", "secondTag": "plane"} + ) + expected_UB = ( + "[[ 1.27889 -0. 0. ], [-0. 1.278111 0.04057 ]," + " [-0. -0.044633 1.161768]]" + ) + + assert response.status_code == 200 + assert response.text.replace("\n", ", ") == expected_UB + + +def test_calculate_UB_fails_when_incorrect_tags(client: TestClient): + response = client.get( + "/calculate/test/UB", params={"firstTag": "one", "secondTag": "two"} + ) + + assert response.status_code == codes.calculate_UB_matrix diff --git a/tests/test_ubcalc.py b/tests/test_ubcalc.py index d64cda7..a9e0b24 100644 --- a/tests/test_ubcalc.py +++ b/tests/test_ubcalc.py @@ -1,4 +1,3 @@ -import ast from pathlib import Path import numpy as np @@ -202,22 +201,3 @@ def test_modify_non_existent_property(client: TestClient): json=[0, 0, 1], ) assert response.status_code == codes.check_property_is_valid - - -def test_calculate_UB(client: TestClient): - dummyHkl.ubcalc.add_reflection([0, 0, 1], Position(7, 0, 10, 0, 0, 0), 12, "foo") - dummyHkl.ubcalc.add_orientation([0, 1, 0], [0, 1, 0], None, "bar") - dummyHkl.ubcalc.set_lattice(name="test", a=2) - - response = client.get("/ub/test/UB", params={"firstTag": "foo", "secondTag": "bar"}) - - expected_UB = [[3.141593, 0, 0], [0, 3.139679, 0.10964], [-0, -0.10964, 3.139679]] - - assert response.status_code == 200 - assert ast.literal_eval(response._content.decode().replace('"', "")) == expected_UB - - -def test_calculate_UB_fails_when_incorrect_tags(client: TestClient): - response = client.get("/ub/test/UB", params={"firstTag": "one", "secondTag": "two"}) - - assert response.status_code == codes.calculate_UB_matrix From 50ca8098190c7e08ab3661cf90a2fa3e7d84cd2b Mon Sep 17 00:00:00 2001 From: Rose Yemelyanova Date: Wed, 13 Jul 2022 14:45:26 +0000 Subject: [PATCH 2/2] removed unpythonic __str__ method and replaced with str() function call instead --- src/diffcalc_API/errors/HklCalculation.py | 2 +- src/diffcalc_API/routes/Constraints.py | 4 +--- src/diffcalc_API/routes/HklCalculation.py | 2 +- src/diffcalc_API/routes/UBCalculation.py | 2 +- src/diffcalc_API/server.py | 4 ++-- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/diffcalc_API/errors/HklCalculation.py b/src/diffcalc_API/errors/HklCalculation.py index 177fe66..bc3d37c 100644 --- a/src/diffcalc_API/errors/HklCalculation.py +++ b/src/diffcalc_API/errors/HklCalculation.py @@ -46,6 +46,6 @@ def calculate_UB_matrix( except Exception as e: raise DiffcalcAPIException( status_code=codes.calculate_UB_matrix, - detail=f"Error calculating UB matrix: {e.__str__()}", + detail=f"Error calculating UB matrix: {str(e)}", ) return diff --git a/src/diffcalc_API/routes/Constraints.py b/src/diffcalc_API/routes/Constraints.py index a4776b8..b29c0fb 100644 --- a/src/diffcalc_API/routes/Constraints.py +++ b/src/diffcalc_API/routes/Constraints.py @@ -19,9 +19,7 @@ async def get_constraints_status( name: str, hklCalc: HklCalculation = Depends(unpickleHkl) ): - return Response( - content=hklCalc.constraints.__str__(), media_type="application/text" - ) + return Response(content=str(hklCalc.constraints), media_type="application/text") @router.put("/{name}/set") diff --git a/src/diffcalc_API/routes/HklCalculation.py b/src/diffcalc_API/routes/HklCalculation.py index e4bd964..e201010 100644 --- a/src/diffcalc_API/routes/HklCalculation.py +++ b/src/diffcalc_API/routes/HklCalculation.py @@ -33,7 +33,7 @@ async def calculate_UB( persist(hklCalc, name) return Response( - content=np.round(hklCalc.ubcalc.UB, 6).__str__(), media_type="application/text" + content=str(np.round(hklCalc.ubcalc.UB, 6)), media_type="application/text" ) diff --git a/src/diffcalc_API/routes/UBCalculation.py b/src/diffcalc_API/routes/UBCalculation.py index 609e7e2..b19db19 100644 --- a/src/diffcalc_API/routes/UBCalculation.py +++ b/src/diffcalc_API/routes/UBCalculation.py @@ -25,7 +25,7 @@ @router.get("/{name}") async def get_UB_status(name: str, hklCalc: HklCalculation = Depends(unpickleHkl)): - return Response(content=hklCalc.ubcalc.__str__(), media_type="application/text") + return Response(content=str(hklCalc.ubcalc), media_type="application/text") @router.put("/{name}/reflection") diff --git a/src/diffcalc_API/server.py b/src/diffcalc_API/server.py index 683cfb2..8669c80 100644 --- a/src/diffcalc_API/server.py +++ b/src/diffcalc_API/server.py @@ -24,7 +24,7 @@ async def diffcalc_exception_handler(request: Request, exc: DiffcalcException): return responses.JSONResponse( status_code=400, - content={"message": exc.__str__(), "type": str(type(exc))}, + content={"message": str(exc), "type": str(type(exc))}, ) @@ -46,7 +46,7 @@ async def server_exceptions_middleware(request: Request, call_next): return responses.JSONResponse( status_code=500, - content={"message": e.__str__(), "type": str(type(e))}, + content={"message": str(e), "type": str(type(e))}, )