Skip to content
This repository was archived by the owner on May 7, 2026. It is now read-only.
Binary file added dump.rdb
Binary file not shown.
37 changes: 37 additions & 0 deletions src/diffcalc_API/examples/UBCalculation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from diffcalc_API.models.UBCalculation import (
addOrientationParams,
addReflectionParams,
editOrientationParams,
editReflectionParams,
setLatticeParams,
)

addReflection: addReflectionParams = addReflectionParams(
**{
"hkl": [0, 0, 1],
"position": [7.31, 0.0, 10.62, 0, 0.0, 0],
"energy": 12.39842,
"tag": "refl1",
}
)

editReflection: editReflectionParams = editReflectionParams(
**{"energy": 12.45, "tagOrIdx": "refl1"}
)

addOrientation: addOrientationParams = addOrientationParams(
**{
"hkl": [0, 1, 0],
"xyz": [0, 1, 0],
"tag": "plane",
}
)

editOrientation: editOrientationParams = editOrientationParams(
**{
"hkl": (0, 1, 0),
"tagOrIdx": "plane",
}
)

setLattice: setLatticeParams = setLatticeParams(**{"a": 4.913, "c": 5.405})
3 changes: 3 additions & 0 deletions src/diffcalc_API/examples/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from diffcalc_API.examples import UBCalculation

__all__ = ["UBCalculation"]
28 changes: 5 additions & 23 deletions src/diffcalc_API/routes/Constraints.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
from pathlib import Path
from typing import Callable, Dict, Tuple, Union
from typing import Callable, Dict, Union

from diffcalc.hkl.calc import HklCalculation
from diffcalc.hkl.constraints import Constraints
from fastapi import APIRouter, Body, Depends, Response

from diffcalc_API.config import constraintsWithNoValue
from diffcalc_API.errors.Constraints import check_constraint_exists
from diffcalc_API.fileHandling import supplyPersist, unpickleHkl
from diffcalc_API.services import Constraints as service

router = APIRouter(prefix="/constraints", tags=["constraints"])


singleConstraintType = Union[Tuple[str, float], str]


