add the option to dump the nonlocal field values for the ASlibs via the programm dump_nonlocal_field.

This commit is contained in:
suter_a 2021-08-18 16:57:29 +02:00
parent c6c7deec9c
commit 4a2d865282
4 changed files with 322 additions and 0 deletions

View File

@ -1,5 +1,7 @@
# - Nonlocal library ----------------------------------------------------------
add_subdirectory(prog)
#--- generate necessary dictionaries ------------------------------------------
set(MUSRFIT_INC ${CMAKE_SOURCE_DIR}/src/include)
set(NONLOCAL_INC ${CMAKE_SOURCE_DIR}/src/external/Nonlocal)

View File

@ -0,0 +1,4 @@
// dnlf_config.h
#define PROJECT_VERSION "@PROJECT_VERSION@"

View File

@ -0,0 +1,30 @@
#--- dump_nonlocal_field ------------------------------------------------------
project(dump_nonlocal_field VERSION 1.0.0 LANGUAGES C CXX)
#--- feed dnlf_config.h -----------------------------------------
set(HAVE_DNLF_CONFIG_H 1 CACHE INTERNAL "dnlf_config.h is available")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/dnlf_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/dnlf_config.h)
add_executable(dump_nonlocal_field ${GIT_REV_H} dump_nonlocal_field.cpp)
target_compile_options(dump_nonlocal_field BEFORE PRIVATE "-DHAVE_CONFIG_H" "-DHAVE_DNLF_CONFIG_H" "${HAVE_GIT_REV_H}")
target_include_directories(dump_nonlocal_field
BEFORE PRIVATE
$<BUILD_INTERFACE:${Boost_INCLUDE_DIR}>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/..>
)
target_link_libraries(dump_nonlocal_field ${ROOT_LIBRARIES} ${MUSRFIT_LIBS} PNL_PippardFitter)
#--- installation info --------------------------------------------------------
install(
TARGETS
dump_nonlocal_field
RUNTIME DESTINATION
bin
)

View File

