# BornAgain/Tests/Examples/CMakeLists.txt
#
# For the Python scripts in directory BornAgain/Examples:
# - test against reference, with mini detectors
# - under target 'figures', generate high-resolution figures for hugo
# - under target 'excopy', copy example sources to hugo

file(MAKE_DIRECTORY ${TEST_OUTPUT_DIR_PY_PERSIST})

set(FIG_DIR ${CMAKE_SOURCE_DIR}/hugo/static/img/auto)

add_custom_target(figures) # generate high-resolution figures and store them in FIG_DIR
add_custom_target(manualtest)

file(MAKE_DIRECTORY ${FIG_DIR})
foreach(subdir ff fq offspec scatter2d specular varia)
    file(MAKE_DIRECTORY ${TEST_OUTPUT_DIR_PY_PERSIST}/${subdir})
    file(MAKE_DIRECTORY ${FIG_DIR}/${subdir})
endforeach()

add_custom_target(excopy
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${EXAMPLES_PUBL_DIR}
       ${CMAKE_SOURCE_DIR}/hugo/static/py/auto/Examples)

####################################################################################################
#  Test functions
####################################################################################################

macro(parse_example example)
    cmake_path(SET MINI_SCRIPT NORMALIZE ${EXAMPLES_TEST_DIR}/${example}.py)
    cmake_path(SET PUBL_SCRIPT NORMALIZE ${EXAMPLES_PUBL_DIR}/${example}.py)
    get_filename_component(EXAMPLE_NAME ${MINI_SCRIPT} NAME_WE)
    get_filename_component(EXAMPLE_SUBDIR ${example} DIRECTORY)
endmacro()

set(launch_env COMMAND ${CMAKE_COMMAND} -E env)
set(launch_py
    BA_DATA_DIR=${EXAMPLES_DATA_DIR}
    PYTHONPATH=${CMAKE_BINARY_DIR}/lib
    ${Python3_EXECUTABLE})

# Register example that plots but has no persistence test.
function(run_example example)
    parse_example(${example})
    string(REPLACE "/" "." TARGET_NAME Example.${example}.fig)
    add_test(NAME Example.run.${EXAMPLE_NAME}
        ${launch_env} ${launch_py} ${MINI_SCRIPT} show=n)
    add_custom_target(${TARGET_NAME}
        ${launch_env} ${launch_py} ${PUBL_SCRIPT}
           show=n figfile=${FIG_DIR}/${EXAMPLE_SUBDIR}/${EXAMPLE_NAME}.png)
    add_dependencies(figures ${TARGET_NAME})
endfunction()

