Skip to content
Snippets Groups Projects
Commit 6f69ed12 authored by pospelov's avatar pospelov
Browse files

New infrastructure for python Functional Tests

parent 82cb7f7f
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,7 @@
#include "OutputDataIOFactory.h"
#include "TCanvas.h"
#include "TH2D.h"
/* ************************************************************************* */
// global functions
......@@ -47,9 +48,9 @@ void TestMesoCrystal1::execute()
experiment.setSampleBuilder(mp_sample_builder);
// experiment.setDetectorParameters(256, 0.3*Units::degree, 0.073
// , 256, -0.4*Units::degree, 0.066);
// experiment.setDetectorParameters(218, 0.0201647, 0.0599528, 218, 0.00010879, 0.0399347); // values as in experimental sample from TestMesoCrystal2
experiment.setDetectorParameters(80, -0.025, 0.026, 80 , 0.0, 0.05);
// experiment.setDetectorResolutionFunction(new ResolutionFunction2DSimple(0.00017, 0.00017));
experiment.setDetectorParameters(218, 0.0201647, 0.0599528, 218, 0.00010879, 0.0399347); // values as in experimental sample from TestMesoCrystal2
// experiment.setDetectorParameters(80, -0.025, 0.026, 80 , 0.0, 0.05);
experiment.setDetectorResolutionFunction(new ResolutionFunction2DSimple(0.00017, 0.00017));
experiment.setBeamParameters(1.77*Units::angstrom, -0.4*Units::degree, 0.0*Units::degree);
experiment.setBeamIntensity(8e12);
......@@ -67,32 +68,65 @@ void TestMesoCrystal1::execute()
// IsGISAXSTools::drawLogOutputData(*mp_intensity_output, "c1_test_meso_crystal", "mesocrystal",
// "CONT4 Z", "mesocrystal");
TCanvas *c1 = DrawHelper::instance().createAndRegisterCanvas("c1_test_meso_crystal", "mesocrystal");
TCanvas *c1 = DrawHelper::instance().createAndRegisterCanvas("sim_meso_crystal", "mesocrystal", 1024, 768);
c1->cd(); gPad->SetLogz();
gPad->SetRightMargin(0.115);
gPad->SetLeftMargin(0.115);
gPad->SetLeftMargin(0.13);
IsGISAXSTools::setMinimum(100.);
IsGISAXSTools::setMaximum(1e7);
IsGISAXSTools::drawOutputDataInPad(*mp_intensity_output, "CONT4 Z", "meso");
TH2D *h2 = IsGISAXSTools::getOutputDataTH2D(*mp_intensity_output, "mesocrystal");
h2->SetTitle("");
h2->SetMinimum(100.);
h2->GetXaxis()->SetTitle("#phi_{f}");
h2->GetYaxis()->SetTitle("#alpha_{f}");
h2->GetXaxis()->SetTitleOffset(0.9);
h2->GetYaxis()->SetTitleOffset(1.0);
h2->SetMaximum(1e5);
h2->Draw("CONT4 Z");
// IsGISAXSTools::setMinimum(100.);
// IsGISAXSTools::setMaximum(1e7);
// IsGISAXSTools::drawOutputDataInPad(*mp_intensity_output, "CONT4 Z", "meso");
OutputDataIOFactory::writeOutputData(*mp_intensity_output, Utils::FileSystem::GetHomePath()+"./Examples/MesoCrystals/ex01_spheres/mesocrystal.ima");
std::string file_name = Utils::FileSystem::GetHomePath()+"Examples/MesoCrystals/ex02_fitspheres/004_230_P144_im_full_phitheta.txt.gz";
OutputData<double > *real_data = OutputDataIOFactory::getOutputData(file_name);
TCanvas *c2 = DrawHelper::instance().createAndRegisterCanvas("exp_meso_crystal", "mesocrystal", 1024, 768);
c2->cd(); gPad->SetLogz();
gPad->SetRightMargin(0.115);
gPad->SetLeftMargin(0.13);
TH2D *h2b = IsGISAXSTools::getOutputDataTH2D(*real_data, "mesocrystal");
h2b->SetTitle("");
h2b->SetMinimum(100.);
h2b->SetMaximum(1e5);
h2b->GetXaxis()->SetTitle("#phi_{f}");
h2b->GetYaxis()->SetTitle("#alpha_{f}");
h2b->GetXaxis()->SetTitleOffset(0.9);
h2b->GetYaxis()->SetTitleOffset(1.2);
h2b->GetYaxis()->SetRangeUser(0.0,0.039);
h2b->GetXaxis()->SetRangeUser(0.0,0.059);
h2b->Draw("COLZ Z");
}
/* ************************************************************************* */
// MesoCrystalBuilder member definitions
/* ************************************************************************* */
MesoCrystalBuilder::MesoCrystalBuilder()
: m_meso_radius(1000.0*Units::nanometer)
, m_surface_filling_ratio(0.25)
, m_meso_height(200.0*Units::nanometer)
, m_sigma_meso_height(20.0*Units::nanometer)
, m_sigma_meso_radius(50.0*Units::nanometer)
, m_lattice_length_a(6.15*Units::nanometer)
, m_nanoparticle_radius(4.3*Units::nanometer)
, m_sigma_nanoparticle_radius(0.14*Units::nanometer)
, m_sigma_lattice_length_a(1.5*Units::nanometer)
, m_roughness(0.0*Units::nanometer)
//: m_meso_radius(1000.0*Units::nanometer)
//, m_surface_filling_ratio(0.25)
//, m_meso_height(200.0*Units::nanometer)
//, m_sigma_meso_height(20.0*Units::nanometer)
//, m_sigma_meso_radius(50.0*Units::nanometer)
//, m_lattice_length_a(6.15*Units::nanometer)
//, m_nanoparticle_radius(4.3*Units::nanometer)
//, m_sigma_nanoparticle_radius(0.14*Units::nanometer)
//, m_sigma_lattice_length_a(1.5*Units::nanometer)
//, m_roughness(0.0*Units::nanometer)
// attempt 0
//: m_meso_radius(1370*Units::nanometer)
//, m_surface_filling_ratio(0.114748)
......@@ -105,16 +139,16 @@ MesoCrystalBuilder::MesoCrystalBuilder()
//, m_sigma_lattice_length_a(1.95504*Units::nanometer)
//, m_roughness(0.13464*Units::nanometer)
// attempt II
//: m_meso_radius(9.4639e+02*Units::nanometer)
//, m_surface_filling_ratio(0.159)
//, m_meso_height(1.2470e+02*Units::nanometer)
//, m_sigma_meso_height(10*Units::nanometer)
//, m_sigma_meso_radius(10*Units::nanometer)
//, m_lattice_length_a(6.212*Units::nanometer)
//, m_nanoparticle_radius(5.947*Units::nanometer)
//, m_sigma_nanoparticle_radius(6.8688e-02*Units::nanometer)
//, m_sigma_lattice_length_a(2.3596*Units::nanometer)
//, m_roughness(0.6517*Units::nanometer)
: m_meso_radius(9.4639e+02*Units::nanometer)
, m_surface_filling_ratio(0.159)
, m_meso_height(1.2470e+02*Units::nanometer)
, m_sigma_meso_height(10*Units::nanometer)
, m_sigma_meso_radius(10*Units::nanometer)
, m_lattice_length_a(6.212*Units::nanometer)
, m_nanoparticle_radius(5.947*Units::nanometer)
, m_sigma_nanoparticle_radius(6.8688e-02*Units::nanometer)
, m_sigma_lattice_length_a(2.3596*Units::nanometer)
, m_roughness(0.6517*Units::nanometer)
{
init_parameters();
}
......
......@@ -3,10 +3,10 @@ TEMPLATE = subdirs
SUBDIRS += \
IsGISAXS01 \
IsGISAXS02 \
IsGISAXS03 \
IsGISAXS07 \
IsGISAXS010 \
IsGISAXS011
IsGISAXS02
# IsGISAXS03 \
# IsGISAXS07 \
# IsGISAXS010 \
# IsGISAXS011
CONFIG += ordered
......@@ -67,7 +67,6 @@ void FunctionalTests::IsGISAXS01::run()
}
int FunctionalTests::IsGISAXS01::analyseResults()
{
const double threshold(1e-10);
......@@ -79,6 +78,7 @@ int FunctionalTests::IsGISAXS01::analyseResults()
// calculating average relative difference
*m_result -= *reference;
*m_result /= *reference;
double diff(0);
for(OutputData<double>::const_iterator it=m_result->begin(); it!=m_result->end(); ++it) {
diff+= std::fabs(*it);
......
......@@ -31,6 +31,8 @@ def parse_output(testName, stdout, stderr):
descr=descr.strip("[OK]")
descr=descr.strip("[FAILED]")
descr = descr[:55]
descr = descr.ljust(55)
return descr, status
......
# IsGISAXS01 example: Mixture of cylinders and prisms without interference
import sys
import os
import numpy
import gzip
sys.path.append(os.path.abspath(
os.path.join(os.path.split(__file__)[0],
'..', '..', '..', 'lib')))
from libBornAgainCore import *
# ----------------------------------
# describe sample and run simulation
# ----------------------------------
def RunSimulation():
# defining materials
matMng = MaterialManager.instance()
mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
# collection of particles
n_particle = complex(1.0-6e-4, 2e-8)
cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
cylinder = Particle(n_particle, cylinder_ff)
prism_ff = FormFactorPrism3(5*nanometer, 5*nanometer)
prism = Particle(n_particle, prism_ff)
particle_decoration = ParticleDecoration()
particle_decoration.addParticle(cylinder, 0.0, 0.5)
particle_decoration.addParticle(prism, 0.0, 0.5)
interference = InterferenceFunctionNone()
particle_decoration.addInterferenceFunction(interference)
# air layer with particles and substrate form multi layer
air_layer = Layer(mAmbience)
air_layer_decorator = LayerDecorator(air_layer, particle_decoration);
substrate_layer = Layer(mSubstrate, 0)
multi_layer = MultiLayer()
multi_layer.addLayer(air_layer_decorator);
multi_layer.addLayer(substrate_layer);
# build and run experiment
experiment = GISASExperiment()
experiment.setDetectorParameters(100,-1.0*degree, 1.0*degree, 100, 0.0*degree, 2.0*degree, True)
experiment.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
experiment.setSample(multi_layer)
experiment.runSimulation()
# intensity data
return GetOutputData(experiment)
# ----------------------------------
# read reference data from file
# ----------------------------------
def GetReferenceData():
path = os.path.split(__file__)[0]
if path: path +="/"
f = gzip.open(path+'../TestCore/IsGISAXS01/isgisaxs01_reference.ima.gz', 'rb')
reference=numpy.fromstring(f.read(),numpy.float64,sep=' ')
f.close()
return reference
# --------------------------------------------------------------
# calculate numeric difference between result and reference data
# --------------------------------------------------------------
def GetDifference(data, reference):
reference = reference.reshape(data.shape)
# calculating relative average difference
data -= reference
diff=0.0
epsilon = sys.float_info.epsilon
for x, y in numpy.ndindex(data.shape):
v1 = data[x][y]
v2 = reference[x][y]
if v1 <= epsilon and v2 <= epsilon:
diff += 0.0
elif(v2 <= epsilon):
diff += abs(v1/epsilon)
else:
diff += abs(v1/v2)
return diff/data.size
# --------------------------------------------------------------
# run test and analyse test results
# --------------------------------------------------------------
def RunTest():
result = RunSimulation()
reference = GetReferenceData()
diff = GetDifference(result, reference)
status = "OK"
if(diff > 1e-10): status = "FAILED"
return "IsGISAXS01" + "Mixture of cylinders and prisms without interference " + status
#-------------------------------------------------------------
# main()
#-------------------------------------------------------------
if __name__ == '__main__':
print RunTest()
# run all tests
import sys
import os
import subprocess
import time
import isgisaxs01
Tests = {
"IsGISAXS01": isgisaxs01.RunTest,
"IsGISAXS02": isgisaxs01.RunTest
}
test_info = []
# parse stdout, stderr for test description and test result
def parse_output(testName, test_result):
# normally the message from test looks like "IsGISAXS01 Mixture of cylinders and prisms [OK]"
# we want to find status (FAILED or OK) and extract description "Mixture of cylinders and prisms"
status="OK"
descr=""
if testName in test_result:
if "FAILED" in test_result:
status="FAILED"
descr=test_result.strip(testName).strip("\n")
descr=descr.strip("[OK]")
descr=descr.strip("[FAILED]")
else:
descr = "Can't parse the description"
descr = descr[:55]
descr = descr.ljust(55)
return descr, status
# run tests one by one
def runTests():
for testName in Tests:
print "Running test ", testName
start_time = time.time()
result = Tests[testName]()
total_time = time.time() - start_time
descr, status = parse_output(testName, result)
test_info.append((testName, descr, total_time, status))
# print test results
def printResults():
print "========================================"
n=1
for x in test_info:
print '{0}. {1} {2} {3:.3f}sec [{4}] '.format(n, x[0],x[1],x[2],x[3])
n+=1
#-------------------------------------------------------------
# main()
#-------------------------------------------------------------
if __name__ == '__main__':
runTests()
printResults()
......@@ -98,8 +98,8 @@ DEPENDPATH += $${LOCATIONS}
# optimization flag used in release builds (the -O2 is the default used by qmake)
QMAKE_CXXFLAGS_DEBUG += -fdiagnostics-show-option # to find out in gcc which option control warning
#QMAKE_CXXFLAGS_RELEASE += -O3 -ffast-math -msse3
QMAKE_CXXFLAGS_RELEASE -= -O2
QMAKE_CXXFLAGS_RELEASE += -O0 # -ffast-math removed because of problems with NaNs
#QMAKE_CXXFLAGS_RELEASE -= -O2
#QMAKE_CXXFLAGS_RELEASE += -O0 # -ffast-math removed because of problems with NaNs
#QMAKE_CXXFLAGS_RELEASE += -g # -ffast-math removed because of problems with NaNs
#QMAKE_STRIP=: # produces non-stripped (very large) libraries
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment