import bornagain as ba
from bornagain import ba_plot as bp, deg, nm
import numpy as np

def get_sample(P):
    """
    A sample with cylinders and pyramids on a substrate,
    forming a hexagonal lattice.
    """
    radius = P['radius']
    lattice_length = P['length']

    vacuum = ba.RefractiveMaterial("Vacuum", 0, 0)
    material_substrate = ba.RefractiveMaterial("Substrate", 6e-6, 2e-8)
    material_particle = ba.RefractiveMaterial("Particle", 6e-4, 2e-8)

    sphere_ff = ba.Sphere(radius)
    sphere = ba.Particle(material_particle, sphere_ff)
    particle_layout = ba.ParticleLayout()
    particle_layout.addParticle(sphere)

    interference = ba.Interference2DLattice(
        ba.HexagonalLattice2D(lattice_length, 0))
    pdf = ba.Profile2DCauchy(10*nm, 10*nm, 0)
    interference.setDecayFunction(pdf)

    particle_layout.setInterference(interference)

    vacuum_layer = ba.Layer(vacuum)
    vacuum_layer.addLayout(particle_layout)
    substrate_layer = ba.Layer(material_substrate, 0)
    sample = ba.Sample()
    sample.addLayer(vacuum_layer)
    sample.addLayer(substrate_layer)
    return sample


def get_simulation(P):
    """
    Create and return GISAXS simulation with beam and detector defined
    """
    n = 100
    beam = ba.Beam(1e8, 0.1*nm, 0.2*deg)
    detector = ba.SphericalDetector(n, -1*deg, 1*deg, n, 0, 2*deg)
    sample = get_sample(P)
    simulation = ba.ScatteringSimulation(beam, sample, detector)

    return simulation


def fake_data():
    """
    Generating "real" data by adding noise to the simulated data.
    """
    P = {'radius': 6*nm, 'length': 12*nm}
    simulation = get_simulation(P)
    result = simulation.simulate()

    return result.noisy(0.1, 0.1)

if __name__ == '__main__':
    raise Exception("This source file is a module for use from fitting examples."
                    " It is not meant to be called as a main program.")