@router.get("/{name}")
async def get_constraints_status(
name: str, hklCalc: HklCalculation = Depends(unpickleHkl)
Expand All @@ -31,12 +26,7 @@ async def set_constraints(
hklCalc: HklCalculation = Depends(unpickleHkl),
persist: Callable[[HklCalculation, str], Path] = Depends(supplyPersist),
):
booleanConstraints = set(constraintDict.keys()).intersection(constraintsWithNoValue)
for constraint in booleanConstraints:
constraintDict[constraint] = bool(constraintDict[constraint])

hklCalc.constraints = Constraints(constraintDict)
persist(hklCalc, name)
service.set_constraints(name, constraintDict, hklCalc, persist)
return {"message": f"constraints updated (replaced) for crystal {name}"}


Expand All @@ -47,9 +37,7 @@ async def remove_constraint(
hklCalc: HklCalculation = Depends(unpickleHkl),
persist: Callable[[HklCalculation, str], Path] = Depends(supplyPersist),
):
check_constraint_exists(property)
setattr(hklCalc.constraints, property, None)
persist(hklCalc, name)
service.remove_constraint(name, property, hklCalc, persist)

return {
"message": (
Expand All @@ -67,13 +55,7 @@ async def set_constraint(
hklCalc: HklCalculation = Depends(unpickleHkl),
persist: Callable[[HklCalculation, str], Path] = Depends(supplyPersist),
):
check_constraint_exists(property)

if property in constraintsWithNoValue:
value = bool(value)

setattr(hklCalc.constraints, property, value)
persist(hklCalc, name)
service.set_constraint(name, property, value, hklCalc, persist)

return {
"message": (
Expand Down
80 changes: 20 additions & 60 deletions src/diffcalc_API/routes/HklCalculation.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
from itertools import product
from pathlib import Path
from typing import Callable, Dict, List, Optional, Tuple, Union
from typing import Callable, 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, Response

from diffcalc_API.errors.HklCalculation import (
calculate_UB_matrix,
check_valid_miller_indices,
check_valid_scan_bounds,
)
from diffcalc_API.fileHandling import supplyPersist, unpickleHkl
from diffcalc_API.services import HklCalculation as service

router = APIRouter(prefix="/calculate", tags=["hkl"])
router = APIRouter(
prefix="/calculate", tags=["hkl"], dependencies=[Depends(unpickleHkl)]
)


singleConstraintType = Union[Tuple[str, float], str]
Expand All @@ -29,9 +25,7 @@ async def calculate_UB(
hklCalc: HklCalculation = Depends(unpickleHkl),
persist: Callable[[HklCalculation, str], Path] = Depends(supplyPersist),
):
calculate_UB_matrix(hklCalc, firstTag, secondTag)

persist(hklCalc, name)
service.calculate_UB(name, firstTag, secondTag, hklCalc, persist)
return Response(
content=str(np.round(hklCalc.ubcalc.UB, 6)), media_type="application/text"
)
Expand All @@ -44,10 +38,11 @@ async def lab_position_from_miller_indices(
wavelength: float = Query(..., example=1.0),
hklCalc: HklCalculation = Depends(unpickleHkl),
):
check_valid_miller_indices(millerIndices)
allPositions = hklCalc.get_position(*millerIndices, wavelength)
positions = service.lab_position_from_miller_indices(
millerIndices, wavelength, hklCalc
)

return {"payload": combine_lab_position_results(allPositions)}
return {"payload": positions}


@router.get("/{name}/position/hkl")
Expand All @@ -59,13 +54,8 @@ async def miller_indices_from_lab_position(
wavelength: float = Query(..., example=1.0),
hklCalc: HklCalculation = Depends(unpickleHkl),
):
hklPosition = hklCalc.get_hkl(Position(*pos), wavelength)
return {"payload": tuple(np.round(hklPosition, 16))}


def generate_axis(start: float, stop: float, inc: float):
check_valid_scan_bounds(start, stop, inc)
return np.arange(start, stop + inc, inc)
hkl = service.miller_indices_from_lab_position(pos, wavelength, hklCalc)
return {"payload": hkl}


@router.get("/{name}/scan/hkl")
Expand All @@ -77,19 +67,8 @@ async def scan_hkl(
wavelength: float = Query(..., example=1),
hklCalc: HklCalculation = Depends(unpickleHkl),
):
valueOfAxes = [
generate_axis(start[i], stop[i], inc[i]) if inc[i] != 0 else [0]
for i in range(3)
]

results = {}

for h, k, l in product(*valueOfAxes):
check_valid_miller_indices((h, k, l))
allPositions = hklCalc.get_position(h, k, l, wavelength)
results[f"({h}, {k}, {l})"] = combine_lab_position_results(allPositions)

return {"payload": results}
scanResults = service.scan_hkl(start, stop, inc, wavelength, hklCalc)
return {"payload": scanResults}


@router.get("/{name}/scan/wavelength")
Expand All @@ -101,15 +80,8 @@ async def scan_wavelength(
hkl: positionType = Query(..., example=(1, 0, 1)),
hklCalc: HklCalculation = Depends(unpickleHkl),
):
check_valid_scan_bounds(start, stop, inc)
wavelengths = np.arange(start, stop + inc, inc)
result = {}

for wavelength in wavelengths:
allPositions = hklCalc.get_position(*hkl, wavelength)
result[f"{wavelength}"] = combine_lab_position_results(allPositions)

return {"payload": result}
scanResults = service.scan_wavelength(start, stop, inc, hkl, hklCalc)
return {"payload": scanResults}


@router.get("/{name}/scan/{constraint}")
Expand All @@ -123,20 +95,8 @@ async def scan_constraint(
wavelength: float = Query(..., example=1.0),
hklCalc: HklCalculation = Depends(unpickleHkl),
):
check_valid_scan_bounds(start, stop, inc)
result = {}
for value in np.arange(start, stop + inc, inc):
setattr(hklCalc, constraint, value)
allPositions = hklCalc.get_position(*hkl, wavelength)
result[f"{value}"] = combine_lab_position_results(allPositions)

return {"payload": result}


def combine_lab_position_results(positions: List[Tuple[Position, Dict[str, float]]]):
result = []

for position in positions:
result.append({**position[0].asdict, **position[1]})
scanResults = service.scan_constraint(
constraint, start, stop, inc, hkl, wavelength, hklCalc
)

return result
return {"payload": scanResults}
Loading