@ -0,0 +1,286 @@
/***************************************************************************
dump_nonlocal_field.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
***************************************************************************/
/***************************************************************************
* Copyright (C) 2009-2021 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <cstring>
#include <boost/algorithm/string.hpp>
#include "PNL_PippardFitter.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_DNLF_CONFIG_H
#include "dnlf_config.h"
#endif
#ifdef HAVE_GIT_REV_H
#include "git-revision.h"
#endif
void dnlf_syntax()
{
std::cout << std::endl;
std::cout << "usage: dump_nonlocal_field [<msr-file> --out <field-dump> [--step <stepVal>] | --version | --help]" << std::endl;
std::cout << " <msr-file> : nonlocal msr-file name." << std::endl;
std::cout << " --out <field-dump> : ascii field dump output file name." << std::endl;
std::cout << " --step <stepVal> : this optional parameters allows to define the z-value step size in (nm)." << std::endl;
std::cout << " --version : dumps the version" << std::endl;
std::cout << " --help : will dump this help" << std::endl;
std::cout << std::endl << std::endl;
}
bool dnlf_read_msr(const std::string fln, std::vector<double> &param)
{
std::ifstream fin(fln.c_str(), std::ifstream::in);
if (!fin.is_open()) {
std::cerr << std::endl;
std::cerr << "**ERROR** couldn't open msr-file: " << fln << std::endl;
std::cerr << std::endl;
return false;
}
std::vector<std::string> msrData;
std::string line;
while (fin.good()) {
std::getline(fin, line);
msrData.push_back(line);
}
fin.close();
// find userFcn line
line = "";
for (int i=0; i<msrData.size(); i++) {
if (msrData[i].find("userFcn") != std::string::npos) {
line = msrData[i];
if (line.find("PNL_PippardFitter") != std::string::npos)
break;
line = "";
}
}
if (line.empty()) {
std::cerr << std::endl;
std::cerr << "**ERROR** msr-file: " << fln << " seems not a proper nonlocal fit file." << std::endl;
std::cerr << std::endl;
return false;
}
// tokenize parameter part.
size_t pos=0;
pos = line.find(" PNL_PippardFitter");
line = line.substr(pos+18); // remove the 'userFcn libPNL_PippardFitter PNL_PippardFitter' part
boost::algorithm::trim(line); // remove leading/trailing whitespaces
std::vector<std::string> tok;
boost::split(tok, line, boost::is_any_of(" \t"), boost::token_compress_on);
std::vector<int> paramIdx;
int ival;
for (int i=0; i<tok.size(); i++) {
try {
ival = std::stoi(tok[i]);
}
catch(std::exception& e) {
ival = 0;
}
paramIdx.push_back(ival);
}
// find parameter value which corresponds to param index
bool inFitParamBlock(false);
std::map<int, double> paramMap;
double dval;
for (int i=0; i<msrData.size(); i++) {
if (inFitParamBlock) {
if (msrData[i].empty()) {
continue;
} else if (msrData[i][0] == '#') {
continue;
} else if (msrData[i].find("THEORY") != std::string::npos) {
inFitParamBlock = false;
break;
} else {
tok.clear();
line = msrData[i];
boost::algorithm::trim(line); // remove leading/trailing whitespaces
boost::split(tok, line, boost::is_any_of(" \t"), boost::token_compress_on);
if (tok.size() < 3) {
std::cerr << "**ERROR** bug in the fit parameter block!" << std::endl;
std::cerr << "'" << msrData[i] << "'" << std::endl;
return false;
}
// param index
try {
ival = std::stoi(tok[0]);
}
catch(std::exception& e) {
ival = 0;
}
// param value
try {
dval = std::stod(tok[2]);
}
catch(std::exception& e) {
dval = 0.0;
}
paramMap[ival] = dval;
}
} else {
if (msrData[i].find("FITPARAMETER") != std::string::npos) {
inFitParamBlock = true;
}
}
}
for (int i=0; i<paramIdx.size(); i++) {
if (paramIdx[i] != 0)
dval = paramMap.find(paramIdx[i])->second;
else
dval = 0.0;
param.push_back(dval);
}
return true;
}
int main(int argc, char* argv[])
{
std::string msrFileName("");
std::string outFileName("");
double step(0.0);
bool show_syntax(false);
if (argc == 1) {
dnlf_syntax();
return 0;
}
for (int i=0; i<argc; i++) {
if (argv[i][0] != '-') { // must be the msr-file name
msrFileName = argv[i];
} else if (!strcmp(argv[i], "--version")) {
#ifdef HAVE_CONFIG_H
#ifdef HAVE_GIT_REV_H
std::cout << std::endl << "dump_nonlocal_field version: " << PROJECT_VERSION << " (" << PACKAGE_VERSION << "), git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
#else
std::cout << std::endl << "dump_nonlocal_field version: " << PROJECT_VERSION << " (" << PACKAGE_VERSION << "/" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
#endif
#else
#ifdef HAVE_GIT_REV_H
std::cout << std::endl << "dump_nonlocal_field git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
#else
std::cout << std::endl << "dump_nonlocal_field version: unknown" << std::endl << std::endl;
#endif
#endif
return 0;
} else if (!strcmp(argv[i], "--help")) {
dnlf_syntax();
return 0;
} else if (!strcmp(argv[i], "--out")) {
if (i < argc-1) {
outFileName = argv[i+1];
i++;
} else {
std::cerr << std::endl << "dump_nonlocal_field: **ERROR** found option --out without <field-dump>" << std::endl;
show_syntax = true;
break;
}
} else if (!strcmp(argv[i], "--step")) {
if (i < argc-1) {
try {
step = std::stod(argv[i+1]);
}
catch(std::exception& e) {
std::cout << "dump_nonlocal_field: **ERROR** <stepVal> '" << argv[i+1] << "' seems not to be a double." << std::endl;
show_syntax = true;
break;
}
i++;
} else {
std::cerr << std::endl << "dump_nonlocal_field: **ERROR** found option --step without <stepVal>" << std::endl;
show_syntax = true;
break;
}
}
}
if (show_syntax) {
dnlf_syntax();
return -1;
}
std::vector<double> param;
if (!dnlf_read_msr(msrFileName, param)) {
return -2;
}
// calculate field and write it to file
PNL_PippardFitterGlobal pip;
pip.CalculateField(param);
std::ofstream fout(outFileName.c_str(), std::ofstream::out);
if (!fout.is_open()) {
std::cout << std::endl;
std::cerr << "**ERROR** can not write to file '" << outFileName << "'." << std::endl;
std::cout << std::endl;
return -3;
}
// write header
fout << "% z (nm), field (G)" << std::endl;
// write data
double z=0.0;
if (step == 0.0)
step = 0.1;
double prevField=0.0, field=0.0;
bool done(false);
double deadLayer = param[8];
double b0 = param[6];
do {
if (z < deadLayer) {
fout << z << ", " << b0 << std::endl;
} else {
field = pip.GetMagneticField(z-deadLayer);
fout << z << ", " << b0*field << std::endl;
if (fabs(prevField-field) < 1.0e-10)
done = true;
prevField = field;
}
z += step;
} while (!done);
fout.close();
return 0;
}