# Register example that has no output but is tested for running through.
function(run_plotless example)
    parse_example(${example})
    string(REPLACE "/" "." TARGET_NAME Example.${example}.run)
    add_test(NAME ${TARGET_NAME}
        ${launch_env} ${launch_py} ${MINI_SCRIPT}
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
endfunction()

# Register example with target 'manualtest'.
function(run_manually example)
    parse_example(${example})
    string(REPLACE "/" "." TARGET_NAME Example.${example}.run)
    add_custom_target(${TARGET_NAME}
        COMMAND echo "### MANUAL TEST: EXAMPLE ${EXAMPLE_NAME}"
        ${launch_env} ${launch_py} ${MINI_SCRIPT}
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
    add_dependencies(manualtest ${TARGET_NAME})
endfunction()

# Register example that plots and has persistence test.
function(test_equality example reference tolerance)
    parse_example(${example})
    string(REPLACE "/" "." TARGET_NAME Example.${example}.fig)
    cmake_path(SET outfile NORMALIZE ${TEST_OUTPUT_DIR_PY_PERSIST}/${example})
    cmake_path(SET reffile NORMALIZE ${REFERENCE_DIR_MINIEXAMPLES}/${reference})
    add_test(NAME ${TARGET_NAME}
        ${launch_env} ${launch_py} ${MINI_SCRIPT} show=n datfile=${outfile}
            tolerance=${tolerance} reference=${reffile}
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
    add_custom_target(${TARGET_NAME}
        ${launch_env} ${launch_py} ${PUBL_SCRIPT}
          show=n figfile=${FIG_DIR}/${EXAMPLE_SUBDIR}/${EXAMPLE_NAME}.png)
    add_dependencies(figures ${TARGET_NAME})
endfunction()

# Python persistence test: run modified example, and compare with reference data.
function(test_example example tolerance)
    test_equality(${example} ${example} ${tolerance})
endfunction()

####################################################################################################
#  Test collection
####################################################################################################

test_example(ff/Bipyramid4 2e-10)
test_example(ff/Box 2e-10)
test_example(ff/CantellatedCube 2e-10)
test_example(ff/Cone 2e-10)
test_example(ff/Cylinder 2e-10)
test_example(ff/Dodecahedron 2e-10)
test_example(ff/EllipsoidalCylinder 2e-10)
test_example(ff/HemiEllipsoid 2e-10)
test_example(ff/HorizontalCylinder 2e-10)
test_example(ff/Icosahedron 2e-10)
test_example(ff/PlatonicOctahedron 2e-10)
test_example(ff/PlatonicTetrahedron 2e-10)
test_example(ff/Prism3 2e-10)
test_example(ff/Prism6 2e-10)
test_example(ff/Pyramid2 2e-10)
test_example(ff/Pyramid3 2e-10)
test_example(ff/Pyramid4 2e-10)
test_example(ff/Pyramid6 2e-10)
test_example(ff/SawtoothRippleBox 2e-10)
test_example(ff/Sphere 2e-10)
test_example(ff/Spheroid 2e-10)
test_example(ff/TruncatedCube 2e-10)
test_example(ff/TruncatedSphere 2e-10)
test_example(ff/TruncatedSpheroid 2e-10)

run_example(fq/Sphere)

test_example(scatter2d/ApproximationDA 2e-10)
test_example(scatter2d/ApproximationLMA 2e-10)
test_example(scatter2d/ApproximationSSCA 2e-10)
test_example(scatter2d/BeamDivergence 2e-10)
test_example(scatter2d/BiMaterialCylinders 2e-10)
test_example(scatter2d/BoxesWithSpecularPeak 2e-10)
test_example(scatter2d/ConstantBackground 2e-10)
test_example(scatter2d/CoreShellNanoparticles 2e-10)
test_example(scatter2d/CoreShellNanoparticles2 2e-10)
test_example(scatter2d/CorrelatedRoughness 2e-10)
test_example(scatter2d/CosineRipplesAtRectLattice 2e-10)
test_example(scatter2d/CustomFormFactor 2e-10)
test_example(scatter2d/Cylinders 2e-10)
test_example(scatter2d/CylindersAndPrisms 2e-10)
test_example(scatter2d/CylindersInAverageLayer 2e-10)
test_example(scatter2d/CylindersInBA 2e-10)
test_example(scatter2d/DetectorResolutionFunction 2e-10)
test_example(scatter2d/DodecahedraSAS 2e-10)
test_example(scatter2d/HalfSpheresInAverageTopLayer 2e-10)
test_example(scatter2d/HexagonalLatticesWithBasis 2e-10)
test_example(scatter2d/Interference1DLattice 1.5)
test_example(scatter2d/Interference1DRadialParacrystal 2e-10)
test_example(scatter2d/Interference2DCenteredSquareLattice 2e-10)
test_example(scatter2d/Interference2DParacrystal 2e-10)
test_example(scatter2d/Interference2DRotatedSquareLattice 2e-10)
test_example(scatter2d/Interference2DSquareFiniteLattice 2e-10)
test_example(scatter2d/LatticeOrientationDistribution 2e-10)
test_example(scatter2d/MagneticSpheres 2e-10)
test_example(scatter2d/Mesocrystal 2e-10)
test_example(scatter2d/Mesocrystal2 2e-10)
test_example(scatter2d/Mesocrystal3 2e-10)
test_example(scatter2d/ParticleAcrossInterface 2e-10)
test_example(scatter2d/PolarizedSANS 2e-10)
test_example(scatter2d/PolydisperseCylinders 2e-10)
test_example(scatter2d/RectangularGrating 0.5)
test_example(scatter2d/RotatedPyramids 2e-10)
test_example(scatter2d/SpheresAtHexLattice 2e-10)
test_example(scatter2d/TriangularRipple 2e-10)
test_example(scatter2d/MagneticCylinders1 2e-10)
test_example(scatter2d/MagneticCylinders2 2e-10)
test_example(scatter2d/SlicedLayer 2e-10)

test_example(scatter2d/LargeParticlesFormFactor 0.5)
test_example(scatter2d/GratingMC .9) # TODO reduce tolerance

run_example(scatter2d/PositionVariance) # TODO -> test
run_example(scatter2d/AxesInDifferentUnits)
run_example(scatter2d/FindPeaks)

test_example(specular/AlternatingLayers1 2e-13)
test_equality(specular/AlternatingLayers2 specular/AlternatingLayers1 2e-13)
test_example(specular/BeamFullDivergence 2e-10)
test_example(specular/Distributions 2e-10)
test_example(specular/FootprintCorrection 2e-10)
test_example(specular/GaussianBeams 3e-10)
test_example(specular/MagneticLayer 2e-10)
test_example(specular/MagneticLayerImperfect 2e-10)
test_example(specular/RoughnessModel 3e-10)
test_example(specular/SpecularSimulationWithRoughness 3e-10)
test_example(specular/TOFRWithResolution 2e-10)
test_example(specular/TimeOfFlightReflectometry 2e-10)
test_example(specular/VsGenx 2e-10)

run_example(specular/PolarizedSpinAsymmetry)

test_example(offspec/Offspec1 2e-10)

test_example(varia/Depthprobe1 2e-10)
test_example(varia/TransmittedModulus 2e-10)
test_example(varia/Resonator 2e-10)
test_example(varia/AccessingSimulationResults 2e-10)
run_example(varia/MaterialProfile)
run_example(varia/MaterialProfileWithParticles)

run_plotless(fit/algo/fit_rosenbrock)
run_plotless(fit/scatter2d/fit2d)
run_plotless(fit/scatter2d/custom_objective_function)
run_example(fit/specular/Specular1Par)
run_manually(fit/specular/Pt_layer_fit)
run_manually(fit/specular/Honeycomb_fit)
# TODO restore (needs ParameterDistribution) # run_plotless(fit/scatter2d/expfit_galaxi)
run_manually(fit/scatter2d/find_background)
run_manually(fit/scatter2d/fit_along_slices)
run_manually(fit/scatter2d/fit_with_masks)
# TODO (CI needs python3-lmfit) run_plotless(fit/scatter2d/lmfit_basics)
run_manually(fit/scatter2d/lmfit_with_plotting)

test_example(scatter2d/ObsoleteSimN 2e-10)
#test_equality(scatter2d/ObsoleteSimN scatter2d/Cylinders 4e-16)
