Newer
Older
// ************************************************************************** //
// BornAgain: simulate and fit scattering at grazing incidence
//
//! @brief Implements class IsGISAXSTools.
//
//! Homepage: apps.jcns.fz-juelich.de/BornAgain
//! License: GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2013
//! @authors Scientific Computing Group at MLZ Garching
//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
//
// ************************************************************************** //
Van Herck, Walter
committed
#include "IsGISAXSTools.h"
#include "BornAgainNamespace.h"
Van Herck, Walter
committed
#include "Units.h"
#include "Exceptions.h"
pospelov
committed
#include "DrawHelper.h"
Van Herck, Walter
committed
Van Herck, Walter
committed
#include "TCanvas.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TH3D.h"
Van Herck, Walter
committed
#include "TStyle.h"
#include "TPolyMarker.h"
Van Herck, Walter
committed
#include <iostream>
Van Herck, Walter
committed
#include <fstream>
#include <sstream>
#include <vector>
#include <iterator>
#include <iomanip>
#include <cassert>
Van Herck, Walter
committed
double IsGISAXSTools::m_hist_min = 0;
double IsGISAXSTools::m_hist_max = 0;
bool IsGISAXSTools::m_has_min = false;
bool IsGISAXSTools::m_has_max = false;
//! Draw 2D histogram representing logarithm of OutputData (in new canvas).
Van Herck, Walter
committed
void IsGISAXSTools::drawLogOutputData(const OutputData<double>& output,
const std::string& canvas_name, const std::string& canvas_title,
const std::string& draw_options, const std::string& histogram_title)
assert(&output);
TCanvas *c1 = new
TCanvas(canvas_name.c_str(), canvas_title.c_str(), 0, 0, 1024, 768);
gPad->SetLogz();
drawOutputDataInPad(output, draw_options, histogram_title);
//! Draw 4 2D histograms representing logarithm of polarized OutputData
//! (in new canvas).
void IsGISAXSTools::drawLogOutputDataPol(
const OutputData<Eigen::Matrix2d>& output,
const std::string& canvas_name, const std::string& canvas_title,
const std::string& draw_options, const std::string& histogram_title)
{
assert(&output);
TCanvas *c1 = new
TCanvas(canvas_name.c_str(), canvas_title.c_str(), 0, 0, 1024, 768);
c1->Divide(2,2);
OutputData<double> data;
data.copyShapeFrom(output);
// plus - plus
c1->cd(1); gPad->SetLogz();
gPad->SetRightMargin(0.12);
setMinimum(1.);
copyElementsWithPosition(output, data, 0, 0);
drawOutputDataInPad(data, draw_options, histogram_title + ": + +");
// plus - min
c1->cd(2); gPad->SetLogz();
gPad->SetRightMargin(0.12);
setMinimum(1.);
copyElementsWithPosition(output, data, 0, 1);
drawOutputDataInPad(data, draw_options, histogram_title + ": + -");
// min - plus
c1->cd(3); gPad->SetLogz();
gPad->SetRightMargin(0.12);
setMinimum(1.);
copyElementsWithPosition(output, data, 1, 0);
drawOutputDataInPad(data, draw_options, histogram_title + ": - +");
// min - min
c1->cd(4); gPad->SetLogz();
gPad->SetRightMargin(0.12);
setMinimum(1.);
copyElementsWithPosition(output, data, 1, 1);
drawOutputDataInPad(data, draw_options, histogram_title + ": - -");
}
//! Draw 2D histogram representing OutputData (in new canvas).
void IsGISAXSTools::drawOutputData(const OutputData<double>& output,
const std::string& canvas_name, const std::string& canvas_title,
const std::string& draw_options, const std::string& histogram_title)
assert(&output);
TCanvas *c1 = new
TCanvas(canvas_name.c_str(), canvas_title.c_str(), 0, 0, 1024, 768);
c1->cd();
drawOutputDataInPad(output, draw_options, histogram_title);
}
//! Draw 1D or 2D histograms representing OutputData (in current gPad).
void IsGISAXSTools::drawOutputDataInPad(const OutputData<double>& output,
const std::string& draw_options, const std::string& histogram_title)
Van Herck, Walter
committed
{
if( !&output) throw NullPointerException("IsGISAXSTools::drawOutputDataInPad() -> Error! Null output data");
if(!gPad) {
throw NullPointerException("IsGISAXSTools::drawOutputDataInPad() -> Error! No canvas exists.");
}
pospelov
committed
TH1 *hist(0);
pospelov
committed
hist = IsGISAXSTools::getOutputDataTH2D(output, "p_hist1D");
} else {
hist = IsGISAXSTools::getOutputDataTH123D(output, "p_hist1D");
}
hist->SetContour(99);
pospelov
committed
if( hasMinimum() ) hist->SetMinimum(m_hist_min);
if( hasMaximum() ) hist->SetMaximum(m_hist_max);
hist->SetTitle(histogram_title.c_str());
hist->DrawCopy(draw_options.c_str());
// dealing with masks
if(output.getMask()) {
TPolyMarker *poly = new TPolyMarker();
const IAxis *p_axis0 = output.getAxis(0);
const IAxis *p_axis1 = output.getAxis(1);
int i_point(0);
for(OutputData<double>::const_iterator it = output.begin();
it!= output.end(); ++it) {
size_t axis0_index = output.toCoordinate(it.getIndex(), 0);
size_t axis1_index = output.toCoordinate(it.getIndex(), 1);
double axis0_value = (*p_axis0)[axis0_index];
double axis1_value = (*p_axis1)[axis1_index];
poly->SetPoint(i_point++, axis0_value, axis1_value);
}
poly->Draw("same");
}
pospelov
committed
delete hist;
Van Herck, Walter
committed
}
//! Creates TH2D from OutputData.
TH2D *IsGISAXSTools::getOutputDataTH2D(const OutputData<double>& output,
const std::string& histo_name)
assert(&output);
throw( "IsGISAXSTools::getOutputDataTH2D() -> "
"Warning! Expected number of dimensiobs is 2.");
pospelov
committed
std::vector<AxisStructure > haxises;
pospelov
committed
// we assume variable bin size and prepare [nbins+1] array of left edges of each bin plus right edge of the last bin
for(size_t i_axis=0; i_axis<output.getRank(); ++i_axis) {
Van Herck, Walter
committed
const IAxis *axis = output.getAxis(i_axis);
pospelov
committed
if( !axis ) throw("IsGISAXSTools::getOutputDataTH123D() -> Error! Can't cast axis");
pospelov
committed
haxises[i_axis].nbins = axis->getSize();
haxises[i_axis].name = axis->getName();
if( axis->getSize() == 0) {
throw LogicErrorException("IsGISAXSTools::getOutputDataTH123D() -> Error! Axis with zero size.");
}else if( axis->getSize() == 1 ) {
// only one bin, let's invent fake bin size
dx = 0.1*(*axis)[0];
haxises[i_axis].xbins.push_back((*axis)[0]-dx/2.);
haxises[i_axis].xbins.push_back((*axis)[0]+dx/2.);
}else {
for(size_t i_bin=0; i_bin<axis->getSize(); ++i_bin) {
if(i_bin == 0) {
dx = (*axis)[1]-(*axis)[0];
} else {
dx = (*axis)[i_bin] - (*axis)[i_bin-1];
}
haxises[i_axis].xbins.push_back( (*axis)[i_bin] - dx/2.);
pospelov
committed
haxises[i_axis].xbins.push_back((*axis)[axis->getSize()-1] + dx/2.); // right bin edge of last bin, so for 100 bins size of vector will be 101
pospelov
committed
// creation of 2D with variable bin size
// std::cout << "XXXYYY " << (int)haxises[0].nbins << " " << (int)haxises[1].nbins;
// for(size_t i=0; i<haxises[0].xbins.size(); ++i) {
// std::cout << i << " axis0:" << haxises[0].xbins[i] << std::endl;
// }
// for(size_t i=0; i<haxises[1].xbins.size(); ++i) {
// std::cout << i << " axis1:" << haxises[1].xbins[i] << std::endl;
// }
TH2D *hist2 = new TH2D(histo_name.c_str(), histo_name.c_str(), (int)haxises[0].nbins, &haxises[0].xbins[0], (int)haxises[1].nbins, &haxises[1].xbins[0]);
pospelov
committed
hist2->GetXaxis()->SetTitle( haxises[0].name.c_str() );
hist2->GetYaxis()->SetTitle( haxises[1].name.c_str() );
OutputData<double>::const_iterator it = output.begin();
while (it != output.end())
pospelov
committed
double x = output.getValueOfAxis( haxises[0].name.c_str(), it.getIndex() );
double y = output.getValueOfAxis( haxises[1].name.c_str(), it.getIndex() );
pospelov
committed
double value = *it++;
hist2->Fill(x, y, value);
pospelov
committed
hist2->SetContour(50);
hist2->SetStats(0);
hist2->GetYaxis()->SetTitleOffset(1.1);
gStyle->SetPalette(1);
gStyle->SetOptStat(0);
pospelov
committed
return hist2;
pospelov
committed
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/* ************************************************************************* */
// create TH2D from OutputData
/* ************************************************************************* */
//TH2D *IsGISAXSTools::getOutputDataTH2D(const OutputData<double>& output, const std::string &histo_name)
//{
// assert(&output);
// if (output.getNdimensions() !=2) throw( "IsGISAXSTools::getOutputDataTH2D() -> Warning! Expected number of dimensiobs is 2.");
// std::vector<AxisStructure > haxises;
// haxises.resize(output.getNdimensions());
// // we assume variable bin size and prepare [nbins+1] array of left edges of each bin plus right edge of the last bin
// for(size_t i_axis=0; i_axis<output.getNdimensions(); ++i_axis) {
// const IAxis *axis = output.getAxis(i_axis);
// if( !axis ) throw("IsGISAXSTools::getOutputDataTH123D() -> Error! Can't cast axis");
// double dx(0);
// haxises[i_axis].nbins = axis->getSize();
// haxises[i_axis].name = axis->getName();
// if( axis->getSize() == 0) {
// throw LogicErrorException("IsGISAXSTools::getOutputDataTH123D() -> Error! Axis with zero size.");
// }else if( axis->getSize() == 1 ) {
// // only one bin, let's invent fake bin size
// dx = 0.1*(*axis)[0];
// haxises[i_axis].xbins.push_back((*axis)[0]-dx/2.);
// haxises[i_axis].xbins.push_back((*axis)[0]+dx/2.);
// }else {
// for(size_t i_bin=0; i_bin<axis->getSize(); ++i_bin) {
// if(i_bin == 0) {
// dx = (*axis)[1]-(*axis)[0];
// } else {
// dx = (*axis)[i_bin] - (*axis)[i_bin-1];
// }
// haxises[i_axis].xbins.push_back( (*axis)[i_bin] - dx/2.);
// }
// haxises[i_axis].xbins.push_back((*axis)[axis->getSize()-1] + dx/2.); // right bin edge of last bin, so for 100 bins size of vector will be 101
// }
// }
// // creation of 2D with variable bin size
// std::cout << "XXXYYY " << (int)haxises[0].nbins << " " << (int)haxises[1].nbins;
// for(size_t i=0; i<haxises[0].xbins.size(); ++i) {
// std::cout << i << " axis0:" << haxises[0].xbins[i] << std::endl;
// }
// for(size_t i=0; i<haxises[1].xbins.size(); ++i) {
// std::cout << i << " axis1:" << haxises[1].xbins[i] << std::endl;
// }
// TH2D *hist2 = new TH2D(histo_name.c_str(), histo_name.c_str(), (int)haxises[0].nbins, &haxises[0].xbins[0], (int)haxises[1].nbins, &haxises[1].xbins[0]);
// hist2->GetXaxis()->SetTitle( haxises[0].name.c_str() );
// hist2->GetYaxis()->SetTitle( haxises[1].name.c_str() );
// OutputData<double>::const_iterator it = output.begin();
// while (it != output.end())
// {
// double x = output.getValueOfAxis( haxises[0].name.c_str(), it.getIndex() );
// double y = output.getValueOfAxis( haxises[1].name.c_str(), it.getIndex() );
// double value = *it++;
// //std::cout << "OOO " << x << " " << y << std::endl;
// hist2->Fill(x, y, value);
// }
// hist2->SetContour(50);
// hist2->SetStats(0);
// hist2->GetYaxis()->SetTitleOffset(1.1);
// gStyle->SetPalette(1);
// gStyle->SetOptStat(0);
// return hist2;
//}
pospelov
committed
/* ************************************************************************* */
// create TH1D, TH2D or TH3D from OutputData
/* ************************************************************************* */
TH1 *IsGISAXSTools::getOutputDataTH123D(const OutputData<double>& output, const std::string& histo_name)
pospelov
committed
{
assert(&output);
pospelov
committed
std::cout << "IsGISAXSTools::getOutputDataTH123D() -> Warning! Expected number of dimensions should be not more than 3" << std::endl;
return 0;
}
std::vector<AxisStructure > haxises;
pospelov
committed
pospelov
committed
// we assume variable bin size and prepare [nbins+1] array of left edges of each bin plus right edge of the last bin
for(size_t i_axis=0; i_axis<output.getRank(); ++i_axis) {
Van Herck, Walter
committed
const IAxis *axis = output.getAxis(i_axis);
pospelov
committed
if( !axis ) throw("IsGISAXSTools::getOutputDataTH123D() -> Error! Can't cast axis");
pospelov
committed
double dx(0);
haxises[i_axis].nbins = axis->getSize();
haxises[i_axis].name = axis->getName();
pospelov
committed
if( axis->getSize() == 0) {
throw LogicErrorException("IsGISAXSTools::getOutputDataTH123D() -> Error! Axis with zero size.");
}else if( axis->getSize() == 1 ) {
// only one bin, let's invent fake bin size
dx = 0.1*(*axis)[0];
haxises[i_axis].xbins.push_back((*axis)[0]-dx/2.);
haxises[i_axis].xbins.push_back((*axis)[0]+dx/2.);
}else {
for(size_t i_bin=0; i_bin<axis->getSize(); ++i_bin) {
if(i_bin == 0) {
dx = (*axis)[1]-(*axis)[0];
} else {
dx = (*axis)[i_bin] - (*axis)[i_bin-1];
}
haxises[i_axis].xbins.push_back( (*axis)[i_bin] - dx/2.);
pospelov
committed
}
haxises[i_axis].xbins.push_back((*axis)[axis->getSize()-1] + dx/2.); // right bin edge of last bin, so for 100 bins size of vector will be 101
pospelov
committed
}
pospelov
committed
}
pospelov
committed
// for(size_t i_axis=0; i_axis<output.getNdimensions(); ++i_axis) {
// std::cout << "axis " << i_axis << " size:" << haxises[i_axis].xbins.size() << std::endl;
// for(size_t i_bin=0; i_bin<haxises[i_axis].xbins.size(); ++i_bin) {
// std::cout << haxises[i_axis].xbins[i_bin] << " ";
// }
// std::cout << std::endl;
pospelov
committed
// }
pospelov
committed
// creation of 1D, 2D or 3D histogram with variable bin size
pospelov
committed
TH1 *hist(0);
TH1D *hist1(0);
TH2D *hist2(0);
TH3D *hist3(0);
hist1 = new TH1D(histo_name.c_str(), histo_name.c_str(), (int)haxises[0].nbins, &haxises[0].xbins[0]);
pospelov
committed
hist1->GetXaxis()->SetTitle( haxises[0].name.c_str() );
hist = hist1;
hist2 = new TH2D(histo_name.c_str(), histo_name.c_str(), (int)haxises[0].nbins, &haxises[0].xbins[0], (int)haxises[1].nbins, &haxises[1].xbins[0]);
pospelov
committed
hist2->GetXaxis()->SetTitle( haxises[0].name.c_str() );
hist2->GetYaxis()->SetTitle( haxises[1].name.c_str() );
hist = hist2;
hist3 = new TH3D(histo_name.c_str(), histo_name.c_str(), (int)haxises[0].nbins, &haxises[0].xbins[0], (int)haxises[1].nbins, &haxises[1].xbins[0], (int)haxises[1].nbins, &haxises[1].xbins[0]);
pospelov
committed
hist3->GetXaxis()->SetTitle( haxises[0].name.c_str() );
hist3->GetYaxis()->SetTitle( haxises[1].name.c_str() );
hist3->GetZaxis()->SetTitle( haxises[2].name.c_str() );
hist = hist3;
pospelov
committed
} else {
pospelov
committed
throw LogicErrorException("IsGISAXSTools::getOutputDataTH123D() -> Error! Wrong number of dimensions.");
pospelov
committed
}
OutputData<double>::const_iterator it = output.begin();
while (it != output.end())
{
std::vector<double > xyz;
for(size_t i_axis=0; i_axis<haxises.size(); ++i_axis) {
pospelov
committed
xyz.push_back(output.getValueOfAxis( haxises[i_axis].name.c_str(), it.getIndex() ) );
pospelov
committed
}
double value = *it++;
pospelov
committed
if(hist1) hist1->Fill(xyz[0], value);
if(hist2) hist2->Fill(xyz[0], xyz[1], value);
if(hist3) hist3->Fill(xyz[0], xyz[1], xyz[2], value);
pospelov
committed
}
hist->SetContour(50);
hist->SetStats(0);
hist->GetYaxis()->SetTitleOffset(1.1);
gStyle->SetPalette(1);
gStyle->SetOptStat(0);
return hist;
}
/* ************************************************************************* */
// draw 1D distribution over values stored in OutputData
// binning of histogram is calculated on the fly
/* ************************************************************************* */
void IsGISAXSTools::drawOutputDataDistribution1D(const OutputData<double>& output, const std::string& draw_options, const std::string& histogram_title)
if(!gPad) {
throw NullPointerException("IsGISAXSTools::drawOutputDataDistribution1D() -> Error! No canvas exists.");
}
std::string histo_name = histogram_title;
if (histo_name.empty()) {
histo_name = gPad->GetTitle();
}
// creating histogram with automatic binning
TH1::SetDefaultBufferSize(5000);
TH1D h1_spect("h1_spect", histo_name.c_str(), 200, 1.0, -1.0); // xmin > xmax as a sign of automatic binning
OutputData<double>::const_iterator it = output.begin();
while (it != output.end())
}
h1_spect.DrawCopy(draw_options.c_str());
}
/* ************************************************************************* */
// draw 1D distribution over relative difference in two OutputData sets
/* ************************************************************************* */
void IsGISAXSTools::drawOutputDataDifference1D(const OutputData<double>& left, const OutputData<double>& right, const std::string& draw_options, const std::string& histogram_title)
assert(&left);
assert(&right);
if(!gPad) {
throw NullPointerException("IsGISAXSTools::drawOutputDataDifference1D() -> Error! No canvas exists.");
}
OutputData<double> *left_clone = left.clone();
OutputData<double> *right_clone = right.clone();
*left_clone -= *right_clone;
*left_clone /= *right_clone;
std::string histo_name = histogram_title;
if (histo_name.empty()) {
histo_name = gPad->GetTitle();
}
TH1D h1_spect("difference", histo_name.c_str(), 40, -20.0, 20.0);
h1_spect.GetXaxis()->SetTitle("log10( (we-isgi)/isgi )");
OutputData<double>::const_iterator it = left_clone->begin();
while (it != left_clone->end())
if(x!=0) {
x = log10(fabs(x));
} else {
// lets put the cases when the difference is exactly 0 to underflow bin
x = -21.;
}
gPad->SetRightMargin(0.115);
gPad->SetLeftMargin(0.115);
h1_spect.SetStats(1);
gStyle->SetOptStat(111111);
if( hasMinimum() ) h1_spect.SetMinimum(m_hist_min);
if( hasMaximum() ) h1_spect.SetMaximum(m_hist_max);
h1_spect.DrawCopy(draw_options.c_str());
delete left_clone;
delete right_clone;
}
/* ************************************************************************* */
// draw relative difference of two 2D OutputData sets
/* ************************************************************************* */
void IsGISAXSTools::drawOutputDataRelativeDifference2D(const OutputData<double>& left, const OutputData<double>& right, const std::string& draw_options, const std::string& histogram_title)
assert(&left);
assert(&right);
if(!gPad) {
throw NullPointerException("IsGISAXSTools::drawOutputDataDifference2D -> Error! No canvas exists.");
}
OutputData<double> *left_clone = left.clone();
OutputData<double> *right_clone = right.clone();
*left_clone -= *right_clone;
*left_clone /= *right_clone;
left_clone->scaleAll(100.0);
IsGISAXSTools::drawOutputDataInPad(*left_clone, draw_options, histogram_title);
delete left_clone;
delete right_clone;
}
/* ************************************************************************* */
// draw relative chi2 difference of two 2D OutputData sets
/* ************************************************************************* */
void IsGISAXSTools::drawOutputDataChi2Difference2D(const OutputData<double>& left, const OutputData<double>& right, const std::string& draw_options, const std::string& histogram_title)
{
assert(&left);
assert(&right);
if(!gPad) {
throw NullPointerException("IsGISAXSTools::drawOutputDataDifference2D -> Error! No canvas exists.");
}
OutputData<double> *left_clone = left.clone();
OutputData<double> *right_clone = right.clone();
*left_clone -= *right_clone;
OutputData<double> *tmp = left_clone->clone();
*left_clone *= *tmp;
left_clone->scaleAll(1./left_clone->totalSum());
IsGISAXSTools::drawOutputDataInPad(*left_clone, draw_options, histogram_title);
delete left_clone;
delete right_clone;
delete tmp;
}
void IsGISAXSTools::exportOutputDataInVectors2D(const OutputData<double>& input_data
, std::vector<std::vector<double > >& v_data
, std::vector<std::vector<double > >& v_axis0
, std::vector<std::vector<double > >& v_axis1)
assert(&input_data);
if (input_data.getRank() != 2) return;
OutputData<double> *data = input_data.clone();
const IAxis *p_axis0 = data->getAxis(0);
const IAxis *p_axis1 = data->getAxis(1);
size_t axis0_size = p_axis0->getSize();
size_t axis1_size = p_axis1->getSize();
v_data.clear();
v_axis0.clear();
v_axis1.clear();
v_data.resize(axis0_size);
v_axis0.resize(axis0_size);
v_axis1.resize(axis0_size);
for(size_t i=0; i<axis0_size; ++i) {
v_data[i].resize(axis1_size,0.0);
v_axis0[i].resize(axis1_size,0.0);
v_axis1[i].resize(axis1_size,0.0);
}
// saving data
OutputData<double>::const_iterator it = data->begin();
while (it != data->end())
size_t axis0_index = data->toCoordinates(it.getIndex())[0];
size_t axis1_index = data->toCoordinates(it.getIndex())[1];
v_data[axis0_index][axis1_index] = intensity;
}
// saving axis
data->removeAllMasks();
it = data->begin();
while (it != data->end())
{
size_t axis0_index = data->toCoordinates(it.getIndex())[0];
size_t axis1_index = data->toCoordinates(it.getIndex())[1];
double axis0_value = (*p_axis0)[axis0_index];
double axis1_value = (*p_axis1)[axis1_index];
v_axis0[axis0_index][axis1_index] = axis0_value;
v_axis1[axis0_index][axis1_index] = axis1_value;
/* ************************************************************************* */
// Create TLine for displaying of one-dimensional data scan
// OutputData should be 2D, and one of two dimensions should have number of bins == 1
/* ************************************************************************* */
TLine *IsGISAXSTools::getOutputDataScanLine(const OutputData<double>& data)
assert(&data);
if(data.getRank() != 2) throw LogicErrorException("IsGISAXSTools::getOutputDataScanLine() -> Error! Number of dimensions should be 2");
if( data.getAxis(BA::ALPHA_AXIS_NAME) && data.getAxis(BA::ALPHA_AXIS_NAME)->getSize() == 1) {
x1 = data.getAxis(BA::PHI_AXIS_NAME)->getMin();
x2 = data.getAxis(BA::PHI_AXIS_NAME)->getMax();
y1 = y2 = data.getAxis(BA::ALPHA_AXIS_NAME)->getMin();
}else if( data.getAxis(BA::PHI_AXIS_NAME) && data.getAxis(BA::PHI_AXIS_NAME)->getSize() == 1 ) {
x1 = x2 = data.getAxis(BA::PHI_AXIS_NAME)->getMin();
y1 = data.getAxis(BA::ALPHA_AXIS_NAME)->getMin();
y2 = data.getAxis(BA::ALPHA_AXIS_NAME)->getMax();
} else {
throw LogicErrorException("IsGISAXSTools::getOutputDataScanLine() -> Error! Can't handle these axes.");
}
TLine *line = new TLine(x1,y1,x2,y2);
line->SetLineColor(kRed);
line->SetLineStyle(1);
line->SetLineWidth(2);
return line;
}
/* ************************************************************************* */
// Create TH1D for displaying of one-dimensional data scan
// OutputData should be 2D, and one of two dimensions should have number of bins == 1
/* ************************************************************************* */
TH1D *IsGISAXSTools::getOutputDataScanHist(const OutputData<double>& data, const std::string& hname)
assert(&data);
if(data.getRank() != 2) throw LogicErrorException("IsGISAXSTools::getOutputDataScanHist() -> Error! Number of dimensions should be 2");
pospelov
committed
// one of axis should have dimension 1
if( (data.getAxis(BA::ALPHA_AXIS_NAME) && data.getAxis(BA::ALPHA_AXIS_NAME)->getSize() != 1) && (data.getAxis(BA::PHI_AXIS_NAME) && data.getAxis(BA::PHI_AXIS_NAME)->getSize() != 1))
pospelov
committed
throw LogicErrorException("IsGISAXSTools::getOutputDataScanHist() -> Info. Can't create 1D histogram from these axes");
//std::cout << "IsGISAXSTools::getOutputDataScanHist() -> Info. Can't create 1D histogram from these axes" << std::endl;
//return 0;
pospelov
committed
TH2D *hist2 = IsGISAXSTools::getOutputDataTH2D( data, hname);
pospelov
committed
std::ostringstream ostr_title;
if( data.getAxis(BA::ALPHA_AXIS_NAME) && data.getAxis(BA::ALPHA_AXIS_NAME)->getSize() == 1) {
pospelov
committed
hist1 = hist2->ProjectionX();
ostr_title << hname << ", alpha_f=" << data.getAxis(BA::ALPHA_AXIS_NAME)->getMin();
}else if( data.getAxis(BA::PHI_AXIS_NAME) && data.getAxis(BA::PHI_AXIS_NAME)->getSize() == 1 ) {
pospelov
committed
hist1 = hist2->ProjectionY();
ostr_title << hname << ", phi_f=" << data.getAxis(BA::PHI_AXIS_NAME)->getMin();
} else {
throw LogicErrorException("IsGISAXSTools::getOutputDataScanHist() -> Error! Unexpected place");
}
delete hist2;
pospelov
committed
if( !hist1 ) throw LogicErrorException("IsGISAXSTools::getOutputDataScanHist() -> Error! Failed to make projection, existing name?");
hist1->SetTitle(ostr_title.str().c_str());
Van Herck, Walter
committed
// FIXME remove this trick to bypass weird bug with DrawCopy of TH1D projection of TH1D histograms
TH1D *h1 = dynamic_cast<TH1D*>(hist1->Clone());
pospelov
committed
delete hist1;
return h1;
/* ************************************************************************* */
// add noise to data
/* ************************************************************************* */
OutputData<double > *IsGISAXSTools::createNoisyData(const OutputData<double>& exact_data, double noise_factor)
assert(&exact_data);
OutputData<double > *real_data = exact_data.clone();
OutputData<double>::iterator it = real_data->begin();
while (it != real_data->end()) {
double current = *it;
double sigma = noise_factor*std::sqrt(current);
double random = MathFunctions::GenerateNormalRandom(current, sigma);
if (random<0.0) random = 0.0;
*it = random;
++it;
}
return real_data;
}
OutputData<double > *IsGISAXSTools::createDataWithGaussianNoise(const OutputData<double>& exact_data, double sigma)
assert(&exact_data);
OutputData<double > *real_data = exact_data.clone();
OutputData<double>::iterator it = real_data->begin();
while (it != real_data->end()) {
double current = *it;
double random = MathFunctions::GenerateNormalRandom(0.0, sigma);
*it = current+random;
++it;
}
return real_data;
}
void IsGISAXSTools::drawOutputDataComparisonResults(
const OutputData<double>& data, const OutputData<double>& reference,
const std::string& name, const std::string& title, double hmin,
double hmax, double hdiff)
pospelov
committed
{
assert(&data);
assert(&reference);
TCanvas *c1 = DrawHelper::createAndRegisterCanvas(name, title);
pospelov
committed
c1->Divide(2,2);
// our calculations
c1->cd(1); gPad->SetLogz();
gPad->SetRightMargin(0.12);
Ganeva, Marina
committed
if(hasMinimum()) IsGISAXSTools::setMinimum(hmin);
//if(hmax>0) IsGISAXSTools::setMaximum(hmax);
if(hasMaximum()) IsGISAXSTools::setMaximum(hmax);
pospelov
committed
IsGISAXSTools::drawOutputDataInPad(data, "CONT4 Z", "this");
// isgisaxs data
c1->cd(2); gPad->SetLogz();
gPad->SetRightMargin(0.12);
IsGISAXSTools::drawOutputDataInPad(reference, "CONT4 Z", "isgi");
// difference
c1->cd(3);
gPad->SetRightMargin(0.12);
IsGISAXSTools::setMinimum(-hdiff);
IsGISAXSTools::setMaximum(hdiff);
IsGISAXSTools::drawOutputDataRelativeDifference2D(data, reference,
"CONT4 Z", "2D Difference map");
pospelov
committed
// difference
c1->cd(4);
gPad->SetRightMargin(0.12);
IsGISAXSTools::resetMinimumAndMaximum();
IsGISAXSTools::setMinimum(1);
IsGISAXSTools::drawOutputDataDifference1D(data, reference, "",
"Difference spectra");
pospelov
committed
}
void IsGISAXSTools::copyElementsWithPosition(
const OutputData<Eigen::Matrix2d>& source,
OutputData<double>& destination, int pos_x, int pos_y)
{
OutputData<Eigen::Matrix2d>::const_iterator it_source =
source.begin();
OutputData<double>::iterator it_dest = destination.begin();
while (it_source != source.end()) {
*it_dest = (*it_source)(pos_x, pos_y);
it_source++;
it_dest++;
}
}