diff --git a/.gitignore b/.gitignore index 1d210680..05d93abd 100644 --- a/.gitignore +++ b/.gitignore @@ -15,11 +15,13 @@ *Copy*.cpp MULTEM_binary MULTEM_binary.rar +MULTEM_binary.zip compile_mex_general.m mex_examples_general mex_files_general visual_studio_multem src_temporal +mex_test design build-multem-Desktop_Qt_5_9_0_MSVC2015_64bit-Debug build-multem-Desktop_Qt_5_9_0_MSVC2015_64bit-Release diff --git a/README.md b/README.md index 93fe2c3e..c7d481c0 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Introduction ============ -**MULTEM** is a collection of routines written in C++ with CUDA to perform accurate and fast multislice simulations for different TEM experiments as: HRTEM, STEM, ISTEM, ED, PED, CBED, ADF-TEM, ABF-HC, EFTEM and EELS. +**MULTEM** is a collection of routines written in C++ with CUDA to perform accurate and fast multislice simulations for different TEM experiments as: HRTEM, STEM, ISTEM, ED, PED, CBED, ADF-TEM, ABF-HC, EFTEM and EELS. It is developed by Ivan Lobato (Ivanlh20@gmail.com). Currently, there are three supported ways to use MULTEM: - C++: using the library itself @@ -15,9 +15,9 @@ The Matlab interface is the recommended way for researchers. Remarks ================================= -In order to use the GPU capability of MULTEM, you need a Nvidia Graphic card with **compute capability greater than 2.0** and **CUDA 8.0** installed in your operating system. You can check the compute capability of your graphic card using the following [nvidia website](https://developer.nvidia.com/cuda-gpus) +In order to use the GPU capability of MULTEM, you need a Nvidia Graphic card with **compute capability greater than 2.0** and **CUDA 8.0** installed in your operating system. You can check the compute capability of your graphic card using the following nvidia website: https://developer.nvidia.com/cuda-gpus. -Using GUI interface +Using precompile GUI interface ================================= The precompile GUI interface is only available for Windows operating system. @@ -34,18 +34,70 @@ The precompile mexfiles are only available for Windows operating system. - Add to the Matlab path the following folders: crystalline_materials, matlab_functions and mex_bin. - Run the examples located in 'mex_examples_multem'. -Compiling MULTEM for Matlab +Building MULTEM for Matlab ================================= -The following steps work using Matlab R2017a and CUDA 8.0. It assumes that Visual studio 2015, g++4.9 or Clang compiler is installed in your operating system: +The following steps work using Matlab R2017a and CUDA 8.0. It assumes that Visual studio 2015 professional, g++4.9 or Clang(Xcode 8.x) compiler is installed in your operating system. Additionally, Multem also requires fftw3, blas and lapack libraries. -- First of all, you have to add to the Matlab path the following folders: crystalline_materials, matlab_functions and mex_bin. +- First of all, you have to set a C++ compiler to Matlab by executing the following comand: `mex -setup cpp`. Be aware that Matlab 2017a only support the above compilers. +- Then add to the Matlab path the following folders: crystalline_materials, matlab_functions and mex_bin. +- Run the `compile_mex_multem.m` script. This will create the required executable files to run the examples. +- Run the examples located in `mex_examples_multem`. -- Then you need to modify the `mex_CUDA_xxxx` file located in the `mex_files_multem` folder, which corresponds to your operating system: - 1. for Windows `mex_CUDA_win64` - 2. for Linux `mex_CUDA_glnxa64` - 3. for Mac `mex_CUDA_maci64` +Troubleshooting +================================= +- If MULTEM do not compile with the above procedures, one of the following procedures might fix it -- Go to the line which contains the following definition`NVCCFLAGS="$xxxxx ..."` and replace 'xxxxx' by 'SINGLE_CARD' or 'MULTI_CARD'. 'SINGLE_CARD'/'MULTI_CARD' defines the compute capability of your graphic card. + **for Windows:** + + - Verify the installation of Visual studio 2015 professional. + - Verify the installation of Cuda 8.0 (https://developer.nvidia.com/cuda-downloads). + + **for Linux:** + + - Verify that gcc-4.9 and g++4.9 are the default compilers installed in your operating system. In Ubuntu, it can be installed by executing the following commands: + + * `sudo add-apt-repository ppa:ubuntu-toolchain-r/test` + * `sudo apt-get update` + * `sudo apt-get install gcc-4.9 g++-4.9` + * `sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9` -- Run the `compile_mex_multem.m` script. This will create the required executable files to run the examples. -- Run the examples located in 'mex_examples_multem'. + - Verify the correct installation of Cuda 8.0 (https://developer.nvidia.com/cuda-downloads). + + - Verify the installation of fftw3 libraries. In Ubuntu, it can be installed by executing the following command: + * `sudo apt-get install libfftw3-dev libfftw3-doc` + + - Verify the installation of blas and lapack libraries. In Ubuntu, it can be installed by executing the following command: + * `sudo apt-get install libblas-dev liblapack-dev` + +- Verify the intallation path of cuda 8.0, fftw3, blas and lapack. Their installation path should be specified in the `MEX.m` file located at `matlab_functions`. + +**Please cite MULTEM in your publications if it helps your research:** + + @article{LVAV16_1, + Author = {I.Lobato and S.Van Aert and J.Verbeeck}, + Journal = {Ultramicroscopy}, + Title = {Progress and new advances in simulating electron microscopy datasets using MULTEM}, + Year = {2016}, + volume = {168}, + pages = {17-27} + } + + @article{LD15_2, + Author = {I. Lobato and D. Van Dyck}, + Journal = {Ultramicroscopy}, + Title = {MULTEM: A new multislice program to perform accurate and fast electron diffraction and imaging simulations using Graphics Processing Units with CUDA}, + Year = {2015}, + volume = {156}, + pages = {9-17} + } + +**if you use our parameterization of the electronscattering factors, please cite the following article:** + + @Article{LD14_1, + Title = {{An accurate parameterization for the scattering factors, electron densities and electrostatic potentials for neutral atoms that obey all physical constraints}}, + Author = {I. Lobato and D. Van Dyck}, + Journal = {Acta Crystallographica Section A}, + Year = {2014}, + Pages = {636-649}, + Volume = {70} + } \ No newline at end of file diff --git a/compile_mex_multem.m b/compile_mex_multem.m index bb4ce293..e7f4a0aa 100644 --- a/compile_mex_multem.m +++ b/compile_mex_multem.m @@ -1,34 +1,55 @@ addpath([ pwd '/matlab_functions']) -files = {'mex_lambda',... - 'mex_sigma',... - 'mex_gamma',... - 'mex_fxeg_tabulated_data',... - 'mex_feg',... - 'mex_fxg',... - 'mex_Pr',... - 'mex_Vz',... - 'mex_Vr',... - 'mex_Vp',... - 'mex_mrad_2_rAngs',... - 'mex_scherzer_defocus',... - 'mex_scherzer_aperture',... - 'mex_crystal_by_lays',... - 'mex_rdf_3d',... - 'mex_amorp_spec',... - 'mex_add_amorp_lay',... - 'mex_spec_rot',... - 'mex_spec_planes',... - 'mex_spec_slicing',... - 'mex_incident_wave',... +files = {'mex_incident_wave',... 'mex_propagate',... 'mex_microscope_aberrations',... 'mex_projected_potential',... - 'mex_transmission_function',... + 'mex_transmission_function',... 'mex_wave_function',... 'mex_MULTEM'}; for file=files disp(['Compiling ' file{1}]) run(['mex_files_multem/',file{1}]) -end \ No newline at end of file +end + +% addpath([ pwd '/matlab_functions']) +% +% files = {'mex_lambda',... +% 'mex_sigma',... +% 'mex_gamma',... +% 'mex_fxeg_tabulated_data',... +% 'mex_feg',... +% 'mex_fxg',... +% 'mex_Pr',... +% 'mex_Vz',... +% 'mex_Vr',... +% 'mex_Vp',... +% 'mex_gmax',... +% 'mex_min_spl',... +% 'mex_mrad_2_rAngs',... +% 'mex_mrad_2_sigma',... +% 'mex_fwhm_2_sigma',... +% 'mex_hwhm_2_sigma',... +% 'mex_iehwgd_2_sigma',... +% 'mex_scherzer_defocus',... +% 'mex_scherzer_aperture',... +% 'mex_crystal_by_lays',... +% 'mex_rdf_3d',... +% 'mex_amorp_spec',... +% 'mex_add_amorp_lay',... +% 'mex_spec_rot',... +% 'mex_spec_planes',... +% 'mex_spec_slicing',... +% 'mex_incident_wave',... +% 'mex_propagate',... +% 'mex_microscope_aberrations',... +% 'mex_projected_potential',... +% 'mex_transmission_function',... +% 'mex_wave_function',... +% 'mex_MULTEM'}; +% +% for file=files +% disp(['Compiling ' file{1}]) +% run(['mex_files_multem/',file{1}]) +% end \ No newline at end of file diff --git a/gui_multem/mainwindow.cpp b/gui_multem/mainwindow.cpp index cbea1083..df95612c 100644 --- a/gui_multem/mainwindow.cpp +++ b/gui_multem/mainwindow.cpp @@ -19,69 +19,69 @@ MainWindow::MainWindow(): central_widget(new QLabel) { - rs_thread = new RS_Thread(this); - connect(rs_thread, SIGNAL(resultReady()), this, SLOT(show_data())); + rs_thread = new RS_Thread(this); + connect(rs_thread, SIGNAL(resultReady()), this, SLOT(show_data())); - pb_timer = new PB_Timer(this); + pb_timer = new PB_Timer(this); - // set seed to generate random numbers - qsrand(QTime::currentTime().msec()); + // set seed to generate random numbers + qsrand(QTime::currentTime().msec()); - setWindowTitle(tr("MULTEM")); - setDockOptions(QMainWindow::AnimatedDocks); + setWindowTitle(tr("MULTEM")); + setDockOptions(QMainWindow::AnimatedDocks); - create_menubar(); + create_menubar(); - central_widget->setFrameStyle(QFrame::Box | QFrame::Sunken); - central_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding); + central_widget->setFrameStyle(QFrame::Box | QFrame::Sunken); + central_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding); - setCentralWidget(central_widget); + setCentralWidget(central_widget); - create_general_dock_widget(); - create_specimen_dock_widget(); - create_experiment_dock_widget(); - create_microscope_dock_widget(); + create_general_dock_widget(); + create_specimen_dock_widget(); + create_experiment_dock_widget(); + create_microscope_dock_widget(); - statusBar()->showMessage("MULTEM"); + statusBar()->showMessage("MULTEM"); - QList allComboBoxes = findChildren(); - for (auto icb = 0; icb < allComboBoxes.size(); icb++) - { - connect(allComboBoxes[icb], static_cast(&QComboBox::highlighted), - [=](int index){statusBar()->showMessage(allComboBoxes[icb]->itemData(index, Qt::ToolTipRole).toString());}); - } + QList allComboBoxes = findChildren(); + for (auto icb = 0; icb < allComboBoxes.size(); icb++) + { + connect(allComboBoxes[icb], static_cast(&QComboBox::highlighted), + [=](int index){statusBar()->showMessage(allComboBoxes[icb]->itemData(index, Qt::ToolTipRole).toString());}); + } - QList allQWidgets= findChildren(); - for (auto iw = 0; iw < allQWidgets.size(); iw++) - { - allQWidgets[iw]->setToolTip(allQWidgets[iw]->statusTip()); - } + QList allQWidgets= findChildren(); + for (auto iw = 0; iw < allQWidgets.size(); iw++) + { + allQWidgets[iw]->setToolTip(allQWidgets[iw]->statusTip()); + } - connect(cb_iw_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_iw_type_currentIndexChanged(int))); + connect(cb_iw_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_iw_type_currentIndexChanged(int))); - connect(cb_sim_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_sim_type_currentIndexChanged(int))); - auto sim_type = cb_sim_type->findData(mt::eTEMST_EWRS); - cb_sim_type->setCurrentIndex(sim_type); - cb_sim_type_currentIndexChanged(sim_type); + connect(cb_sim_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_sim_type_currentIndexChanged(int))); + auto sim_type = cb_sim_type->findData(mt::eTEMST_EWRS); + cb_sim_type->setCurrentIndex(sim_type); + cb_sim_type_currentIndexChanged(sim_type); - connect(cb_elec_spec_int_model, SIGNAL(currentIndexChanged(int)), SLOT(cb_elec_spec_int_model_currentIndexChanged(int))); - cb_elec_spec_int_model->setCurrentIndex(0); - cb_elec_spec_int_model_currentIndexChanged(0); + connect(cb_elec_spec_int_model, SIGNAL(currentIndexChanged(int)), SLOT(cb_elec_spec_int_model_currentIndexChanged(int))); + cb_elec_spec_int_model->setCurrentIndex(0); + cb_elec_spec_int_model_currentIndexChanged(0); - set_specimen_enable(false); - default_sim(); + set_specimen_enable(false); + default_sim(); - // connect(cb_potential_type, static_cast(&QComboBox::highlighted), - // [&](int index){statusBar()->showMessage(cb_potential_type->itemData(index, Qt::ToolTipRole).toString());}); + // connect(cb_potential_type, static_cast(&QComboBox::highlighted), + // [&](int index){statusBar()->showMessage(cb_potential_type->itemData(index, Qt::ToolTipRole).toString());}); - // QList allPButtons = findChildren(); - // qDebug() << "Amount of children found :" << allPButtons.count(); + // QList allPButtons = findChildren(); + // qDebug() << "Amount of children found :" << allPButtons.count(); - // [=](int index){statusBar()->showMessage(itemData(index, Qt::ToolTipRole).toString());}; - // auto cc = QColor("#F1D8D8").toRgb(); - // setStyleSheet("QFrame { background: "+ cc.name() +" }"); - // setStyleSheet("QPushButton, QLineEdit, QComboBox { color: red }"); - // setStyleSheet("QComboBox::drop-down { image: url(dropdown.png) }"); + // [=](int index){statusBar()->showMessage(itemData(index, Qt::ToolTipRole).toString());}; + // auto cc = QColor("#F1D8D8").toRgb(); + // setStyleSheet("QFrame { background: "+ cc.name() +" }"); + // setStyleSheet("QPushButton, QLineEdit, QComboBox { color: red }"); + // setStyleSheet("QComboBox::drop-down { image: url(dropdown.png) }"); } void MainWindow::open_sim() @@ -111,3538 +111,3538 @@ void MainWindow::about() void MainWindow::default_sim() { - default_general_dock_widget(); + default_general_dock_widget(); - default_specimen_dock_widget(); + default_specimen_dock_widget(); - default_experiment_dock_widget(); + default_experiment_dock_widget(); - default_microscope_dock_widget(); + default_microscope_dock_widget(); - act_default_sim->setEnabled(true); - act_start_sim->setEnabled(false); - act_stop_sim->setEnabled(false); + act_default_sim->setEnabled(true); + act_start_sim->setEnabled(false); + act_stop_sim->setEnabled(false); } void MainWindow::start_sim() { - set_enable_running_simulation(false); + set_enable_running_simulation(false); - rs_thread->start(); + rs_thread->start(); - pb_timer->start(); + pb_timer->start(); } void MainWindow::stop_sim() { - mt_stop_multislice(system_conf); + mt_stop_multislice(system_conf); } /**********************************************************/ void MainWindow::progress_run_update() { - auto niter = mt_niter(system_conf); - auto iter = mt_iter(system_conf); - pb_progress_run->setMaximum(niter); - pb_progress_run->setValue(iter); + auto niter = mt_niter(system_conf); + auto iter = mt_iter(system_conf); + pb_progress_run->setMaximum(niter); + pb_progress_run->setValue(iter); } void MainWindow::run_sim() { - read_system_configuration(); + read_system_configuration(); - /**********************************************/ -// if(system_conf.is_float_host()) -// { - mt::Input_Multislice input_multislice; - read_input_multislice(input_multislice); + /**********************************************/ +// if(system_conf.is_float_host()) +// { + mt::Input_Multislice input_multislice; + read_input_multislice(input_multislice); - output_multislice_float.set_input_data(&input_multislice); + output_multislice_float.set_input_data(&input_multislice); - mt_run_multislice(system_conf, input_multislice, output_multislice_float); -// } + mt_run_multislice(system_conf, input_multislice, output_multislice_float); +// } -// if(system_conf.is_double_host()) -// { -// mt::Input_Multislice input_multislice; -// read_input_multislice(input_multislice); +// if(system_conf.is_double_host()) +// { +// mt::Input_Multislice input_multislice; +// read_input_multislice(input_multislice); -// mt::Output_Multislice output_multislice; -// output_multislice.set_input_data(&input_multislice); +// mt::Output_Multislice output_multislice; +// output_multislice.set_input_data(&input_multislice); -// run_multislice(system_conf, input_multislice, output_multislice); +// run_multislice(system_conf, input_multislice, output_multislice); -// if(success_multislice()) -// { -// auto image = new Data_Viewer(this); -// image->set_input_data(output_multislice); -// image->show(); -// } -// } +// if(success_multislice()) +// { +// auto image = new Data_Viewer(this); +// image->set_input_data(output_multislice); +// image->show(); +// } +// } -// if(system_conf.is_float_device()) -// { -// mt::Input_Multislice input_multislice; -// read_input_multislice(input_multislice); +// if(system_conf.is_float_device()) +// { +// mt::Input_Multislice input_multislice; +// read_input_multislice(input_multislice); -// mt::Output_Multislice output_multislice; -// output_multislice.set_input_data(&input_multislice); +// mt::Output_Multislice output_multislice; +// output_multislice.set_input_data(&input_multislice); -// run_multislice(system_conf, input_multislice, output_multislice); +// run_multislice(system_conf, input_multislice, output_multislice); -// if(success_multislice()) -// { -// auto image = new Data_Viewer(this); -// image->set_input_data(output_multislice); -// image->show(); -// } -// } +// if(success_multislice()) +// { +// auto image = new Data_Viewer(this); +// image->set_input_data(output_multislice); +// image->show(); +// } +// } -// if(system_conf.is_double_device()) -// { -// mt::Input_Multislice input_multislice; -// read_input_multislice(input_multislice); +// if(system_conf.is_double_device()) +// { +// mt::Input_Multislice input_multislice; +// read_input_multislice(input_multislice); -// mt::Output_Multislice output_multislice; -// output_multislice.set_input_data(&input_multislice); +// mt::Output_Multislice output_multislice; +// output_multislice.set_input_data(&input_multislice); -// run_multislice(system_conf, input_multislice, output_multislice); +// run_multislice(system_conf, input_multislice, output_multislice); -// if(success_multislice()) -// { -// auto image = new Data_Viewer(this); -// image->set_input_data(output_multislice); -// image->show(); -// } -// } +// if(success_multislice()) +// { +// auto image = new Data_Viewer(this); +// image->set_input_data(output_multislice); +// image->show(); +// } +// } } void MainWindow::show_data() { - pb_timer->stop(); + pb_timer->stop(); - pb_progress_run->setValue(pb_progress_run->maximum()); + pb_progress_run->setValue(pb_progress_run->maximum()); - set_enable_running_simulation(true); + set_enable_running_simulation(true); - if(mt_success_multislice(system_conf)) - { - statusBar()->showMessage("Simulation ready"); + if(mt_success_multislice(system_conf)) + { + statusBar()->showMessage("Simulation ready"); - auto image = new Data_Viewer(output_multislice_float); - image->show(); - image->activateWindow(); - } - else - { - output_multislice_float.clear(); - pb_progress_run->setMinimum(0); - pb_progress_run->setMaximum(100); - pb_progress_run->setValue(0); - } + auto image = new Data_Viewer(output_multislice_float); + image->show(); + image->activateWindow(); + } + else + { + output_multislice_float.clear(); + pb_progress_run->setMinimum(0); + pb_progress_run->setMaximum(100); + pb_progress_run->setValue(0); + } } /**********************************************************/ void MainWindow::cb_device_currentIndexChanged(int index) { - auto device = cb_device->itemData(index); - auto bb_cpu = (device == mt::e_host); + auto device = cb_device->itemData(index); + auto bb_cpu = (device == mt::e_host); - lb_nthreads->setVisible(bb_cpu); - sb_nthreads->setVisible(bb_cpu); - lb_gpu_card->setVisible(!bb_cpu); - cb_gpu_card->setVisible(!bb_cpu); + lb_nthreads->setVisible(bb_cpu); + sb_nthreads->setVisible(bb_cpu); + lb_gpu_card->setVisible(!bb_cpu); + cb_gpu_card->setVisible(!bb_cpu); } void MainWindow::cb_elec_spec_int_model_currentIndexChanged(int index) { - auto elec_spec_int_model = cb_elec_spec_int_model->itemData(index); - auto bb = (elec_spec_int_model == mt::eESIM_Multislice); - gbg_potential_slic->setEnabled(bb); + auto elec_spec_int_model = cb_elec_spec_int_model->itemData(index); + auto bb = (elec_spec_int_model == mt::eESIM_Multislice); + gbg_potential_slic->setEnabled(bb); } void MainWindow::pb_spec_load_released() { - QString filename = QFileDialog::getOpenFileName(this, - tr("Open specimen txt file"), "", tr("Specimen (*.txt)")); - - QFileInfo info(filename); - default_specimen_dock_widget(); - - if(!filename.isEmpty() && info.isFile()) - { - Load_Specimen load_specimen; - bool success = false; - - try - { - success = load_specimen(filename, atoms); - statusBar()->showMessage("Specimen loaded", 1000); - } - catch(...) - { - atoms.clear(); - success = false; - le_spec_file->clear(); - lb_pptf_n_slices->setText(tr(n_slices_qba(0))); - cb_pptf_slice->clear(); - wg_pptf->setEnabled(false); - - statusBar()->showMessage("An error occurred while trying to load the specimen file", 1000); - } - - set_specimen_enable(success); - if(success) - { - le_spec_file->setText(filename); - - auto n_atoms = atoms.size(); - auto n_types = atoms.Z_unique.size(); - - lb_spec_n_atom_types->setText(tr(n_atoms_types_qba(n_atoms, n_types))); - le_spec_lx->setText(QString::number(atoms.l_x, 'f', 4)); - le_spec_ly->setText(QString::number(atoms.l_y, 'f', 4)); - pb_spec_recenter->setEnabled(false); - - le_thk_0->setText(QString::number(atoms.z_min, 'f', 4)); - le_thk_d->setText(QString::number(atoms.dz, 'f', 4)); - le_thk_e->setText(QString::number(atoms.z_max, 'f', 4)); - - le_pot_slic_thick->setText(QString::number(atoms.dz, 'f', 4)); - - /****************************************************/ - le_iw_x->setText(QString::number(le_spec_lx->text().toDouble()/2, 'f', 3)); - le_iw_y->setText(QString::number(le_spec_ly->text().toDouble()/2, 'f', 3)); - - /****************************************************/ - le_stem_sc_px_e->setText(QString::number(le_spec_lx->text().toDouble(), 'f', 3)); - le_stem_sc_py_e->setText(QString::number(le_spec_ly->text().toDouble(), 'f', 3)); - - disconnect(cb_eels_element, SIGNAL(currentIndexChanged(int)), this, SLOT(cb_eels_element_currentIndexChanged(int))); - - cb_eels_element->clear(); - for(auto itype=0; itypeaddItem(QString::fromStdString(atomic_data.Z_name(Z)), QVariant(Z)); - } - cb_eels_element_currentIndexChanged(0); - - connect(cb_eels_element, SIGNAL(currentIndexChanged(int)), SLOT(cb_eels_element_currentIndexChanged(int))); - - } - act_start_sim->setEnabled(success); - } - else - { - atoms.clear(); - set_specimen_enable(false); - le_spec_file->clear(); - le_stem_sc_px_e->setText("0.000"); - le_stem_sc_py_e->setText("0.000"); - cb_eels_element->clear(); - - lb_pptf_n_slices->setText(tr(n_slices_qba(0))); - cb_pptf_slice->clear(); - wg_pptf->setEnabled(false); - - act_start_sim->setEnabled(false); - } + QString filename = QFileDialog::getOpenFileName(this, + tr("Open specimen txt file"), "", tr("Specimen (*.txt)")); + + QFileInfo info(filename); + default_specimen_dock_widget(); + + if(!filename.isEmpty() && info.isFile()) + { + Load_Specimen load_specimen; + bool success = false; + + try + { + success = load_specimen(filename, atoms); + statusBar()->showMessage("Specimen loaded", 1000); + } + catch(...) + { + atoms.clear(); + success = false; + le_spec_file->clear(); + lb_pptf_n_slices->setText(tr(n_slices_qba(0))); + cb_pptf_slice->clear(); + wg_pptf->setEnabled(false); + + statusBar()->showMessage("An error occurred while trying to load the specimen file", 1000); + } + + set_specimen_enable(success); + if(success) + { + le_spec_file->setText(filename); + + auto n_atoms = atoms.size(); + auto n_types = atoms.Z_unique.size(); + + lb_spec_n_atom_types->setText(tr(n_atoms_types_qba(n_atoms, n_types))); + le_spec_lx->setText(QString::number(atoms.l_x, 'f', 4)); + le_spec_ly->setText(QString::number(atoms.l_y, 'f', 4)); + pb_spec_recenter->setEnabled(false); + + le_thk_0->setText(QString::number(atoms.z_min, 'f', 4)); + le_thk_d->setText(QString::number(atoms.dz, 'f', 4)); + le_thk_e->setText(QString::number(atoms.z_max, 'f', 4)); + + le_pot_slic_thick->setText(QString::number(atoms.dz, 'f', 4)); + + /****************************************************/ + le_iw_x->setText(QString::number(le_spec_lx->text().toDouble()/2, 'f', 3)); + le_iw_y->setText(QString::number(le_spec_ly->text().toDouble()/2, 'f', 3)); + + /****************************************************/ + le_stem_sc_px_e->setText(QString::number(le_spec_lx->text().toDouble(), 'f', 3)); + le_stem_sc_py_e->setText(QString::number(le_spec_ly->text().toDouble(), 'f', 3)); + + disconnect(cb_eels_element, SIGNAL(currentIndexChanged(int)), this, SLOT(cb_eels_element_currentIndexChanged(int))); + + cb_eels_element->clear(); + for(auto itype=0; itypeaddItem(QString::fromStdString(atomic_data.Z_name(Z)), QVariant(Z)); + } + cb_eels_element_currentIndexChanged(0); + + connect(cb_eels_element, SIGNAL(currentIndexChanged(int)), SLOT(cb_eels_element_currentIndexChanged(int))); + + } + act_start_sim->setEnabled(success); + } + else + { + atoms.clear(); + set_specimen_enable(false); + le_spec_file->clear(); + le_stem_sc_px_e->setText("0.000"); + le_stem_sc_py_e->setText("0.000"); + cb_eels_element->clear(); + + lb_pptf_n_slices->setText(tr(n_slices_qba(0))); + cb_pptf_slice->clear(); + wg_pptf->setEnabled(false); + + act_start_sim->setEnabled(false); + } } void MainWindow::le_spec_lx_ly_textChanged(const QString &) { - pb_spec_recenter->setEnabled(atoms.size()>0); - le_iw_x->setText(QString::number(le_spec_lx->text().toDouble()/2, 'f', 3)); - le_iw_y->setText(QString::number(le_spec_ly->text().toDouble()/2, 'f', 3)); + pb_spec_recenter->setEnabled(atoms.size()>0); + le_iw_x->setText(QString::number(le_spec_lx->text().toDouble()/2, 'f', 3)); + le_iw_y->setText(QString::number(le_spec_ly->text().toDouble()/2, 'f', 3)); } void MainWindow::pb_spec_recenter_released() { - if(atoms.size()>0) - { - auto lx = le_spec_lx->text().toDouble(); - auto ly = le_spec_ly->text().toDouble(); + if(atoms.size()>0) + { + auto lx = le_spec_lx->text().toDouble(); + auto ly = le_spec_ly->text().toDouble(); - atoms.xy_recenter(lx, ly); + atoms.xy_recenter(lx, ly); - statusBar()->showMessage("The specimen was recenter along x-y directions"); - } + statusBar()->showMessage("The specimen was recenter along x-y directions"); + } } void MainWindow::cb_spec_rot_center_type_currentIndexChanged(int index) { - auto spec_rot_p0_type = cb_spec_rot_center_type->itemData(index); - auto bb = !(spec_rot_p0_type == mt::eRPT_geometric_center); - lb_spec_rot_center_p->setEnabled(bb); - le_spec_rot_center_px->setEnabled(bb); - le_spec_rot_center_py->setEnabled(bb); - le_spec_rot_center_pz->setEnabled(bb); + auto spec_rot_p0_type = cb_spec_rot_center_type->itemData(index); + auto bb = !(spec_rot_p0_type == mt::eRPT_geometric_center); + lb_spec_rot_center_p->setEnabled(bb); + le_spec_rot_center_px->setEnabled(bb); + le_spec_rot_center_py->setEnabled(bb); + le_spec_rot_center_pz->setEnabled(bb); } void MainWindow::cb_pot_slic_type_currentIndexChanged(int index) { - auto potential_slic = cb_pot_slic_type->itemData(index); - auto bb = (potential_slic != mt::ePS_Planes)&&(potential_slic != mt::ePS_Auto); - lb_pot_slic_thick->setEnabled(bb); - le_pot_slic_thick->setEnabled(bb); + auto potential_slic = cb_pot_slic_type->itemData(index); + auto bb = (potential_slic != mt::ePS_Planes)&&(potential_slic != mt::ePS_Auto); + lb_pot_slic_thick->setEnabled(bb); + le_pot_slic_thick->setEnabled(bb); } void MainWindow::cb_thk_type_currentIndexChanged(int index) { - auto thk_type = cb_thk_type->itemData(index); - auto bb_ws = (thk_type==mt::eTT_Whole_Spec); - lb_thk_0->setVisible(!bb_ws); - le_thk_0->setVisible(!bb_ws); - lb_thk_d->setVisible(!bb_ws); - le_thk_d->setVisible(!bb_ws); - lb_thk_e->setVisible(!bb_ws); - le_thk_e->setVisible(!bb_ws); + auto thk_type = cb_thk_type->itemData(index); + auto bb_ws = (thk_type==mt::eTT_Whole_Spec); + lb_thk_0->setVisible(!bb_ws); + le_thk_0->setVisible(!bb_ws); + lb_thk_d->setVisible(!bb_ws); + le_thk_d->setVisible(!bb_ws); + lb_thk_e->setVisible(!bb_ws); + le_thk_e->setVisible(!bb_ws); } void MainWindow::le_pot_slic_thick_editingFinished() { - atoms.dz = le_pot_slic_thick->text().toDouble(); + atoms.dz = le_pot_slic_thick->text().toDouble(); } void MainWindow::cb_sim_type_currentIndexChanged(int index) { - auto sim_type = QVar_to_enum(cb_sim_type->itemData(index)); - - wg_electron_phonon->setEnabled(!mt::is_IWFS_IWRS(sim_type)); - - /***********************************************************/ - set_cb_iw_type_using_eTEM_Sim_Type(sim_type); - auto iw_type = QVar_to_enum(cb_iw_type->currentData()); - iw_type = mt::validate_incident_wave_type(sim_type, iw_type); - - /***********************************************************/ - auto bb_ss = (!mt::is_specimen_required(sim_type))?true:false; - if(bb_ss) - { - le_spec_file->clear(); - default_specimen_dock_widget(); - set_specimen_enable(false); - - le_spec_lx->setText(QString::number(40, 'f', 4)); - le_spec_ly->setText(QString::number(40, 'f', 4)); - - le_iw_x->setText(QString::number(le_spec_lx->text().toDouble()/2, 'f', 3)); - le_iw_y->setText(QString::number(le_spec_ly->text().toDouble()/2, 'f', 3)); - - pb_spec_load->setEnabled(false); - } - else - { - bb_ss = !le_spec_file->text().isEmpty(); - pb_spec_load->setEnabled(true); - } - act_start_sim->setEnabled(bb_ss); - - lb_spec_lx->setEnabled(bb_ss); - le_spec_lx->setEnabled(bb_ss); - lb_spec_ly->setEnabled(bb_ss); - le_spec_ly->setEnabled(bb_ss); - - /***********************************************************/ - auto bb_cl = mt::is_scanning(sim_type)||mt::is_CBED_CBEI(sim_type)||mt::is_IWFS_IWRS(sim_type); - bb_cl = bb_cl||mt::is_EWFS_EWRS(sim_type)||mt::is_EFTEM(sim_type); - bb_cl = bb_cl && mt::is_convergent_wave(iw_type); - - wg_cond_lens->setEnabled(bb_cl); - - /***********************************************************/ - auto bb_ob = mt::is_ISTEM(sim_type)||mt::is_CBEI(sim_type); - bb_ob = bb_ob||mt::is_HRTEM(sim_type)||mt::is_HCTEM(sim_type)||mt::is_EFTEM(sim_type); - - set_objective_lens_tab_enable(bb_ob); - - auto bb_ob_defocus =bb_ob||mt::is_EWFS_EWRS(sim_type); - - lb_ol_sa_c_10_zero->setEnabled(bb_ob_defocus); - cb_ol_sa_c_10_zero->setEnabled(bb_ob_defocus); - - bb_ob_defocus = bb_ob_defocus && (cb_ol_sa_c_10_zero->currentData()==mt::eZDT_User_Define); - - lb_ol_sa_c_10_z->setEnabled(bb_ob_defocus); - le_ol_sa_c_10_z->setEnabled(bb_ob_defocus); - - /***********************************************************/ - wg_stem->setVisible(false); - wg_pcs->setVisible(false); - wg_eels->setVisible(false); - wg_pptf->setVisible(false); - - if(mt::is_STEM_ISTEM(sim_type)) - { - wg_stem->setVisible(true); - gbg_stem_detector->setVisible(mt::is_STEM(sim_type)); - } - else if(mt::is_PED_HCTEM(sim_type)) - { - auto str = (mt::is_PED(sim_type))?tr("Precession"):tr("Hollow cone"); - gbg_pcs->setTitle(str); - wg_pcs->setVisible(true); - } - else if(mt::is_EELS_EFTEM(sim_type)) - { - wg_eels->setVisible(true); - auto str = (mt::is_EELS(sim_type))?tr("Collection angle"):tr("Objective aperture"); - le_eels_coll_angle->setStatusTip(str); - } - else if(mt::is_PPFS_PPRS(sim_type) || mt::is_TFFS_TFRS(sim_type)) - { - auto str = (mt::is_PPFS_PPRS(sim_type))?tr("Projected potential"):tr("Transmission function"); - gbh_pptf->setTitle(str); - wg_pptf->setEnabled(!le_spec_file->text().isEmpty()); - wg_pptf->setVisible(true); - } - - // select obj lens - auto idx_lens = (mt::is_plane_wave(iw_type))?1:0; - tb_lens->setCurrentIndex(idx_lens); - - // hide incident wave - auto bb_iw = !(mt::is_PPFS_PPRS(sim_type)||mt::is_TFFS_TFRS(sim_type)); - wg_iw->setVisible(bb_iw); - - set_cb_illu_model_using_eTEM_Sim_Type(sim_type); + auto sim_type = QVar_to_enum(cb_sim_type->itemData(index)); + + wg_electron_phonon->setEnabled(!mt::is_IWFS_IWRS(sim_type)); + + /***********************************************************/ + set_cb_iw_type_using_eTEM_Sim_Type(sim_type); + auto iw_type = QVar_to_enum(cb_iw_type->currentData()); + iw_type = mt::validate_incident_wave_type(sim_type, iw_type); + + /***********************************************************/ + auto bb_ss = (!mt::is_specimen_required(sim_type))?true:false; + if(bb_ss) + { + le_spec_file->clear(); + default_specimen_dock_widget(); + set_specimen_enable(false); + + le_spec_lx->setText(QString::number(40, 'f', 4)); + le_spec_ly->setText(QString::number(40, 'f', 4)); + + le_iw_x->setText(QString::number(le_spec_lx->text().toDouble()/2, 'f', 3)); + le_iw_y->setText(QString::number(le_spec_ly->text().toDouble()/2, 'f', 3)); + + pb_spec_load->setEnabled(false); + } + else + { + bb_ss = !le_spec_file->text().isEmpty(); + pb_spec_load->setEnabled(true); + } + act_start_sim->setEnabled(bb_ss); + + lb_spec_lx->setEnabled(bb_ss); + le_spec_lx->setEnabled(bb_ss); + lb_spec_ly->setEnabled(bb_ss); + le_spec_ly->setEnabled(bb_ss); + + /***********************************************************/ + auto bb_cl = mt::is_scanning(sim_type)||mt::is_CBED_CBEI(sim_type)||mt::is_IWFS_IWRS(sim_type); + bb_cl = bb_cl||mt::is_EWFS_EWRS(sim_type)||mt::is_EFTEM(sim_type); + bb_cl = bb_cl && mt::is_convergent_wave(iw_type); + + wg_cond_lens->setEnabled(bb_cl); + + /***********************************************************/ + auto bb_ob = mt::is_ISTEM(sim_type)||mt::is_CBEI(sim_type); + bb_ob = bb_ob||mt::is_HRTEM(sim_type)||mt::is_HCTEM(sim_type)||mt::is_EFTEM(sim_type); + + set_objective_lens_tab_enable(bb_ob); + + auto bb_ob_defocus =bb_ob||mt::is_EWFS_EWRS(sim_type); + + lb_ol_sa_c_10_zero->setEnabled(bb_ob_defocus); + cb_ol_sa_c_10_zero->setEnabled(bb_ob_defocus); + + bb_ob_defocus = bb_ob_defocus && (cb_ol_sa_c_10_zero->currentData()==mt::eZDT_User_Define); + + lb_ol_sa_c_10_z->setEnabled(bb_ob_defocus); + le_ol_sa_c_10_z->setEnabled(bb_ob_defocus); + + /***********************************************************/ + wg_stem->setVisible(false); + wg_pcs->setVisible(false); + wg_eels->setVisible(false); + wg_pptf->setVisible(false); + + if(mt::is_STEM_ISTEM(sim_type)) + { + wg_stem->setVisible(true); + gbg_stem_detector->setVisible(mt::is_STEM(sim_type)); + } + else if(mt::is_PED_HCTEM(sim_type)) + { + auto str = (mt::is_PED(sim_type))?tr("Precession"):tr("Hollow cone"); + gbg_pcs->setTitle(str); + wg_pcs->setVisible(true); + } + else if(mt::is_EELS_EFTEM(sim_type)) + { + wg_eels->setVisible(true); + auto str = (mt::is_EELS(sim_type))?tr("Collection angle"):tr("Objective aperture"); + le_eels_coll_angle->setStatusTip(str); + } + else if(mt::is_PPFS_PPRS(sim_type) || mt::is_TFFS_TFRS(sim_type)) + { + auto str = (mt::is_PPFS_PPRS(sim_type))?tr("Projected potential"):tr("Transmission function"); + gbh_pptf->setTitle(str); + wg_pptf->setEnabled(!le_spec_file->text().isEmpty()); + wg_pptf->setVisible(true); + } + + // select obj lens + auto idx_lens = (mt::is_plane_wave(iw_type))?1:0; + tb_lens->setCurrentIndex(idx_lens); + + // hide incident wave + auto bb_iw = !(mt::is_PPFS_PPRS(sim_type)||mt::is_TFFS_TFRS(sim_type)); + wg_iw->setVisible(bb_iw); + + set_cb_illu_model_using_eTEM_Sim_Type(sim_type); } void MainWindow::cb_iw_type_currentIndexChanged(int index) { - auto sim_type = QVar_to_enum(cb_sim_type->currentData()); - auto iw_type = QVar_to_enum(cb_iw_type->itemData(index)); - iw_type = mt::validate_incident_wave_type(sim_type, iw_type); + auto sim_type = QVar_to_enum(cb_sim_type->currentData()); + auto iw_type = QVar_to_enum(cb_iw_type->itemData(index)); + iw_type = mt::validate_incident_wave_type(sim_type, iw_type); - /***********************************************************/ - wg_cond_lens->setEnabled(mt::is_convergent_wave(iw_type)); + /***********************************************************/ + wg_cond_lens->setEnabled(mt::is_convergent_wave(iw_type)); - /***********************************************************/ - auto bb_ud = mt::is_user_define_wave(iw_type); - lb_iw_file->setVisible(bb_ud); - le_iw_file->setVisible(bb_ud); - pb_iw_load->setVisible(bb_ud); + /***********************************************************/ + auto bb_ud = mt::is_user_define_wave(iw_type); + lb_iw_file->setVisible(bb_ud); + le_iw_file->setVisible(bb_ud); + pb_iw_load->setVisible(bb_ud); - auto bb_pw = (!mt::is_scanning(sim_type) && mt::is_convergent_wave(iw_type)) || bb_ud; + auto bb_pw = (!mt::is_scanning(sim_type) && mt::is_convergent_wave(iw_type)) || bb_ud; - lb_iw_x->setVisible(bb_pw); - le_iw_x->setVisible(bb_pw); - lb_iw_y->setVisible(bb_pw); - le_iw_y->setVisible(bb_pw); - pb_iw_p->setVisible(bb_pw); + lb_iw_x->setVisible(bb_pw); + le_iw_x->setVisible(bb_pw); + lb_iw_y->setVisible(bb_pw); + le_iw_y->setVisible(bb_pw); + pb_iw_p->setVisible(bb_pw); - if(!bb_ud) - { - iw_psi.clear(); - grid_2d_iw_psi.set_input_data(0, 0, 0, 0); - le_iw_file->clear(); - } + if(!bb_ud) + { + iw_psi.clear(); + grid_2d_iw_psi.set_input_data(0, 0, 0, 0); + le_iw_file->clear(); + } - // select obj lens - auto idx_lens = (mt::is_convergent_wave(iw_type))?0:1; - tb_lens->setCurrentIndex(idx_lens); + // select obj lens + auto idx_lens = (mt::is_convergent_wave(iw_type))?0:1; + tb_lens->setCurrentIndex(idx_lens); } void MainWindow::pb_iw_load_released() { - QString filename = QFileDialog::getOpenFileName(this, - tr("Open user incident wave binary file"), "", tr("Incident wave (*.bin)")); + QString filename = QFileDialog::getOpenFileName(this, + tr("Open user incident wave binary file"), "", tr("Incident wave (*.bin)")); - QFileInfo info(filename); + QFileInfo info(filename); - if(!filename.isEmpty() && info.isFile()) - { - try - { - mt::read_mat_binary_matrix(filename.toUtf8(), grid_2d_iw_psi, iw_psi); + if(!filename.isEmpty() && info.isFile()) + { + try + { + mt::read_mat_binary_matrix(filename.toUtf8(), grid_2d_iw_psi, iw_psi); - QString str = "User define incident wave loaded (nx, ny) = (" + QString::number(grid_2d_iw_psi.nx); - str += ", " + QString::number(grid_2d_iw_psi.ny) + ")"; - statusBar()->showMessage(str); + QString str = "User define incident wave loaded (nx, ny) = (" + QString::number(grid_2d_iw_psi.nx); + str += ", " + QString::number(grid_2d_iw_psi.ny) + ")"; + statusBar()->showMessage(str); - le_iw_file->setText(filename); - } - catch(...) - { - le_iw_file->clear(); - statusBar()->showMessage("An error occurred while trying to load the user define incident wave"); - } - } - else - { - le_iw_file->clear(); - } + le_iw_file->setText(filename); + } + catch(...) + { + le_iw_file->clear(); + statusBar()->showMessage("An error occurred while trying to load the user define incident wave"); + } + } + else + { + le_iw_file->clear(); + } } void MainWindow::cb_stem_det_type_currentIndexChanged(int index) { - stem_detector.type = QVar_to_enum(cb_stem_det_type->itemData(index)); - auto bb_det_type = stem_detector.is_detector_circular(); + stem_detector.type = QVar_to_enum(cb_stem_det_type->itemData(index)); + auto bb_det_type = stem_detector.is_detector_circular(); - fr_stem_detector_ideal->setVisible(bb_det_type); - fr_stem_detector_exp->setVisible(!bb_det_type); + fr_stem_detector_ideal->setVisible(bb_det_type); + fr_stem_detector_exp->setVisible(!bb_det_type); - stem_detector.clear(); - stem_detector.resize(le_stem_det_n_det->text().toInt()); + stem_detector.clear(); + stem_detector.resize(le_stem_det_n_det->text().toInt()); - cb_stem_det_k_det->setCurrentIndex(0); + cb_stem_det_k_det->setCurrentIndex(0); - le_stem_det_ideal_inner_angle->setText("40.000"); - le_stem_det_ideal_outer_angle->setText("100.000"); + le_stem_det_ideal_inner_angle->setText("40.000"); + le_stem_det_ideal_outer_angle->setText("100.000"); - le_stem_det_exp_file->clear(); + le_stem_det_exp_file->clear(); - if(bb_det_type) - { - stem_detector.g_inner[0] = le_stem_det_ideal_inner_angle->text().toDouble(); - stem_detector.g_outer[0] = le_stem_det_ideal_outer_angle->text().toDouble(); - } + if(bb_det_type) + { + stem_detector.g_inner[0] = le_stem_det_ideal_inner_angle->text().toDouble(); + stem_detector.g_outer[0] = le_stem_det_ideal_outer_angle->text().toDouble(); + } } void MainWindow::le_stem_det_n_det_editingFinished() { - auto n_det = le_stem_det_n_det->text().toInt(); + auto n_det = le_stem_det_n_det->text().toInt(); - if(n_det==stem_detector.size()) - { - return; - } + if(n_det==stem_detector.size()) + { + return; + } - stem_detector.type = QVar_to_enum(cb_stem_det_type->currentData()); - stem_detector.clear(); - stem_detector.resize(n_det); + stem_detector.type = QVar_to_enum(cb_stem_det_type->currentData()); + stem_detector.clear(); + stem_detector.resize(n_det); - le_stem_det_ideal_inner_angle->setText("40.000"); - le_stem_det_ideal_outer_angle->setText("100.000"); + le_stem_det_ideal_inner_angle->setText("40.000"); + le_stem_det_ideal_outer_angle->setText("100.000"); - auto bb_det_type = stem_detector.is_detector_circular(); - if(bb_det_type) - { - stem_detector.g_inner[0] = le_stem_det_ideal_inner_angle->text().toDouble(); - stem_detector.g_outer[0] = le_stem_det_ideal_outer_angle->text().toDouble(); - } + auto bb_det_type = stem_detector.is_detector_circular(); + if(bb_det_type) + { + stem_detector.g_inner[0] = le_stem_det_ideal_inner_angle->text().toDouble(); + stem_detector.g_outer[0] = le_stem_det_ideal_outer_angle->text().toDouble(); + } - disconnect(cb_stem_det_k_det, SIGNAL(currentIndexChanged(int)), this, SLOT(cb_stem_det_k_det_currentIndexChanged(int))); + disconnect(cb_stem_det_k_det, SIGNAL(currentIndexChanged(int)), this, SLOT(cb_stem_det_k_det_currentIndexChanged(int))); - cb_stem_det_k_det->clear(); - for(auto i_det = 0; i_detaddItem(QString::number(i_det+1), QVariant(i_det)); - } - cb_stem_det_k_det->setCurrentIndex(0); + cb_stem_det_k_det->clear(); + for(auto i_det = 0; i_detaddItem(QString::number(i_det+1), QVariant(i_det)); + } + cb_stem_det_k_det->setCurrentIndex(0); - connect(cb_stem_det_k_det, SIGNAL(currentIndexChanged(int)), SLOT(cb_stem_det_k_det_currentIndexChanged(int))); + connect(cb_stem_det_k_det, SIGNAL(currentIndexChanged(int)), SLOT(cb_stem_det_k_det_currentIndexChanged(int))); } void MainWindow::cb_stem_det_k_det_currentIndexChanged(int index) { - switch (stem_detector.type) - { - case mt::eDT_Circular: - { - auto inner_ang = stem_detector.g_inner[index]; - le_stem_det_ideal_inner_angle->setText(QString::number(inner_ang, 'f', 3)); - auto outer_ang = stem_detector.g_outer[index]; - le_stem_det_ideal_outer_angle->setText(QString::number(outer_ang, 'f', 3)); - } - break; - case mt::eDT_Radial: - { -// auto fx = mx_get_matrix_field(mx_detector, i, "fx"); -// mt::assign(fx, input_multislice.detector.fx[i]); - } - break; - case mt::eDT_Matrix: - { - le_stem_det_exp_file->setText(QString::fromStdString(stem_detector.fn[index])); - } - break; - } + switch (stem_detector.type) + { + case mt::eDT_Circular: + { + auto inner_ang = stem_detector.g_inner[index]; + le_stem_det_ideal_inner_angle->setText(QString::number(inner_ang, 'f', 3)); + auto outer_ang = stem_detector.g_outer[index]; + le_stem_det_ideal_outer_angle->setText(QString::number(outer_ang, 'f', 3)); + } + break; + case mt::eDT_Radial: + { +// auto fx = mx_get_matrix_field(mx_detector, i, "fx"); +// mt::assign(fx, input_multislice.detector.fx[i]); + } + break; + case mt::eDT_Matrix: + { + le_stem_det_exp_file->setText(QString::fromStdString(stem_detector.fn[index])); + } + break; + } } void MainWindow::le_stem_det_ideal_editingFinished() { - auto idx = cb_stem_det_k_det->currentData().toInt(); - stem_detector.g_inner[idx] = le_stem_det_ideal_inner_angle->text().toDouble(); - stem_detector.g_outer[idx] = le_stem_det_ideal_outer_angle->text().toDouble(); + auto idx = cb_stem_det_k_det->currentData().toInt(); + stem_detector.g_inner[idx] = le_stem_det_ideal_inner_angle->text().toDouble(); + stem_detector.g_outer[idx] = le_stem_det_ideal_outer_angle->text().toDouble(); } void MainWindow::pb_stem_det_exp_load_released() { - QString filename = QFileDialog::getOpenFileName(this, - tr("Open detector binary file"), "", tr("Detector file (*.bin)")); - - QFileInfo info(filename); - - if(!filename.isEmpty() && info.isFile()) - { - try - { - auto idx = cb_stem_det_k_det->currentData().toInt(); - stem_detector.fn[idx] = filename.toStdString(); - mt::read_mat_binary_matrix(filename.toUtf8(), stem_detector.grid_2d[idx], stem_detector.fR[idx]); - - QString str = "Detector sensitivity loaded (nx, ny) = (" + QString::number(stem_detector.grid_2d[idx].nx); - str += ", " + QString::number(stem_detector.grid_2d[idx].ny) + ")"; - statusBar()->showMessage(str); - - le_stem_det_exp_file->setText(filename); - } - catch(...) - { - le_stem_det_exp_file->clear(); - statusBar()->showMessage("An error occurred while trying to load the user define incident wave"); - } - } - else - { - le_stem_det_exp_file->clear(); - } + QString filename = QFileDialog::getOpenFileName(this, + tr("Open detector binary file"), "", tr("Detector file (*.bin)")); + + QFileInfo info(filename); + + if(!filename.isEmpty() && info.isFile()) + { + try + { + auto idx = cb_stem_det_k_det->currentData().toInt(); + stem_detector.fn[idx] = filename.toStdString(); + mt::read_mat_binary_matrix(filename.toUtf8(), stem_detector.grid_2d[idx], stem_detector.fR[idx]); + + QString str = "Detector sensitivity loaded (nx, ny) = (" + QString::number(stem_detector.grid_2d[idx].nx); + str += ", " + QString::number(stem_detector.grid_2d[idx].ny) + ")"; + statusBar()->showMessage(str); + + le_stem_det_exp_file->setText(filename); + } + catch(...) + { + le_stem_det_exp_file->clear(); + statusBar()->showMessage("An error occurred while trying to load the user define incident wave"); + } + } + else + { + le_stem_det_exp_file->clear(); + } } void MainWindow::cb_eels_element_currentIndexChanged(int index) { - int Z = cb_eels_element->itemData(index).toInt(); + int Z = cb_eels_element->itemData(index).toInt(); - cb_eels_energy->clear(); - if(Z>0) - { - auto energy = atomic_data.extract_major_edges(Z); - for(auto ik=0; ikaddItem(QString::number(energy[ik])); - } - } + cb_eels_energy->clear(); + if(Z>0) + { + auto energy = atomic_data.extract_major_edges(Z); + for(auto ik=0; ikaddItem(QString::number(energy[ik])); + } + } } void MainWindow::cb_illu_model_currentIndexChanged(int index) { - auto im_model = cb_illu_model->itemData(index); - auto bb_incoh = (im_model != mt::eIM_Coherent); - auto bb_fint = (im_model == mt::eIM_Full_Integration); + auto im_model = cb_illu_model->itemData(index); + auto bb_incoh = (im_model != mt::eIM_Coherent); + auto bb_fint = (im_model == mt::eIM_Full_Integration); - lb_illu_beta->setVisible(bb_incoh); - le_illu_beta->setVisible(bb_incoh); - le_illu_beta->setMaximumWidth((bb_fint)?QWIDGETSIZE_MAX:80); + lb_illu_beta->setVisible(bb_incoh); + le_illu_beta->setVisible(bb_incoh); + le_illu_beta->setMaximumWidth((bb_fint)?QWIDGETSIZE_MAX:80); - lb_illu_nbeta->setVisible(bb_fint); - le_illu_nbeta->setVisible(bb_fint); + lb_illu_nbeta->setVisible(bb_fint); + le_illu_nbeta->setVisible(bb_fint); - /***************************************************/ - lb_cl_sa_delta->setVisible(bb_incoh); - le_cl_sa_delta->setVisible(bb_incoh); + /***************************************************/ + lb_cl_sa_delta->setVisible(bb_incoh); + le_cl_sa_delta->setVisible(bb_incoh); - lb_cl_sa_ndelta->setVisible(bb_fint); - cb_cl_sa_ndelta->setVisible(bb_fint); + lb_cl_sa_ndelta->setVisible(bb_fint); + cb_cl_sa_ndelta->setVisible(bb_fint); - /***************************************************/ - lb_ol_sa_delta->setVisible(bb_incoh); - le_ol_sa_delta->setVisible(bb_incoh); + /***************************************************/ + lb_ol_sa_delta->setVisible(bb_incoh); + le_ol_sa_delta->setVisible(bb_incoh); - lb_ol_sa_ndelta->setVisible(bb_fint); - cb_ol_sa_ndelta->setVisible(bb_fint); + lb_ol_sa_ndelta->setVisible(bb_fint); + cb_ol_sa_ndelta->setVisible(bb_fint); } void MainWindow::cb_cl_sa_c_10_zero_currentIndexChanged(int index) { - auto c_10_z = cb_cl_sa_c_10_zero->itemData(index); - auto bb_z = (c_10_z != mt::eZDT_First); - lb_cl_sa_c_10_z->setEnabled(bb_z); - le_cl_sa_c_10_z->setEnabled(bb_z); + auto c_10_z = cb_cl_sa_c_10_zero->itemData(index); + auto bb_z = (c_10_z != mt::eZDT_First); + lb_cl_sa_c_10_z->setEnabled(bb_z); + le_cl_sa_c_10_z->setEnabled(bb_z); } void MainWindow::cb_ol_sa_c_10_zero_currentIndexChanged(int index) { - auto c_10_z = cb_ol_sa_c_10_zero->itemData(index); - auto bb_z = (c_10_z == mt::eZDT_User_Define); - lb_ol_sa_c_10_z->setEnabled(bb_z); - le_ol_sa_c_10_z->setEnabled(bb_z); + auto c_10_z = cb_ol_sa_c_10_zero->itemData(index); + auto bb_z = (c_10_z == mt::eZDT_User_Define); + lb_ol_sa_c_10_z->setEnabled(bb_z); + le_ol_sa_c_10_z->setEnabled(bb_z); } void MainWindow::pb_cl_sa_c_10_opt_released() { - auto E0 = le_mic_acc_vol->text().toDouble(); - auto c_30 = le_cl_sa_c_30->text().toDouble()*mt::c_mm_2_Angs; - auto f = mt::get_Scherzer_defocus(E0, c_30); - le_cl_sa_c_10->setText(QString::number(f, 'f', 3)); + auto E0 = le_mic_acc_vol->text().toDouble(); + auto c_30 = le_cl_sa_c_30->text().toDouble()*mt::c_mm_2_Angs; + auto f = mt::get_Scherzer_defocus(E0, c_30); + le_cl_sa_c_10->setText(QString::number(f, 'f', 3)); } void MainWindow::pb_ol_sa_c_10_opt_released() { - auto E0 = le_mic_acc_vol->text().toDouble(); - auto c_30 = le_ol_sa_c_30->text().toDouble()*mt::c_mm_2_Angs; - auto f = mt::get_Scherzer_defocus(E0, c_30); - le_ol_sa_c_10->setText(QString::number(f, 'f', 3)); + auto E0 = le_mic_acc_vol->text().toDouble(); + auto c_30 = le_ol_sa_c_30->text().toDouble()*mt::c_mm_2_Angs; + auto f = mt::get_Scherzer_defocus(E0, c_30); + le_ol_sa_c_10->setText(QString::number(f, 'f', 3)); } void MainWindow::disable_item_cb_iw_type(mt::eIncident_Wave_Type iwt, bool disabled) { - auto index_dis = cb_iw_type->findData(QVariant(iwt)); - if(disabled && (index_dis==cb_iw_type->currentIndex())) - { - auto index_sel = cb_iw_type->findData(QVariant(mt::eIWT_Auto)); - cb_iw_type->setCurrentIndex(index_sel); - } - disable_item_QComboBox(cb_iw_type, index_dis, disabled); + auto index_dis = cb_iw_type->findData(QVariant(iwt)); + if(disabled && (index_dis==cb_iw_type->currentIndex())) + { + auto index_sel = cb_iw_type->findData(QVariant(mt::eIWT_Auto)); + cb_iw_type->setCurrentIndex(index_sel); + } + disable_item_QComboBox(cb_iw_type, index_dis, disabled); } void MainWindow::disable_item_cb_illu_model(mt::eIllumination_Model ill_model, bool disabled) { - auto index_dis = cb_illu_model->findData(QVariant(ill_model)); - if(disabled && (index_dis==cb_illu_model->currentIndex())) - { - auto index_sel = cb_illu_model->findData(QVariant(mt::eIM_Coherent)); - cb_illu_model->setCurrentIndex(index_sel); - } - disable_item_QComboBox(cb_illu_model, index_dis, disabled); + auto index_dis = cb_illu_model->findData(QVariant(ill_model)); + if(disabled && (index_dis==cb_illu_model->currentIndex())) + { + auto index_sel = cb_illu_model->findData(QVariant(mt::eIM_Coherent)); + cb_illu_model->setCurrentIndex(index_sel); + } + disable_item_QComboBox(cb_illu_model, index_dis, disabled); } void MainWindow::create_menubar() { - file_menu = menuBar()->addMenu(tr("&File")); - QToolBar *file_tool_bar = addToolBar(tr("File")); - - const QIcon icon_open_sim = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); - act_open_sim = new QAction(icon_open_sim, tr("&Open simulation"), this); - act_open_sim->setShortcuts(QKeySequence::Open); - act_open_sim->setStatusTip(tr("Open a TEM simulation")); - connect(act_open_sim, &QAction::triggered, this, &MainWindow::open_sim); - file_menu->addAction(act_open_sim); - file_tool_bar->addAction(act_open_sim); - act_open_sim->setEnabled(false); - - file_menu->addSeparator(); - - const QIcon icon_save_sim = QIcon::fromTheme("document-open", QIcon(":/images/save.png")); - act_save_sim = new QAction(icon_save_sim, tr("&Save simulation"), this); - act_save_sim->setShortcuts(QKeySequence::Save); - act_save_sim->setStatusTip(tr("Save the current TEM simulation")); - connect(act_save_sim, &QAction::triggered, this, &MainWindow::save_sim); - file_menu->addAction(act_save_sim); - file_tool_bar->addAction(act_save_sim); - act_save_sim->setEnabled(false); - - file_tool_bar->addSeparator(); - - /******************************************************************/ - act_save_as_sim = new QAction(tr("&Save simulation as"), this); - act_save_as_sim->setShortcuts(QKeySequence::SaveAs); - act_save_as_sim->setStatusTip(tr("Save the current TEM simulation")); - connect(act_save_as_sim, &QAction::triggered, this, &MainWindow::save_as_sim); - file_menu->addAction(act_save_as_sim); - - file_menu->addSeparator(); - - act_exit = new QAction(tr("&Exit"), this); - act_exit->setShortcuts(QKeySequence::Quit); - act_exit->setStatusTip(tr("Exit the application")); - connect(act_exit, &QAction::triggered, this, &MainWindow::exit); - file_menu->addAction(act_exit); - - /******************************************************************/ - const QIcon icon_default_sim = QIcon::fromTheme("Set default values", QIcon(":/images/default.png")); - act_default_sim = new QAction(icon_default_sim, tr("&Default values"), this); - act_default_sim->setShortcuts(QKeySequence::Save); - act_default_sim->setStatusTip(tr("Set default values")); - connect(act_default_sim, &QAction::triggered, this, &MainWindow::default_sim); - file_tool_bar->addAction(act_default_sim); - - const QIcon icon_start_sim = QIcon::fromTheme("Start simulation", QIcon(":/images/start.png")); - act_start_sim = new QAction(icon_start_sim, tr("&Start Simulation"), this); - act_start_sim->setStatusTip(tr("Start simulation")); - act_start_sim->setEnabled(false); - connect(act_start_sim, &QAction::triggered, this, &MainWindow::start_sim); - file_tool_bar->addAction(act_start_sim); - - const QIcon icon_stop_sim = QIcon::fromTheme("Stop simulation", QIcon(":/images/stop.png")); - act_stop_sim = new QAction(icon_stop_sim, tr("&Stop Simulation"), this); - act_stop_sim->setStatusTip(tr("Stop simulation")); - act_stop_sim->setEnabled(false); - connect(act_stop_sim, &QAction::triggered, this, &MainWindow::stop_sim); - file_tool_bar->addAction(act_stop_sim); - - file_tool_bar->addSeparator(); - - pb_progress_run = new QProgressBar; - pb_progress_run->setMinimum(0); - pb_progress_run->setMaximum(100); - pb_progress_run->setValue(0); - - file_tool_bar->addWidget(pb_progress_run); + file_menu = menuBar()->addMenu(tr("&File")); + QToolBar *file_tool_bar = addToolBar(tr("File")); + + const QIcon icon_open_sim = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + act_open_sim = new QAction(icon_open_sim, tr("&Open simulation"), this); + act_open_sim->setShortcuts(QKeySequence::Open); + act_open_sim->setStatusTip(tr("Open a TEM simulation")); + connect(act_open_sim, &QAction::triggered, this, &MainWindow::open_sim); + file_menu->addAction(act_open_sim); + file_tool_bar->addAction(act_open_sim); + act_open_sim->setEnabled(false); + + file_menu->addSeparator(); + + const QIcon icon_save_sim = QIcon::fromTheme("document-open", QIcon(":/images/save.png")); + act_save_sim = new QAction(icon_save_sim, tr("&Save simulation"), this); + act_save_sim->setShortcuts(QKeySequence::Save); + act_save_sim->setStatusTip(tr("Save the current TEM simulation")); + connect(act_save_sim, &QAction::triggered, this, &MainWindow::save_sim); + file_menu->addAction(act_save_sim); + file_tool_bar->addAction(act_save_sim); + act_save_sim->setEnabled(false); + + file_tool_bar->addSeparator(); + + /******************************************************************/ + act_save_as_sim = new QAction(tr("&Save simulation as"), this); + act_save_as_sim->setShortcuts(QKeySequence::SaveAs); + act_save_as_sim->setStatusTip(tr("Save the current TEM simulation")); + connect(act_save_as_sim, &QAction::triggered, this, &MainWindow::save_as_sim); + file_menu->addAction(act_save_as_sim); + + file_menu->addSeparator(); + + act_exit = new QAction(tr("&Exit"), this); + act_exit->setShortcuts(QKeySequence::Quit); + act_exit->setStatusTip(tr("Exit the application")); + connect(act_exit, &QAction::triggered, this, &MainWindow::exit); + file_menu->addAction(act_exit); + + /******************************************************************/ + const QIcon icon_default_sim = QIcon::fromTheme("Set default values", QIcon(":/images/default.png")); + act_default_sim = new QAction(icon_default_sim, tr("&Default values"), this); + act_default_sim->setShortcuts(QKeySequence::Save); + act_default_sim->setStatusTip(tr("Set default values")); + connect(act_default_sim, &QAction::triggered, this, &MainWindow::default_sim); + file_tool_bar->addAction(act_default_sim); + + const QIcon icon_start_sim = QIcon::fromTheme("Start simulation", QIcon(":/images/start.png")); + act_start_sim = new QAction(icon_start_sim, tr("&Start Simulation"), this); + act_start_sim->setStatusTip(tr("Start simulation")); + act_start_sim->setEnabled(false); + connect(act_start_sim, &QAction::triggered, this, &MainWindow::start_sim); + file_tool_bar->addAction(act_start_sim); + + const QIcon icon_stop_sim = QIcon::fromTheme("Stop simulation", QIcon(":/images/stop.png")); + act_stop_sim = new QAction(icon_stop_sim, tr("&Stop Simulation"), this); + act_stop_sim->setStatusTip(tr("Stop simulation")); + act_stop_sim->setEnabled(false); + connect(act_stop_sim, &QAction::triggered, this, &MainWindow::stop_sim); + file_tool_bar->addAction(act_stop_sim); + + file_tool_bar->addSeparator(); + + pb_progress_run = new QProgressBar; + pb_progress_run->setMinimum(0); + pb_progress_run->setMaximum(100); + pb_progress_run->setValue(0); + + file_tool_bar->addWidget(pb_progress_run); } /*******************************************************/ void MainWindow::read_system_configuration() { - system_conf.device = QVar_to_enum(cb_device->currentData()); - system_conf.precision = QVar_to_enum(cb_precision->currentData()); - system_conf.cpu_ncores = 1; - system_conf.cpu_nthread = sb_nthreads->value(); - system_conf.gpu_device = cb_gpu_card->currentData().toInt(); - system_conf.gpu_nstream = 1; - system_conf.active = true; + system_conf.device = QVar_to_enum(cb_device->currentData()); + system_conf.precision = QVar_to_enum(cb_precision->currentData()); + system_conf.cpu_ncores = 1; + system_conf.cpu_nthread = sb_nthreads->value(); + system_conf.gpu_device = cb_gpu_card->currentData().toInt(); + system_conf.gpu_nstream = 1; + system_conf.active = true; - system_conf.validate_parameters(); + system_conf.validate_parameters(); } template void MainWindow::read_input_multislice(mt::Input_Multislice &input_multislice) { - /************************ simulation type **************************/ - input_multislice.simulation_type = QVar_to_enum(cb_sim_type->currentData()); - - /*******************************************************************/ - input_multislice.interaction_model = QVar_to_enum(cb_elec_spec_int_model->currentData()); - input_multislice.potential_type = QVar_to_enum(cb_potential_type->currentData()); - - /*******************************************************************/ - input_multislice.operation_mode = mt::eOM_Normal; - input_multislice.reverse_multislice = false; - - /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = QVar_to_enum(cb_pn_model->currentData()); - input_multislice.pn_coh_contrib = ckb_pn_coh_contrib->isChecked(); - input_multislice.pn_single_conf = ckb_pn_single_conf->isChecked(); - input_multislice.pn_nconf = le_pn_nconf->text().toInt(); - input_multislice.pn_dim.set(cb_pn_dim->currentData().toInt()); - input_multislice.pn_seed = le_pn_seed->text().toInt(); - - if(input_multislice.is_specimen_required()) - { - /**************************** Specimen *****************************/ - auto ct_na = 1; - auto ct_nb = 1; - auto ct_nc = 1; - auto ct_a = 0; - auto ct_b = 0; - auto ct_c = 0; - auto ct_x0 = 0; - auto ct_y0 = 0; - - mt::Vector, mt::e_host> amorp_lay_info(0); - for(auto i = 0; itext().toDouble()*mt::c_deg_2_rad; - auto u_x = le_spec_rot_ux->text().toDouble(); - auto u_y = le_spec_rot_uy->text().toDouble(); - auto u_z = le_spec_rot_uz->text().toDouble(); - input_multislice.spec_rot_u0 = mt::r3d(u_x, u_y, u_z); - input_multislice.spec_rot_center_type = QVar_to_enum(cb_spec_rot_center_type->currentData()); - auto p_x = le_spec_rot_center_px->text().toDouble(); - auto p_y = le_spec_rot_center_py->text().toDouble(); - auto p_z = le_spec_rot_center_pz->text().toDouble(); - input_multislice.spec_rot_center_p = mt::r3d(p_x, p_y, p_z); - - /************************ Specimen thickness ***********************/ - input_multislice.thick_type = QVar_to_enum(cb_thk_type->currentData()); - if(!input_multislice.is_whole_spec()) - { - auto thk_0 = le_thk_0->text().toDouble(); - auto thk_d = le_thk_d->text().toDouble(); - auto thk_e = le_thk_e->text().toDouble() + mt::epsilon_rel(); - - auto n_thk = int(floor((thk_e-thk_0)/thk_d+0.5))+2; - input_multislice.thick.clear(); - input_multislice.thick.reserve(n_thk); - - auto thk = thk_0; - while(thk<=thk_e) - { - input_multislice.thick.push_back(thk); - thk += thk_d; - } - } - - /************************ Potential slicing ************************/ - input_multislice.potential_slicing = QVar_to_enum(cb_pot_slic_type->currentData()); -// atoms.dz = le_pot_slic_thick->text().toDouble(); -// input_multislice.atoms.dz = atoms.dz; - } - - auto lx = le_spec_lx->text().toDouble(); - auto ly = le_spec_ly->text().toDouble(); - auto dz = le_pot_slic_thick->text().toDouble(); - - /************************** xy sampling ****************************/ - auto nx = le_samp_nx->text().toDouble(); - auto ny = le_samp_nx->text().toDouble(); - bool bwl = ckb_samp_bandwidth->isChecked(); - bool pbc_xy = true; - - input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); - - /************************ Incident wave ****************************/ - auto iw_type = QVar_to_enum(cb_iw_type->currentData()); - input_multislice.set_incident_wave_type(iw_type); - - if(input_multislice.is_user_define_wave()) - { - mt::assign(iw_psi, input_multislice.iw_psi); - } - - // read iw_x and iw_y - auto iw_x = le_iw_x->text().toDouble(); - auto iw_y = le_iw_y->text().toDouble(); - - input_multislice.iw_x.clear(); - input_multislice.iw_x.push_back(iw_x); - - input_multislice.iw_y.clear(); - input_multislice.iw_y.push_back(iw_y); - - /********************* Microscope parameter ***********************/ - input_multislice.E_0 = le_mic_acc_vol->text().toDouble(); - input_multislice.theta = le_tilt_theta->text().toDouble(); - input_multislice.phi = le_tilt_phi->text().toDouble(); - - /********************* Illumination model *************************/ - input_multislice.illumination_model = QVar_to_enum(cb_illu_model->currentData()); - input_multislice.temporal_spatial_incoh = mt::eTSI_Temporal_Spatial; - - input_multislice.cond_lens.beta = le_illu_beta->text().toDouble()*mt::c_mrad_2_rad; // divergence semi-angle (mrad-->rad) - input_multislice.cond_lens.nbeta = le_illu_nbeta->text().toInt(); // Number of integration steps for the divergence semi-angle - - /*********************** Objective lens **************************/ - /********************* Symmetric aberrations *********************/ - input_multislice.cond_lens.c_30 = le_cl_sa_c_30->text().toDouble()*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) - input_multislice.cond_lens.c_50 = le_cl_sa_c_50->text().toDouble()*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) - input_multislice.cond_lens.m = le_cl_sa_m->text().toInt(); // momentum of the vortex - - input_multislice.cond_lens.c_10 = le_cl_sa_c_10->text().toDouble(); // defocus (Angstrom) - input_multislice.cond_lens.zero_defocus_type = QVar_to_enum(cb_cl_sa_c_10_zero->currentData()); // Zero defocus type - input_multislice.cond_lens.zero_defocus_plane = le_cl_sa_c_10_z->text().toDouble(); // Zero defocus position - input_multislice.cond_lens.sf = le_cl_sa_delta->text().toDouble(); // Defocus spread (Angstrom) - input_multislice.cond_lens.nsf = cb_cl_sa_ndelta->currentData().toInt(); // Number of integration steps for the defocus Spread - - /******************** Non-symmetric aberrations ******************/ - input_multislice.cond_lens.c_12 = le_cl_c_12->text().toDouble(); // 2-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_12 = le_cl_phi_12->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_21 = le_cl_c_21->text().toDouble(); // Axial coma (Angstrom) - input_multislice.cond_lens.phi_21 = le_cl_phi_21->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) - input_multislice.cond_lens.c_23 = le_cl_c_23->text().toDouble(); // 3-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_23 = le_cl_phi_23->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_32 = le_cl_c_32->text().toDouble(); // Axial star aberration (Angstrom) - input_multislice.cond_lens.phi_32 = le_cl_phi_32->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) - input_multislice.cond_lens.c_34 = le_cl_c_34->text().toDouble(); // 4-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_34 = le_cl_phi_34->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_41 = le_cl_c_41->text().toDouble(); // 4th order axial coma (Angstrom) - input_multislice.cond_lens.phi_41 = le_cl_phi_41->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) - input_multislice.cond_lens.c_43 = le_cl_c_43->text().toDouble(); // 3-lobe aberration (Angstrom) - input_multislice.cond_lens.phi_43 = le_cl_phi_43->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) - input_multislice.cond_lens.c_45 = le_cl_c_45->text().toDouble(); // 5-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_45 = le_cl_phi_45->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.c_52 = le_cl_c_52->text().toDouble(); // 5th order axial star aberration (Angstrom) - input_multislice.cond_lens.phi_52 = le_cl_phi_52->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) - input_multislice.cond_lens.c_54 = le_cl_c_54->text().toDouble(); // 5th order rosette aberration (Angstrom) - input_multislice.cond_lens.phi_54 = le_cl_phi_54->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration (degrees-->rad) - input_multislice.cond_lens.c_56 = le_cl_c_56->text().toDouble(); // 6-fold astigmatism (Angstrom) - input_multislice.cond_lens.phi_56 = le_cl_phi_56->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - - input_multislice.cond_lens.inner_aper_ang = le_cl_ar_min->text().toDouble()*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) - input_multislice.cond_lens.outer_aper_ang = le_cl_ar_max->text().toDouble()*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - - input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /*********************** Objective lens **************************/ - /********************* Symmetric aberrations *********************/ - input_multislice.obj_lens.c_30 = le_ol_sa_c_30->text().toDouble()*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) - input_multislice.obj_lens.c_50 = le_ol_sa_c_50->text().toDouble()*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) - input_multislice.obj_lens.m = le_ol_sa_m->text().toInt(); // momentum of the vortex - - input_multislice.obj_lens.c_10 = le_ol_sa_c_10->text().toDouble(); // defocus (Angstrom) - input_multislice.obj_lens.zero_defocus_type = QVar_to_enum(cb_ol_sa_c_10_zero->currentData()); // Zero defocus type - input_multislice.obj_lens.zero_defocus_plane = le_ol_sa_c_10_z->text().toDouble(); // Zero defocus position - input_multislice.obj_lens.sf = le_ol_sa_delta->text().toDouble(); // Defocus spread (Angstrom) - input_multislice.obj_lens.nsf = cb_ol_sa_ndelta->currentData().toInt(); // Number of integration steps for the defocus Spread - - /****************** Non-symmetric aberrations *******************/ - input_multislice.obj_lens.c_12 = le_ol_c_12->text().toDouble(); // 2-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_12 = le_ol_phi_12->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_21 = le_ol_c_21->text().toDouble(); // Axial coma (Angstrom) - input_multislice.obj_lens.phi_21 = le_ol_phi_21->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) - input_multislice.obj_lens.c_23 = le_ol_c_23->text().toDouble(); // 3-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_23 = le_ol_phi_23->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_32 = le_ol_c_32->text().toDouble(); // Axial star aberration (Angstrom) - input_multislice.obj_lens.phi_32 = le_ol_phi_32->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) - input_multislice.obj_lens.c_34 = le_ol_c_34->text().toDouble(); // 4-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_34 = le_ol_phi_34->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_41 = le_ol_c_41->text().toDouble(); // 4th order axial coma (Angstrom) - input_multislice.obj_lens.phi_41 = le_ol_phi_41->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) - input_multislice.obj_lens.c_43 = le_ol_c_43->text().toDouble(); // 3-lobe aberration (Angstrom) - input_multislice.obj_lens.phi_43 = le_ol_phi_43->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) - input_multislice.obj_lens.c_45 = le_ol_c_45->text().toDouble(); // 5-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_45 = le_ol_phi_45->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.c_52 = le_ol_c_52->text().toDouble(); // 5th order axial star aberration (Angstrom) - input_multislice.obj_lens.phi_52 = le_ol_phi_52->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) - input_multislice.obj_lens.c_54 = le_ol_c_54->text().toDouble(); // 5th order rosette aberration (Angstrom) - input_multislice.obj_lens.phi_54 = le_ol_phi_54->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration (degrees-->rad) - input_multislice.obj_lens.c_56 = le_ol_c_56->text().toDouble(); // 6-fold astigmatism (Angstrom) - input_multislice.obj_lens.phi_56 = le_ol_phi_56->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - - input_multislice.obj_lens.inner_aper_ang = le_ol_ar_min->text().toDouble()*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) - input_multislice.obj_lens.outer_aper_ang = le_ol_ar_max->text().toDouble()*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - - input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - - /************************* ISTEM/STEM **************************/ - if(input_multislice.is_scanning()) - { - input_multislice.scanning.type = QVar_to_enum(cb_stem_sc_type->currentData()); - input_multislice.scanning.pbc = ckb_stem_sc_incl_last_point->isChecked(); - input_multislice.scanning.ns = le_stem_sc_n_points->text().toInt(); - input_multislice.scanning.x0 = le_stem_sc_px_0->text().toDouble(); - input_multislice.scanning.y0 = le_stem_sc_py_0->text().toDouble(); - input_multislice.scanning.xe = le_stem_sc_px_e->text().toDouble(); - input_multislice.scanning.ye = le_stem_sc_py_e->text().toDouble(); - input_multislice.scanning.set_grid(); - } - - if(input_multislice.is_STEM()) - { - input_multislice.detector.type = QVar_to_enum(cb_stem_det_type->currentData()); - input_multislice.detector.assign(stem_detector); - - if(input_multislice.detector.is_detector_circular()) - { - auto lambda = mt::get_lambda(input_multislice.E_0); - for(auto idet=0; idettext().toDouble()*mt::c_deg_2_rad; - input_multislice.nrot = le_pcs_n_rotation->text().toInt(); - } - else if (input_multislice.is_EELS_EFTEM()) - { - mt::eSpace space = (input_multislice.is_EELS())?mt::eS_Reciprocal:mt::eS_Real; - - auto Z = cb_eels_element->currentData().toInt(); - auto E_loss = cb_eels_energy->currentText().toDouble()*mt::c_eV_2_keV; - auto collection_angle = le_eels_coll_angle->text().toDouble()*mt::c_mrad_2_rad; - auto m_selection = cb_eels_m_selection->currentData().toInt(); - auto channelling_type = QVar_to_enum(cb_eels_m_selection->currentData()); - - input_multislice.eels_fr.set_input_data(space, input_multislice.E_0, E_loss, m_selection, collection_angle, channelling_type, Z); - } - - input_multislice.validate_parameters(); + /************************ simulation type **************************/ + input_multislice.simulation_type = QVar_to_enum(cb_sim_type->currentData()); + + /*******************************************************************/ + input_multislice.interaction_model = QVar_to_enum(cb_elec_spec_int_model->currentData()); + input_multislice.potential_type = QVar_to_enum(cb_potential_type->currentData()); + + /*******************************************************************/ + input_multislice.operation_mode = mt::eOM_Normal; + input_multislice.reverse_multislice = false; + + /************** Electron-Phonon interaction model ******************/ + input_multislice.pn_model = QVar_to_enum(cb_pn_model->currentData()); + input_multislice.pn_coh_contrib = ckb_pn_coh_contrib->isChecked(); + input_multislice.pn_single_conf = ckb_pn_single_conf->isChecked(); + input_multislice.pn_nconf = le_pn_nconf->text().toInt(); + input_multislice.pn_dim.set(cb_pn_dim->currentData().toInt()); + input_multislice.pn_seed = le_pn_seed->text().toInt(); + + if(input_multislice.is_specimen_required()) + { + /**************************** Specimen *****************************/ + auto ct_na = 1; + auto ct_nb = 1; + auto ct_nc = 1; + auto ct_a = 0; + auto ct_b = 0; + auto ct_c = 0; + auto ct_x0 = 0; + auto ct_y0 = 0; + + mt::Vector, mt::e_host> amorp_lay_info(0); + for(auto i = 0; itext().toDouble()*mt::c_deg_2_rad; + auto u_x = le_spec_rot_ux->text().toDouble(); + auto u_y = le_spec_rot_uy->text().toDouble(); + auto u_z = le_spec_rot_uz->text().toDouble(); + input_multislice.spec_rot_u0 = mt::r3d(u_x, u_y, u_z); + input_multislice.spec_rot_center_type = QVar_to_enum(cb_spec_rot_center_type->currentData()); + auto p_x = le_spec_rot_center_px->text().toDouble(); + auto p_y = le_spec_rot_center_py->text().toDouble(); + auto p_z = le_spec_rot_center_pz->text().toDouble(); + input_multislice.spec_rot_center_p = mt::r3d(p_x, p_y, p_z); + + /************************ Specimen thickness ***********************/ + input_multislice.thick_type = QVar_to_enum(cb_thk_type->currentData()); + if(!input_multislice.is_whole_spec()) + { + auto thk_0 = le_thk_0->text().toDouble(); + auto thk_d = le_thk_d->text().toDouble(); + auto thk_e = le_thk_e->text().toDouble() + mt::epsilon_rel(); + + auto n_thk = int(floor((thk_e-thk_0)/thk_d+0.5))+2; + input_multislice.thick.clear(); + input_multislice.thick.reserve(n_thk); + + auto thk = thk_0; + while(thk<=thk_e) + { + input_multislice.thick.push_back(thk); + thk += thk_d; + } + } + + /************************ Potential slicing ************************/ + input_multislice.potential_slicing = QVar_to_enum(cb_pot_slic_type->currentData()); +// atoms.dz = le_pot_slic_thick->text().toDouble(); +// input_multislice.atoms.dz = atoms.dz; + } + + auto lx = le_spec_lx->text().toDouble(); + auto ly = le_spec_ly->text().toDouble(); + auto dz = le_pot_slic_thick->text().toDouble(); + + /************************** xy sampling ****************************/ + auto nx = le_samp_nx->text().toDouble(); + auto ny = le_samp_nx->text().toDouble(); + bool bwl = ckb_samp_bandwidth->isChecked(); + bool pbc_xy = true; + + input_multislice.grid_2d.set_input_data(nx, ny, lx, ly, dz, bwl, pbc_xy); + + /************************ Incident wave ****************************/ + auto iw_type = QVar_to_enum(cb_iw_type->currentData()); + input_multislice.set_incident_wave_type(iw_type); + + if(input_multislice.is_user_define_wave()) + { + mt::assign(iw_psi, input_multislice.iw_psi); + } + + // read iw_x and iw_y + auto iw_x = le_iw_x->text().toDouble(); + auto iw_y = le_iw_y->text().toDouble(); + + input_multislice.iw_x.clear(); + input_multislice.iw_x.push_back(iw_x); + + input_multislice.iw_y.clear(); + input_multislice.iw_y.push_back(iw_y); + + /********************* Microscope parameter ***********************/ + input_multislice.E_0 = le_mic_acc_vol->text().toDouble(); + input_multislice.theta = le_tilt_theta->text().toDouble(); + input_multislice.phi = le_tilt_phi->text().toDouble(); + + /********************* Illumination model *************************/ + input_multislice.illumination_model = QVar_to_enum(cb_illu_model->currentData()); + input_multislice.temporal_spatial_incoh = mt::eTSI_Temporal_Spatial; + + input_multislice.cond_lens.beta = le_illu_beta->text().toDouble()*mt::c_mrad_2_rad; // divergence semi-angle (mrad-->rad) + input_multislice.cond_lens.nbeta = le_illu_nbeta->text().toInt(); // Number of integration steps for the divergence semi-angle + + /*********************** Objective lens **************************/ + /********************* Symmetric aberrations *********************/ + input_multislice.cond_lens.c_30 = le_cl_sa_c_30->text().toDouble()*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) + input_multislice.cond_lens.c_50 = le_cl_sa_c_50->text().toDouble()*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) + input_multislice.cond_lens.m = le_cl_sa_m->text().toInt(); // momentum of the vortex + + input_multislice.cond_lens.c_10 = le_cl_sa_c_10->text().toDouble(); // defocus (Angstrom) + input_multislice.cond_lens.zero_defocus_type = QVar_to_enum(cb_cl_sa_c_10_zero->currentData()); // Zero defocus type + input_multislice.cond_lens.zero_defocus_plane = le_cl_sa_c_10_z->text().toDouble(); // Zero defocus position + input_multislice.cond_lens.sf = le_cl_sa_delta->text().toDouble(); // Defocus spread (Angstrom) + input_multislice.cond_lens.nsf = cb_cl_sa_ndelta->currentData().toInt(); // Number of integration steps for the defocus Spread + + /******************** Non-symmetric aberrations ******************/ + input_multislice.cond_lens.c_12 = le_cl_c_12->text().toDouble(); // 2-fold astigmatism (Angstrom) + input_multislice.cond_lens.phi_12 = le_cl_phi_12->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) + + input_multislice.cond_lens.c_21 = le_cl_c_21->text().toDouble(); // Axial coma (Angstrom) + input_multislice.cond_lens.phi_21 = le_cl_phi_21->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) + input_multislice.cond_lens.c_23 = le_cl_c_23->text().toDouble(); // 3-fold astigmatism (Angstrom) + input_multislice.cond_lens.phi_23 = le_cl_phi_23->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) + + input_multislice.cond_lens.c_32 = le_cl_c_32->text().toDouble(); // Axial star aberration (Angstrom) + input_multislice.cond_lens.phi_32 = le_cl_phi_32->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) + input_multislice.cond_lens.c_34 = le_cl_c_34->text().toDouble(); // 4-fold astigmatism (Angstrom) + input_multislice.cond_lens.phi_34 = le_cl_phi_34->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) + + input_multislice.cond_lens.c_41 = le_cl_c_41->text().toDouble(); // 4th order axial coma (Angstrom) + input_multislice.cond_lens.phi_41 = le_cl_phi_41->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) + input_multislice.cond_lens.c_43 = le_cl_c_43->text().toDouble(); // 3-lobe aberration (Angstrom) + input_multislice.cond_lens.phi_43 = le_cl_phi_43->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) + input_multislice.cond_lens.c_45 = le_cl_c_45->text().toDouble(); // 5-fold astigmatism (Angstrom) + input_multislice.cond_lens.phi_45 = le_cl_phi_45->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) + + input_multislice.cond_lens.c_52 = le_cl_c_52->text().toDouble(); // 5th order axial star aberration (Angstrom) + input_multislice.cond_lens.phi_52 = le_cl_phi_52->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) + input_multislice.cond_lens.c_54 = le_cl_c_54->text().toDouble(); // 5th order rosette aberration (Angstrom) + input_multislice.cond_lens.phi_54 = le_cl_phi_54->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration (degrees-->rad) + input_multislice.cond_lens.c_56 = le_cl_c_56->text().toDouble(); // 6-fold astigmatism (Angstrom) + input_multislice.cond_lens.phi_56 = le_cl_phi_56->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) + + input_multislice.cond_lens.inner_aper_ang = le_cl_ar_min->text().toDouble()*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) + input_multislice.cond_lens.outer_aper_ang = le_cl_ar_max->text().toDouble()*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) + + input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); + + /*********************** Objective lens **************************/ + /********************* Symmetric aberrations *********************/ + input_multislice.obj_lens.c_30 = le_ol_sa_c_30->text().toDouble()*mt::c_mm_2_Angs; // 3rd order spherical aberration (mm-->Angstrom) + input_multislice.obj_lens.c_50 = le_ol_sa_c_50->text().toDouble()*mt::c_mm_2_Angs; // 5th order spherical aberration (mm-->Angstrom) + input_multislice.obj_lens.m = le_ol_sa_m->text().toInt(); // momentum of the vortex + + input_multislice.obj_lens.c_10 = le_ol_sa_c_10->text().toDouble(); // defocus (Angstrom) + input_multislice.obj_lens.zero_defocus_type = QVar_to_enum(cb_ol_sa_c_10_zero->currentData()); // Zero defocus type + input_multislice.obj_lens.zero_defocus_plane = le_ol_sa_c_10_z->text().toDouble(); // Zero defocus position + input_multislice.obj_lens.sf = le_ol_sa_delta->text().toDouble(); // Defocus spread (Angstrom) + input_multislice.obj_lens.nsf = cb_ol_sa_ndelta->currentData().toInt(); // Number of integration steps for the defocus Spread + + /****************** Non-symmetric aberrations *******************/ + input_multislice.obj_lens.c_12 = le_ol_c_12->text().toDouble(); // 2-fold astigmatism (Angstrom) + input_multislice.obj_lens.phi_12 = le_ol_phi_12->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 2-fold astigmatism (degrees-->rad) + + input_multislice.obj_lens.c_21 = le_ol_c_21->text().toDouble(); // Axial coma (Angstrom) + input_multislice.obj_lens.phi_21 = le_ol_phi_21->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of axial coma (degrees-->rad) + input_multislice.obj_lens.c_23 = le_ol_c_23->text().toDouble(); // 3-fold astigmatism (Angstrom) + input_multislice.obj_lens.phi_23 = le_ol_phi_23->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 3-fold astigmatism (degrees-->rad) + + input_multislice.obj_lens.c_32 = le_ol_c_32->text().toDouble(); // Axial star aberration (Angstrom) + input_multislice.obj_lens.phi_32 = le_ol_phi_32->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of axial star aberration (degrees-->rad) + input_multislice.obj_lens.c_34 = le_ol_c_34->text().toDouble(); // 4-fold astigmatism (Angstrom) + input_multislice.obj_lens.phi_34 = le_ol_phi_34->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 4-fold astigmatism (degrees-->rad) + + input_multislice.obj_lens.c_41 = le_ol_c_41->text().toDouble(); // 4th order axial coma (Angstrom) + input_multislice.obj_lens.phi_41 = le_ol_phi_41->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 4th order axial coma (degrees-->rad) + input_multislice.obj_lens.c_43 = le_ol_c_43->text().toDouble(); // 3-lobe aberration (Angstrom) + input_multislice.obj_lens.phi_43 = le_ol_phi_43->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 3-lobe aberration (degrees-->rad) + input_multislice.obj_lens.c_45 = le_ol_c_45->text().toDouble(); // 5-fold astigmatism (Angstrom) + input_multislice.obj_lens.phi_45 = le_ol_phi_45->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5-fold astigmatism (degrees-->rad) + + input_multislice.obj_lens.c_52 = le_ol_c_52->text().toDouble(); // 5th order axial star aberration (Angstrom) + input_multislice.obj_lens.phi_52 = le_ol_phi_52->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5th order axial star aberration (degrees-->rad) + input_multislice.obj_lens.c_54 = le_ol_c_54->text().toDouble(); // 5th order rosette aberration (Angstrom) + input_multislice.obj_lens.phi_54 = le_ol_phi_54->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration (degrees-->rad) + input_multislice.obj_lens.c_56 = le_ol_c_56->text().toDouble(); // 6-fold astigmatism (Angstrom) + input_multislice.obj_lens.phi_56 = le_ol_phi_56->text().toDouble()*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) + + input_multislice.obj_lens.inner_aper_ang = le_ol_ar_min->text().toDouble()*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) + input_multislice.obj_lens.outer_aper_ang = le_ol_ar_max->text().toDouble()*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) + + input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); + + /************************* ISTEM/STEM **************************/ + if(input_multislice.is_scanning()) + { + input_multislice.scanning.type = QVar_to_enum(cb_stem_sc_type->currentData()); + input_multislice.scanning.pbc = ckb_stem_sc_incl_last_point->isChecked(); + input_multislice.scanning.ns = le_stem_sc_n_points->text().toInt(); + input_multislice.scanning.x0 = le_stem_sc_px_0->text().toDouble(); + input_multislice.scanning.y0 = le_stem_sc_py_0->text().toDouble(); + input_multislice.scanning.xe = le_stem_sc_px_e->text().toDouble(); + input_multislice.scanning.ye = le_stem_sc_py_e->text().toDouble(); + input_multislice.scanning.set_grid(); + } + + if(input_multislice.is_STEM()) + { + input_multislice.detector.type = QVar_to_enum(cb_stem_det_type->currentData()); + input_multislice.detector.assign(stem_detector); + + if(input_multislice.detector.is_detector_circular()) + { + auto lambda = mt::get_lambda(input_multislice.E_0); + for(auto idet=0; idettext().toDouble()*mt::c_deg_2_rad; + input_multislice.nrot = le_pcs_n_rotation->text().toInt(); + } + else if (input_multislice.is_EELS_EFTEM()) + { + mt::eSpace space = (input_multislice.is_EELS())?mt::eS_Reciprocal:mt::eS_Real; + + auto Z = cb_eels_element->currentData().toInt(); + auto E_loss = cb_eels_energy->currentText().toDouble()*mt::c_eV_2_keV; + auto collection_angle = le_eels_coll_angle->text().toDouble()*mt::c_mrad_2_rad; + auto m_selection = cb_eels_m_selection->currentData().toInt(); + auto channelling_type = QVar_to_enum(cb_eels_m_selection->currentData()); + + input_multislice.eels_fr.set_input_data(space, input_multislice.E_0, E_loss, m_selection, collection_angle, channelling_type, Z); + } + + input_multislice.validate_parameters(); } void MainWindow::set_specimen_enable(bool enable) { - lb_spec_n_atom_types->setEnabled(enable); - lb_spec_lx->setEnabled(enable); - le_spec_lx->setEnabled(enable); - lb_spec_ly->setEnabled(enable); - le_spec_ly->setEnabled(enable); - pb_spec_recenter->setEnabled(enable); + lb_spec_n_atom_types->setEnabled(enable); + lb_spec_lx->setEnabled(enable); + le_spec_lx->setEnabled(enable); + lb_spec_ly->setEnabled(enable); + le_spec_ly->setEnabled(enable); + pb_spec_recenter->setEnabled(enable); - gbg_spec_rot->setEnabled(enable); - gbg_thk->setEnabled(enable); - gbg_potential_slic->setEnabled(enable); + gbg_spec_rot->setEnabled(enable); + gbg_thk->setEnabled(enable); + gbg_potential_slic->setEnabled(enable); } void MainWindow::set_cb_iw_type_using_eTEM_Sim_Type(mt::eTEM_Sim_Type sim_type) { - auto iw_type = (mt::is_IWFS_IWRS(sim_type))?mt::eIWT_Convergent_Wave:mt::eIWT_Auto; - auto idx_iw_type = cb_iw_type->findData(QVariant(iw_type)); - cb_iw_type->setCurrentIndex(idx_iw_type); - cb_iw_type_currentIndexChanged(idx_iw_type); + auto iw_type = (mt::is_IWFS_IWRS(sim_type))?mt::eIWT_Convergent_Wave:mt::eIWT_Auto; + auto idx_iw_type = cb_iw_type->findData(QVariant(iw_type)); + cb_iw_type->setCurrentIndex(idx_iw_type); + cb_iw_type_currentIndexChanged(idx_iw_type); - // disable plane wave - auto bb_plane = mt::is_scanning(sim_type)||mt::is_CBED_CBEI(sim_type); - disable_item_cb_iw_type(mt::eIWT_Plane_Wave, bb_plane); + // disable plane wave + auto bb_plane = mt::is_scanning(sim_type)||mt::is_CBED_CBEI(sim_type); + disable_item_cb_iw_type(mt::eIWT_Plane_Wave, bb_plane); - // disable convergent beam - auto bb_cb = mt::is_ED_HRTEM(sim_type)||mt::is_PED_HCTEM(sim_type); - disable_item_cb_iw_type(mt::eIWT_Convergent_Wave, bb_cb); + // disable convergent beam + auto bb_cb = mt::is_ED_HRTEM(sim_type)||mt::is_PED_HCTEM(sim_type); + disable_item_cb_iw_type(mt::eIWT_Convergent_Wave, bb_cb); - // disable user define wave - auto bb_user_def = mt::is_PED_HCTEM(sim_type); - disable_item_cb_iw_type(mt::eIWT_User_Define_Wave, bb_user_def); + // disable user define wave + auto bb_user_def = mt::is_PED_HCTEM(sim_type); + disable_item_cb_iw_type(mt::eIWT_User_Define_Wave, bb_user_def); - // disable auto wave - auto bb_auto = mt::is_IWFS_IWRS(sim_type); - disable_item_cb_iw_type(mt::eIWT_Auto, bb_auto); + // disable auto wave + auto bb_auto = mt::is_IWFS_IWRS(sim_type); + disable_item_cb_iw_type(mt::eIWT_Auto, bb_auto); } void MainWindow::set_cb_illu_model_using_eTEM_Sim_Type(mt::eTEM_Sim_Type sim_type) { - auto bb_full_int = mt::is_EELS_EFTEM(sim_type)||mt::is_EWFS_EWRS(sim_type); - bb_full_int = bb_full_int||mt::is_IWFS_IWRS(sim_type)||mt::is_PPFS_PPRS(sim_type); - bb_full_int = bb_full_int||mt::is_TFFS_TFRS(sim_type); + auto bb_full_int = mt::is_EELS_EFTEM(sim_type)||mt::is_EWFS_EWRS(sim_type); + bb_full_int = bb_full_int||mt::is_IWFS_IWRS(sim_type)||mt::is_PPFS_PPRS(sim_type); + bb_full_int = bb_full_int||mt::is_TFFS_TFRS(sim_type); - auto bb_part_coh = bb_full_int||mt::is_STEM(sim_type)||mt::is_CBED(sim_type); + auto bb_part_coh = bb_full_int||mt::is_STEM(sim_type)||mt::is_CBED(sim_type); - disable_item_cb_illu_model(mt::eIM_Coherent, false); - disable_item_cb_illu_model(mt::eIM_Partial_Coherent, bb_part_coh); - disable_item_cb_illu_model(mt::eIM_Trans_Cross_Coef, true); - disable_item_cb_illu_model(mt::eIM_Full_Integration, bb_full_int); + disable_item_cb_illu_model(mt::eIM_Coherent, false); + disable_item_cb_illu_model(mt::eIM_Partial_Coherent, bb_part_coh); + disable_item_cb_illu_model(mt::eIM_Trans_Cross_Coef, true); + disable_item_cb_illu_model(mt::eIM_Full_Integration, bb_full_int); - cb_illu_model->setCurrentIndex(cb_illu_model->findData(mt::eIM_Coherent)); + cb_illu_model->setCurrentIndex(cb_illu_model->findData(mt::eIM_Coherent)); } /*******************************************************/ void MainWindow::default_general_dock_widget() { - if(cb_gpu_card->count()>0) - { - cb_device->setCurrentIndex(cb_device->findData(mt::e_device)); - cb_gpu_card->setCurrentIndex(0); - } - else - { - cb_device->setCurrentIndex(cb_device->findData(mt::e_host)); - } + if(cb_gpu_card->count()>0) + { + cb_device->setCurrentIndex(cb_device->findData(mt::e_device)); + cb_gpu_card->setCurrentIndex(0); + } + else + { + cb_device->setCurrentIndex(cb_device->findData(mt::e_host)); + } - cb_precision->setCurrentIndex(cb_precision->findData(mt::eP_float)); + cb_precision->setCurrentIndex(cb_precision->findData(mt::eP_float)); - sb_nthreads->setValue(sb_nthreads->maximum()); + sb_nthreads->setValue(sb_nthreads->maximum()); - cb_elec_spec_int_model->setCurrentIndex(cb_elec_spec_int_model->findData(mt::eESIM_Multislice)); - cb_potential_type->setCurrentIndex(cb_potential_type->findData(mt::ePT_Lobato_0_12)); + cb_elec_spec_int_model->setCurrentIndex(cb_elec_spec_int_model->findData(mt::eESIM_Multislice)); + cb_potential_type->setCurrentIndex(cb_potential_type->findData(mt::ePT_Lobato_0_12)); - cb_pn_model->setCurrentIndex(cb_pn_model->findData(mt::ePM_Frozen_Phonon)); - ckb_pn_coh_contrib->setChecked(false); - ckb_pn_single_conf->setChecked(false); - le_pn_nconf->setText("5"); - cb_pn_dim->setCurrentIndex(cb_pn_dim->findData(110)); - le_pn_seed->setText("300183"); - ckb_pn_auto_seed->setChecked(false); + cb_pn_model->setCurrentIndex(cb_pn_model->findData(mt::ePM_Frozen_Phonon)); + ckb_pn_coh_contrib->setChecked(false); + ckb_pn_single_conf->setChecked(false); + le_pn_nconf->setText("5"); + cb_pn_dim->setCurrentIndex(cb_pn_dim->findData(110)); + le_pn_seed->setText("300183"); + ckb_pn_auto_seed->setChecked(false); } void MainWindow::default_specimen_dock_widget() { - /*******************************************************/ - /**********************Specimen info********************/ - /*******************************************************/ - le_spec_file->clear(); - - lb_spec_n_atom_types->setText(tr(n_atoms_types_qba(0, 0))); - le_spec_lx->setText("0.000"); - le_spec_ly->setText("0.000"); - pb_spec_recenter->setEnabled(false); - - /*******************************************************/ - /*********************** Rotation **********************/ - /*******************************************************/ - le_spec_rot_theta->setText("0.000"); - le_spec_rot_ux->setText("1.0"); - le_spec_rot_uy->setText("0.0"); - le_spec_rot_uz->setText("0.0"); - - /*******************************************************/ - cb_spec_rot_center_type->setCurrentIndex(0); - cb_spec_rot_center_type_currentIndexChanged(0); - - le_spec_rot_center_px->setText("0.0"); - le_spec_rot_center_py->setText("0.0"); - le_spec_rot_center_pz->setText("0.0"); - - /*******************************************************/ - /*********************** Thickness *********************/ - /*******************************************************/ - cb_thk_type->setCurrentIndex(0); - cb_thk_type_currentIndexChanged(0); - - /***************************************************/ - le_thk_0->setText("0.0000"); - le_thk_d->setText("0.0000"); - le_thk_e->setText("0.0000"); - - /*******************************************************/ - /***************** Potential slicing *******************/ - /*******************************************************/ - cb_pot_slic_type->setCurrentIndex(0); - cb_pot_slic_type_currentIndexChanged(0); - - le_pot_slic_thick->setText("2.0000"); - - /*******************************************************/ - /********************** xy sampling ********************/ - /*******************************************************/ - le_samp_nx->setText("1024"); - le_samp_ny->setText("1024"); - ckb_samp_bandwidth->setChecked(false); - - /*******************************************************/ - /******************** Clear atoms **********************/ - /*******************************************************/ - atoms.clear(); - - le_iw_x->setText("0.000"); - le_iw_y->setText("0.000"); - le_stem_sc_px_e->setText("0.000"); - le_stem_sc_py_e->setText("0.000"); - - cb_eels_energy->clear(); - cb_eels_element->clear(); + /*******************************************************/ + /**********************Specimen info********************/ + /*******************************************************/ + le_spec_file->clear(); + + lb_spec_n_atom_types->setText(tr(n_atoms_types_qba(0, 0))); + le_spec_lx->setText("0.000"); + le_spec_ly->setText("0.000"); + pb_spec_recenter->setEnabled(false); + + /*******************************************************/ + /*********************** Rotation **********************/ + /*******************************************************/ + le_spec_rot_theta->setText("0.000"); + le_spec_rot_ux->setText("1.0"); + le_spec_rot_uy->setText("0.0"); + le_spec_rot_uz->setText("0.0"); + + /*******************************************************/ + cb_spec_rot_center_type->setCurrentIndex(0); + cb_spec_rot_center_type_currentIndexChanged(0); + + le_spec_rot_center_px->setText("0.0"); + le_spec_rot_center_py->setText("0.0"); + le_spec_rot_center_pz->setText("0.0"); + + /*******************************************************/ + /*********************** Thickness *********************/ + /*******************************************************/ + cb_thk_type->setCurrentIndex(0); + cb_thk_type_currentIndexChanged(0); + + /***************************************************/ + le_thk_0->setText("0.0000"); + le_thk_d->setText("0.0000"); + le_thk_e->setText("0.0000"); + + /*******************************************************/ + /***************** Potential slicing *******************/ + /*******************************************************/ + cb_pot_slic_type->setCurrentIndex(0); + cb_pot_slic_type_currentIndexChanged(0); + + le_pot_slic_thick->setText("2.0000"); + + /*******************************************************/ + /********************** xy sampling ********************/ + /*******************************************************/ + le_samp_nx->setText("1024"); + le_samp_ny->setText("1024"); + ckb_samp_bandwidth->setChecked(false); + + /*******************************************************/ + /******************** Clear atoms **********************/ + /*******************************************************/ + atoms.clear(); + + le_iw_x->setText("0.000"); + le_iw_y->setText("0.000"); + le_stem_sc_px_e->setText("0.000"); + le_stem_sc_py_e->setText("0.000"); + + cb_eels_energy->clear(); + cb_eels_element->clear(); } void MainWindow::default_iw_widget() { - cb_iw_type->setCurrentIndex(cb_iw_type->findData(mt::eIWT_Auto)); - le_iw_x->setText("0.000"); - le_iw_y->setText("0.000"); - le_iw_file->clear(); + cb_iw_type->setCurrentIndex(cb_iw_type->findData(mt::eIWT_Auto)); + le_iw_x->setText("0.000"); + le_iw_y->setText("0.000"); + le_iw_file->clear(); } void MainWindow::default_stem_widget() { - cb_stem_sc_type->setCurrentIndex(1); - ckb_stem_sc_incl_last_point->setChecked(true); - le_stem_sc_n_points->setText("10"); - cb_stem_sc_np_assign->setCurrentIndex(0); - le_stem_sc_px_0->setText("0.000"); - le_stem_sc_py_0->setText("0.000"); - le_stem_sc_px_e->setText("0.000"); - le_stem_sc_py_e->setText("0.000"); + cb_stem_sc_type->setCurrentIndex(1); + ckb_stem_sc_incl_last_point->setChecked(true); + le_stem_sc_n_points->setText("10"); + cb_stem_sc_np_assign->setCurrentIndex(0); + le_stem_sc_px_0->setText("0.000"); + le_stem_sc_py_0->setText("0.000"); + le_stem_sc_px_e->setText("0.000"); + le_stem_sc_py_e->setText("0.000"); - cb_stem_det_type->setCurrentIndex(cb_stem_det_type->findData(mt::eDT_Circular)); - le_stem_det_n_det->setText("1"); - cb_stem_det_type->setCurrentIndex(0); - cb_stem_det_type_currentIndexChanged(0); + cb_stem_det_type->setCurrentIndex(cb_stem_det_type->findData(mt::eDT_Circular)); + le_stem_det_n_det->setText("1"); + cb_stem_det_type->setCurrentIndex(0); + cb_stem_det_type_currentIndexChanged(0); - stem_detector.resize(cb_stem_det_k_det->count()); - le_stem_det_ideal_inner_angle->setText("40.000"); - le_stem_det_ideal_outer_angle->setText("100.000"); + stem_detector.resize(cb_stem_det_k_det->count()); + le_stem_det_ideal_inner_angle->setText("40.000"); + le_stem_det_ideal_outer_angle->setText("100.000"); - le_stem_det_exp_file->clear(); + le_stem_det_exp_file->clear(); } void MainWindow::default_pcs_widget() { - le_pcs_tilt_angle->setText("1.5"); - le_pcs_n_rotation->setText("4"); + le_pcs_tilt_angle->setText("1.5"); + le_pcs_n_rotation->setText("4"); } void MainWindow::default_eels_widget() { - cb_eels_energy->clear(); - cb_eels_element->clear(); - le_eels_coll_angle->setText("25.000"); - cb_eels_m_selection->setCurrentIndex(0); - cb_eels_channelling_type->setCurrentIndex(0); + cb_eels_energy->clear(); + cb_eels_element->clear(); + le_eels_coll_angle->setText("25.000"); + cb_eels_m_selection->setCurrentIndex(0); + cb_eels_channelling_type->setCurrentIndex(0); } void MainWindow::default_pptf_widget() { - cb_pptf_slice->clear(); + cb_pptf_slice->clear(); } void MainWindow::default_experiment_dock_widget() { - default_iw_widget(); - default_stem_widget(); - default_pcs_widget(); - default_eels_widget(); - default_pptf_widget(); + default_iw_widget(); + default_stem_widget(); + default_pcs_widget(); + default_eels_widget(); + default_pptf_widget(); - cb_sim_type->setCurrentIndex(cb_sim_type->findData(mt::eTEMST_EWRS)); + cb_sim_type->setCurrentIndex(cb_sim_type->findData(mt::eTEMST_EWRS)); } void MainWindow::default_condenser_lens_tab() { - le_cl_sa_c_30->setText("0.001"); - le_cl_sa_c_50->setText("0.000"); - le_cl_sa_m->setText("0"); - le_cl_sa_c_10->setText("0.000"); - cb_cl_sa_c_10_zero->setCurrentIndex(cb_cl_sa_c_10_zero->findData(mt::eZDT_First)); - le_cl_sa_c_10_z->setText("0.000"); - le_cl_sa_delta->setText("20.0"); - cb_cl_sa_ndelta->setCurrentIndex(6); - pb_cl_sa_c_10_opt_released(); + le_cl_sa_c_30->setText("0.001"); + le_cl_sa_c_50->setText("0.000"); + le_cl_sa_m->setText("0"); + le_cl_sa_c_10->setText("0.000"); + cb_cl_sa_c_10_zero->setCurrentIndex(cb_cl_sa_c_10_zero->findData(mt::eZDT_First)); + le_cl_sa_c_10_z->setText("0.000"); + le_cl_sa_delta->setText("20.0"); + cb_cl_sa_ndelta->setCurrentIndex(6); + pb_cl_sa_c_10_opt_released(); - le_cl_c_12->setText("0.000"); - le_cl_phi_12->setText("0.000"); + le_cl_c_12->setText("0.000"); + le_cl_phi_12->setText("0.000"); - le_cl_c_21->setText("0.000"); - le_cl_phi_21->setText("0.000"); + le_cl_c_21->setText("0.000"); + le_cl_phi_21->setText("0.000"); - le_cl_c_23->setText("0.000"); - le_cl_phi_23->setText("0.000"); + le_cl_c_23->setText("0.000"); + le_cl_phi_23->setText("0.000"); - le_cl_c_32->setText("0.000"); - le_cl_phi_32->setText("0.000"); + le_cl_c_32->setText("0.000"); + le_cl_phi_32->setText("0.000"); - le_cl_c_34->setText("0.000"); - le_cl_phi_34->setText("0.000"); + le_cl_c_34->setText("0.000"); + le_cl_phi_34->setText("0.000"); - le_cl_c_41->setText("0.000"); - le_cl_phi_41->setText("0.000"); + le_cl_c_41->setText("0.000"); + le_cl_phi_41->setText("0.000"); - le_cl_c_43->setText("0.000"); - le_cl_phi_43->setText("0.000"); + le_cl_c_43->setText("0.000"); + le_cl_phi_43->setText("0.000"); - le_cl_c_45->setText("0.000"); - le_cl_phi_45->setText("0.000"); + le_cl_c_45->setText("0.000"); + le_cl_phi_45->setText("0.000"); - le_cl_c_52->setText("0.000"); - le_cl_phi_52->setText("0.000"); + le_cl_c_52->setText("0.000"); + le_cl_phi_52->setText("0.000"); - le_cl_c_54->setText("0.000"); - le_cl_phi_54->setText("0.000"); + le_cl_c_54->setText("0.000"); + le_cl_phi_54->setText("0.000"); - le_cl_c_56->setText("0.000"); - le_cl_phi_56->setText("0.000"); + le_cl_c_56->setText("0.000"); + le_cl_phi_56->setText("0.000"); - le_cl_ar_min->setText("0.000"); - le_cl_ar_max->setText("21.000"); + le_cl_ar_min->setText("0.000"); + le_cl_ar_max->setText("21.000"); } void MainWindow::default_objective_lens_tab() { - le_ol_sa_c_30->setText("0.001"); - le_ol_sa_c_50->setText("0.000"); - le_ol_sa_m->setText("0"); - le_ol_sa_c_10->setText("0.000"); - cb_ol_sa_c_10_zero->setCurrentIndex(cb_ol_sa_c_10_zero->findData(mt::eZDT_Last)); - le_ol_sa_c_10_z->setText("0.000"); - le_ol_sa_delta->setText("20.0"); - cb_ol_sa_ndelta->setCurrentIndex(6); - pb_ol_sa_c_10_opt_released(); + le_ol_sa_c_30->setText("0.001"); + le_ol_sa_c_50->setText("0.000"); + le_ol_sa_m->setText("0"); + le_ol_sa_c_10->setText("0.000"); + cb_ol_sa_c_10_zero->setCurrentIndex(cb_ol_sa_c_10_zero->findData(mt::eZDT_Last)); + le_ol_sa_c_10_z->setText("0.000"); + le_ol_sa_delta->setText("20.0"); + cb_ol_sa_ndelta->setCurrentIndex(6); + pb_ol_sa_c_10_opt_released(); - le_ol_c_12->setText("0.000"); - le_ol_phi_12->setText("0.000"); + le_ol_c_12->setText("0.000"); + le_ol_phi_12->setText("0.000"); - le_ol_c_21->setText("0.000"); - le_ol_phi_21->setText("0.000"); + le_ol_c_21->setText("0.000"); + le_ol_phi_21->setText("0.000"); - le_ol_c_23->setText("0.000"); - le_ol_phi_23->setText("0.000"); + le_ol_c_23->setText("0.000"); + le_ol_phi_23->setText("0.000"); - le_ol_c_32->setText("0.000"); - le_ol_phi_32->setText("0.000"); + le_ol_c_32->setText("0.000"); + le_ol_phi_32->setText("0.000"); - le_ol_c_34->setText("0.000"); - le_ol_phi_34->setText("0.000"); + le_ol_c_34->setText("0.000"); + le_ol_phi_34->setText("0.000"); - le_ol_c_41->setText("0.000"); - le_ol_phi_41->setText("0.000"); + le_ol_c_41->setText("0.000"); + le_ol_phi_41->setText("0.000"); - le_ol_c_43->setText("0.000"); - le_ol_phi_43->setText("0.000"); + le_ol_c_43->setText("0.000"); + le_ol_phi_43->setText("0.000"); - le_ol_c_45->setText("0.000"); - le_ol_phi_45->setText("0.000"); + le_ol_c_45->setText("0.000"); + le_ol_phi_45->setText("0.000"); - le_ol_c_52->setText("0.000"); - le_ol_phi_52->setText("0.000"); + le_ol_c_52->setText("0.000"); + le_ol_phi_52->setText("0.000"); - le_ol_c_54->setText("0.000"); - le_ol_phi_54->setText("0.000"); + le_ol_c_54->setText("0.000"); + le_ol_phi_54->setText("0.000"); - le_ol_c_56->setText("0.000"); - le_ol_phi_56->setText("0.000"); + le_ol_c_56->setText("0.000"); + le_ol_phi_56->setText("0.000"); - le_ol_ar_min->setText("0.000"); - le_ol_ar_max->setText("0.000"); + le_ol_ar_min->setText("0.000"); + le_ol_ar_max->setText("0.000"); } void MainWindow::default_microscope_dock_widget() { - cb_mic_name->setCurrentIndex(0); - le_mic_acc_vol->setText("300.0"); + cb_mic_name->setCurrentIndex(0); + le_mic_acc_vol->setText("300.0"); - le_tilt_theta->setText("0.000"); - le_tilt_phi->setText("0.000"); + le_tilt_theta->setText("0.000"); + le_tilt_phi->setText("0.000"); - cb_illu_model->setCurrentIndex(cb_illu_model->findData(mt::eIM_Coherent)); - le_illu_beta->setText("0.100"); - le_illu_nbeta->setText("8"); + cb_illu_model->setCurrentIndex(cb_illu_model->findData(mt::eIM_Coherent)); + le_illu_beta->setText("0.100"); + le_illu_nbeta->setText("8"); - default_condenser_lens_tab(); - default_objective_lens_tab(); + default_condenser_lens_tab(); + default_objective_lens_tab(); } /*******************************************************/ void MainWindow::set_enable_running_simulation(bool enable) { - act_default_sim->setEnabled(enable); - act_start_sim->setEnabled(enable); - act_stop_sim->setEnabled(!enable); + act_default_sim->setEnabled(enable); + act_start_sim->setEnabled(enable); + act_stop_sim->setEnabled(!enable); - dw_general->setEnabled(enable); - dw_specimen->setEnabled(enable); - dw_simulation->setEnabled(enable); - dw_microscope->setEnabled(enable); + dw_general->setEnabled(enable); + dw_specimen->setEnabled(enable); + dw_simulation->setEnabled(enable); + dw_microscope->setEnabled(enable); } void MainWindow::set_objective_lens_tab_enable(boolean enable) { - lb_ol_sa_c_30->setEnabled(enable); - le_ol_sa_c_30->setEnabled(enable); - lb_ol_sa_c_50->setEnabled(enable); - le_ol_sa_c_50->setEnabled(enable); - lb_ol_sa_m->setEnabled(enable); - le_ol_sa_m->setEnabled(enable); + lb_ol_sa_c_30->setEnabled(enable); + le_ol_sa_c_30->setEnabled(enable); + lb_ol_sa_c_50->setEnabled(enable); + le_ol_sa_c_50->setEnabled(enable); + lb_ol_sa_m->setEnabled(enable); + le_ol_sa_m->setEnabled(enable); - lb_ol_sa_c_10->setEnabled(enable); - le_ol_sa_c_10->setEnabled(enable); - pb_ol_sa_c_10_opt->setEnabled(enable); - lb_ol_sa_c_10_zero->setEnabled(enable); - cb_ol_sa_c_10_zero->setEnabled(enable); - lb_ol_sa_c_10_z->setEnabled(enable); - le_ol_sa_c_10_z->setEnabled(enable); + lb_ol_sa_c_10->setEnabled(enable); + le_ol_sa_c_10->setEnabled(enable); + pb_ol_sa_c_10_opt->setEnabled(enable); + lb_ol_sa_c_10_zero->setEnabled(enable); + cb_ol_sa_c_10_zero->setEnabled(enable); + lb_ol_sa_c_10_z->setEnabled(enable); + le_ol_sa_c_10_z->setEnabled(enable); - lb_ol_sa_delta->setEnabled(enable); - le_ol_sa_delta->setEnabled(enable); - lb_ol_sa_ndelta->setEnabled(enable); - cb_ol_sa_ndelta->setEnabled(enable); + lb_ol_sa_delta->setEnabled(enable); + le_ol_sa_delta->setEnabled(enable); + lb_ol_sa_ndelta->setEnabled(enable); + cb_ol_sa_ndelta->setEnabled(enable); - gbge_ol_nsa->setEnabled(enable); + gbge_ol_nsa->setEnabled(enable); - gbh_ol_ar->setEnabled(enable); + gbh_ol_ar->setEnabled(enable); } /*******************************************************/ void MainWindow::create_iw_widget() { - lb_iw_type = new QLabel(tr("Type")); + lb_iw_type = new QLabel(tr("Type")); - cb_iw_type = new QComboBox; - cb_iw_type->setStatusTip(tr("Incident wave type")); - cb_iw_type->addItem(tr("Plane wave"), QVariant(mt::eIWT_Plane_Wave)); - cb_iw_type->setItemData(0, tr("Plane wave illumination"), Qt::ToolTipRole); - cb_iw_type->addItem(tr("Convergent wave"), QVariant(mt::eIWT_Convergent_Wave)); - cb_iw_type->setItemData(1, tr("Convergent wave illumination"), Qt::ToolTipRole); - cb_iw_type->addItem(tr("User define"), QVariant(mt::eIWT_User_Define_Wave)); - cb_iw_type->setItemData(2, tr("User define (matrix)"), Qt::ToolTipRole); - cb_iw_type->addItem(tr("Auto"), QVariant(mt::eIWT_Auto)); - cb_iw_type->setItemData(3, tr("It is defined by the experiment"), Qt::ToolTipRole); + cb_iw_type = new QComboBox; + cb_iw_type->setStatusTip(tr("Incident wave type")); + cb_iw_type->addItem(tr("Plane wave"), QVariant(mt::eIWT_Plane_Wave)); + cb_iw_type->setItemData(0, tr("Plane wave illumination"), Qt::ToolTipRole); + cb_iw_type->addItem(tr("Convergent wave"), QVariant(mt::eIWT_Convergent_Wave)); + cb_iw_type->setItemData(1, tr("Convergent wave illumination"), Qt::ToolTipRole); + cb_iw_type->addItem(tr("User define"), QVariant(mt::eIWT_User_Define_Wave)); + cb_iw_type->setItemData(2, tr("User define (matrix)"), Qt::ToolTipRole); + cb_iw_type->addItem(tr("Auto"), QVariant(mt::eIWT_Auto)); + cb_iw_type->setItemData(3, tr("It is defined by the experiment"), Qt::ToolTipRole); - /***************************************************/ - lb_iw_x = new QLabel(tr("X0 [Å]")); + /***************************************************/ + lb_iw_x = new QLabel(tr("X0 [Å]")); - le_iw_x = new QLineEdit; - le_iw_x->setStatusTip(tr("Initial x scan position")); - le_iw_x->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_iw_x->setText("0.000"); + le_iw_x = new QLineEdit; + le_iw_x->setStatusTip(tr("Initial x scan position")); + le_iw_x->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_iw_x->setText("0.000"); - lb_iw_y = new QLabel(tr("Y0 [Å]")); + lb_iw_y = new QLabel(tr("Y0 [Å]")); - le_iw_y = new QLineEdit; - le_iw_y->setStatusTip(tr("Initial y scan position")); - le_iw_y->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_iw_y->setText("0.000"); + le_iw_y = new QLineEdit; + le_iw_y->setStatusTip(tr("Initial y scan position")); + le_iw_y->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_iw_y->setText("0.000"); - pb_iw_p = new QPushButton(QIcon(":/images/cross_pointer.png"), ""); - pb_iw_p->setStatusTip(tr("Select position of the incidente wave")); - pb_iw_p->setMaximumSize(22, 22); + pb_iw_p = new QPushButton(QIcon(":/images/cross_pointer.png"), ""); + pb_iw_p->setStatusTip(tr("Select position of the incidente wave")); + pb_iw_p->setMaximumSize(22, 22); - /***************************************************/ - lb_iw_file = new QLabel(tr("Filename")); + /***************************************************/ + lb_iw_file = new QLabel(tr("Filename")); - le_iw_file = new QLineEdit; - le_iw_file->setStatusTip(tr("User define incident wave filename")); - le_iw_file->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + le_iw_file = new QLineEdit; + le_iw_file->setStatusTip(tr("User define incident wave filename")); + le_iw_file->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - set_non_editable_QLineEdit(le_iw_file); + set_non_editable_QLineEdit(le_iw_file); - pb_iw_load = new QPushButton(QIcon(":/images/open.png"), ""); - pb_iw_load->setStatusTip(tr("Load user define incident wave")); - pb_iw_load->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + pb_iw_load = new QPushButton(QIcon(":/images/open.png"), ""); + pb_iw_load->setStatusTip(tr("Load user define incident wave")); + pb_iw_load->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - /***************************************************/ - gbg_iw = new MGroupBox_G(tr("Incident wave")); - gbg_iw->addWidget(lb_iw_type, 0, 0); - gbg_iw->addWidget(cb_iw_type, 0, 1, 1, 4); + /***************************************************/ + gbg_iw = new MGroupBox_G(tr("Incident wave")); + gbg_iw->addWidget(lb_iw_type, 0, 0); + gbg_iw->addWidget(cb_iw_type, 0, 1, 1, 4); - gbg_iw->addWidget(lb_iw_x, 1, 0); - gbg_iw->addWidget(le_iw_x, 1, 1); - gbg_iw->addWidget(lb_iw_y, 1, 2); - gbg_iw->addWidget(le_iw_y, 1, 3); - gbg_iw->addWidget(pb_iw_p, 1, 4); + gbg_iw->addWidget(lb_iw_x, 1, 0); + gbg_iw->addWidget(le_iw_x, 1, 1); + gbg_iw->addWidget(lb_iw_y, 1, 2); + gbg_iw->addWidget(le_iw_y, 1, 3); + gbg_iw->addWidget(pb_iw_p, 1, 4); - gbg_iw->addWidget(lb_iw_file, 2, 0); - gbg_iw->addWidget(le_iw_file, 2, 1, 1, 3); - gbg_iw->addWidget(pb_iw_load, 2, 4); + gbg_iw->addWidget(lb_iw_file, 2, 0); + gbg_iw->addWidget(le_iw_file, 2, 1, 1, 3); + gbg_iw->addWidget(pb_iw_load, 2, 4); - connect(pb_iw_load, SIGNAL(released()), SLOT(pb_iw_load_released())); + connect(pb_iw_load, SIGNAL(released()), SLOT(pb_iw_load_released())); - auto layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSizeConstraint(QLayout::SetMinimumSize); - layout->addWidget(gbg_iw); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSizeConstraint(QLayout::SetMinimumSize); + layout->addWidget(gbg_iw); - wg_iw = new QWidget; - wg_iw->setLayout(layout); + wg_iw = new QWidget; + wg_iw->setLayout(layout); } void MainWindow::create_stem_widget() { - /*******************************************************/ - /**********************scannning************************/ - /*******************************************************/ - - lb_stem_sc_type = new QLabel(tr("Type")); - - cb_stem_sc_type = new QComboBox; - cb_stem_sc_type->setStatusTip(tr("Scan type")); - cb_stem_sc_type->addItem(tr("Line"), QVariant(1)); - cb_stem_sc_type->setItemData(0, tr("Scan along a line"), Qt::ToolTipRole); - cb_stem_sc_type->addItem(tr("Area"), QVariant(2)); - cb_stem_sc_type->setItemData(1, tr("Scan an area"), Qt::ToolTipRole); - cb_stem_sc_type->setCurrentIndex(1); - - lb_stem_sc_n_points = new QLabel(tr(x_sub_to_qba("N", "scans", "x-large"))); - lb_stem_sc_n_points->setAlignment(Qt::AlignHCenter); - - le_stem_sc_n_points = new QLineEdit; - le_stem_sc_n_points->setMaximumWidth(45); - le_stem_sc_n_points->setStatusTip(tr("Number of scanning points")); - le_stem_sc_n_points->setValidator(new QIntValidator(2, int_lim)); - le_stem_sc_n_points->setText("10"); - - lb_stem_sc_np_assign = new QLabel(tr("Assign")); - - cb_stem_sc_np_assign = new QComboBox; - cb_stem_sc_np_assign->setStatusTip(tr("Assign number of scanning points to Lx or Ly")); - cb_stem_sc_np_assign->addItem(tr("max"), QVariant(1)); - cb_stem_sc_np_assign->setItemData(0, tr("Assign number of scanning points to the maximun between Lx & Ly"), Qt::ToolTipRole); - cb_stem_sc_np_assign->addItem(tr("Lx"), QVariant(2)); - cb_stem_sc_np_assign->setItemData(1, tr("Assign number of scanning points to Lx"), Qt::ToolTipRole); - cb_stem_sc_np_assign->addItem(tr("Ly"), QVariant(3)); - cb_stem_sc_np_assign->setItemData(2, tr("Assign number of scanning points to Ly"), Qt::ToolTipRole); - cb_stem_sc_np_assign->setCurrentIndex(0); - - ckb_stem_sc_incl_last_point = new QCheckBox(tr("pbc")); - ckb_stem_sc_incl_last_point->setStatusTip(tr("Exclude last point in the scanning process")); - ckb_stem_sc_incl_last_point->setChecked(true); - - auto lyh_scanning = new QHBoxLayout; - lyh_scanning->setSpacing(3); - lyh_scanning->addWidget(cb_stem_sc_type); - lyh_scanning->addWidget(lb_stem_sc_n_points); - lyh_scanning->addWidget(le_stem_sc_n_points); - lyh_scanning->addWidget(cb_stem_sc_np_assign); - lyh_scanning->addWidget(ckb_stem_sc_incl_last_point); - /********************************************************/ - lb_stem_sc_px_0 = new QLabel(tr("X0 [Å]")); - - le_stem_sc_px_0 = new QLineEdit; - le_stem_sc_px_0->setStatusTip(tr("Initial x scan position")); - le_stem_sc_px_0->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_stem_sc_px_0->setText("0.000"); - - lb_stem_sc_py_0 = new QLabel(tr("Y0 [Å]")); - - le_stem_sc_py_0 = new QLineEdit; - le_stem_sc_py_0->setStatusTip(tr("Initial y scan position")); - le_stem_sc_py_0->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_stem_sc_py_0->setText("0.000"); - - pb_stem_sc_p_0 = new QPushButton(QIcon(":/images/cross_pointer.png"), ""); - pb_stem_sc_p_0->setStatusTip(tr("Select initial scanning point")); - pb_stem_sc_p_0->setMaximumSize(22, 22); - - lb_stem_sc_px_e = new QLabel(tr("Xe [Å]")); - - le_stem_sc_px_e = new QLineEdit; - le_stem_sc_px_e->setStatusTip(tr("Final x scan position")); - le_stem_sc_px_e->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_stem_sc_px_e->setText("0.000"); - - lb_stem_sc_py_e = new QLabel(tr("Ye [Å]")); - - le_stem_sc_py_e = new QLineEdit; - le_stem_sc_py_e->setStatusTip(tr("Final y scan position")); - le_stem_sc_py_e->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_stem_sc_py_e->setText("0.000"); - - pb_stem_sc_p_e = new QPushButton(QIcon(":/images/cross_pointer.png"), ""); - pb_stem_sc_p_e->setStatusTip(tr("Select end scanning point")); - pb_stem_sc_p_e->setMaximumSize(22, 22); - - gbg_stem_scanning = new MGroupBox_G(tr("Scanning")); - gbg_stem_scanning->layout->setVerticalSpacing(0); - - gbg_stem_scanning->layout->addLayout(lyh_scanning, 0, 0, 1, 5); - - gbg_stem_scanning->layout->setRowMinimumHeight(2, 2); - - auto hl_stem_scanning = new MLine_H; - gbg_stem_scanning->addWidget(hl_stem_scanning, 3, 0, 1, 5); - - gbg_stem_scanning->addWidget(lb_stem_sc_px_0, 4, 0); - gbg_stem_scanning->addWidget(le_stem_sc_px_0, 4, 1); - gbg_stem_scanning->addWidget(lb_stem_sc_py_0, 4, 2); - gbg_stem_scanning->addWidget(le_stem_sc_py_0, 4, 3); - gbg_stem_scanning->addWidget(pb_stem_sc_p_0, 4, 4); - - gbg_stem_scanning->addWidget(lb_stem_sc_px_e, 5, 0); - gbg_stem_scanning->addWidget(le_stem_sc_px_e, 5, 1); - gbg_stem_scanning->addWidget(lb_stem_sc_py_e, 5, 2); - gbg_stem_scanning->addWidget(le_stem_sc_py_e, 5, 3); - gbg_stem_scanning->addWidget(pb_stem_sc_p_e, 5, 4); - - /*******************************************************/ - /***********************detectors***********************/ - /*******************************************************/ - cb_stem_det_type = new QComboBox; - cb_stem_det_type->setStatusTip(tr("Detector types")); - cb_stem_det_type->addItem(tr("Ideal"), mt::eDT_Circular); - cb_stem_det_type->setItemData(0, tr("Ideal annular detector sensitivity"), Qt::ToolTipRole); - cb_stem_det_type->addItem(tr("Radial"), mt::eDT_Radial); - cb_stem_det_type->setItemData(1, tr("Radial detector sensitivity"), Qt::ToolTipRole); - cb_stem_det_type->addItem(tr("Matrix"), mt::eDT_Matrix); - cb_stem_det_type->setItemData(2, tr("Experimental image detector sensitivity"), Qt::ToolTipRole); - - disable_item_QComboBox(cb_stem_det_type, 1); - - /*******************************************************/ - lb_stem_det_n_det = new QLabel(tr(x_sub_to_qba("N", "det.", "x-large"))); - lb_stem_det_n_det->setAlignment(Qt::AlignCenter); - - le_stem_det_n_det = new QLineEdit; - le_stem_det_n_det->setMaximumWidth(45); - le_stem_det_n_det->setStatusTip(tr("Number of detectors")); - le_stem_det_n_det->setValidator(new QIntValidator(1, int_lim)); - le_stem_det_n_det->setText("1"); - - /*******************************************************/ - lb_stem_det_k_det = new QLabel(tr("Detector")); - lb_stem_det_k_det->setAlignment(Qt::AlignCenter); - - cb_stem_det_k_det = new QComboBox; - cb_stem_det_k_det->setStatusTip(tr("Select specific detector")); - cb_stem_det_k_det->addItem(tr("1"), QVariant(0)); - cb_stem_det_k_det->setCurrentIndex(0); - - stem_detector.resize(cb_stem_det_k_det->count()); - /***************************************************/ - pb_stem_det_view = new QPushButton(QIcon(":/images/view.png"), ""); - pb_stem_det_view->setStatusTip(tr("Show Detectpr")); - pb_stem_det_view->setMaximumSize(22, 22); - pb_stem_det_view->setEnabled(false); - - /***************************************************/ - auto lyh_stem_det= new QHBoxLayout; - lyh_stem_det->setContentsMargins(0, 0, 0, 0); - lyh_stem_det->setSpacing(2); - lyh_stem_det->addWidget(cb_stem_det_type); - lyh_stem_det->addWidget(lb_stem_det_n_det); - lyh_stem_det->addWidget(le_stem_det_n_det); - lyh_stem_det->addWidget(lb_stem_det_k_det); - lyh_stem_det->addWidget(cb_stem_det_k_det); - lyh_stem_det->addWidget(pb_stem_det_view); - - connect(le_stem_det_n_det, SIGNAL(editingFinished()), SLOT(le_stem_det_n_det_editingFinished())); - connect(cb_stem_det_k_det, SIGNAL(currentIndexChanged(int)), SLOT(cb_stem_det_k_det_currentIndexChanged(int))); - - /***************************************************/ - /*******************Ideal detector******************/ - /***************************************************/ - - /************Idel detector - inner angle************/ - lb_stem_det_ideal_inner_angle = new QLabel(tr("Inner [mrad]")); - - le_stem_det_ideal_inner_angle = new QLineEdit; - le_stem_det_ideal_inner_angle->setStatusTip(tr("Inner detector angle")); - le_stem_det_ideal_inner_angle->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_stem_det_ideal_inner_angle->setText("40.000"); - - /************Idel detector - outer angle************/ - lb_stem_det_ideal_outer_angle = new QLabel(tr("Outer [mrad]")); - - le_stem_det_ideal_outer_angle = new QLineEdit; - le_stem_det_ideal_outer_angle->setStatusTip(tr("Outer detector angle")); - le_stem_det_ideal_outer_angle->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_stem_det_ideal_outer_angle->setText("100.000"); - - /***************************************************/ - auto lyh_stem_det_ideal = new QHBoxLayout; - lyh_stem_det_ideal->setContentsMargins(2, 2, 2, 2); - lyh_stem_det_ideal->addWidget(lb_stem_det_ideal_inner_angle); - lyh_stem_det_ideal->addWidget(le_stem_det_ideal_inner_angle); - lyh_stem_det_ideal->addWidget(lb_stem_det_ideal_outer_angle); - lyh_stem_det_ideal->addWidget(le_stem_det_ideal_outer_angle); - - fr_stem_detector_ideal = new QFrame; - fr_stem_detector_ideal->setFrameStyle(QFrame::Box | QFrame::Sunken); - fr_stem_detector_ideal->setLineWidth(1); - fr_stem_detector_ideal->setLayout(lyh_stem_det_ideal); - - connect(le_stem_det_ideal_inner_angle, SIGNAL(editingFinished()), SLOT(le_stem_det_ideal_editingFinished())); - connect(le_stem_det_ideal_outer_angle, SIGNAL(editingFinished()), SLOT(le_stem_det_ideal_editingFinished())); - - /***************************************************/ - /*************Experimental detector*****************/ - /***************************************************/ - - lb_stem_det_exp_file = new QLabel(tr("Filename")); - - le_stem_det_exp_file = new QLineEdit; - le_stem_det_exp_file->setStatusTip(tr("Experimental detector sensitivity filename")); - le_stem_det_exp_file->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - - set_non_editable_QLineEdit(le_stem_det_exp_file); - - pb_stem_det_exp_load = new QPushButton(QIcon(":/images/open.png"), ""); - pb_stem_det_exp_load->setStatusTip(tr("Load experimental detector sensitivity")); - pb_stem_det_exp_load->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - - auto lyg_stem_detector_exp = new QGridLayout; - lyg_stem_detector_exp->setVerticalSpacing(0); - lyg_stem_detector_exp->setHorizontalSpacing(2); - lyg_stem_detector_exp->setContentsMargins(2, 2, 2, 2); - lyg_stem_detector_exp->addWidget(lb_stem_det_exp_file, 0, 0); - lyg_stem_detector_exp->addWidget(le_stem_det_exp_file, 0, 1); - lyg_stem_detector_exp->addWidget(pb_stem_det_exp_load, 0, 2); - - fr_stem_detector_exp = new QFrame; - fr_stem_detector_exp->setFrameStyle(QFrame::Box | QFrame::Sunken); - fr_stem_detector_exp->setLineWidth(1); - fr_stem_detector_exp->setLayout(lyg_stem_detector_exp); - - connect(pb_stem_det_exp_load, SIGNAL(released()), SLOT(pb_stem_det_exp_load_released())); - /***************************************************/ - gbg_stem_detector = new MGroupBox_G(tr("Detectors")); - gbg_stem_detector->layout->addLayout(lyh_stem_det, 0, 0); - gbg_stem_detector->layout->setRowMinimumHeight(1, 3); - gbg_stem_detector->addWidget(fr_stem_detector_ideal, 2, 0); - gbg_stem_detector->addWidget(fr_stem_detector_exp, 2, 0); - - connect(cb_stem_det_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_stem_det_type_currentIndexChanged(int))); - - cb_stem_det_type->setCurrentIndex(0); - cb_stem_det_type_currentIndexChanged(0); - - auto layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setContentsMargins(2, 1, 1, 0); - layout->setSizeConstraint(QLayout::SetMinimumSize); - layout->addWidget(gbg_stem_scanning); - layout->addWidget(gbg_stem_detector); - - wg_stem = new QWidget; - wg_stem->setLayout(layout); + /*******************************************************/ + /**********************scannning************************/ + /*******************************************************/ + + lb_stem_sc_type = new QLabel(tr("Type")); + + cb_stem_sc_type = new QComboBox; + cb_stem_sc_type->setStatusTip(tr("Scan type")); + cb_stem_sc_type->addItem(tr("Line"), QVariant(1)); + cb_stem_sc_type->setItemData(0, tr("Scan along a line"), Qt::ToolTipRole); + cb_stem_sc_type->addItem(tr("Area"), QVariant(2)); + cb_stem_sc_type->setItemData(1, tr("Scan an area"), Qt::ToolTipRole); + cb_stem_sc_type->setCurrentIndex(1); + + lb_stem_sc_n_points = new QLabel(tr(x_sub_to_qba("N", "scans", "x-large"))); + lb_stem_sc_n_points->setAlignment(Qt::AlignHCenter); + + le_stem_sc_n_points = new QLineEdit; + le_stem_sc_n_points->setMaximumWidth(45); + le_stem_sc_n_points->setStatusTip(tr("Number of scanning points")); + le_stem_sc_n_points->setValidator(new QIntValidator(2, int_lim)); + le_stem_sc_n_points->setText("10"); + + lb_stem_sc_np_assign = new QLabel(tr("Assign")); + + cb_stem_sc_np_assign = new QComboBox; + cb_stem_sc_np_assign->setStatusTip(tr("Assign number of scanning points to Lx or Ly")); + cb_stem_sc_np_assign->addItem(tr("max"), QVariant(1)); + cb_stem_sc_np_assign->setItemData(0, tr("Assign number of scanning points to the maximun between Lx & Ly"), Qt::ToolTipRole); + cb_stem_sc_np_assign->addItem(tr("Lx"), QVariant(2)); + cb_stem_sc_np_assign->setItemData(1, tr("Assign number of scanning points to Lx"), Qt::ToolTipRole); + cb_stem_sc_np_assign->addItem(tr("Ly"), QVariant(3)); + cb_stem_sc_np_assign->setItemData(2, tr("Assign number of scanning points to Ly"), Qt::ToolTipRole); + cb_stem_sc_np_assign->setCurrentIndex(0); + + ckb_stem_sc_incl_last_point = new QCheckBox(tr("pbc")); + ckb_stem_sc_incl_last_point->setStatusTip(tr("Exclude last point in the scanning process")); + ckb_stem_sc_incl_last_point->setChecked(true); + + auto lyh_scanning = new QHBoxLayout; + lyh_scanning->setSpacing(3); + lyh_scanning->addWidget(cb_stem_sc_type); + lyh_scanning->addWidget(lb_stem_sc_n_points); + lyh_scanning->addWidget(le_stem_sc_n_points); + lyh_scanning->addWidget(cb_stem_sc_np_assign); + lyh_scanning->addWidget(ckb_stem_sc_incl_last_point); + /********************************************************/ + lb_stem_sc_px_0 = new QLabel(tr("X0 [Å]")); + + le_stem_sc_px_0 = new QLineEdit; + le_stem_sc_px_0->setStatusTip(tr("Initial x scan position")); + le_stem_sc_px_0->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_stem_sc_px_0->setText("0.000"); + + lb_stem_sc_py_0 = new QLabel(tr("Y0 [Å]")); + + le_stem_sc_py_0 = new QLineEdit; + le_stem_sc_py_0->setStatusTip(tr("Initial y scan position")); + le_stem_sc_py_0->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_stem_sc_py_0->setText("0.000"); + + pb_stem_sc_p_0 = new QPushButton(QIcon(":/images/cross_pointer.png"), ""); + pb_stem_sc_p_0->setStatusTip(tr("Select initial scanning point")); + pb_stem_sc_p_0->setMaximumSize(22, 22); + + lb_stem_sc_px_e = new QLabel(tr("Xe [Å]")); + + le_stem_sc_px_e = new QLineEdit; + le_stem_sc_px_e->setStatusTip(tr("Final x scan position")); + le_stem_sc_px_e->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_stem_sc_px_e->setText("0.000"); + + lb_stem_sc_py_e = new QLabel(tr("Ye [Å]")); + + le_stem_sc_py_e = new QLineEdit; + le_stem_sc_py_e->setStatusTip(tr("Final y scan position")); + le_stem_sc_py_e->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_stem_sc_py_e->setText("0.000"); + + pb_stem_sc_p_e = new QPushButton(QIcon(":/images/cross_pointer.png"), ""); + pb_stem_sc_p_e->setStatusTip(tr("Select end scanning point")); + pb_stem_sc_p_e->setMaximumSize(22, 22); + + gbg_stem_scanning = new MGroupBox_G(tr("Scanning")); + gbg_stem_scanning->layout->setVerticalSpacing(0); + + gbg_stem_scanning->layout->addLayout(lyh_scanning, 0, 0, 1, 5); + + gbg_stem_scanning->layout->setRowMinimumHeight(2, 2); + + auto hl_stem_scanning = new MLine_H; + gbg_stem_scanning->addWidget(hl_stem_scanning, 3, 0, 1, 5); + + gbg_stem_scanning->addWidget(lb_stem_sc_px_0, 4, 0); + gbg_stem_scanning->addWidget(le_stem_sc_px_0, 4, 1); + gbg_stem_scanning->addWidget(lb_stem_sc_py_0, 4, 2); + gbg_stem_scanning->addWidget(le_stem_sc_py_0, 4, 3); + gbg_stem_scanning->addWidget(pb_stem_sc_p_0, 4, 4); + + gbg_stem_scanning->addWidget(lb_stem_sc_px_e, 5, 0); + gbg_stem_scanning->addWidget(le_stem_sc_px_e, 5, 1); + gbg_stem_scanning->addWidget(lb_stem_sc_py_e, 5, 2); + gbg_stem_scanning->addWidget(le_stem_sc_py_e, 5, 3); + gbg_stem_scanning->addWidget(pb_stem_sc_p_e, 5, 4); + + /*******************************************************/ + /***********************detectors***********************/ + /*******************************************************/ + cb_stem_det_type = new QComboBox; + cb_stem_det_type->setStatusTip(tr("Detector types")); + cb_stem_det_type->addItem(tr("Ideal"), mt::eDT_Circular); + cb_stem_det_type->setItemData(0, tr("Ideal annular detector sensitivity"), Qt::ToolTipRole); + cb_stem_det_type->addItem(tr("Radial"), mt::eDT_Radial); + cb_stem_det_type->setItemData(1, tr("Radial detector sensitivity"), Qt::ToolTipRole); + cb_stem_det_type->addItem(tr("Matrix"), mt::eDT_Matrix); + cb_stem_det_type->setItemData(2, tr("Experimental image detector sensitivity"), Qt::ToolTipRole); + + disable_item_QComboBox(cb_stem_det_type, 1); + + /*******************************************************/ + lb_stem_det_n_det = new QLabel(tr(x_sub_to_qba("N", "det.", "x-large"))); + lb_stem_det_n_det->setAlignment(Qt::AlignCenter); + + le_stem_det_n_det = new QLineEdit; + le_stem_det_n_det->setMaximumWidth(45); + le_stem_det_n_det->setStatusTip(tr("Number of detectors")); + le_stem_det_n_det->setValidator(new QIntValidator(1, int_lim)); + le_stem_det_n_det->setText("1"); + + /*******************************************************/ + lb_stem_det_k_det = new QLabel(tr("Detector")); + lb_stem_det_k_det->setAlignment(Qt::AlignCenter); + + cb_stem_det_k_det = new QComboBox; + cb_stem_det_k_det->setStatusTip(tr("Select specific detector")); + cb_stem_det_k_det->addItem(tr("1"), QVariant(0)); + cb_stem_det_k_det->setCurrentIndex(0); + + stem_detector.resize(cb_stem_det_k_det->count()); + /***************************************************/ + pb_stem_det_view = new QPushButton(QIcon(":/images/view.png"), ""); + pb_stem_det_view->setStatusTip(tr("Show Detectpr")); + pb_stem_det_view->setMaximumSize(22, 22); + pb_stem_det_view->setEnabled(false); + + /***************************************************/ + auto lyh_stem_det= new QHBoxLayout; + lyh_stem_det->setContentsMargins(0, 0, 0, 0); + lyh_stem_det->setSpacing(2); + lyh_stem_det->addWidget(cb_stem_det_type); + lyh_stem_det->addWidget(lb_stem_det_n_det); + lyh_stem_det->addWidget(le_stem_det_n_det); + lyh_stem_det->addWidget(lb_stem_det_k_det); + lyh_stem_det->addWidget(cb_stem_det_k_det); + lyh_stem_det->addWidget(pb_stem_det_view); + + connect(le_stem_det_n_det, SIGNAL(editingFinished()), SLOT(le_stem_det_n_det_editingFinished())); + connect(cb_stem_det_k_det, SIGNAL(currentIndexChanged(int)), SLOT(cb_stem_det_k_det_currentIndexChanged(int))); + + /***************************************************/ + /*******************Ideal detector******************/ + /***************************************************/ + + /************Idel detector - inner angle************/ + lb_stem_det_ideal_inner_angle = new QLabel(tr("Inner [mrad]")); + + le_stem_det_ideal_inner_angle = new QLineEdit; + le_stem_det_ideal_inner_angle->setStatusTip(tr("Inner detector angle")); + le_stem_det_ideal_inner_angle->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_stem_det_ideal_inner_angle->setText("40.000"); + + /************Idel detector - outer angle************/ + lb_stem_det_ideal_outer_angle = new QLabel(tr("Outer [mrad]")); + + le_stem_det_ideal_outer_angle = new QLineEdit; + le_stem_det_ideal_outer_angle->setStatusTip(tr("Outer detector angle")); + le_stem_det_ideal_outer_angle->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_stem_det_ideal_outer_angle->setText("100.000"); + + /***************************************************/ + auto lyh_stem_det_ideal = new QHBoxLayout; + lyh_stem_det_ideal->setContentsMargins(2, 2, 2, 2); + lyh_stem_det_ideal->addWidget(lb_stem_det_ideal_inner_angle); + lyh_stem_det_ideal->addWidget(le_stem_det_ideal_inner_angle); + lyh_stem_det_ideal->addWidget(lb_stem_det_ideal_outer_angle); + lyh_stem_det_ideal->addWidget(le_stem_det_ideal_outer_angle); + + fr_stem_detector_ideal = new QFrame; + fr_stem_detector_ideal->setFrameStyle(QFrame::Box | QFrame::Sunken); + fr_stem_detector_ideal->setLineWidth(1); + fr_stem_detector_ideal->setLayout(lyh_stem_det_ideal); + + connect(le_stem_det_ideal_inner_angle, SIGNAL(editingFinished()), SLOT(le_stem_det_ideal_editingFinished())); + connect(le_stem_det_ideal_outer_angle, SIGNAL(editingFinished()), SLOT(le_stem_det_ideal_editingFinished())); + + /***************************************************/ + /*************Experimental detector*****************/ + /***************************************************/ + + lb_stem_det_exp_file = new QLabel(tr("Filename")); + + le_stem_det_exp_file = new QLineEdit; + le_stem_det_exp_file->setStatusTip(tr("Experimental detector sensitivity filename")); + le_stem_det_exp_file->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + + set_non_editable_QLineEdit(le_stem_det_exp_file); + + pb_stem_det_exp_load = new QPushButton(QIcon(":/images/open.png"), ""); + pb_stem_det_exp_load->setStatusTip(tr("Load experimental detector sensitivity")); + pb_stem_det_exp_load->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + auto lyg_stem_detector_exp = new QGridLayout; + lyg_stem_detector_exp->setVerticalSpacing(0); + lyg_stem_detector_exp->setHorizontalSpacing(2); + lyg_stem_detector_exp->setContentsMargins(2, 2, 2, 2); + lyg_stem_detector_exp->addWidget(lb_stem_det_exp_file, 0, 0); + lyg_stem_detector_exp->addWidget(le_stem_det_exp_file, 0, 1); + lyg_stem_detector_exp->addWidget(pb_stem_det_exp_load, 0, 2); + + fr_stem_detector_exp = new QFrame; + fr_stem_detector_exp->setFrameStyle(QFrame::Box | QFrame::Sunken); + fr_stem_detector_exp->setLineWidth(1); + fr_stem_detector_exp->setLayout(lyg_stem_detector_exp); + + connect(pb_stem_det_exp_load, SIGNAL(released()), SLOT(pb_stem_det_exp_load_released())); + /***************************************************/ + gbg_stem_detector = new MGroupBox_G(tr("Detectors")); + gbg_stem_detector->layout->addLayout(lyh_stem_det, 0, 0); + gbg_stem_detector->layout->setRowMinimumHeight(1, 3); + gbg_stem_detector->addWidget(fr_stem_detector_ideal, 2, 0); + gbg_stem_detector->addWidget(fr_stem_detector_exp, 2, 0); + + connect(cb_stem_det_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_stem_det_type_currentIndexChanged(int))); + + cb_stem_det_type->setCurrentIndex(0); + cb_stem_det_type_currentIndexChanged(0); + + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->setContentsMargins(2, 1, 1, 0); + layout->setSizeConstraint(QLayout::SetMinimumSize); + layout->addWidget(gbg_stem_scanning); + layout->addWidget(gbg_stem_detector); + + wg_stem = new QWidget; + wg_stem->setLayout(layout); } void MainWindow::create_pcs_widget() { - lb_pcs_tilt_angle = new QLabel(tr("q [°]")); + lb_pcs_tilt_angle = new QLabel(tr("q [°]")); - le_pcs_tilt_angle = new QLineEdit; - le_pcs_tilt_angle->setStatusTip(tr("Precession angle")); - le_pcs_tilt_angle->setValidator(new QDoubleValidator(-25, 25, 3)); - le_pcs_tilt_angle->setText("1.5"); + le_pcs_tilt_angle = new QLineEdit; + le_pcs_tilt_angle->setStatusTip(tr("Precession angle")); + le_pcs_tilt_angle->setValidator(new QDoubleValidator(-25, 25, 3)); + le_pcs_tilt_angle->setText("1.5"); - /***************************************************/ - lb_pcs_n_rotation = new QLabel(tr("# of rotations")); + /***************************************************/ + lb_pcs_n_rotation = new QLabel(tr("# of rotations")); - le_pcs_n_rotation = new QLineEdit; - le_pcs_n_rotation->setStatusTip(tr("Number of rotation angles")); - le_pcs_n_rotation->setValidator(new QIntValidator(4, int_lim)); - le_pcs_n_rotation->setText("4"); + le_pcs_n_rotation = new QLineEdit; + le_pcs_n_rotation->setStatusTip(tr("Number of rotation angles")); + le_pcs_n_rotation->setValidator(new QIntValidator(4, int_lim)); + le_pcs_n_rotation->setText("4"); - /***************************************************/ - gbg_pcs = new MGroupBox_G(tr("Precession")); - gbg_pcs->addWidget(lb_pcs_tilt_angle, 0, 0); - gbg_pcs->addWidget(le_pcs_tilt_angle, 0, 1); + /***************************************************/ + gbg_pcs = new MGroupBox_G(tr("Precession")); + gbg_pcs->addWidget(lb_pcs_tilt_angle, 0, 0); + gbg_pcs->addWidget(le_pcs_tilt_angle, 0, 1); - gbg_pcs->addWidget(lb_pcs_n_rotation, 0, 2); - gbg_pcs->addWidget(le_pcs_n_rotation, 0, 3); + gbg_pcs->addWidget(lb_pcs_n_rotation, 0, 2); + gbg_pcs->addWidget(le_pcs_n_rotation, 0, 3); - auto layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setContentsMargins(2, 1, 1, 0); - layout->setSizeConstraint(QLayout::SetMinimumSize); - layout->addWidget(gbg_pcs); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->setContentsMargins(2, 1, 1, 0); + layout->setSizeConstraint(QLayout::SetMinimumSize); + layout->addWidget(gbg_pcs); - wg_pcs = new QWidget; - wg_pcs->setLayout(layout); + wg_pcs = new QWidget; + wg_pcs->setLayout(layout); } void MainWindow::create_eels_widget() { - lb_eels_element = new QLabel(tr("Element")); - lb_eels_element->setAlignment(Qt::AlignCenter); + lb_eels_element = new QLabel(tr("Element")); + lb_eels_element->setAlignment(Qt::AlignCenter); - cb_eels_element = new QComboBox; - cb_eels_element->setStatusTip(tr("Element name")); - cb_eels_element->setMaximumWidth(55); + cb_eels_element = new QComboBox; + cb_eels_element->setStatusTip(tr("Element name")); + cb_eels_element->setMaximumWidth(55); - /***************************************************/ - lb_eels_energy = new QLabel(tr("Energy")); + /***************************************************/ + lb_eels_energy = new QLabel(tr("Energy")); - cb_eels_energy = new QComboBox; - cb_eels_energy->setStatusTip(tr("Energy Loss")); - cb_eels_energy->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + cb_eels_energy = new QComboBox; + cb_eels_energy->setStatusTip(tr("Energy Loss")); + cb_eels_energy->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - /***************************************************/ - lb_eels_coll_angle = new QLabel(tr("q [mrad]")); + /***************************************************/ + lb_eels_coll_angle = new QLabel(tr("q [mrad]")); - le_eels_coll_angle = new QLineEdit; - le_eels_coll_angle->setStatusTip(tr("Collection angle")); - le_eels_coll_angle->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_eels_coll_angle->setText("25.000"); - le_eels_coll_angle->setMaximumWidth(55); + le_eels_coll_angle = new QLineEdit; + le_eels_coll_angle->setStatusTip(tr("Collection angle")); + le_eels_coll_angle->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_eels_coll_angle->setText("25.000"); + le_eels_coll_angle->setMaximumWidth(55); - /***************************************************/ - lb_eels_m_selection = new QLabel(tr("m selection")); + /***************************************************/ + lb_eels_m_selection = new QLabel(tr("m selection")); - cb_eels_m_selection = new QComboBox; - cb_eels_m_selection->setStatusTip(tr("MDOS selection rule")); - cb_eels_m_selection->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - cb_eels_m_selection->addItem(tr("Kx,Ky,Kz"), QVariant(3)); - cb_eels_m_selection->addItem(tr("Kx"), QVariant(-2)); - cb_eels_m_selection->addItem(tr("Ky"), QVariant(2)); - cb_eels_m_selection->addItem(tr("Kz"), QVariant(0)); - cb_eels_m_selection->addItem(tr("Kx-iKy"), QVariant(-1)); - cb_eels_m_selection->addItem(tr("Kx+iKy"), QVariant(1)); + cb_eels_m_selection = new QComboBox; + cb_eels_m_selection->setStatusTip(tr("MDOS selection rule")); + cb_eels_m_selection->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + cb_eels_m_selection->addItem(tr("Kx,Ky,Kz"), QVariant(3)); + cb_eels_m_selection->addItem(tr("Kx"), QVariant(-2)); + cb_eels_m_selection->addItem(tr("Ky"), QVariant(2)); + cb_eels_m_selection->addItem(tr("Kz"), QVariant(0)); + cb_eels_m_selection->addItem(tr("Kx-iKy"), QVariant(-1)); + cb_eels_m_selection->addItem(tr("Kx+iKy"), QVariant(1)); - cb_eels_m_selection->setCurrentIndex(0); + cb_eels_m_selection->setCurrentIndex(0); - /***************************************************/ - lb_eels_channelling_type = new QLabel(tr("Approx.")); + /***************************************************/ + lb_eels_channelling_type = new QLabel(tr("Approx.")); - cb_eels_channelling_type = new QComboBox; - cb_eels_channelling_type->setStatusTip(tr("Channelling approximation type")); - cb_eels_channelling_type->addItem(tr("Single Channelling approx."), enum_to_QVar(mt::eCT_Single_Channelling)); - cb_eels_channelling_type->setItemData(0, tr("Single Channelling approximation"), Qt::ToolTipRole); - cb_eels_channelling_type->addItem(tr("Mixed Channelling approx."), enum_to_QVar(mt::eCT_Mixed_Channelling)); - cb_eels_channelling_type->setItemData(1, tr("Mixed Channelling approximation"), Qt::ToolTipRole); - cb_eels_channelling_type->addItem(tr("Double Channelling"), enum_to_QVar(mt::eCT_Double_Channelling)); - cb_eels_channelling_type->setItemData(2, tr("Double Channelling"), Qt::ToolTipRole); + cb_eels_channelling_type = new QComboBox; + cb_eels_channelling_type->setStatusTip(tr("Channelling approximation type")); + cb_eels_channelling_type->addItem(tr("Single Channelling approx."), enum_to_QVar(mt::eCT_Single_Channelling)); + cb_eels_channelling_type->setItemData(0, tr("Single Channelling approximation"), Qt::ToolTipRole); + cb_eels_channelling_type->addItem(tr("Mixed Channelling approx."), enum_to_QVar(mt::eCT_Mixed_Channelling)); + cb_eels_channelling_type->setItemData(1, tr("Mixed Channelling approximation"), Qt::ToolTipRole); + cb_eels_channelling_type->addItem(tr("Double Channelling"), enum_to_QVar(mt::eCT_Double_Channelling)); + cb_eels_channelling_type->setItemData(2, tr("Double Channelling"), Qt::ToolTipRole); - cb_eels_channelling_type->setCurrentIndex(0); - /***************************************************/ - gbg_eels = new MGroupBox_G(tr("Energy Loss")); - gbg_eels->addWidget(lb_eels_element, 0, 0); - gbg_eels->addWidget(cb_eels_element, 0, 1); + cb_eels_channelling_type->setCurrentIndex(0); + /***************************************************/ + gbg_eels = new MGroupBox_G(tr("Energy Loss")); + gbg_eels->addWidget(lb_eels_element, 0, 0); + gbg_eels->addWidget(cb_eels_element, 0, 1); - gbg_eels->addWidget(lb_eels_energy, 0, 2); - gbg_eels->addWidget(cb_eels_energy, 0, 3); + gbg_eels->addWidget(lb_eels_energy, 0, 2); + gbg_eels->addWidget(cb_eels_energy, 0, 3); - gbg_eels->addWidget(lb_eels_coll_angle, 1, 0); - gbg_eels->addWidget(le_eels_coll_angle, 1, 1); + gbg_eels->addWidget(lb_eels_coll_angle, 1, 0); + gbg_eels->addWidget(le_eels_coll_angle, 1, 1); - gbg_eels->addWidget(lb_eels_m_selection, 1, 2); - gbg_eels->addWidget(cb_eels_m_selection, 1, 3); + gbg_eels->addWidget(lb_eels_m_selection, 1, 2); + gbg_eels->addWidget(cb_eels_m_selection, 1, 3); - gbg_eels->addWidget(lb_eels_channelling_type, 2, 0); - gbg_eels->addWidget(cb_eels_channelling_type, 2, 1, 1, 3); + gbg_eels->addWidget(lb_eels_channelling_type, 2, 0); + gbg_eels->addWidget(cb_eels_channelling_type, 2, 1, 1, 3); - auto layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setContentsMargins(2, 1, 1, 0); - layout->setSizeConstraint(QLayout::SetMinimumSize); - layout->addWidget(gbg_eels); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->setContentsMargins(2, 1, 1, 0); + layout->setSizeConstraint(QLayout::SetMinimumSize); + layout->addWidget(gbg_eels); - wg_eels = new QWidget; - wg_eels->setLayout(layout); + wg_eels = new QWidget; + wg_eels->setLayout(layout); - connect(cb_eels_element, SIGNAL(currentIndexChanged(int)), SLOT(cb_eels_element_currentIndexChanged(int))); + connect(cb_eels_element, SIGNAL(currentIndexChanged(int)), SLOT(cb_eels_element_currentIndexChanged(int))); } void MainWindow::create_pptf_widget() { - lb_pptf_n_slices = new QLabel(tr(n_slices_qba(0))); - lb_pptf_n_slices->setFrameStyle(QFrame::Box | QFrame::Sunken); - lb_pptf_n_slices->setAlignment(Qt::AlignCenter); - lb_pptf_n_slices->setMinimumHeight(22); - lb_pptf_n_slices->setMinimumWidth(60); + lb_pptf_n_slices = new QLabel(tr(n_slices_qba(0))); + lb_pptf_n_slices->setFrameStyle(QFrame::Box | QFrame::Sunken); + lb_pptf_n_slices->setAlignment(Qt::AlignCenter); + lb_pptf_n_slices->setMinimumHeight(22); + lb_pptf_n_slices->setMinimumWidth(60); - lb_pptf_slice = new QLabel(tr("Slice")); + lb_pptf_slice = new QLabel(tr("Slice")); - cb_pptf_slice = new QComboBox; - cb_pptf_slice->setStatusTip(tr("Slice")); - cb_pptf_slice->setMaximumWidth(50); + cb_pptf_slice = new QComboBox; + cb_pptf_slice->setStatusTip(tr("Slice")); + cb_pptf_slice->setMaximumWidth(50); - /***************************************************/ - gbh_pptf = new MGroupBox_H(tr("Projected potential")); - gbh_pptf->addWidget(lb_pptf_n_slices); - gbh_pptf->layout->addSpacing(4); - gbh_pptf->addWidget(lb_pptf_slice); - gbh_pptf->addWidget(cb_pptf_slice); - gbh_pptf->layout->addStretch(1); + /***************************************************/ + gbh_pptf = new MGroupBox_H(tr("Projected potential")); + gbh_pptf->addWidget(lb_pptf_n_slices); + gbh_pptf->layout->addSpacing(4); + gbh_pptf->addWidget(lb_pptf_slice); + gbh_pptf->addWidget(cb_pptf_slice); + gbh_pptf->layout->addStretch(1); - auto layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setContentsMargins(2, 1, 1, 0); - layout->setSizeConstraint(QLayout::SetMinimumSize); - layout->addWidget(gbh_pptf); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->setContentsMargins(2, 1, 1, 0); + layout->setSizeConstraint(QLayout::SetMinimumSize); + layout->addWidget(gbh_pptf); - wg_pptf = new QWidget; - wg_pptf->setLayout(layout); + wg_pptf = new QWidget; + wg_pptf->setLayout(layout); } void MainWindow::create_condenser_lens_tab(QWidget *&lens) { - /*******************************************************/ - /*****************Symmetrical aberrations***************/ - /*******************************************************/ - - /************3rd order spherical aberration************/ - lb_cl_sa_c_30 = new QLabel(tr(c_nm_to_qba(30, " [mm]"))); - lb_cl_sa_c_30->setAlignment(Qt::AlignCenter); - - le_cl_sa_c_30 = new QLineEdit; - le_cl_sa_c_30->setStatusTip(tr("3rd order spherical aberration")); - le_cl_sa_c_30->setValidator(new QDoubleValidator(-double_lim, double_lim, 5)); - le_cl_sa_c_30->setText("0.001"); - - /************5th order spherical aberration************/ - lb_cl_sa_c_50 = new QLabel(tr(c_nm_to_qba(50, " [mm]"))); - lb_cl_sa_c_50->setAlignment(Qt::AlignCenter); - - le_cl_sa_c_50 = new QLineEdit; - le_cl_sa_c_50->setStatusTip(tr("5th order spherical aberration")); - le_cl_sa_c_50->setValidator(new QDoubleValidator(-double_lim, double_lim, 5)); - le_cl_sa_c_50->setText("0.000"); - - /*******************Vortex momentum*********************/ - lb_cl_sa_m = new QLabel(tr("m")); - lb_cl_sa_m->setAlignment(Qt::AlignCenter); - - le_cl_sa_m = new QLineEdit; - le_cl_sa_m->setStatusTip(tr("Vortex momentum")); - le_cl_sa_m->setValidator(new QIntValidator(-int_lim, int_lim)); - le_cl_sa_m->setText("0"); - - /*************************Defocus***********************/ - lb_cl_sa_c_10 = new QLabel(tr(c_nm_to_qba(10, " [Å]"))); - lb_cl_sa_c_10->setAlignment(Qt::AlignCenter); - - le_cl_sa_c_10 = new QLineEdit; - le_cl_sa_c_10->setStatusTip(tr("Defocus [Å]")); - le_cl_sa_c_10->setValidator(new QDoubleValidator(-double_lim, double_lim, 3)); - le_cl_sa_c_10->setText("0.000"); - - pb_cl_sa_c_10_opt = new QPushButton(QIcon(":/images/opt.png"), ""); - pb_cl_sa_c_10_opt->setStatusTip(tr("Scherzer defocus")); - pb_cl_sa_c_10_opt->setMaximumSize(22, 22); - - /*******************************************************/ - lb_cl_sa_c_10_zero = new QLabel(tr("Focus at")); - - cb_cl_sa_c_10_zero = new QComboBox; - cb_cl_sa_c_10_zero->setStatusTip(tr("Position to focus the incident beam")); - cb_cl_sa_c_10_zero->addItem(tr("First atom"), QVariant(mt::eZDT_First)); - cb_cl_sa_c_10_zero->setItemData(0, tr("Focus at the first atom"), Qt::ToolTipRole); - cb_cl_sa_c_10_zero->addItem(tr("User def."), QVariant(mt::eZDT_User_Define)); - cb_cl_sa_c_10_zero->setItemData(1, tr("Focus at user define plane"), Qt::ToolTipRole); + /*******************************************************/ + /*****************Symmetrical aberrations***************/ + /*******************************************************/ + + /************3rd order spherical aberration************/ + lb_cl_sa_c_30 = new QLabel(tr(c_nm_to_qba(30, " [mm]"))); + lb_cl_sa_c_30->setAlignment(Qt::AlignCenter); + + le_cl_sa_c_30 = new QLineEdit; + le_cl_sa_c_30->setStatusTip(tr("3rd order spherical aberration")); + le_cl_sa_c_30->setValidator(new QDoubleValidator(-double_lim, double_lim, 5)); + le_cl_sa_c_30->setText("0.001"); + + /************5th order spherical aberration************/ + lb_cl_sa_c_50 = new QLabel(tr(c_nm_to_qba(50, " [mm]"))); + lb_cl_sa_c_50->setAlignment(Qt::AlignCenter); + + le_cl_sa_c_50 = new QLineEdit; + le_cl_sa_c_50->setStatusTip(tr("5th order spherical aberration")); + le_cl_sa_c_50->setValidator(new QDoubleValidator(-double_lim, double_lim, 5)); + le_cl_sa_c_50->setText("0.000"); + + /*******************Vortex momentum*********************/ + lb_cl_sa_m = new QLabel(tr("m")); + lb_cl_sa_m->setAlignment(Qt::AlignCenter); + + le_cl_sa_m = new QLineEdit; + le_cl_sa_m->setStatusTip(tr("Vortex momentum")); + le_cl_sa_m->setValidator(new QIntValidator(-int_lim, int_lim)); + le_cl_sa_m->setText("0"); + + /*************************Defocus***********************/ + lb_cl_sa_c_10 = new QLabel(tr(c_nm_to_qba(10, " [Å]"))); + lb_cl_sa_c_10->setAlignment(Qt::AlignCenter); + + le_cl_sa_c_10 = new QLineEdit; + le_cl_sa_c_10->setStatusTip(tr("Defocus [Å]")); + le_cl_sa_c_10->setValidator(new QDoubleValidator(-double_lim, double_lim, 3)); + le_cl_sa_c_10->setText("0.000"); + + pb_cl_sa_c_10_opt = new QPushButton(QIcon(":/images/opt.png"), ""); + pb_cl_sa_c_10_opt->setStatusTip(tr("Scherzer defocus")); + pb_cl_sa_c_10_opt->setMaximumSize(22, 22); + + /*******************************************************/ + lb_cl_sa_c_10_zero = new QLabel(tr("Focus at")); + + cb_cl_sa_c_10_zero = new QComboBox; + cb_cl_sa_c_10_zero->setStatusTip(tr("Position to focus the incident beam")); + cb_cl_sa_c_10_zero->addItem(tr("First atom"), QVariant(mt::eZDT_First)); + cb_cl_sa_c_10_zero->setItemData(0, tr("Focus at the first atom"), Qt::ToolTipRole); + cb_cl_sa_c_10_zero->addItem(tr("User def."), QVariant(mt::eZDT_User_Define)); + cb_cl_sa_c_10_zero->setItemData(1, tr("Focus at user define plane"), Qt::ToolTipRole); - /*******************************************************/ - lb_cl_sa_c_10_z = new QLabel(tr("Plane [Å]")); - - le_cl_sa_c_10_z = new QLineEdit; - le_cl_sa_c_10_z->setStatusTip(tr("Set focus plane")); - le_cl_sa_c_10_z->setValidator(new QDoubleValidator(-double_lim, double_lim, 3)); - le_cl_sa_c_10_z->setText("0.000"); + /*******************************************************/ + lb_cl_sa_c_10_z = new QLabel(tr("Plane [Å]")); + + le_cl_sa_c_10_z = new QLineEdit; + le_cl_sa_c_10_z->setStatusTip(tr("Set focus plane")); + le_cl_sa_c_10_z->setValidator(new QDoubleValidator(-double_lim, double_lim, 3)); + le_cl_sa_c_10_z->setText("0.000"); - /*******************************************************/ - lb_cl_sa_delta = new QLabel(tr("D [Å]")); - lb_cl_sa_delta->setAlignment(Qt::AlignCenter); - - le_cl_sa_delta = new QLineEdit; - le_cl_sa_delta->setStatusTip(tr("Defocus spread")); - le_cl_sa_delta->setValidator(new QDoubleValidator(0, std::numeric_limits::max(), 3)); - le_cl_sa_delta->setText("20.0"); - - /*******************************************************/ - lb_cl_sa_ndelta = new QLabel(tr("ND")); - lb_cl_sa_ndelta->setAlignment(Qt::AlignCenter); - - cb_cl_sa_ndelta = new QComboBox; - cb_cl_sa_ndelta->setStatusTip(tr("Number of integration points")); - for(auto ik=2; ik<=128; ik++) - { - cb_cl_sa_ndelta->addItem(QString::number(ik), QVariant(ik)); - } - cb_cl_sa_ndelta->setCurrentIndex(6); - - /*******************************************************/ - auto lyg_cl_sa = new QGridLayout; - lyg_cl_sa->setHorizontalSpacing(3); - lyg_cl_sa->setVerticalSpacing(0); - lyg_cl_sa->setContentsMargins(2, 1, 1, 0); + /*******************************************************/ + lb_cl_sa_delta = new QLabel(tr("D [Å]")); + lb_cl_sa_delta->setAlignment(Qt::AlignCenter); + + le_cl_sa_delta = new QLineEdit; + le_cl_sa_delta->setStatusTip(tr("Defocus spread")); + le_cl_sa_delta->setValidator(new QDoubleValidator(0, std::numeric_limits::max(), 3)); + le_cl_sa_delta->setText("20.0"); + + /*******************************************************/ + lb_cl_sa_ndelta = new QLabel(tr("ND")); + lb_cl_sa_ndelta->setAlignment(Qt::AlignCenter); + + cb_cl_sa_ndelta = new QComboBox; + cb_cl_sa_ndelta->setStatusTip(tr("Number of integration points")); + for(auto ik=2; ik<=128; ik++) + { + cb_cl_sa_ndelta->addItem(QString::number(ik), QVariant(ik)); + } + cb_cl_sa_ndelta->setCurrentIndex(6); + + /*******************************************************/ + auto lyg_cl_sa = new QGridLayout; + lyg_cl_sa->setHorizontalSpacing(3); + lyg_cl_sa->setVerticalSpacing(0); + lyg_cl_sa->setContentsMargins(2, 1, 1, 0); - lyg_cl_sa->addWidget(lb_cl_sa_c_30, 0, 0); - lyg_cl_sa->addWidget(le_cl_sa_c_30, 0, 1); - lyg_cl_sa->addWidget(lb_cl_sa_c_50, 0, 2); - lyg_cl_sa->addWidget(le_cl_sa_c_50, 0, 3); + lyg_cl_sa->addWidget(lb_cl_sa_c_30, 0, 0); + lyg_cl_sa->addWidget(le_cl_sa_c_30, 0, 1); + lyg_cl_sa->addWidget(lb_cl_sa_c_50, 0, 2); + lyg_cl_sa->addWidget(le_cl_sa_c_50, 0, 3); - lyg_cl_sa->addWidget(lb_cl_sa_m, 1, 0); - lyg_cl_sa->addWidget(le_cl_sa_m, 1, 1); - lyg_cl_sa->addWidget(lb_cl_sa_c_10, 1, 2); + lyg_cl_sa->addWidget(lb_cl_sa_m, 1, 0); + lyg_cl_sa->addWidget(le_cl_sa_m, 1, 1); + lyg_cl_sa->addWidget(lb_cl_sa_c_10, 1, 2); - auto lyh_c_10_opt = new QHBoxLayout; - lyh_c_10_opt->setSpacing(0); - lyh_c_10_opt->addWidget(le_cl_sa_c_10); - lyh_c_10_opt->addWidget(pb_cl_sa_c_10_opt); + auto lyh_c_10_opt = new QHBoxLayout; + lyh_c_10_opt->setSpacing(0); + lyh_c_10_opt->addWidget(le_cl_sa_c_10); + lyh_c_10_opt->addWidget(pb_cl_sa_c_10_opt); - lyg_cl_sa->addLayout(lyh_c_10_opt, 1, 3); - - lyg_cl_sa->addWidget(lb_cl_sa_c_10_zero, 2, 0); - lyg_cl_sa->addWidget(cb_cl_sa_c_10_zero, 2, 1); - lyg_cl_sa->addWidget(lb_cl_sa_c_10_z, 2, 2); - lyg_cl_sa->addWidget(le_cl_sa_c_10_z, 2, 3); + lyg_cl_sa->addLayout(lyh_c_10_opt, 1, 3); + + lyg_cl_sa->addWidget(lb_cl_sa_c_10_zero, 2, 0); + lyg_cl_sa->addWidget(cb_cl_sa_c_10_zero, 2, 1); + lyg_cl_sa->addWidget(lb_cl_sa_c_10_z, 2, 2); + lyg_cl_sa->addWidget(le_cl_sa_c_10_z, 2, 3); - lyg_cl_sa->addWidget(lb_cl_sa_delta, 3, 0); - lyg_cl_sa->addWidget(le_cl_sa_delta, 3, 1); - lyg_cl_sa->addWidget(lb_cl_sa_ndelta, 3, 2); - lyg_cl_sa->addWidget(cb_cl_sa_ndelta, 3, 3); + lyg_cl_sa->addWidget(lb_cl_sa_delta, 3, 0); + lyg_cl_sa->addWidget(le_cl_sa_delta, 3, 1); + lyg_cl_sa->addWidget(lb_cl_sa_ndelta, 3, 2); + lyg_cl_sa->addWidget(cb_cl_sa_ndelta, 3, 3); - connect(pb_cl_sa_c_10_opt, SIGNAL(released()), SLOT(pb_cl_sa_c_10_opt_released())); - pb_cl_sa_c_10_opt->click(); + connect(pb_cl_sa_c_10_opt, SIGNAL(released()), SLOT(pb_cl_sa_c_10_opt_released())); + pb_cl_sa_c_10_opt->click(); - connect(cb_cl_sa_c_10_zero, SIGNAL(currentIndexChanged(int)), SLOT(cb_cl_sa_c_10_zero_currentIndexChanged(int))); + connect(cb_cl_sa_c_10_zero, SIGNAL(currentIndexChanged(int)), SLOT(cb_cl_sa_c_10_zero_currentIndexChanged(int))); - cb_cl_sa_c_10_zero_currentIndexChanged(cb_cl_sa_c_10_zero->findData(mt::eZDT_First)); + cb_cl_sa_c_10_zero_currentIndexChanged(cb_cl_sa_c_10_zero->findData(mt::eZDT_First)); - /*******************************************************/ - /***************Nonsymmetrical aberrations**************/ - /*******************************************************/ + /*******************************************************/ + /***************Nonsymmetrical aberrations**************/ + /*******************************************************/ - /*******************2-fold astigmatism******************/ - lb_cl_c_12 = new QLabel(tr(c_nm_to_qba(12, " [Å]"))); + /*******************2-fold astigmatism******************/ + lb_cl_c_12 = new QLabel(tr(c_nm_to_qba(12, " [Å]"))); - le_cl_c_12 = new QLineEdit; - le_cl_c_12->setStatusTip(tr("2-fold astigmatism")); - le_cl_c_12->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_12->setText("0.000"); + le_cl_c_12 = new QLineEdit; + le_cl_c_12->setStatusTip(tr("2-fold astigmatism")); + le_cl_c_12->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_12->setText("0.000"); - lb_cl_phi_12 = new QLabel(tr(phi_nm_to_qba(12, " [°]"))); + lb_cl_phi_12 = new QLabel(tr(phi_nm_to_qba(12, " [°]"))); - le_cl_phi_12 = new QLineEdit; - le_cl_phi_12->setStatusTip(tr("Azimuthal angle of 2-fold astigmatism")); - le_cl_phi_12->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_12->setText("0.000"); + le_cl_phi_12 = new QLineEdit; + le_cl_phi_12->setStatusTip(tr("Azimuthal angle of 2-fold astigmatism")); + le_cl_phi_12->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_12->setText("0.000"); - /*******************************************************/ - /***************************c2**************************/ + /*******************************************************/ + /***************************c2**************************/ - /***********************Axial coma**********************/ - lb_cl_c_21 = new QLabel(tr(c_nm_to_qba(21, " [Å]"))); + /***********************Axial coma**********************/ + lb_cl_c_21 = new QLabel(tr(c_nm_to_qba(21, " [Å]"))); - le_cl_c_21 = new QLineEdit; - le_cl_c_21->setStatusTip(tr("Axial coma")); - le_cl_c_21->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_21->setText("0.000"); + le_cl_c_21 = new QLineEdit; + le_cl_c_21->setStatusTip(tr("Axial coma")); + le_cl_c_21->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_21->setText("0.000"); - lb_cl_phi_21 = new QLabel(tr(phi_nm_to_qba(21, " [°]"))); + lb_cl_phi_21 = new QLabel(tr(phi_nm_to_qba(21, " [°]"))); - le_cl_phi_21 = new QLineEdit; - le_cl_phi_21->setStatusTip(tr("Azimuthal angle of axial coma")); - le_cl_phi_21->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_21->setText("0.000"); + le_cl_phi_21 = new QLineEdit; + le_cl_phi_21->setStatusTip(tr("Azimuthal angle of axial coma")); + le_cl_phi_21->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_21->setText("0.000"); - /*******************3-fold astigmatism******************/ - lb_cl_c_23 = new QLabel(tr(c_nm_to_qba(23, " [Å]"))); + /*******************3-fold astigmatism******************/ + lb_cl_c_23 = new QLabel(tr(c_nm_to_qba(23, " [Å]"))); - le_cl_c_23 = new QLineEdit; - le_cl_c_23->setStatusTip(tr("3-fold astigmatism")); - le_cl_c_23->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_23->setText("0.000"); + le_cl_c_23 = new QLineEdit; + le_cl_c_23->setStatusTip(tr("3-fold astigmatism")); + le_cl_c_23->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_23->setText("0.000"); - lb_cl_phi_23 = new QLabel(tr(phi_nm_to_qba(23, " [°]"))); + lb_cl_phi_23 = new QLabel(tr(phi_nm_to_qba(23, " [°]"))); - le_cl_phi_23 = new QLineEdit; - le_cl_phi_23->setStatusTip(tr("Azimuthal angle of 3-fold astigmatism")); - le_cl_phi_23->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_23->setText("0.000"); + le_cl_phi_23 = new QLineEdit; + le_cl_phi_23->setStatusTip(tr("Azimuthal angle of 3-fold astigmatism")); + le_cl_phi_23->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_23->setText("0.000"); - /*******************************************************/ - /***************************c3**************************/ + /*******************************************************/ + /***************************c3**************************/ - /****************Axial star aberration******************/ - lb_cl_c_32 = new QLabel(tr(c_nm_to_qba(32, " [Å]"))); + /****************Axial star aberration******************/ + lb_cl_c_32 = new QLabel(tr(c_nm_to_qba(32, " [Å]"))); - le_cl_c_32 = new QLineEdit; - le_cl_c_32->setStatusTip(tr("Axial star aberration")); - le_cl_c_32->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_32->setText("0.000"); + le_cl_c_32 = new QLineEdit; + le_cl_c_32->setStatusTip(tr("Axial star aberration")); + le_cl_c_32->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_32->setText("0.000"); - lb_cl_phi_32 = new QLabel(tr(phi_nm_to_qba(32, " [°]"))); + lb_cl_phi_32 = new QLabel(tr(phi_nm_to_qba(32, " [°]"))); - le_cl_phi_32 = new QLineEdit; - le_cl_phi_32->setStatusTip(tr("Azimuthal angle of axial star aberration")); - le_cl_phi_32->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_32->setText("0.000"); + le_cl_phi_32 = new QLineEdit; + le_cl_phi_32->setStatusTip(tr("Azimuthal angle of axial star aberration")); + le_cl_phi_32->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_32->setText("0.000"); - /*******************4-fold astigmatism******************/ - lb_cl_c_34 = new QLabel(tr(c_nm_to_qba(34, " [Å]"))); + /*******************4-fold astigmatism******************/ + lb_cl_c_34 = new QLabel(tr(c_nm_to_qba(34, " [Å]"))); - le_cl_c_34 = new QLineEdit; - le_cl_c_34->setStatusTip(tr("4-fold astigmatism")); - le_cl_c_34->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_34->setText("0.000"); + le_cl_c_34 = new QLineEdit; + le_cl_c_34->setStatusTip(tr("4-fold astigmatism")); + le_cl_c_34->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_34->setText("0.000"); - lb_cl_phi_34 = new QLabel(tr(phi_nm_to_qba(34, " [°]"))); + lb_cl_phi_34 = new QLabel(tr(phi_nm_to_qba(34, " [°]"))); - le_cl_phi_34 = new QLineEdit; - le_cl_phi_34->setStatusTip(tr("Azimuthal angle of 4-fold astigmatism")); - le_cl_phi_34->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_34->setText("0.000"); + le_cl_phi_34 = new QLineEdit; + le_cl_phi_34->setStatusTip(tr("Azimuthal angle of 4-fold astigmatism")); + le_cl_phi_34->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_34->setText("0.000"); - /*******************************************************/ - /***************************c4**************************/ + /*******************************************************/ + /***************************c4**************************/ - /*****************4th order axial coma******************/ - lb_cl_c_41 = new QLabel(tr(c_nm_to_qba(41, " [Å]"))); + /*****************4th order axial coma******************/ + lb_cl_c_41 = new QLabel(tr(c_nm_to_qba(41, " [Å]"))); - le_cl_c_41 = new QLineEdit; - le_cl_c_41->setStatusTip(tr("4th order axial coma")); - le_cl_c_41->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_41->setText("0.000"); + le_cl_c_41 = new QLineEdit; + le_cl_c_41->setStatusTip(tr("4th order axial coma")); + le_cl_c_41->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_41->setText("0.000"); - lb_cl_phi_41 = new QLabel(tr(phi_nm_to_qba(41, " [°]"))); + lb_cl_phi_41 = new QLabel(tr(phi_nm_to_qba(41, " [°]"))); - le_cl_phi_41 = new QLineEdit; - le_cl_phi_41->setStatusTip(tr("Azimuthal angle of 4th order axial coma")); - le_cl_phi_41->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_41->setText("0.000"); + le_cl_phi_41 = new QLineEdit; + le_cl_phi_41->setStatusTip(tr("Azimuthal angle of 4th order axial coma")); + le_cl_phi_41->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_41->setText("0.000"); - /*******************3-lobe aberration******************/ - lb_cl_c_43 = new QLabel(tr(c_nm_to_qba(43, " [Å]"))); + /*******************3-lobe aberration******************/ + lb_cl_c_43 = new QLabel(tr(c_nm_to_qba(43, " [Å]"))); - le_cl_c_43 = new QLineEdit; - le_cl_c_43->setStatusTip(tr("3-lobe aberration")); - le_cl_c_43->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_43->setText("0.000"); + le_cl_c_43 = new QLineEdit; + le_cl_c_43->setStatusTip(tr("3-lobe aberration")); + le_cl_c_43->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_43->setText("0.000"); - lb_cl_phi_43 = new QLabel(tr(phi_nm_to_qba(43, " [°]"))); + lb_cl_phi_43 = new QLabel(tr(phi_nm_to_qba(43, " [°]"))); - le_cl_phi_43 = new QLineEdit; - le_cl_phi_43->setStatusTip(tr("Azimuthal angle of 3-lobe aberration")); - le_cl_phi_43->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_43->setText("0.000"); - - /*******************5-fold astigmatism******************/ - lb_cl_c_45 = new QLabel(tr(c_nm_to_qba(45, " [Å]"))); - - le_cl_c_45 = new QLineEdit; - le_cl_c_45->setStatusTip(tr("5-fold astigmatism")); - le_cl_c_45->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_45->setText("0.000"); - - lb_cl_phi_45 = new QLabel(tr(phi_nm_to_qba(45, " [°]"))); - - le_cl_phi_45 = new QLineEdit; - le_cl_phi_45->setStatusTip(tr("Azimuthal angle of 5-fold astigmatism")); - le_cl_phi_45->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_45->setText("0.000"); - - /*******************************************************/ - /***************************c5**************************/ - - /*************5th order axial star aberration***********/ - lb_cl_c_52 = new QLabel(tr(c_nm_to_qba(52, " [Å]"))); - - le_cl_c_52 = new QLineEdit; - le_cl_c_52->setStatusTip(tr("5th order axial star aberration")); - le_cl_c_52->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_52->setText("0.000"); - - lb_cl_phi_52 = new QLabel(tr(phi_nm_to_qba(52, " [°]"))); - - le_cl_phi_52 = new QLineEdit; - le_cl_phi_52->setStatusTip(tr("Azimuthal angle of 5th order axial star aberration")); - le_cl_phi_52->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_52->setText("0.000"); - - /**************5th order rosette aberration*************/ - lb_cl_c_54 = new QLabel(tr(c_nm_to_qba(54, " [Å]"))); - - le_cl_c_54 = new QLineEdit; - le_cl_c_54->setStatusTip(tr("5th order rosette aberration")); - le_cl_c_54->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_54->setText("0.000"); - - lb_cl_phi_54 = new QLabel(tr(phi_nm_to_qba(54, " [°]"))); - - le_cl_phi_54 = new QLineEdit; - le_cl_phi_54->setStatusTip(tr("Azimuthal angle of 5th order rosette aberration")); - le_cl_phi_54->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_54->setText("0.000"); - - /*******************6-fold astigmatism******************/ - lb_cl_c_56 = new QLabel(tr(c_nm_to_qba(56, " [Å]"))); - - le_cl_c_56 = new QLineEdit; - le_cl_c_56->setStatusTip(tr("6-fold astigmatism")); - le_cl_c_56->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_c_56->setText("0.000"); - - lb_cl_phi_56 = new QLabel(tr(phi_nm_to_qba(56, " [°]"))); - - le_cl_phi_56 = new QLineEdit; - le_cl_phi_56->setStatusTip(tr("Azimuthal angle of 6-fold astigmatism")); - le_cl_phi_56->setValidator(new QDoubleValidator(-360, 360, 3)); - le_cl_phi_56->setText("0.000"); - - gbge_cl_nsa = new MGroupBox_GE(tr("Nonsymmetrical aberrations")); - gbge_cl_nsa->layout->setVerticalSpacing(0); - - gbge_cl_nsa->addWidget(lb_cl_c_12, 0, 0); - gbge_cl_nsa->addWidget(le_cl_c_12, 0, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_12, 0, 2); - gbge_cl_nsa->addWidget(le_cl_phi_12, 0, 3); - - gbge_cl_nsa->addWidget(lb_cl_c_21, 1, 0); - gbge_cl_nsa->addWidget(le_cl_c_21, 1, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_21, 1, 2); - gbge_cl_nsa->addWidget(le_cl_phi_21, 1, 3); - gbge_cl_nsa->addWidget(lb_cl_c_23, 2, 0); - gbge_cl_nsa->addWidget(le_cl_c_23, 2, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_23, 2, 2); - gbge_cl_nsa->addWidget(le_cl_phi_23, 2, 3); - - gbge_cl_nsa->addWidget(lb_cl_c_32, 3, 0); - gbge_cl_nsa->addWidget(le_cl_c_32, 3, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_32, 3, 2); - gbge_cl_nsa->addWidget(le_cl_phi_32, 3, 3); - gbge_cl_nsa->addWidget(lb_cl_c_34, 4, 0); - gbge_cl_nsa->addWidget(le_cl_c_34, 4, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_34, 4, 2); - gbge_cl_nsa->addWidget(le_cl_phi_34, 4, 3); - - gbge_cl_nsa->addWidget(lb_cl_c_41, 5, 0); - gbge_cl_nsa->addWidget(le_cl_c_41, 5, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_41, 5, 2); - gbge_cl_nsa->addWidget(le_cl_phi_41, 5, 3); - gbge_cl_nsa->addWidget(lb_cl_c_43, 6, 0); - gbge_cl_nsa->addWidget(le_cl_c_43, 6, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_43, 6, 2); - gbge_cl_nsa->addWidget(le_cl_phi_43, 6, 3); - gbge_cl_nsa->addWidget(lb_cl_c_45, 7, 0); - gbge_cl_nsa->addWidget(le_cl_c_45, 7, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_45, 7, 2); - gbge_cl_nsa->addWidget(le_cl_phi_45, 7, 3); - - gbge_cl_nsa->addWidget(lb_cl_c_52, 8, 0); - gbge_cl_nsa->addWidget(le_cl_c_52, 8, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_52, 8, 2); - gbge_cl_nsa->addWidget(le_cl_phi_52, 8, 3); - gbge_cl_nsa->addWidget(lb_cl_c_54, 9, 0); - gbge_cl_nsa->addWidget(le_cl_c_54, 9, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_54, 9, 2); - gbge_cl_nsa->addWidget(le_cl_phi_54, 9, 3); - gbge_cl_nsa->addWidget(lb_cl_c_56, 10, 0); - gbge_cl_nsa->addWidget(le_cl_c_56, 10, 1); - gbge_cl_nsa->addWidget(lb_cl_phi_56, 10, 2); - gbge_cl_nsa->addWidget(le_cl_phi_56, 10, 3); - - /*******************************************************/ - /*********************Aperture radius*******************/ - /*******************************************************/ - lb_cl_ar_min = new QLabel(tr("rmin [mrad]")); - - le_cl_ar_min = new QLineEdit; - le_cl_ar_min->setStatusTip(tr("Minimum aperture radius")); - le_cl_ar_min->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_ar_min->setText("0.000"); - - lb_cl_ar_max = new QLabel(tr("rmax [mrad]")); - - le_cl_ar_max = new QLineEdit; - le_cl_ar_max->setStatusTip(tr("Maximum aperture radius")); - le_cl_ar_max->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_cl_ar_max->setText("21.000"); - - gbh_cl_ar = new MGroupBox_H(tr("Aperture radius")); - gbh_cl_ar->addWidget(lb_cl_ar_min, le_cl_ar_min, lb_cl_ar_max, le_cl_ar_max); - - /*******************************************************/ - /*********************Condenser lens********************/ - /*******************************************************/ - auto layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setContentsMargins(2, 1, 1, 0); - layout->addLayout(lyg_cl_sa); - layout->addWidget(gbge_cl_nsa); - layout->addWidget(gbh_cl_ar); - layout->addStretch(); - - lens = new QWidget; - lens->setLayout(layout); + le_cl_phi_43 = new QLineEdit; + le_cl_phi_43->setStatusTip(tr("Azimuthal angle of 3-lobe aberration")); + le_cl_phi_43->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_43->setText("0.000"); + + /*******************5-fold astigmatism******************/ + lb_cl_c_45 = new QLabel(tr(c_nm_to_qba(45, " [Å]"))); + + le_cl_c_45 = new QLineEdit; + le_cl_c_45->setStatusTip(tr("5-fold astigmatism")); + le_cl_c_45->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_45->setText("0.000"); + + lb_cl_phi_45 = new QLabel(tr(phi_nm_to_qba(45, " [°]"))); + + le_cl_phi_45 = new QLineEdit; + le_cl_phi_45->setStatusTip(tr("Azimuthal angle of 5-fold astigmatism")); + le_cl_phi_45->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_45->setText("0.000"); + + /*******************************************************/ + /***************************c5**************************/ + + /*************5th order axial star aberration***********/ + lb_cl_c_52 = new QLabel(tr(c_nm_to_qba(52, " [Å]"))); + + le_cl_c_52 = new QLineEdit; + le_cl_c_52->setStatusTip(tr("5th order axial star aberration")); + le_cl_c_52->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_52->setText("0.000"); + + lb_cl_phi_52 = new QLabel(tr(phi_nm_to_qba(52, " [°]"))); + + le_cl_phi_52 = new QLineEdit; + le_cl_phi_52->setStatusTip(tr("Azimuthal angle of 5th order axial star aberration")); + le_cl_phi_52->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_52->setText("0.000"); + + /**************5th order rosette aberration*************/ + lb_cl_c_54 = new QLabel(tr(c_nm_to_qba(54, " [Å]"))); + + le_cl_c_54 = new QLineEdit; + le_cl_c_54->setStatusTip(tr("5th order rosette aberration")); + le_cl_c_54->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_54->setText("0.000"); + + lb_cl_phi_54 = new QLabel(tr(phi_nm_to_qba(54, " [°]"))); + + le_cl_phi_54 = new QLineEdit; + le_cl_phi_54->setStatusTip(tr("Azimuthal angle of 5th order rosette aberration")); + le_cl_phi_54->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_54->setText("0.000"); + + /*******************6-fold astigmatism******************/ + lb_cl_c_56 = new QLabel(tr(c_nm_to_qba(56, " [Å]"))); + + le_cl_c_56 = new QLineEdit; + le_cl_c_56->setStatusTip(tr("6-fold astigmatism")); + le_cl_c_56->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_c_56->setText("0.000"); + + lb_cl_phi_56 = new QLabel(tr(phi_nm_to_qba(56, " [°]"))); + + le_cl_phi_56 = new QLineEdit; + le_cl_phi_56->setStatusTip(tr("Azimuthal angle of 6-fold astigmatism")); + le_cl_phi_56->setValidator(new QDoubleValidator(-360, 360, 3)); + le_cl_phi_56->setText("0.000"); + + gbge_cl_nsa = new MGroupBox_GE(tr("Nonsymmetrical aberrations")); + gbge_cl_nsa->layout->setVerticalSpacing(0); + + gbge_cl_nsa->addWidget(lb_cl_c_12, 0, 0); + gbge_cl_nsa->addWidget(le_cl_c_12, 0, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_12, 0, 2); + gbge_cl_nsa->addWidget(le_cl_phi_12, 0, 3); + + gbge_cl_nsa->addWidget(lb_cl_c_21, 1, 0); + gbge_cl_nsa->addWidget(le_cl_c_21, 1, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_21, 1, 2); + gbge_cl_nsa->addWidget(le_cl_phi_21, 1, 3); + gbge_cl_nsa->addWidget(lb_cl_c_23, 2, 0); + gbge_cl_nsa->addWidget(le_cl_c_23, 2, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_23, 2, 2); + gbge_cl_nsa->addWidget(le_cl_phi_23, 2, 3); + + gbge_cl_nsa->addWidget(lb_cl_c_32, 3, 0); + gbge_cl_nsa->addWidget(le_cl_c_32, 3, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_32, 3, 2); + gbge_cl_nsa->addWidget(le_cl_phi_32, 3, 3); + gbge_cl_nsa->addWidget(lb_cl_c_34, 4, 0); + gbge_cl_nsa->addWidget(le_cl_c_34, 4, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_34, 4, 2); + gbge_cl_nsa->addWidget(le_cl_phi_34, 4, 3); + + gbge_cl_nsa->addWidget(lb_cl_c_41, 5, 0); + gbge_cl_nsa->addWidget(le_cl_c_41, 5, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_41, 5, 2); + gbge_cl_nsa->addWidget(le_cl_phi_41, 5, 3); + gbge_cl_nsa->addWidget(lb_cl_c_43, 6, 0); + gbge_cl_nsa->addWidget(le_cl_c_43, 6, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_43, 6, 2); + gbge_cl_nsa->addWidget(le_cl_phi_43, 6, 3); + gbge_cl_nsa->addWidget(lb_cl_c_45, 7, 0); + gbge_cl_nsa->addWidget(le_cl_c_45, 7, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_45, 7, 2); + gbge_cl_nsa->addWidget(le_cl_phi_45, 7, 3); + + gbge_cl_nsa->addWidget(lb_cl_c_52, 8, 0); + gbge_cl_nsa->addWidget(le_cl_c_52, 8, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_52, 8, 2); + gbge_cl_nsa->addWidget(le_cl_phi_52, 8, 3); + gbge_cl_nsa->addWidget(lb_cl_c_54, 9, 0); + gbge_cl_nsa->addWidget(le_cl_c_54, 9, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_54, 9, 2); + gbge_cl_nsa->addWidget(le_cl_phi_54, 9, 3); + gbge_cl_nsa->addWidget(lb_cl_c_56, 10, 0); + gbge_cl_nsa->addWidget(le_cl_c_56, 10, 1); + gbge_cl_nsa->addWidget(lb_cl_phi_56, 10, 2); + gbge_cl_nsa->addWidget(le_cl_phi_56, 10, 3); + + /*******************************************************/ + /*********************Aperture radius*******************/ + /*******************************************************/ + lb_cl_ar_min = new QLabel(tr("rmin [mrad]")); + + le_cl_ar_min = new QLineEdit; + le_cl_ar_min->setStatusTip(tr("Minimum aperture radius")); + le_cl_ar_min->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_ar_min->setText("0.000"); + + lb_cl_ar_max = new QLabel(tr("rmax [mrad]")); + + le_cl_ar_max = new QLineEdit; + le_cl_ar_max->setStatusTip(tr("Maximum aperture radius")); + le_cl_ar_max->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_cl_ar_max->setText("21.000"); + + gbh_cl_ar = new MGroupBox_H(tr("Aperture radius")); + gbh_cl_ar->addWidget(lb_cl_ar_min, le_cl_ar_min, lb_cl_ar_max, le_cl_ar_max); + + /*******************************************************/ + /*********************Condenser lens********************/ + /*******************************************************/ + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->setContentsMargins(2, 1, 1, 0); + layout->addLayout(lyg_cl_sa); + layout->addWidget(gbge_cl_nsa); + layout->addWidget(gbh_cl_ar); + layout->addStretch(); + + lens = new QWidget; + lens->setLayout(layout); } void MainWindow::create_objective_lens_tab(QWidget *&lens) { - /*******************************************************/ - /*****************Symmetrical aberrations***************/ - /*******************************************************/ - /************3rd order spherical aberration************/ - lb_ol_sa_c_30 = new QLabel(tr(c_nm_to_qba(30, " [mm]"))); - - le_ol_sa_c_30 = new QLineEdit; - le_ol_sa_c_30->setStatusTip(tr("3rd order spherical aberration")); - le_ol_sa_c_30->setValidator(new QDoubleValidator(-double_lim, double_lim, 5)); - le_ol_sa_c_30->setText("0.001"); - - /************5th order spherical aberration************/ - lb_ol_sa_c_50 = new QLabel(tr(c_nm_to_qba(50, " [mm]"))); - - le_ol_sa_c_50 = new QLineEdit; - le_ol_sa_c_50->setStatusTip(tr("5th order spherical aberration")); - le_ol_sa_c_50->setValidator(new QDoubleValidator(-double_lim, double_lim, 5)); - le_ol_sa_c_50->setText("0.000"); - - /*******************Vortex momentum*********************/ - lb_ol_sa_m = new QLabel(tr("m")); - lb_ol_sa_m->setAlignment(Qt::AlignCenter); - - le_ol_sa_m = new QLineEdit; - le_ol_sa_m->setStatusTip(tr("Vortex momentum")); - le_ol_sa_m->setValidator(new QIntValidator(-int_lim, int_lim)); - le_ol_sa_m->setText("0"); - - /*************************Defocus***********************/ - lb_ol_sa_c_10 = new QLabel(tr(c_nm_to_qba(10, " [Å]"))); - - le_ol_sa_c_10 = new QLineEdit; - le_ol_sa_c_10->setStatusTip(tr("Defocus [Å]")); - le_ol_sa_c_10->setValidator(new QDoubleValidator(-double_lim, double_lim, 3)); - le_ol_sa_c_10->setText("0.000"); - - pb_ol_sa_c_10_opt = new QPushButton(QIcon(":/images/opt.png"), ""); - pb_ol_sa_c_10_opt->setStatusTip(tr("Scherzer defocus")); - pb_ol_sa_c_10_opt->setMaximumSize(22, 22); - - lb_ol_sa_c_10_zero = new QLabel(tr("Zero focus")); - - cb_ol_sa_c_10_zero = new QComboBox; - cb_ol_sa_c_10_zero->setStatusTip(tr("Zero reference focus")); - cb_ol_sa_c_10_zero->addItem(tr("First atom"), QVariant(mt::eZDT_First)); - cb_ol_sa_c_10_zero->setItemData(0, tr("Zero focus located at the first atom"), Qt::ToolTipRole); - cb_ol_sa_c_10_zero->addItem(tr("Half thick."), QVariant(mt::eZDT_Middle)); - cb_ol_sa_c_10_zero->setItemData(1, tr("Zero focus located at half thickness"), Qt::ToolTipRole); - cb_ol_sa_c_10_zero->addItem(tr("Last atom"), QVariant(mt::eZDT_Last)); - cb_ol_sa_c_10_zero->setItemData(2, tr("Zero focus located at the last atom"), Qt::ToolTipRole); - cb_ol_sa_c_10_zero->addItem(tr("User def."), QVariant(mt::eZDT_User_Define)); - cb_ol_sa_c_10_zero->setItemData(3, tr("Zero focus located at user define plane"), Qt::ToolTipRole); - lb_ol_sa_c_10_z = new QLabel(tr("Plane [Å]")); - - le_ol_sa_c_10_z = new QLineEdit; - le_ol_sa_c_10_z->setStatusTip(tr("Set focus plane")); - le_ol_sa_c_10_z->setValidator(new QDoubleValidator(-double_lim, double_lim, 3)); - le_ol_sa_c_10_z->setText("0.000"); - - /*******************************************************/ - lb_ol_sa_delta = new QLabel(tr("D [Å]")); - lb_ol_sa_delta->setAlignment(Qt::AlignCenter); - - le_ol_sa_delta = new QLineEdit; - le_ol_sa_delta->setStatusTip(tr("Defocus spread")); - le_ol_sa_delta->setValidator(new QDoubleValidator(0, std::numeric_limits::max(), 3)); - le_ol_sa_delta->setText("20.0"); - - /*******************************************************/ - lb_ol_sa_ndelta = new QLabel(tr("ND")); - lb_ol_sa_ndelta->setAlignment(Qt::AlignCenter); - - cb_ol_sa_ndelta = new QComboBox; - cb_ol_sa_ndelta->setStatusTip(tr("Number of integration points")); - for(auto ik=2; ik<=128; ik++) - { - cb_ol_sa_ndelta->addItem(QString::number(ik), QVariant(ik)); - } - cb_ol_sa_ndelta->setCurrentIndex(6); - - /*******************************************************/ - auto lyg_ol_sa = new QGridLayout; - lyg_ol_sa->setHorizontalSpacing(3); - lyg_ol_sa->setVerticalSpacing(0); - lyg_ol_sa->setContentsMargins(2, 1, 1, 0); - - lyg_ol_sa->addWidget(lb_ol_sa_c_30, 0, 0); - lyg_ol_sa->addWidget(le_ol_sa_c_30, 0, 1); - lyg_ol_sa->addWidget(lb_ol_sa_c_50, 0, 2); - lyg_ol_sa->addWidget(le_ol_sa_c_50, 0, 3); - - lyg_ol_sa->addWidget(lb_ol_sa_m, 1, 0); - lyg_ol_sa->addWidget(le_ol_sa_m, 1, 1); - lyg_ol_sa->addWidget(lb_ol_sa_c_10, 1, 2); - - auto lyh_c_10_opt = new QHBoxLayout; - lyh_c_10_opt->setSpacing(0); - lyh_c_10_opt->addWidget(le_ol_sa_c_10); - lyh_c_10_opt->addWidget(pb_ol_sa_c_10_opt); - - lyg_ol_sa->addLayout(lyh_c_10_opt, 1, 3); - - lyg_ol_sa->addWidget(lb_ol_sa_c_10_zero, 2, 0); - lyg_ol_sa->addWidget(cb_ol_sa_c_10_zero, 2, 1); - lyg_ol_sa->addWidget(lb_ol_sa_c_10_z, 2, 2); - lyg_ol_sa->addWidget(le_ol_sa_c_10_z, 2, 3); - - lyg_ol_sa->addWidget(lb_ol_sa_delta, 3, 0); - lyg_ol_sa->addWidget(le_ol_sa_delta, 3, 1); - lyg_ol_sa->addWidget(lb_ol_sa_ndelta, 3, 2); - lyg_ol_sa->addWidget(cb_ol_sa_ndelta, 3, 3); - - connect(pb_ol_sa_c_10_opt, SIGNAL(released()), SLOT(pb_ol_sa_c_10_opt_released())); - pb_ol_sa_c_10_opt->click(); - - connect(cb_ol_sa_c_10_zero, SIGNAL(currentIndexChanged(int)), SLOT(cb_ol_sa_c_10_zero_currentIndexChanged(int))); - auto idx = cb_ol_sa_c_10_zero->findData(mt::eZDT_Last); - cb_ol_sa_c_10_zero->setCurrentIndex(idx); - cb_ol_sa_c_10_zero_currentIndexChanged(idx); - - /*******************************************************/ - /***************Nonsymmetrical aberrations**************/ - /*******************************************************/ - - /*******************2-fold astigmatism******************/ - lb_ol_c_12 = new QLabel(tr(c_nm_to_qba(12, " [Å]"))); - - le_ol_c_12 = new QLineEdit; - le_ol_c_12->setStatusTip(tr("2-fold astigmatism")); - le_ol_c_12->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_12->setText("0.000"); - - lb_ol_phi_12 = new QLabel(tr(phi_nm_to_qba(12, " [°]"))); - - le_ol_phi_12 = new QLineEdit; - le_ol_phi_12->setStatusTip(tr("Azimuthal angle of 2-fold astigmatism")); - le_ol_phi_12->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_12->setText("0.000"); - - /*******************************************************/ - /***************************c2**************************/ - - /***********************Axial coma**********************/ - lb_ol_c_21 = new QLabel(tr(c_nm_to_qba(21, " [Å]"))); - - le_ol_c_21 = new QLineEdit; - le_ol_c_21->setStatusTip(tr("Axial coma")); - le_ol_c_21->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_21->setText("0.000"); + /*******************************************************/ + /*****************Symmetrical aberrations***************/ + /*******************************************************/ + /************3rd order spherical aberration************/ + lb_ol_sa_c_30 = new QLabel(tr(c_nm_to_qba(30, " [mm]"))); + + le_ol_sa_c_30 = new QLineEdit; + le_ol_sa_c_30->setStatusTip(tr("3rd order spherical aberration")); + le_ol_sa_c_30->setValidator(new QDoubleValidator(-double_lim, double_lim, 5)); + le_ol_sa_c_30->setText("0.001"); + + /************5th order spherical aberration************/ + lb_ol_sa_c_50 = new QLabel(tr(c_nm_to_qba(50, " [mm]"))); + + le_ol_sa_c_50 = new QLineEdit; + le_ol_sa_c_50->setStatusTip(tr("5th order spherical aberration")); + le_ol_sa_c_50->setValidator(new QDoubleValidator(-double_lim, double_lim, 5)); + le_ol_sa_c_50->setText("0.000"); + + /*******************Vortex momentum*********************/ + lb_ol_sa_m = new QLabel(tr("m")); + lb_ol_sa_m->setAlignment(Qt::AlignCenter); + + le_ol_sa_m = new QLineEdit; + le_ol_sa_m->setStatusTip(tr("Vortex momentum")); + le_ol_sa_m->setValidator(new QIntValidator(-int_lim, int_lim)); + le_ol_sa_m->setText("0"); + + /*************************Defocus***********************/ + lb_ol_sa_c_10 = new QLabel(tr(c_nm_to_qba(10, " [Å]"))); + + le_ol_sa_c_10 = new QLineEdit; + le_ol_sa_c_10->setStatusTip(tr("Defocus [Å]")); + le_ol_sa_c_10->setValidator(new QDoubleValidator(-double_lim, double_lim, 3)); + le_ol_sa_c_10->setText("0.000"); + + pb_ol_sa_c_10_opt = new QPushButton(QIcon(":/images/opt.png"), ""); + pb_ol_sa_c_10_opt->setStatusTip(tr("Scherzer defocus")); + pb_ol_sa_c_10_opt->setMaximumSize(22, 22); + + lb_ol_sa_c_10_zero = new QLabel(tr("Zero focus")); + + cb_ol_sa_c_10_zero = new QComboBox; + cb_ol_sa_c_10_zero->setStatusTip(tr("Zero reference focus")); + cb_ol_sa_c_10_zero->addItem(tr("First atom"), QVariant(mt::eZDT_First)); + cb_ol_sa_c_10_zero->setItemData(0, tr("Zero focus located at the first atom"), Qt::ToolTipRole); + cb_ol_sa_c_10_zero->addItem(tr("Half thick."), QVariant(mt::eZDT_Middle)); + cb_ol_sa_c_10_zero->setItemData(1, tr("Zero focus located at half thickness"), Qt::ToolTipRole); + cb_ol_sa_c_10_zero->addItem(tr("Last atom"), QVariant(mt::eZDT_Last)); + cb_ol_sa_c_10_zero->setItemData(2, tr("Zero focus located at the last atom"), Qt::ToolTipRole); + cb_ol_sa_c_10_zero->addItem(tr("User def."), QVariant(mt::eZDT_User_Define)); + cb_ol_sa_c_10_zero->setItemData(3, tr("Zero focus located at user define plane"), Qt::ToolTipRole); + lb_ol_sa_c_10_z = new QLabel(tr("Plane [Å]")); + + le_ol_sa_c_10_z = new QLineEdit; + le_ol_sa_c_10_z->setStatusTip(tr("Set focus plane")); + le_ol_sa_c_10_z->setValidator(new QDoubleValidator(-double_lim, double_lim, 3)); + le_ol_sa_c_10_z->setText("0.000"); + + /*******************************************************/ + lb_ol_sa_delta = new QLabel(tr("D [Å]")); + lb_ol_sa_delta->setAlignment(Qt::AlignCenter); + + le_ol_sa_delta = new QLineEdit; + le_ol_sa_delta->setStatusTip(tr("Defocus spread")); + le_ol_sa_delta->setValidator(new QDoubleValidator(0, std::numeric_limits::max(), 3)); + le_ol_sa_delta->setText("20.0"); + + /*******************************************************/ + lb_ol_sa_ndelta = new QLabel(tr("ND")); + lb_ol_sa_ndelta->setAlignment(Qt::AlignCenter); + + cb_ol_sa_ndelta = new QComboBox; + cb_ol_sa_ndelta->setStatusTip(tr("Number of integration points")); + for(auto ik=2; ik<=128; ik++) + { + cb_ol_sa_ndelta->addItem(QString::number(ik), QVariant(ik)); + } + cb_ol_sa_ndelta->setCurrentIndex(6); + + /*******************************************************/ + auto lyg_ol_sa = new QGridLayout; + lyg_ol_sa->setHorizontalSpacing(3); + lyg_ol_sa->setVerticalSpacing(0); + lyg_ol_sa->setContentsMargins(2, 1, 1, 0); + + lyg_ol_sa->addWidget(lb_ol_sa_c_30, 0, 0); + lyg_ol_sa->addWidget(le_ol_sa_c_30, 0, 1); + lyg_ol_sa->addWidget(lb_ol_sa_c_50, 0, 2); + lyg_ol_sa->addWidget(le_ol_sa_c_50, 0, 3); + + lyg_ol_sa->addWidget(lb_ol_sa_m, 1, 0); + lyg_ol_sa->addWidget(le_ol_sa_m, 1, 1); + lyg_ol_sa->addWidget(lb_ol_sa_c_10, 1, 2); + + auto lyh_c_10_opt = new QHBoxLayout; + lyh_c_10_opt->setSpacing(0); + lyh_c_10_opt->addWidget(le_ol_sa_c_10); + lyh_c_10_opt->addWidget(pb_ol_sa_c_10_opt); + + lyg_ol_sa->addLayout(lyh_c_10_opt, 1, 3); + + lyg_ol_sa->addWidget(lb_ol_sa_c_10_zero, 2, 0); + lyg_ol_sa->addWidget(cb_ol_sa_c_10_zero, 2, 1); + lyg_ol_sa->addWidget(lb_ol_sa_c_10_z, 2, 2); + lyg_ol_sa->addWidget(le_ol_sa_c_10_z, 2, 3); + + lyg_ol_sa->addWidget(lb_ol_sa_delta, 3, 0); + lyg_ol_sa->addWidget(le_ol_sa_delta, 3, 1); + lyg_ol_sa->addWidget(lb_ol_sa_ndelta, 3, 2); + lyg_ol_sa->addWidget(cb_ol_sa_ndelta, 3, 3); + + connect(pb_ol_sa_c_10_opt, SIGNAL(released()), SLOT(pb_ol_sa_c_10_opt_released())); + pb_ol_sa_c_10_opt->click(); + + connect(cb_ol_sa_c_10_zero, SIGNAL(currentIndexChanged(int)), SLOT(cb_ol_sa_c_10_zero_currentIndexChanged(int))); + auto idx = cb_ol_sa_c_10_zero->findData(mt::eZDT_Last); + cb_ol_sa_c_10_zero->setCurrentIndex(idx); + cb_ol_sa_c_10_zero_currentIndexChanged(idx); + + /*******************************************************/ + /***************Nonsymmetrical aberrations**************/ + /*******************************************************/ + + /*******************2-fold astigmatism******************/ + lb_ol_c_12 = new QLabel(tr(c_nm_to_qba(12, " [Å]"))); + + le_ol_c_12 = new QLineEdit; + le_ol_c_12->setStatusTip(tr("2-fold astigmatism")); + le_ol_c_12->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_12->setText("0.000"); + + lb_ol_phi_12 = new QLabel(tr(phi_nm_to_qba(12, " [°]"))); + + le_ol_phi_12 = new QLineEdit; + le_ol_phi_12->setStatusTip(tr("Azimuthal angle of 2-fold astigmatism")); + le_ol_phi_12->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_12->setText("0.000"); + + /*******************************************************/ + /***************************c2**************************/ + + /***********************Axial coma**********************/ + lb_ol_c_21 = new QLabel(tr(c_nm_to_qba(21, " [Å]"))); + + le_ol_c_21 = new QLineEdit; + le_ol_c_21->setStatusTip(tr("Axial coma")); + le_ol_c_21->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_21->setText("0.000"); - lb_ol_phi_21 = new QLabel(tr(phi_nm_to_qba(21, " [°]"))); + lb_ol_phi_21 = new QLabel(tr(phi_nm_to_qba(21, " [°]"))); - le_ol_phi_21 = new QLineEdit; - le_ol_phi_21->setStatusTip(tr("Azimuthal angle of axial coma")); - le_ol_phi_21->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_21->setText("0.000"); + le_ol_phi_21 = new QLineEdit; + le_ol_phi_21->setStatusTip(tr("Azimuthal angle of axial coma")); + le_ol_phi_21->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_21->setText("0.000"); - /*******************3-fold astigmatism******************/ - lb_ol_c_23 = new QLabel(tr(c_nm_to_qba(23, " [Å]"))); + /*******************3-fold astigmatism******************/ + lb_ol_c_23 = new QLabel(tr(c_nm_to_qba(23, " [Å]"))); - le_ol_c_23 = new QLineEdit; - le_ol_c_23->setStatusTip(tr("3-fold astigmatism")); - le_ol_c_23->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_23->setText("0.000"); + le_ol_c_23 = new QLineEdit; + le_ol_c_23->setStatusTip(tr("3-fold astigmatism")); + le_ol_c_23->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_23->setText("0.000"); - lb_ol_phi_23 = new QLabel(tr(phi_nm_to_qba(23, " [°]"))); + lb_ol_phi_23 = new QLabel(tr(phi_nm_to_qba(23, " [°]"))); - le_ol_phi_23 = new QLineEdit; - le_ol_phi_23->setStatusTip(tr("Azimuthal angle of 3-fold astigmatism")); - le_ol_phi_23->setValidator(new QDoubleValidator(360, 360, 3)); - le_ol_phi_23->setText("0.000"); + le_ol_phi_23 = new QLineEdit; + le_ol_phi_23->setStatusTip(tr("Azimuthal angle of 3-fold astigmatism")); + le_ol_phi_23->setValidator(new QDoubleValidator(360, 360, 3)); + le_ol_phi_23->setText("0.000"); - /*******************************************************/ - /***************************c3**************************/ + /*******************************************************/ + /***************************c3**************************/ - /****************Axial star aberration******************/ - lb_ol_c_32 = new QLabel(tr(c_nm_to_qba(32, " [Å]"))); + /****************Axial star aberration******************/ + lb_ol_c_32 = new QLabel(tr(c_nm_to_qba(32, " [Å]"))); - le_ol_c_32 = new QLineEdit; - le_ol_c_32->setStatusTip(tr("Axial star aberration")); - le_ol_c_32->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_32->setText("0.000"); + le_ol_c_32 = new QLineEdit; + le_ol_c_32->setStatusTip(tr("Axial star aberration")); + le_ol_c_32->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_32->setText("0.000"); - lb_ol_phi_32 = new QLabel(tr(phi_nm_to_qba(32, " [°]"))); + lb_ol_phi_32 = new QLabel(tr(phi_nm_to_qba(32, " [°]"))); - le_ol_phi_32 = new QLineEdit; - le_ol_phi_32->setStatusTip(tr("Azimuthal angle of axial star aberration")); - le_ol_phi_32->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_32->setText("0.000"); + le_ol_phi_32 = new QLineEdit; + le_ol_phi_32->setStatusTip(tr("Azimuthal angle of axial star aberration")); + le_ol_phi_32->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_32->setText("0.000"); - /*******************4-fold astigmatism******************/ - lb_ol_c_34 = new QLabel(tr(c_nm_to_qba(34, " [Å]"))); + /*******************4-fold astigmatism******************/ + lb_ol_c_34 = new QLabel(tr(c_nm_to_qba(34, " [Å]"))); - le_ol_c_34 = new QLineEdit; - le_ol_c_34->setStatusTip(tr("4-fold astigmatism")); - le_ol_c_34->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_34->setText("0.000"); + le_ol_c_34 = new QLineEdit; + le_ol_c_34->setStatusTip(tr("4-fold astigmatism")); + le_ol_c_34->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_34->setText("0.000"); - lb_ol_phi_34 = new QLabel(tr(phi_nm_to_qba(34, " [°]"))); + lb_ol_phi_34 = new QLabel(tr(phi_nm_to_qba(34, " [°]"))); - le_ol_phi_34 = new QLineEdit; - le_ol_phi_34->setStatusTip(tr("Azimuthal angle of 4-fold astigmatism")); - le_ol_phi_34->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_34->setText("0.000"); + le_ol_phi_34 = new QLineEdit; + le_ol_phi_34->setStatusTip(tr("Azimuthal angle of 4-fold astigmatism")); + le_ol_phi_34->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_34->setText("0.000"); - /*******************************************************/ - /***************************c4**************************/ + /*******************************************************/ + /***************************c4**************************/ - /*****************4th order axial coma******************/ - lb_ol_c_41 = new QLabel(tr(c_nm_to_qba(41, " [Å]"))); + /*****************4th order axial coma******************/ + lb_ol_c_41 = new QLabel(tr(c_nm_to_qba(41, " [Å]"))); - le_ol_c_41 = new QLineEdit; - le_ol_c_41->setStatusTip(tr("4th order axial coma")); - le_ol_c_41->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_41->setText("0.000"); + le_ol_c_41 = new QLineEdit; + le_ol_c_41->setStatusTip(tr("4th order axial coma")); + le_ol_c_41->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_41->setText("0.000"); - lb_ol_phi_41 = new QLabel(tr(phi_nm_to_qba(41, " [°]"))); + lb_ol_phi_41 = new QLabel(tr(phi_nm_to_qba(41, " [°]"))); - le_ol_phi_41 = new QLineEdit; - le_ol_phi_41->setStatusTip(tr("Azimuthal angle of 4th order axial coma")); - le_ol_phi_41->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_41->setText("0.000"); + le_ol_phi_41 = new QLineEdit; + le_ol_phi_41->setStatusTip(tr("Azimuthal angle of 4th order axial coma")); + le_ol_phi_41->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_41->setText("0.000"); - /*******************3-lobe aberration******************/ - lb_ol_c_43 = new QLabel(tr(c_nm_to_qba(43, " [Å]"))); + /*******************3-lobe aberration******************/ + lb_ol_c_43 = new QLabel(tr(c_nm_to_qba(43, " [Å]"))); - le_ol_c_43 = new QLineEdit; - le_ol_c_43->setStatusTip(tr("3-lobe aberration")); - le_ol_c_43->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_43->setText("0.000"); + le_ol_c_43 = new QLineEdit; + le_ol_c_43->setStatusTip(tr("3-lobe aberration")); + le_ol_c_43->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_43->setText("0.000"); - lb_ol_phi_43 = new QLabel(tr(phi_nm_to_qba(43, " [°]"))); + lb_ol_phi_43 = new QLabel(tr(phi_nm_to_qba(43, " [°]"))); - le_ol_phi_43 = new QLineEdit; - le_ol_phi_43->setStatusTip(tr("Azimuthal angle of 3-lobe aberration")); - le_ol_phi_43->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_43->setText("0.000"); - - /*******************5-fold astigmatism******************/ - lb_ol_c_45 = new QLabel(tr(c_nm_to_qba(45, " [Å]"))); - - le_ol_c_45 = new QLineEdit; - le_ol_c_45->setStatusTip(tr("5-fold astigmatism")); - le_ol_c_45->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_45->setText("0.000"); - - lb_ol_phi_45 = new QLabel(tr(phi_nm_to_qba(45, " [°]"))); - - le_ol_phi_45 = new QLineEdit; - le_ol_phi_45->setStatusTip(tr("Azimuthal angle of 5-fold astigmatism")); - le_ol_phi_45->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_45->setText("0.000"); - - /*******************************************************/ - /***************************c5**************************/ - - /*************5th order axial star aberration***********/ - lb_ol_c_52 = new QLabel(tr(c_nm_to_qba(52, " [Å]"))); - - le_ol_c_52 = new QLineEdit; - le_ol_c_52->setStatusTip(tr("5th order axial star aberration")); - le_ol_c_52->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_52->setText("0.000"); - - lb_ol_phi_52 = new QLabel(tr(phi_nm_to_qba(52, " [°]"))); - - le_ol_phi_52 = new QLineEdit; - le_ol_phi_52->setStatusTip(tr("Azimuthal angle of 5th order axial star aberration")); - le_ol_phi_52->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_52->setText("0.000"); - - /**************5th order rosette aberration*************/ - lb_ol_c_54 = new QLabel(tr(c_nm_to_qba(54, " [Å]"))); - - le_ol_c_54 = new QLineEdit; - le_ol_c_54->setStatusTip(tr("5th order rosette aberration")); - le_ol_c_54->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_54->setText("0.000"); - - lb_ol_phi_54 = new QLabel(tr(phi_nm_to_qba(54, " [°]"))); - - le_ol_phi_54 = new QLineEdit; - le_ol_phi_54->setStatusTip(tr("Azimuthal angle of 5th order rosette aberration")); - le_ol_phi_54->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_54->setText("0.000"); - - /*******************6-fold astigmatism******************/ - lb_ol_c_56 = new QLabel(tr(c_nm_to_qba(56, " [Å]"))); - - le_ol_c_56 = new QLineEdit; - le_ol_c_56->setStatusTip(tr("6-fold astigmatism")); - le_ol_c_56->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_c_56->setText("0.000"); - - lb_ol_phi_56 = new QLabel(tr(phi_nm_to_qba(56, " [°]"))); - - le_ol_phi_56 = new QLineEdit; - le_ol_phi_56->setStatusTip(tr("Azimuthal angle of 6-fold astigmatism")); - le_ol_phi_56->setValidator(new QDoubleValidator(-360, 360, 3)); - le_ol_phi_56->setText("0.000"); - - gbge_ol_nsa = new MGroupBox_GE(tr("Nonsymmetrical aberrations")); - - gbge_ol_nsa->addWidget(lb_ol_c_12, 0, 0); - gbge_ol_nsa->addWidget(le_ol_c_12, 0, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_12, 0, 2); - gbge_ol_nsa->addWidget(le_ol_phi_12, 0, 3); - - gbge_ol_nsa->addWidget(lb_ol_c_21, 1, 0); - gbge_ol_nsa->addWidget(le_ol_c_21, 1, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_21, 1, 2); - gbge_ol_nsa->addWidget(le_ol_phi_21, 1, 3); - gbge_ol_nsa->addWidget(lb_ol_c_23, 2, 0); - gbge_ol_nsa->addWidget(le_ol_c_23, 2, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_23, 2, 2); - gbge_ol_nsa->addWidget(le_ol_phi_23, 2, 3); - - gbge_ol_nsa->addWidget(lb_ol_c_32, 3, 0); - gbge_ol_nsa->addWidget(le_ol_c_32, 3, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_32, 3, 2); - gbge_ol_nsa->addWidget(le_ol_phi_32, 3, 3); - gbge_ol_nsa->addWidget(lb_ol_c_34, 4, 0); - gbge_ol_nsa->addWidget(le_ol_c_34, 4, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_34, 4, 2); - gbge_ol_nsa->addWidget(le_ol_phi_34, 4, 3); - - gbge_ol_nsa->addWidget(lb_ol_c_41, 5, 0); - gbge_ol_nsa->addWidget(le_ol_c_41, 5, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_41, 5, 2); - gbge_ol_nsa->addWidget(le_ol_phi_41, 5, 3); - gbge_ol_nsa->addWidget(lb_ol_c_43, 6, 0); - gbge_ol_nsa->addWidget(le_ol_c_43, 6, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_43, 6, 2); - gbge_ol_nsa->addWidget(le_ol_phi_43, 6, 3); - gbge_ol_nsa->addWidget(lb_ol_c_45, 7, 0); - gbge_ol_nsa->addWidget(le_ol_c_45, 7, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_45, 7, 2); - gbge_ol_nsa->addWidget(le_ol_phi_45, 7, 3); - - gbge_ol_nsa->addWidget(lb_ol_c_52, 8, 0); - gbge_ol_nsa->addWidget(le_ol_c_52, 8, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_52, 8, 2); - gbge_ol_nsa->addWidget(le_ol_phi_52, 8, 3); - gbge_ol_nsa->addWidget(lb_ol_c_54, 9, 0); - gbge_ol_nsa->addWidget(le_ol_c_54, 9, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_54, 9, 2); - gbge_ol_nsa->addWidget(le_ol_phi_54, 9, 3); - gbge_ol_nsa->addWidget(lb_ol_c_56, 10, 0); - gbge_ol_nsa->addWidget(le_ol_c_56, 10, 1); - gbge_ol_nsa->addWidget(lb_ol_phi_56, 10, 2); - gbge_ol_nsa->addWidget(le_ol_phi_56, 10, 3); - - /*******************************************************/ - /*********************Aperture radius*******************/ - /*******************************************************/ - lb_ol_ar_min = new QLabel(tr("rmin [mrad]")); - - le_ol_ar_min = new QLineEdit; - le_ol_ar_min->setStatusTip(tr("Minimum aperture radius")); - le_ol_ar_min->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_ar_min->setText("0.000"); - - lb_ol_ar_max = new QLabel(tr("rmax [mrad]")); - - le_ol_ar_max = new QLineEdit; - le_ol_ar_max->setStatusTip(tr("Maximum aperture radius")); - le_ol_ar_max->setValidator(new QDoubleValidator(0, double_lim, 3)); - le_ol_ar_max->setText("0.000"); - - gbh_ol_ar = new MGroupBox_H(tr("Aperture radius")); - gbh_ol_ar->addWidget(lb_ol_ar_min, le_ol_ar_min, lb_ol_ar_max, le_ol_ar_max); - - /*******************************************************/ - /*********************Objective lens********************/ - /*******************************************************/ - auto layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setContentsMargins(2, 1, 1, 0); - layout->addLayout(lyg_ol_sa); - layout->addWidget(gbge_ol_nsa); - layout->addWidget(gbh_ol_ar); - layout->addStretch(); - - lens = new QWidget; - lens->setLayout(layout); + le_ol_phi_43 = new QLineEdit; + le_ol_phi_43->setStatusTip(tr("Azimuthal angle of 3-lobe aberration")); + le_ol_phi_43->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_43->setText("0.000"); + + /*******************5-fold astigmatism******************/ + lb_ol_c_45 = new QLabel(tr(c_nm_to_qba(45, " [Å]"))); + + le_ol_c_45 = new QLineEdit; + le_ol_c_45->setStatusTip(tr("5-fold astigmatism")); + le_ol_c_45->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_45->setText("0.000"); + + lb_ol_phi_45 = new QLabel(tr(phi_nm_to_qba(45, " [°]"))); + + le_ol_phi_45 = new QLineEdit; + le_ol_phi_45->setStatusTip(tr("Azimuthal angle of 5-fold astigmatism")); + le_ol_phi_45->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_45->setText("0.000"); + + /*******************************************************/ + /***************************c5**************************/ + + /*************5th order axial star aberration***********/ + lb_ol_c_52 = new QLabel(tr(c_nm_to_qba(52, " [Å]"))); + + le_ol_c_52 = new QLineEdit; + le_ol_c_52->setStatusTip(tr("5th order axial star aberration")); + le_ol_c_52->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_52->setText("0.000"); + + lb_ol_phi_52 = new QLabel(tr(phi_nm_to_qba(52, " [°]"))); + + le_ol_phi_52 = new QLineEdit; + le_ol_phi_52->setStatusTip(tr("Azimuthal angle of 5th order axial star aberration")); + le_ol_phi_52->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_52->setText("0.000"); + + /**************5th order rosette aberration*************/ + lb_ol_c_54 = new QLabel(tr(c_nm_to_qba(54, " [Å]"))); + + le_ol_c_54 = new QLineEdit; + le_ol_c_54->setStatusTip(tr("5th order rosette aberration")); + le_ol_c_54->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_54->setText("0.000"); + + lb_ol_phi_54 = new QLabel(tr(phi_nm_to_qba(54, " [°]"))); + + le_ol_phi_54 = new QLineEdit; + le_ol_phi_54->setStatusTip(tr("Azimuthal angle of 5th order rosette aberration")); + le_ol_phi_54->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_54->setText("0.000"); + + /*******************6-fold astigmatism******************/ + lb_ol_c_56 = new QLabel(tr(c_nm_to_qba(56, " [Å]"))); + + le_ol_c_56 = new QLineEdit; + le_ol_c_56->setStatusTip(tr("6-fold astigmatism")); + le_ol_c_56->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_c_56->setText("0.000"); + + lb_ol_phi_56 = new QLabel(tr(phi_nm_to_qba(56, " [°]"))); + + le_ol_phi_56 = new QLineEdit; + le_ol_phi_56->setStatusTip(tr("Azimuthal angle of 6-fold astigmatism")); + le_ol_phi_56->setValidator(new QDoubleValidator(-360, 360, 3)); + le_ol_phi_56->setText("0.000"); + + gbge_ol_nsa = new MGroupBox_GE(tr("Nonsymmetrical aberrations")); + + gbge_ol_nsa->addWidget(lb_ol_c_12, 0, 0); + gbge_ol_nsa->addWidget(le_ol_c_12, 0, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_12, 0, 2); + gbge_ol_nsa->addWidget(le_ol_phi_12, 0, 3); + + gbge_ol_nsa->addWidget(lb_ol_c_21, 1, 0); + gbge_ol_nsa->addWidget(le_ol_c_21, 1, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_21, 1, 2); + gbge_ol_nsa->addWidget(le_ol_phi_21, 1, 3); + gbge_ol_nsa->addWidget(lb_ol_c_23, 2, 0); + gbge_ol_nsa->addWidget(le_ol_c_23, 2, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_23, 2, 2); + gbge_ol_nsa->addWidget(le_ol_phi_23, 2, 3); + + gbge_ol_nsa->addWidget(lb_ol_c_32, 3, 0); + gbge_ol_nsa->addWidget(le_ol_c_32, 3, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_32, 3, 2); + gbge_ol_nsa->addWidget(le_ol_phi_32, 3, 3); + gbge_ol_nsa->addWidget(lb_ol_c_34, 4, 0); + gbge_ol_nsa->addWidget(le_ol_c_34, 4, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_34, 4, 2); + gbge_ol_nsa->addWidget(le_ol_phi_34, 4, 3); + + gbge_ol_nsa->addWidget(lb_ol_c_41, 5, 0); + gbge_ol_nsa->addWidget(le_ol_c_41, 5, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_41, 5, 2); + gbge_ol_nsa->addWidget(le_ol_phi_41, 5, 3); + gbge_ol_nsa->addWidget(lb_ol_c_43, 6, 0); + gbge_ol_nsa->addWidget(le_ol_c_43, 6, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_43, 6, 2); + gbge_ol_nsa->addWidget(le_ol_phi_43, 6, 3); + gbge_ol_nsa->addWidget(lb_ol_c_45, 7, 0); + gbge_ol_nsa->addWidget(le_ol_c_45, 7, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_45, 7, 2); + gbge_ol_nsa->addWidget(le_ol_phi_45, 7, 3); + + gbge_ol_nsa->addWidget(lb_ol_c_52, 8, 0); + gbge_ol_nsa->addWidget(le_ol_c_52, 8, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_52, 8, 2); + gbge_ol_nsa->addWidget(le_ol_phi_52, 8, 3); + gbge_ol_nsa->addWidget(lb_ol_c_54, 9, 0); + gbge_ol_nsa->addWidget(le_ol_c_54, 9, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_54, 9, 2); + gbge_ol_nsa->addWidget(le_ol_phi_54, 9, 3); + gbge_ol_nsa->addWidget(lb_ol_c_56, 10, 0); + gbge_ol_nsa->addWidget(le_ol_c_56, 10, 1); + gbge_ol_nsa->addWidget(lb_ol_phi_56, 10, 2); + gbge_ol_nsa->addWidget(le_ol_phi_56, 10, 3); + + /*******************************************************/ + /*********************Aperture radius*******************/ + /*******************************************************/ + lb_ol_ar_min = new QLabel(tr("rmin [mrad]")); + + le_ol_ar_min = new QLineEdit; + le_ol_ar_min->setStatusTip(tr("Minimum aperture radius")); + le_ol_ar_min->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_ar_min->setText("0.000"); + + lb_ol_ar_max = new QLabel(tr("rmax [mrad]")); + + le_ol_ar_max = new QLineEdit; + le_ol_ar_max->setStatusTip(tr("Maximum aperture radius")); + le_ol_ar_max->setValidator(new QDoubleValidator(0, double_lim, 3)); + le_ol_ar_max->setText("0.000"); + + gbh_ol_ar = new MGroupBox_H(tr("Aperture radius")); + gbh_ol_ar->addWidget(lb_ol_ar_min, le_ol_ar_min, lb_ol_ar_max, le_ol_ar_max); + + /*******************************************************/ + /*********************Objective lens********************/ + /*******************************************************/ + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->setContentsMargins(2, 1, 1, 0); + layout->addLayout(lyg_ol_sa); + layout->addWidget(gbge_ol_nsa); + layout->addWidget(gbh_ol_ar); + layout->addStretch(); + + lens = new QWidget; + lens->setLayout(layout); } /*******************************************************/ void MainWindow::create_general_dock_widget() { - auto fr_general = new MFrame_V; - fr_general->layout->setSpacing(1); - fr_general->setStyleSheet("QFrame { background: "+ QColor("#D8D8D8").name() +" }"); - - /*******************************************************/ - /************************device*************************/ - /*******************************************************/ - cb_device = new QComboBox; - cb_device->setStatusTip(tr("Device calculation")); - - cb_device->setMinimumWidth(80); - cb_device->addItem(tr("CPU"), mt::e_host); - cb_device->setItemData(0, tr("CPU calculation"), Qt::ToolTipRole); - cb_device->addItem(tr("GPU"), mt::e_device); - cb_device->setItemData(1, tr("GPU calculation"), Qt::ToolTipRole); - - /*******************************************************/ - /****************floating point calculation*************/ - /*******************************************************/ - lb_precision = new QLabel(tr("Precision")); - - cb_precision = new QComboBox; - cb_precision->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - cb_precision->setStatusTip(tr("Floating-point precision")); - cb_precision->addItem(tr("Single"), enum_to_QVar(mt::eP_float)); - cb_precision->setItemData(0, tr("Single precision (32 bits)"), Qt::ToolTipRole); - cb_precision->addItem(tr("Double"), enum_to_QVar(mt::eP_double)); - cb_precision->setItemData(1, tr("Double precision (64 bits)"), Qt::ToolTipRole); - cb_precision->setCurrentIndex(0); - - /*******************************************************/ - /*****************Number of threads*********************/ - /*******************************************************/ - lb_nthreads = new QLabel(tr(x_sub_to_qba("N", "threads", "x-large"))); - lb_nthreads->setAlignment(Qt::AlignCenter); - - sb_nthreads = new QSpinBox; - sb_nthreads->setStatusTip(tr("Number of threads")); - auto nthreads = QThread::idealThreadCount(); - sb_nthreads->setRange(1, nthreads); - sb_nthreads->setSingleStep(1); - sb_nthreads->setValue(nthreads); - - /*******************************************************/ - /***********************GPU card************************/ - /*******************************************************/ - lb_gpu_card = new QLabel(tr("Graphic cards")); - lb_gpu_card->setAlignment(Qt::AlignCenter); - - cb_gpu_card = new QComboBox; - cb_gpu_card->setStatusTip(tr("Available graphic cards")); - cb_gpu_card->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); - - std::vector device_properties; - mt::get_device_properties(device_properties); -// for(auto id=0; idaddItem(QString::fromStdString(device_properties[id].name), QVariant(device_properties[id].id)); -// } - - /*******************************************************/ - gbg_device = new MGroupBox_G(tr("Device")); - gbg_device->layout->setVerticalSpacing(2); - gbg_device->layout->setContentsMargins(2, 0, 1, 0); - - gbg_device->addWidget(cb_device, 0, 0); - - auto lyh_precision= new QHBoxLayout; - lyh_precision->setSpacing(2); - lyh_precision->setContentsMargins(0, 0, 0, 1); - lyh_precision->addWidget(lb_precision); - lyh_precision->addWidget(cb_precision); - - gbg_device->layout->addLayout(lyh_precision, 0, 1); - - gbg_device->addWidget(lb_nthreads, 1, 0); - gbg_device->addWidget(sb_nthreads, 1, 1); - gbg_device->addWidget(lb_gpu_card, 1, 0); - gbg_device->addWidget(cb_gpu_card, 1, 1); - - fr_general->layout->addWidget(gbg_device); - - /*******************************************************/ - connect(cb_device, SIGNAL(currentIndexChanged(int)), SLOT(cb_device_currentIndexChanged(int))); - - auto idx = (mt::is_gpu_available())?1:0; - idx = 0; - cb_device->setCurrentIndex(idx); - cb_device_currentIndexChanged(idx); - - /*******************************************************/ - /*********Electron-Specimen interation model************/ - /*******************************************************/ - cb_elec_spec_int_model = new QComboBox; - cb_elec_spec_int_model->setStatusTip(tr("Electron-Specimen interaction model")); - cb_elec_spec_int_model->addItem(tr("Multislice approx."), mt::eESIM_Multislice); - cb_elec_spec_int_model->setItemData(0, tr("Multislice approximation"), Qt::ToolTipRole); - cb_elec_spec_int_model->addItem(tr("Phase object approx."), mt::eESIM_Phase_Object); - cb_elec_spec_int_model->setItemData(1, tr("Phase object approximation"), Qt::ToolTipRole); - cb_elec_spec_int_model->addItem(tr("Weak phase object approx."), mt::eESIM_Weak_Phase_Object); - cb_elec_spec_int_model->setItemData(2, tr("Weak phase object approximation"), Qt::ToolTipRole); - - /*******************************************************/ - /***********Parameterization of the fe(g)***************/ - /*******************************************************/ - lb_potential_type = new QLabel(tr("fₑ(g)")); - lb_potential_type->setAlignment(Qt::AlignCenter); - - cb_potential_type = new QComboBox; - cb_potential_type->setStatusTip(tr("Parameterization of the electron scattering factors")); - cb_potential_type->addItem(tr("Doyle et al. 0 < g < 4")+rAgs, enum_to_QVar(mt::ePT_Doyle_0_4)); - cb_potential_type->setItemData(0, tr("fₑ(g) was fitted for scattering angles 0 < g < 4")+rAgs, Qt::ToolTipRole); - cb_potential_type->addItem(tr("Peng et al. 0 < g < 4")+rAgs, enum_to_QVar(mt::ePT_Peng_0_4)); - cb_potential_type->setItemData(1, tr("fₑ(g) was fitted for scattering angles 0 < g < 4")+rAgs, Qt::ToolTipRole); - cb_potential_type->addItem(tr("Peng et al. 0 < g < 12")+rAgs, enum_to_QVar(mt::ePT_Peng_0_12)); - cb_potential_type->setItemData(2, tr("fₑ(g) was fitted for scattering angles 0 < g < 12")+rAgs, Qt::ToolTipRole); - cb_potential_type->addItem(tr("Kirkland 0 < g < 12")+rAgs, enum_to_QVar(mt::ePT_Kirkland_0_12)); - cb_potential_type->setItemData(3, tr("fₑ(g) was fitted for scattering angles 0 < g < 12")+rAgs, Qt::ToolTipRole); - cb_potential_type->addItem(tr("Weickenmeier et al. 0 < g < 12")+rAgs, enum_to_QVar(mt::ePT_Weickenmeier_0_12)); - cb_potential_type->setItemData(4, tr("fₑ(g) was fitted for scattering angles 0 < g < 12")+rAgs, Qt::ToolTipRole); - cb_potential_type->addItem(tr("Lobato et al. 0 < g < 12")+rAgs, enum_to_QVar(mt::ePT_Lobato_0_12)); - cb_potential_type->setItemData(5, tr("fₑ(g) was fitted for scattering angles 0 < g < 12")+rAgs, Qt::ToolTipRole); - cb_potential_type->setCurrentIndex(5); - - /*******************************************************/ - gbg_elec_spec_int_model = new MGroupBox_G(elec + tr(" - Specimen interaction")); - gbg_elec_spec_int_model->layout->setVerticalSpacing(1); - gbg_elec_spec_int_model->layout->setHorizontalSpacing(4); - - gbg_elec_spec_int_model->addWidget(cb_elec_spec_int_model, 0, 0, 1, 2); - gbg_elec_spec_int_model->addWidget(lb_potential_type, 1, 0); - gbg_elec_spec_int_model->addWidget(cb_potential_type, 1, 1); - - fr_general->layout->addWidget(gbg_elec_spec_int_model); - - /*******************************************************/ - /************Electron-Phonon interation model***********/ - /*******************************************************/ - cb_pn_model = new QComboBox; - cb_pn_model->setStatusTip(tr("Electron-Phonon interaction model")); - cb_pn_model->addItem(tr("Still atom approx."), enum_to_QVar(mt::ePM_Still_Atom)); - cb_pn_model->setItemData(0, tr("Still atom approximation"), Qt::ToolTipRole); - cb_pn_model->addItem(tr("Absorptive pot. approx."), enum_to_QVar(mt::ePM_Absorptive_Model)); - cb_pn_model->setItemData(1, tr("Absorptive potential approximation"), Qt::ToolTipRole); - cb_pn_model->addItem(tr("Frozen phonon approx."), enum_to_QVar(mt::ePM_Frozen_Phonon)); - cb_pn_model->setItemData(2, tr("Frozen phonon approximation"), Qt::ToolTipRole); - cb_pn_model->setCurrentIndex(2); - - disable_item_QComboBox(cb_pn_model, 1); - - /*******************************************************/ - ckb_pn_coh_contrib = new QCheckBox(tr("Coh. contribution")); - ckb_pn_coh_contrib->setStatusTip(tr("Calculate coherent contribution")); - - /*******************************************************/ - ckb_pn_single_conf = new QCheckBox(tr("Sng. configuration")); - ckb_pn_single_conf->setStatusTip(tr("Frozen phonon for a specific configuration")); - - /*******************************************************/ - lb_pn_nconf = new QLabel(tr(x_sub_to_qba("N", "conf.", "x-large"))); - - le_pn_nconf = new QLineEdit; - le_pn_nconf->setStatusTip(tr("Number of configurations")); - le_pn_nconf->setValidator(new QIntValidator(0, std::numeric_limits::max())); - le_pn_nconf->setText("5"); - - /*******************************************************/ - lb_pn_dim = new QLabel(tr("Vibration")); - - cb_pn_dim = new QComboBox; - cb_pn_dim->setStatusTip(tr("Direction of the atomic vibrations")); - cb_pn_dim->addItem("x", QVariant(100)); - cb_pn_dim->setItemData(0, "x vibration", Qt::ToolTipRole); - cb_pn_dim->addItem("y", QVariant(10)); - cb_pn_dim->setItemData(1, "y vibration", Qt::ToolTipRole); - cb_pn_dim->addItem("z", QVariant(1)); - cb_pn_dim->setItemData(2, "z vibration", Qt::ToolTipRole); - cb_pn_dim->addItem("xy", QVariant(110)); - cb_pn_dim->setItemData(3, "x-y vibration", Qt::ToolTipRole); - cb_pn_dim->addItem("xz", QVariant(101)); - cb_pn_dim->setItemData(4, "x-z vibration", Qt::ToolTipRole); - cb_pn_dim->addItem("yz", QVariant(11)); - cb_pn_dim->setItemData(5, "x-z vibration", Qt::ToolTipRole); - cb_pn_dim->addItem("xyz", QVariant(111)); - cb_pn_dim->setItemData(6, "x-y-z vibration", Qt::ToolTipRole); - cb_pn_dim->setCurrentIndex(cb_pn_dim->findData(110)); - - /*******************************************************/ - lb_pn_seed = new QLabel(tr("Rnd seed")); - - le_pn_seed = new QLineEdit; - le_pn_seed->setStatusTip(tr("Random generator seed")); - le_pn_seed->setValidator(new QIntValidator(0, int_lim)); - le_pn_seed->setText("300183"); - - /*******************************************************/ - ckb_pn_auto_seed = new QCheckBox(tr("auto")); - ckb_pn_auto_seed->setStatusTip(tr("Automatic random seed")); - - /*******************************************************/ - auto lyg_frozen_phonon = new QGridLayout; - lyg_frozen_phonon->setVerticalSpacing(0); - lyg_frozen_phonon->setHorizontalSpacing(2); - lyg_frozen_phonon->setContentsMargins(0, 0, 0, 0); - - lyg_frozen_phonon->addWidget(ckb_pn_coh_contrib, 0, 0, 1, 2); - lyg_frozen_phonon->addWidget(ckb_pn_single_conf, 0, 2, 1, 2); - - lyg_frozen_phonon->addWidget(lb_pn_nconf, 1, 0); - lyg_frozen_phonon->addWidget(le_pn_nconf, 1, 1); - lyg_frozen_phonon->addWidget(lb_pn_dim, 1, 2); - lyg_frozen_phonon->addWidget(cb_pn_dim, 1, 3); - - lyg_frozen_phonon->addWidget(lb_pn_seed, 2, 0); - - lyg_frozen_phonon->addWidget(le_pn_seed, 2, 1); - lyg_frozen_phonon->addWidget(ckb_pn_auto_seed, 2, 2); - - wg_electron_phonon = new QWidget; - wg_electron_phonon->setLayout(lyg_frozen_phonon); - - /*******************************************************/ - gbg_elec_phonon_int_model = new MGroupBox_G(elec + tr(" - Phonon interaction")); - gbg_elec_phonon_int_model->layout->setVerticalSpacing(1); - - gbg_elec_phonon_int_model->addWidget(cb_pn_model, 0, 0); - gbg_elec_phonon_int_model->addWidget(wg_electron_phonon, 1, 0); - - fr_general->layout->addWidget(gbg_elec_phonon_int_model); - fr_general->layout->addStretch(1); - - /*******************************************************/ - connect(cb_pn_model, static_cast(&QComboBox::currentIndexChanged), - [this](int index) - { - auto pn_model = QVar_to_enum(cb_pn_model->itemData(index)); - auto bb_frozen_phonon = pn_model == mt::ePM_Frozen_Phonon; - wg_electron_phonon->setEnabled(bb_frozen_phonon); - }); - - connect(ckb_pn_single_conf, &QCheckBox::stateChanged, - [this](int state) - { - if(state==Qt::Checked) - { - lb_pn_nconf->setText(tr("Kconf.")); - le_pn_nconf->setStatusTip(tr("Specific configuration")); - } - else - { - lb_pn_nconf->setText(tr(x_sub_to_qba("N", "conf.", "x-large"))); - le_pn_nconf->setStatusTip(tr("Number of configurations")); - } - }); - - connect(ckb_pn_auto_seed, &QCheckBox::stateChanged, - [this](int state) - { - auto bb = state==Qt::Checked; - le_pn_seed->setEnabled(!bb); - if(bb) - { - le_pn_seed->setText(QString::number(qrand())); - } - - }); - /*******************************************************/ - dw_general = new QDockWidget(tr("General settings"), this); - dw_general->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - dw_general->setFeatures(QDockWidget::NoDockWidgetFeatures); - dw_general->setWidget(fr_general); - addDockWidget(Qt::LeftDockWidgetArea, dw_general); + auto fr_general = new MFrame_V; + fr_general->layout->setSpacing(1); + fr_general->setStyleSheet("QFrame { background: "+ QColor("#D8D8D8").name() +" }"); + + /*******************************************************/ + /************************device*************************/ + /*******************************************************/ + cb_device = new QComboBox; + cb_device->setStatusTip(tr("Device calculation")); + + cb_device->setMinimumWidth(80); + cb_device->addItem(tr("CPU"), mt::e_host); + cb_device->setItemData(0, tr("CPU calculation"), Qt::ToolTipRole); + cb_device->addItem(tr("GPU"), mt::e_device); + cb_device->setItemData(1, tr("GPU calculation"), Qt::ToolTipRole); + + /*******************************************************/ + /****************floating point calculation*************/ + /*******************************************************/ + lb_precision = new QLabel(tr("Precision")); + + cb_precision = new QComboBox; + cb_precision->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + cb_precision->setStatusTip(tr("Floating-point precision")); + cb_precision->addItem(tr("Single"), enum_to_QVar(mt::eP_float)); + cb_precision->setItemData(0, tr("Single precision (32 bits)"), Qt::ToolTipRole); + cb_precision->addItem(tr("Double"), enum_to_QVar(mt::eP_double)); + cb_precision->setItemData(1, tr("Double precision (64 bits)"), Qt::ToolTipRole); + cb_precision->setCurrentIndex(0); + + /*******************************************************/ + /*****************Number of threads*********************/ + /*******************************************************/ + lb_nthreads = new QLabel(tr(x_sub_to_qba("N", "threads", "x-large"))); + lb_nthreads->setAlignment(Qt::AlignCenter); + + sb_nthreads = new QSpinBox; + sb_nthreads->setStatusTip(tr("Number of threads")); + auto nthreads = QThread::idealThreadCount(); + sb_nthreads->setRange(1, nthreads); + sb_nthreads->setSingleStep(1); + sb_nthreads->setValue(nthreads); + + /*******************************************************/ + /***********************GPU card************************/ + /*******************************************************/ + lb_gpu_card = new QLabel(tr("Graphic cards")); + lb_gpu_card->setAlignment(Qt::AlignCenter); + + cb_gpu_card = new QComboBox; + cb_gpu_card->setStatusTip(tr("Available graphic cards")); + cb_gpu_card->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); + + std::vector device_properties; + mt::get_device_properties(device_properties); + for(auto id=0; idaddItem(QString::fromStdString(device_properties[id].name), QVariant(device_properties[id].id)); + } + + /*******************************************************/ + gbg_device = new MGroupBox_G(tr("Device")); + gbg_device->layout->setVerticalSpacing(2); + gbg_device->layout->setContentsMargins(2, 0, 1, 0); + + gbg_device->addWidget(cb_device, 0, 0); + + auto lyh_precision= new QHBoxLayout; + lyh_precision->setSpacing(2); + lyh_precision->setContentsMargins(0, 0, 0, 1); + lyh_precision->addWidget(lb_precision); + lyh_precision->addWidget(cb_precision); + + gbg_device->layout->addLayout(lyh_precision, 0, 1); + + gbg_device->addWidget(lb_nthreads, 1, 0); + gbg_device->addWidget(sb_nthreads, 1, 1); + gbg_device->addWidget(lb_gpu_card, 1, 0); + gbg_device->addWidget(cb_gpu_card, 1, 1); + + fr_general->layout->addWidget(gbg_device); + + /*******************************************************/ + connect(cb_device, SIGNAL(currentIndexChanged(int)), SLOT(cb_device_currentIndexChanged(int))); + + auto idx = (mt::is_gpu_available())?1:0; + idx = 0; + cb_device->setCurrentIndex(idx); + cb_device_currentIndexChanged(idx); + + /*******************************************************/ + /*********Electron-Specimen interation model************/ + /*******************************************************/ + cb_elec_spec_int_model = new QComboBox; + cb_elec_spec_int_model->setStatusTip(tr("Electron-Specimen interaction model")); + cb_elec_spec_int_model->addItem(tr("Multislice approx."), mt::eESIM_Multislice); + cb_elec_spec_int_model->setItemData(0, tr("Multislice approximation"), Qt::ToolTipRole); + cb_elec_spec_int_model->addItem(tr("Phase object approx."), mt::eESIM_Phase_Object); + cb_elec_spec_int_model->setItemData(1, tr("Phase object approximation"), Qt::ToolTipRole); + cb_elec_spec_int_model->addItem(tr("Weak phase object approx."), mt::eESIM_Weak_Phase_Object); + cb_elec_spec_int_model->setItemData(2, tr("Weak phase object approximation"), Qt::ToolTipRole); + + /*******************************************************/ + /***********Parameterization of the fe(g)***************/ + /*******************************************************/ + lb_potential_type = new QLabel(tr("fₑ(g)")); + lb_potential_type->setAlignment(Qt::AlignCenter); + + cb_potential_type = new QComboBox; + cb_potential_type->setStatusTip(tr("Parameterization of the electron scattering factors")); + cb_potential_type->addItem(tr("Doyle et al. 0 < g < 4")+rAgs, enum_to_QVar(mt::ePT_Doyle_0_4)); + cb_potential_type->setItemData(0, tr("fₑ(g) was fitted for scattering angles 0 < g < 4")+rAgs, Qt::ToolTipRole); + cb_potential_type->addItem(tr("Peng et al. 0 < g < 4")+rAgs, enum_to_QVar(mt::ePT_Peng_0_4)); + cb_potential_type->setItemData(1, tr("fₑ(g) was fitted for scattering angles 0 < g < 4")+rAgs, Qt::ToolTipRole); + cb_potential_type->addItem(tr("Peng et al. 0 < g < 12")+rAgs, enum_to_QVar(mt::ePT_Peng_0_12)); + cb_potential_type->setItemData(2, tr("fₑ(g) was fitted for scattering angles 0 < g < 12")+rAgs, Qt::ToolTipRole); + cb_potential_type->addItem(tr("Kirkland 0 < g < 12")+rAgs, enum_to_QVar(mt::ePT_Kirkland_0_12)); + cb_potential_type->setItemData(3, tr("fₑ(g) was fitted for scattering angles 0 < g < 12")+rAgs, Qt::ToolTipRole); + cb_potential_type->addItem(tr("Weickenmeier et al. 0 < g < 12")+rAgs, enum_to_QVar(mt::ePT_Weickenmeier_0_12)); + cb_potential_type->setItemData(4, tr("fₑ(g) was fitted for scattering angles 0 < g < 12")+rAgs, Qt::ToolTipRole); + cb_potential_type->addItem(tr("Lobato et al. 0 < g < 12")+rAgs, enum_to_QVar(mt::ePT_Lobato_0_12)); + cb_potential_type->setItemData(5, tr("fₑ(g) was fitted for scattering angles 0 < g < 12")+rAgs, Qt::ToolTipRole); + cb_potential_type->setCurrentIndex(5); + + /*******************************************************/ + gbg_elec_spec_int_model = new MGroupBox_G(elec + tr(" - Specimen interaction")); + gbg_elec_spec_int_model->layout->setVerticalSpacing(1); + gbg_elec_spec_int_model->layout->setHorizontalSpacing(4); + + gbg_elec_spec_int_model->addWidget(cb_elec_spec_int_model, 0, 0, 1, 2); + gbg_elec_spec_int_model->addWidget(lb_potential_type, 1, 0); + gbg_elec_spec_int_model->addWidget(cb_potential_type, 1, 1); + + fr_general->layout->addWidget(gbg_elec_spec_int_model); + + /*******************************************************/ + /************Electron-Phonon interation model***********/ + /*******************************************************/ + cb_pn_model = new QComboBox; + cb_pn_model->setStatusTip(tr("Electron-Phonon interaction model")); + cb_pn_model->addItem(tr("Still atom approx."), enum_to_QVar(mt::ePM_Still_Atom)); + cb_pn_model->setItemData(0, tr("Still atom approximation"), Qt::ToolTipRole); + cb_pn_model->addItem(tr("Absorptive pot. approx."), enum_to_QVar(mt::ePM_Absorptive_Model)); + cb_pn_model->setItemData(1, tr("Absorptive potential approximation"), Qt::ToolTipRole); + cb_pn_model->addItem(tr("Frozen phonon approx."), enum_to_QVar(mt::ePM_Frozen_Phonon)); + cb_pn_model->setItemData(2, tr("Frozen phonon approximation"), Qt::ToolTipRole); + cb_pn_model->setCurrentIndex(2); + + disable_item_QComboBox(cb_pn_model, 1); + + /*******************************************************/ + ckb_pn_coh_contrib = new QCheckBox(tr("Coh. contribution")); + ckb_pn_coh_contrib->setStatusTip(tr("Calculate coherent contribution")); + + /*******************************************************/ + ckb_pn_single_conf = new QCheckBox(tr("Sng. configuration")); + ckb_pn_single_conf->setStatusTip(tr("Frozen phonon for a specific configuration")); + + /*******************************************************/ + lb_pn_nconf = new QLabel(tr(x_sub_to_qba("N", "conf.", "x-large"))); + + le_pn_nconf = new QLineEdit; + le_pn_nconf->setStatusTip(tr("Number of configurations")); + le_pn_nconf->setValidator(new QIntValidator(0, std::numeric_limits::max())); + le_pn_nconf->setText("5"); + + /*******************************************************/ + lb_pn_dim = new QLabel(tr("Vibration")); + + cb_pn_dim = new QComboBox; + cb_pn_dim->setStatusTip(tr("Direction of the atomic vibrations")); + cb_pn_dim->addItem("x", QVariant(100)); + cb_pn_dim->setItemData(0, "x vibration", Qt::ToolTipRole); + cb_pn_dim->addItem("y", QVariant(10)); + cb_pn_dim->setItemData(1, "y vibration", Qt::ToolTipRole); + cb_pn_dim->addItem("z", QVariant(1)); + cb_pn_dim->setItemData(2, "z vibration", Qt::ToolTipRole); + cb_pn_dim->addItem("xy", QVariant(110)); + cb_pn_dim->setItemData(3, "x-y vibration", Qt::ToolTipRole); + cb_pn_dim->addItem("xz", QVariant(101)); + cb_pn_dim->setItemData(4, "x-z vibration", Qt::ToolTipRole); + cb_pn_dim->addItem("yz", QVariant(11)); + cb_pn_dim->setItemData(5, "x-z vibration", Qt::ToolTipRole); + cb_pn_dim->addItem("xyz", QVariant(111)); + cb_pn_dim->setItemData(6, "x-y-z vibration", Qt::ToolTipRole); + cb_pn_dim->setCurrentIndex(cb_pn_dim->findData(110)); + + /*******************************************************/ + lb_pn_seed = new QLabel(tr("Rnd seed")); + + le_pn_seed = new QLineEdit; + le_pn_seed->setStatusTip(tr("Random generator seed")); + le_pn_seed->setValidator(new QIntValidator(0, int_lim)); + le_pn_seed->setText("300183"); + + /*******************************************************/ + ckb_pn_auto_seed = new QCheckBox(tr("auto")); + ckb_pn_auto_seed->setStatusTip(tr("Automatic random seed")); + + /*******************************************************/ + auto lyg_frozen_phonon = new QGridLayout; + lyg_frozen_phonon->setVerticalSpacing(0); + lyg_frozen_phonon->setHorizontalSpacing(2); + lyg_frozen_phonon->setContentsMargins(0, 0, 0, 0); + + lyg_frozen_phonon->addWidget(ckb_pn_coh_contrib, 0, 0, 1, 2); + lyg_frozen_phonon->addWidget(ckb_pn_single_conf, 0, 2, 1, 2); + + lyg_frozen_phonon->addWidget(lb_pn_nconf, 1, 0); + lyg_frozen_phonon->addWidget(le_pn_nconf, 1, 1); + lyg_frozen_phonon->addWidget(lb_pn_dim, 1, 2); + lyg_frozen_phonon->addWidget(cb_pn_dim, 1, 3); + + lyg_frozen_phonon->addWidget(lb_pn_seed, 2, 0); + + lyg_frozen_phonon->addWidget(le_pn_seed, 2, 1); + lyg_frozen_phonon->addWidget(ckb_pn_auto_seed, 2, 2); + + wg_electron_phonon = new QWidget; + wg_electron_phonon->setLayout(lyg_frozen_phonon); + + /*******************************************************/ + gbg_elec_phonon_int_model = new MGroupBox_G(elec + tr(" - Phonon interaction")); + gbg_elec_phonon_int_model->layout->setVerticalSpacing(1); + + gbg_elec_phonon_int_model->addWidget(cb_pn_model, 0, 0); + gbg_elec_phonon_int_model->addWidget(wg_electron_phonon, 1, 0); + + fr_general->layout->addWidget(gbg_elec_phonon_int_model); + fr_general->layout->addStretch(1); + + /*******************************************************/ + connect(cb_pn_model, static_cast(&QComboBox::currentIndexChanged), + [this](int index) + { + auto pn_model = QVar_to_enum(cb_pn_model->itemData(index)); + auto bb_frozen_phonon = pn_model == mt::ePM_Frozen_Phonon; + wg_electron_phonon->setEnabled(bb_frozen_phonon); + }); + + connect(ckb_pn_single_conf, &QCheckBox::stateChanged, + [this](int state) + { + if(state==Qt::Checked) + { + lb_pn_nconf->setText(tr("Kconf.")); + le_pn_nconf->setStatusTip(tr("Specific configuration")); + } + else + { + lb_pn_nconf->setText(tr(x_sub_to_qba("N", "conf.", "x-large"))); + le_pn_nconf->setStatusTip(tr("Number of configurations")); + } + }); + + connect(ckb_pn_auto_seed, &QCheckBox::stateChanged, + [this](int state) + { + auto bb = state==Qt::Checked; + le_pn_seed->setEnabled(!bb); + if(bb) + { + le_pn_seed->setText(QString::number(qrand())); + } + + }); + /*******************************************************/ + dw_general = new QDockWidget(tr("General settings"), this); + dw_general->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + dw_general->setFeatures(QDockWidget::NoDockWidgetFeatures); + dw_general->setWidget(fr_general); + addDockWidget(Qt::LeftDockWidgetArea, dw_general); } void MainWindow::create_specimen_dock_widget() { - ////////////////////////////////////////////// - auto fr_specimen = new MFrame_V; - fr_specimen->layout->setSpacing(1); - fr_specimen->setStyleSheet("QFrame { background: "+ QColor("#D8D8D8").name() +" }"); - - lb_spec_file = new QLabel(tr("Filename")); - - le_spec_file = new QLineEdit; - le_spec_file->setStatusTip(tr("Specimen filename")); - le_spec_file->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - - set_non_editable_QLineEdit(le_spec_file); - - pb_spec_load = new QPushButton(QIcon(":/images/open.png"), ""); - pb_spec_load->setStatusTip(tr("Load specimen")); - pb_spec_load->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - - pb_spec_show = new QPushButton(QIcon(":/images/view.png"), ""); - pb_spec_show->setStatusTip(tr("Show specimen")); - pb_spec_show->setMaximumSize(22, 22); - pb_spec_show->setEnabled(false); - - auto lyh_spec_file = new QHBoxLayout; - lyh_spec_file->setSpacing(1); - lyh_spec_file->setContentsMargins(2, 0, 1, 0); - lyh_spec_file->addWidget(lb_spec_file); - lyh_spec_file->addSpacing(2); - lyh_spec_file->addWidget(le_spec_file); - lyh_spec_file->addWidget(pb_spec_load); - lyh_spec_file->addWidget(pb_spec_show); - - fr_specimen->layout->addLayout(lyh_spec_file); - - /*******************************************************/ - /**********************Specimen info********************/ - /*******************************************************/ - lb_spec_n_atom_types = new QLabel(tr(n_atoms_types_qba(0, 0))); - lb_spec_n_atom_types->setFrameStyle(QFrame::Box | QFrame::Sunken); - lb_spec_n_atom_types->setAlignment(Qt::AlignCenter); - lb_spec_n_atom_types->setMinimumHeight(25); - - /*******************************************************/ - lb_spec_lx = new QLabel(tr(x_sub_to_qba("L", "x"))); - lb_spec_lx->setAlignment(Qt::AlignCenter); - lb_spec_lx->setMinimumWidth(20); - - le_spec_lx = new QLineEdit; - le_spec_lx->setStatusTip(tr("Simulation box size along x")); - le_spec_lx->setValidator(new QDoubleValidator(0, double_lim, 4)); - le_spec_lx->setText("0.000"); - - lb_spec_ly = new QLabel(tr(x_sub_to_qba("L", "y"))); - lb_spec_ly->setAlignment(Qt::AlignCenter); - lb_spec_ly->setMinimumWidth(20); - - le_spec_ly = new QLineEdit; - le_spec_ly->setStatusTip(tr("Simulation box size along y")); - le_spec_ly->setValidator(new QDoubleValidator(0, double_lim, 4)); - le_spec_ly->setText("0.000"); - - pb_spec_recenter = new QPushButton("Recenter"); - pb_spec_recenter->setStatusTip(tr("Recenter specimen in x-y directions")); - pb_spec_recenter->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - - auto lyt_dim = new QHBoxLayout; - lyt_dim->setSpacing(1); - lyt_dim->setContentsMargins(0, 0, 0, 0); - - lyt_dim->addWidget(lb_spec_lx); - lyt_dim->addWidget(le_spec_lx); - lyt_dim->addWidget(lb_spec_ly); - lyt_dim->addWidget(le_spec_ly); - lyt_dim->addWidget(pb_spec_recenter); - - /*******************************************************/ - gbg_spec_info = new MGroupBox_G(tr("Specimen info")); - gbg_spec_info->layout->setVerticalSpacing(1); - gbg_spec_info->layout->setHorizontalSpacing(2); - gbg_spec_info->layout->setContentsMargins(2, 0, 1, 0); - - gbg_spec_info->addWidget(lb_spec_n_atom_types, 0, 0); - gbg_spec_info->layout->addLayout(lyt_dim, 1, 0); - - fr_specimen->layout->addWidget(gbg_spec_info); - - /*******************************************************/ - /*********************** Rotation **********************/ - /*******************************************************/ - lb_spec_rot_theta = new QLabel(tr("q [°]")); - lb_spec_rot_theta->setAlignment(Qt::AlignCenter); - - le_spec_rot_theta = new QLineEdit; - le_spec_rot_theta->setStatusTip(tr("Rotation angle")); - le_spec_rot_theta->setValidator(new QDoubleValidator(-360, 360, 3)); - le_spec_rot_theta->setText("0.000"); - - lb_spec_rot_u = new QLabel(tr("û")); - lb_spec_rot_u->setAlignment(Qt::AlignCenter); - lb_spec_rot_u->setMinimumWidth(15); - - le_spec_rot_ux = new QLineEdit; - le_spec_rot_ux->setStatusTip(tr("x component of the rotation vector û")); - le_spec_rot_ux->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); - le_spec_rot_ux->setText("0.0"); - le_spec_rot_ux->setMaximumWidth(27); - - le_spec_rot_uy = new QLineEdit; - le_spec_rot_uy->setStatusTip(tr("y component of the rotation vector û")); - le_spec_rot_uy->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); - le_spec_rot_uy->setText("0.0"); - le_spec_rot_uy->setMaximumWidth(27); - - le_spec_rot_uz = new QLineEdit; - le_spec_rot_uz->setStatusTip(tr("z component of the rotation vector û")); - le_spec_rot_uz->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); - le_spec_rot_uz->setText("1.0"); - le_spec_rot_uz->setMaximumWidth(27); - - auto lyt_u = new QHBoxLayout; - lyt_u->setSpacing(1); - lyt_u->setContentsMargins(0, 0, 0, 0); - lyt_u->addWidget(le_spec_rot_ux); - lyt_u->addWidget(le_spec_rot_uy); - lyt_u->addWidget(le_spec_rot_uz); - - /*******************************************************/ - lb_spec_rot_center_type = new QLabel(tr("R. point")); - lb_spec_rot_center_type->setAlignment(Qt::AlignCenter); - - cb_spec_rot_center_type = new QComboBox; - cb_spec_rot_center_type->setStatusTip(tr("Rotation point")); - cb_spec_rot_center_type->addItem(tr("Centroid"), mt::eRPT_geometric_center); - cb_spec_rot_center_type->setItemData(0, tr("Geometric center"), Qt::ToolTipRole); - cb_spec_rot_center_type->addItem(tr("User def."), mt::eRPT_User_Define); - cb_spec_rot_center_type->setItemData(1, tr("User define center"), Qt::ToolTipRole); - - lb_spec_rot_center_p = new QLabel(tr(x_sub_to_qba("P", "0"))); - lb_spec_rot_center_p->setAlignment(Qt::AlignCenter); - lb_spec_rot_center_p->setMinimumWidth(15); - - le_spec_rot_center_px = new QLineEdit; - le_spec_rot_center_px->setStatusTip(tr("x component of the rotation center p0")); - le_spec_rot_center_px->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); - le_spec_rot_center_px->setText("0.0"); - le_spec_rot_center_px->setMaximumWidth(27); - - le_spec_rot_center_py = new QLineEdit; - le_spec_rot_center_py->setStatusTip(tr("y component of the rotation center p0")); - le_spec_rot_center_py->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); - le_spec_rot_center_py->setText("0.0"); - le_spec_rot_center_py->setMaximumWidth(27); - - le_spec_rot_center_pz = new QLineEdit; - le_spec_rot_center_pz->setStatusTip(tr("z component of the rotation center p0")); - le_spec_rot_center_pz->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); - le_spec_rot_center_pz->setText("0.0"); - le_spec_rot_center_pz->setMaximumWidth(27); - - auto lyt_p0 = new QHBoxLayout; - lyt_p0->setSpacing(1); - lyt_p0->setContentsMargins(0, 0, 0, 0); - lyt_p0->addWidget(le_spec_rot_center_px); - lyt_p0->addWidget(le_spec_rot_center_py); - lyt_p0->addWidget(le_spec_rot_center_pz); - - /*******************************************************/ - gbg_spec_rot = new MGroupBox_G(tr("Rotation")); - gbg_spec_rot->layout->setVerticalSpacing(1); - gbg_spec_rot->layout->setHorizontalSpacing(2); - gbg_spec_rot->layout->setContentsMargins(2, 0, 1, 0); - - gbg_spec_rot->addWidget(lb_spec_rot_theta, 0, 0); - gbg_spec_rot->addWidget(le_spec_rot_theta, 0, 1); - gbg_spec_rot->addWidget(lb_spec_rot_u, 0, 2); - gbg_spec_rot->layout->addLayout(lyt_u, 0, 3); - gbg_spec_rot->addWidget(lb_spec_rot_center_type, 1, 0); - gbg_spec_rot->addWidget(cb_spec_rot_center_type, 1, 1); - gbg_spec_rot->addWidget(lb_spec_rot_center_p, 1, 2); - gbg_spec_rot->layout->addLayout(lyt_p0, 1, 3); - - fr_specimen->layout->addWidget(gbg_spec_rot); - - connect(le_spec_lx, SIGNAL(textChanged(QString)), SLOT(le_spec_lx_ly_textChanged(QString))); - connect(le_spec_ly, SIGNAL(textChanged(QString)), SLOT(le_spec_lx_ly_textChanged(QString))); - - connect(pb_spec_recenter, SIGNAL(released()), SLOT(pb_spec_recenter_released())); - - connect(cb_spec_rot_center_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_spec_rot_center_type_currentIndexChanged(int))); - cb_spec_rot_center_type_currentIndexChanged(cb_spec_rot_center_type->currentIndex()); - - /*******************************************************/ - /*********************** Thickness *********************/ - /*******************************************************/ - lb_thk_type = new QLabel(tr("Type")); - lb_thk_type->setAlignment(Qt::AlignCenter); - lb_thk_type->setFrameStyle(QFrame::Box | QFrame::Sunken); - - cb_thk_type = new QComboBox; - cb_thk_type->setStatusTip(tr("Thickness type")); - cb_thk_type->addItem(tr("whole specimen"), QVariant(mt::eTT_Whole_Spec)); - cb_thk_type->setItemData(0, tr("Whole specimen"), Qt::ToolTipRole); - cb_thk_type->addItem(tr("by thickness"), QVariant(mt::eTT_Through_Thick)); - cb_thk_type->setItemData(1, tr("By thickness"), Qt::ToolTipRole); - cb_thk_type->addItem(tr("by slices"), QVariant(mt::eTT_Through_Slices)); - cb_thk_type->setItemData(2, tr("By slices"), Qt::ToolTipRole); - - disable_item_QComboBox(cb_thk_type, 2); - - /***************************************************/ - lb_thk_0 = new QLabel(tr("Thick. min.")); - lb_thk_0->setAlignment(Qt::AlignCenter); - lb_thk_0->setFrameStyle(QFrame::Box | QFrame::Sunken); - - le_thk_0 = new QLineEdit; - le_thk_0->setStatusTip(tr("Minimum thickness")); - le_thk_0->setValidator(new QDoubleValidator(0, double_lim, 4)); - le_thk_0->setText("0.0000"); - - /***************************************************/ - lb_thk_d = new QLabel(tr("Thick. step")); - lb_thk_d->setAlignment(Qt::AlignCenter); - lb_thk_d->setFrameStyle(QFrame::Box | QFrame::Sunken); - - le_thk_d = new QLineEdit; - le_thk_d->setStatusTip(tr("Thickness step")); - le_thk_d->setValidator(new QDoubleValidator(0, double_lim, 4)); - le_thk_d->setText("0.0000"); - - /***************************************************/ - lb_thk_e = new QLabel(tr("Thick. max.")); - lb_thk_e->setAlignment(Qt::AlignCenter); - lb_thk_e->setFrameStyle(QFrame::Box | QFrame::Sunken); - - le_thk_e = new QLineEdit; - le_thk_e->setStatusTip(tr("Maximum thickness")); - le_thk_e->setValidator(new QDoubleValidator(0, double_lim, 4)); - le_thk_e->setText("0.0000"); - - /*******************************************************/ - gbg_thk = new MGroupBox_G(tr("Thickness")); - gbg_thk->layout->setVerticalSpacing(1); - gbg_thk->layout->setHorizontalSpacing(2); - gbg_thk->layout->setContentsMargins(2, 0, 1, 0); - - gbg_thk->addWidget(lb_thk_type, 0, 0); - gbg_thk->addWidget(cb_thk_type, 0, 1, 1, 2); - gbg_thk->addWidget(lb_thk_0, 1, 0); - gbg_thk->addWidget(lb_thk_d, 1, 1); - gbg_thk->addWidget(lb_thk_e, 1, 2); - gbg_thk->addWidget(le_thk_0, 2, 0); - gbg_thk->addWidget(le_thk_d, 2, 1); - gbg_thk->addWidget(le_thk_e, 2, 2); - - fr_specimen->layout->addWidget(gbg_thk); - - connect(cb_thk_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_thk_type_currentIndexChanged(int))); - - /*******************************************************/ - /***************** Potential slicing *******************/ - /*******************************************************/ - cb_pot_slic_type = new QComboBox; - cb_pot_slic_type->setStatusTip(tr("Potential slicing scheme")); - cb_pot_slic_type->addItem(tr("Slicing by planes"), mt::ePS_Planes); - cb_pot_slic_type->setItemData(0, tr("Standard potential slicing approach by automatic identification of planes ")+ - tr("perpedincular to the beam direction"), Qt::ToolTipRole); - cb_pot_slic_type->addItem(tr("Slicing by dz"), mt::ePS_dz_Proj); - cb_pot_slic_type->setItemData(1, tr("Standard potential slicing approach using the given slice thickness"), Qt::ToolTipRole); - cb_pot_slic_type->addItem(tr("Subslicing by dz"), mt::ePS_dz_Sub); - cb_pot_slic_type->setItemData(2, tr("3d potential subslicing using the given slice thickness"), Qt::ToolTipRole); - cb_pot_slic_type->addItem(tr("Auto"), mt::ePS_Auto); - cb_pot_slic_type->setItemData(3, tr("Automatic potential slicing"), Qt::ToolTipRole); - - disable_item_QComboBox(cb_pot_slic_type, 3); - - lb_pot_slic_thick = new QLabel(tr("dz [Å]")); - - le_pot_slic_thick = new QLineEdit; - le_pot_slic_thick->setStatusTip(tr("Slice thickness")); - le_pot_slic_thick->setValidator(new QDoubleValidator(0, double_lim, 4)); - le_pot_slic_thick->setText("2.0000"); - - pb_pot_slic_view = new QPushButton(QIcon(":/images/view.png"), ""); - pb_pot_slic_view->setStatusTip(tr("Show specimen slicing")); - pb_pot_slic_view->setMaximumSize(22, 22); - pb_pot_slic_view->setEnabled(false); - - gbg_potential_slic = new MGroupBox_G(tr("Potential slicing")); - gbg_potential_slic->setContentsMargins(1, 2, 1, 0); - gbg_potential_slic->addWidget(cb_pot_slic_type, 0, 0); - gbg_potential_slic->addWidget(lb_pot_slic_thick, 0, 1); - gbg_potential_slic->addWidget(le_pot_slic_thick, 0, 2); - gbg_potential_slic->addWidget(pb_pot_slic_view, 0, 3); - - fr_specimen->layout->addWidget(gbg_potential_slic); - - connect(cb_pot_slic_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_pot_slic_type_currentIndexChanged(int))); - cb_pot_slic_type->setCurrentIndex(0); - cb_pot_slic_type_currentIndexChanged(0); - - connect(le_pot_slic_thick, SIGNAL(editingFinished()), SLOT(le_pot_slic_thick_editingFinished())); - - connect(pb_spec_load, SIGNAL(released()), SLOT(pb_spec_load_released())); - - /*******************************************************/ - /********************** xy sampling ********************/ - /*******************************************************/ - lb_samp_nx = new QLabel(tr(x_sub_to_qba("N", "x"))); - - le_samp_nx = new QLineEdit; - le_samp_nx->setStatusTip(tr("Number of pixels in the x direction")); - le_samp_nx->setValidator(new QIntValidator(32, int_lim)); - le_samp_nx->setText("1024"); - - lb_samp_ny = new QLabel(tr(x_sub_to_qba("N", "y"))); - - le_samp_ny = new QLineEdit; - le_samp_ny->setStatusTip(tr("Number of pixels in the y direction")); - le_samp_ny->setValidator(new QIntValidator(32, int_lim)); - le_samp_ny->setText("1024"); - - ckb_samp_bandwidth = new QCheckBox(tr("bwl")); - ckb_samp_bandwidth->setStatusTip(tr("Symmetrically bandwidth limit the wave function")); - - gbg_samp = new MGroupBox_G(tr("Box sampling")); - gbg_samp->layout->setVerticalSpacing(1); - gbg_samp->layout->setHorizontalSpacing(3); - - gbg_samp->addWidget(lb_samp_nx, 0, 0); - gbg_samp->addWidget(le_samp_nx, 0, 1); - gbg_samp->addWidget(lb_samp_ny, 0, 2); - gbg_samp->addWidget(le_samp_ny, 0, 3); - gbg_samp->addWidget(ckb_samp_bandwidth, 0, 4); - - fr_specimen->layout->addWidget(gbg_samp); - fr_specimen->layout->addStretch(1); - - /*******************************************************/ - connect(le_samp_nx, &QLineEdit::editingFinished, - [this]() - { - mt::Prime_Num pn; - auto nx = le_samp_nx->text().toInt(); - nx = pn(nx, mt::eDST_Closest); - le_samp_nx->setText(QString::number(nx)); - }); - - connect(le_samp_ny, &QLineEdit::editingFinished, - [this]() - { - mt::Prime_Num pn; - auto ny = le_samp_ny->text().toInt(); - ny = pn(ny, mt::eDST_Closest); - le_samp_ny->setText(QString::number(ny)); - }); - - ////////////////////////////////////////////// - dw_specimen = new QDockWidget(tr("Specimen"), this); - dw_specimen->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - dw_specimen->setFeatures(QDockWidget::NoDockWidgetFeatures); - dw_specimen->setWidget(fr_specimen); - addDockWidget(Qt::LeftDockWidgetArea, dw_specimen); + ////////////////////////////////////////////// + auto fr_specimen = new MFrame_V; + fr_specimen->layout->setSpacing(1); + fr_specimen->setStyleSheet("QFrame { background: "+ QColor("#D8D8D8").name() +" }"); + + lb_spec_file = new QLabel(tr("Filename")); + + le_spec_file = new QLineEdit; + le_spec_file->setStatusTip(tr("Specimen filename")); + le_spec_file->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + + set_non_editable_QLineEdit(le_spec_file); + + pb_spec_load = new QPushButton(QIcon(":/images/open.png"), ""); + pb_spec_load->setStatusTip(tr("Load specimen")); + pb_spec_load->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + pb_spec_show = new QPushButton(QIcon(":/images/view.png"), ""); + pb_spec_show->setStatusTip(tr("Show specimen")); + pb_spec_show->setMaximumSize(22, 22); + pb_spec_show->setEnabled(false); + + auto lyh_spec_file = new QHBoxLayout; + lyh_spec_file->setSpacing(1); + lyh_spec_file->setContentsMargins(2, 0, 1, 0); + lyh_spec_file->addWidget(lb_spec_file); + lyh_spec_file->addSpacing(2); + lyh_spec_file->addWidget(le_spec_file); + lyh_spec_file->addWidget(pb_spec_load); + lyh_spec_file->addWidget(pb_spec_show); + + fr_specimen->layout->addLayout(lyh_spec_file); + + /*******************************************************/ + /**********************Specimen info********************/ + /*******************************************************/ + lb_spec_n_atom_types = new QLabel(tr(n_atoms_types_qba(0, 0))); + lb_spec_n_atom_types->setFrameStyle(QFrame::Box | QFrame::Sunken); + lb_spec_n_atom_types->setAlignment(Qt::AlignCenter); + lb_spec_n_atom_types->setMinimumHeight(25); + + /*******************************************************/ + lb_spec_lx = new QLabel(tr(x_sub_to_qba("L", "x"))); + lb_spec_lx->setAlignment(Qt::AlignCenter); + lb_spec_lx->setMinimumWidth(20); + + le_spec_lx = new QLineEdit; + le_spec_lx->setStatusTip(tr("Simulation box size along x")); + le_spec_lx->setValidator(new QDoubleValidator(0, double_lim, 4)); + le_spec_lx->setText("0.000"); + + lb_spec_ly = new QLabel(tr(x_sub_to_qba("L", "y"))); + lb_spec_ly->setAlignment(Qt::AlignCenter); + lb_spec_ly->setMinimumWidth(20); + + le_spec_ly = new QLineEdit; + le_spec_ly->setStatusTip(tr("Simulation box size along y")); + le_spec_ly->setValidator(new QDoubleValidator(0, double_lim, 4)); + le_spec_ly->setText("0.000"); + + pb_spec_recenter = new QPushButton("Recenter"); + pb_spec_recenter->setStatusTip(tr("Recenter specimen in x-y directions")); + pb_spec_recenter->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + auto lyt_dim = new QHBoxLayout; + lyt_dim->setSpacing(1); + lyt_dim->setContentsMargins(0, 0, 0, 0); + + lyt_dim->addWidget(lb_spec_lx); + lyt_dim->addWidget(le_spec_lx); + lyt_dim->addWidget(lb_spec_ly); + lyt_dim->addWidget(le_spec_ly); + lyt_dim->addWidget(pb_spec_recenter); + + /*******************************************************/ + gbg_spec_info = new MGroupBox_G(tr("Specimen info")); + gbg_spec_info->layout->setVerticalSpacing(1); + gbg_spec_info->layout->setHorizontalSpacing(2); + gbg_spec_info->layout->setContentsMargins(2, 0, 1, 0); + + gbg_spec_info->addWidget(lb_spec_n_atom_types, 0, 0); + gbg_spec_info->layout->addLayout(lyt_dim, 1, 0); + + fr_specimen->layout->addWidget(gbg_spec_info); + + /*******************************************************/ + /*********************** Rotation **********************/ + /*******************************************************/ + lb_spec_rot_theta = new QLabel(tr("q [°]")); + lb_spec_rot_theta->setAlignment(Qt::AlignCenter); + + le_spec_rot_theta = new QLineEdit; + le_spec_rot_theta->setStatusTip(tr("Rotation angle")); + le_spec_rot_theta->setValidator(new QDoubleValidator(-360, 360, 3)); + le_spec_rot_theta->setText("0.000"); + + lb_spec_rot_u = new QLabel(tr("û")); + lb_spec_rot_u->setAlignment(Qt::AlignCenter); + lb_spec_rot_u->setMinimumWidth(15); + + le_spec_rot_ux = new QLineEdit; + le_spec_rot_ux->setStatusTip(tr("x component of the rotation vector û")); + le_spec_rot_ux->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); + le_spec_rot_ux->setText("0.0"); + le_spec_rot_ux->setMaximumWidth(27); + + le_spec_rot_uy = new QLineEdit; + le_spec_rot_uy->setStatusTip(tr("y component of the rotation vector û")); + le_spec_rot_uy->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); + le_spec_rot_uy->setText("0.0"); + le_spec_rot_uy->setMaximumWidth(27); + + le_spec_rot_uz = new QLineEdit; + le_spec_rot_uz->setStatusTip(tr("z component of the rotation vector û")); + le_spec_rot_uz->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); + le_spec_rot_uz->setText("1.0"); + le_spec_rot_uz->setMaximumWidth(27); + + auto lyt_u = new QHBoxLayout; + lyt_u->setSpacing(1); + lyt_u->setContentsMargins(0, 0, 0, 0); + lyt_u->addWidget(le_spec_rot_ux); + lyt_u->addWidget(le_spec_rot_uy); + lyt_u->addWidget(le_spec_rot_uz); + + /*******************************************************/ + lb_spec_rot_center_type = new QLabel(tr("R. point")); + lb_spec_rot_center_type->setAlignment(Qt::AlignCenter); + + cb_spec_rot_center_type = new QComboBox; + cb_spec_rot_center_type->setStatusTip(tr("Rotation point")); + cb_spec_rot_center_type->addItem(tr("Centroid"), mt::eRPT_geometric_center); + cb_spec_rot_center_type->setItemData(0, tr("Geometric center"), Qt::ToolTipRole); + cb_spec_rot_center_type->addItem(tr("User def."), mt::eRPT_User_Define); + cb_spec_rot_center_type->setItemData(1, tr("User define center"), Qt::ToolTipRole); + + lb_spec_rot_center_p = new QLabel(tr(x_sub_to_qba("P", "0"))); + lb_spec_rot_center_p->setAlignment(Qt::AlignCenter); + lb_spec_rot_center_p->setMinimumWidth(15); + + le_spec_rot_center_px = new QLineEdit; + le_spec_rot_center_px->setStatusTip(tr("x component of the rotation center p0")); + le_spec_rot_center_px->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); + le_spec_rot_center_px->setText("0.0"); + le_spec_rot_center_px->setMaximumWidth(27); + + le_spec_rot_center_py = new QLineEdit; + le_spec_rot_center_py->setStatusTip(tr("y component of the rotation center p0")); + le_spec_rot_center_py->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); + le_spec_rot_center_py->setText("0.0"); + le_spec_rot_center_py->setMaximumWidth(27); + + le_spec_rot_center_pz = new QLineEdit; + le_spec_rot_center_pz->setStatusTip(tr("z component of the rotation center p0")); + le_spec_rot_center_pz->setValidator(new QDoubleValidator(-double_lim, double_lim, 1)); + le_spec_rot_center_pz->setText("0.0"); + le_spec_rot_center_pz->setMaximumWidth(27); + + auto lyt_p0 = new QHBoxLayout; + lyt_p0->setSpacing(1); + lyt_p0->setContentsMargins(0, 0, 0, 0); + lyt_p0->addWidget(le_spec_rot_center_px); + lyt_p0->addWidget(le_spec_rot_center_py); + lyt_p0->addWidget(le_spec_rot_center_pz); + + /*******************************************************/ + gbg_spec_rot = new MGroupBox_G(tr("Rotation")); + gbg_spec_rot->layout->setVerticalSpacing(1); + gbg_spec_rot->layout->setHorizontalSpacing(2); + gbg_spec_rot->layout->setContentsMargins(2, 0, 1, 0); + + gbg_spec_rot->addWidget(lb_spec_rot_theta, 0, 0); + gbg_spec_rot->addWidget(le_spec_rot_theta, 0, 1); + gbg_spec_rot->addWidget(lb_spec_rot_u, 0, 2); + gbg_spec_rot->layout->addLayout(lyt_u, 0, 3); + gbg_spec_rot->addWidget(lb_spec_rot_center_type, 1, 0); + gbg_spec_rot->addWidget(cb_spec_rot_center_type, 1, 1); + gbg_spec_rot->addWidget(lb_spec_rot_center_p, 1, 2); + gbg_spec_rot->layout->addLayout(lyt_p0, 1, 3); + + fr_specimen->layout->addWidget(gbg_spec_rot); + + connect(le_spec_lx, SIGNAL(textChanged(QString)), SLOT(le_spec_lx_ly_textChanged(QString))); + connect(le_spec_ly, SIGNAL(textChanged(QString)), SLOT(le_spec_lx_ly_textChanged(QString))); + + connect(pb_spec_recenter, SIGNAL(released()), SLOT(pb_spec_recenter_released())); + + connect(cb_spec_rot_center_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_spec_rot_center_type_currentIndexChanged(int))); + cb_spec_rot_center_type_currentIndexChanged(cb_spec_rot_center_type->currentIndex()); + + /*******************************************************/ + /*********************** Thickness *********************/ + /*******************************************************/ + lb_thk_type = new QLabel(tr("Type")); + lb_thk_type->setAlignment(Qt::AlignCenter); + lb_thk_type->setFrameStyle(QFrame::Box | QFrame::Sunken); + + cb_thk_type = new QComboBox; + cb_thk_type->setStatusTip(tr("Thickness type")); + cb_thk_type->addItem(tr("whole specimen"), QVariant(mt::eTT_Whole_Spec)); + cb_thk_type->setItemData(0, tr("Whole specimen"), Qt::ToolTipRole); + cb_thk_type->addItem(tr("by thickness"), QVariant(mt::eTT_Through_Thick)); + cb_thk_type->setItemData(1, tr("By thickness"), Qt::ToolTipRole); + cb_thk_type->addItem(tr("by slices"), QVariant(mt::eTT_Through_Slices)); + cb_thk_type->setItemData(2, tr("By slices"), Qt::ToolTipRole); + + disable_item_QComboBox(cb_thk_type, 2); + + /***************************************************/ + lb_thk_0 = new QLabel(tr("Thick. min.")); + lb_thk_0->setAlignment(Qt::AlignCenter); + lb_thk_0->setFrameStyle(QFrame::Box | QFrame::Sunken); + + le_thk_0 = new QLineEdit; + le_thk_0->setStatusTip(tr("Minimum thickness")); + le_thk_0->setValidator(new QDoubleValidator(0, double_lim, 4)); + le_thk_0->setText("0.0000"); + + /***************************************************/ + lb_thk_d = new QLabel(tr("Thick. step")); + lb_thk_d->setAlignment(Qt::AlignCenter); + lb_thk_d->setFrameStyle(QFrame::Box | QFrame::Sunken); + + le_thk_d = new QLineEdit; + le_thk_d->setStatusTip(tr("Thickness step")); + le_thk_d->setValidator(new QDoubleValidator(0, double_lim, 4)); + le_thk_d->setText("0.0000"); + + /***************************************************/ + lb_thk_e = new QLabel(tr("Thick. max.")); + lb_thk_e->setAlignment(Qt::AlignCenter); + lb_thk_e->setFrameStyle(QFrame::Box | QFrame::Sunken); + + le_thk_e = new QLineEdit; + le_thk_e->setStatusTip(tr("Maximum thickness")); + le_thk_e->setValidator(new QDoubleValidator(0, double_lim, 4)); + le_thk_e->setText("0.0000"); + + /*******************************************************/ + gbg_thk = new MGroupBox_G(tr("Thickness")); + gbg_thk->layout->setVerticalSpacing(1); + gbg_thk->layout->setHorizontalSpacing(2); + gbg_thk->layout->setContentsMargins(2, 0, 1, 0); + + gbg_thk->addWidget(lb_thk_type, 0, 0); + gbg_thk->addWidget(cb_thk_type, 0, 1, 1, 2); + gbg_thk->addWidget(lb_thk_0, 1, 0); + gbg_thk->addWidget(lb_thk_d, 1, 1); + gbg_thk->addWidget(lb_thk_e, 1, 2); + gbg_thk->addWidget(le_thk_0, 2, 0); + gbg_thk->addWidget(le_thk_d, 2, 1); + gbg_thk->addWidget(le_thk_e, 2, 2); + + fr_specimen->layout->addWidget(gbg_thk); + + connect(cb_thk_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_thk_type_currentIndexChanged(int))); + + /*******************************************************/ + /***************** Potential slicing *******************/ + /*******************************************************/ + cb_pot_slic_type = new QComboBox; + cb_pot_slic_type->setStatusTip(tr("Potential slicing scheme")); + cb_pot_slic_type->addItem(tr("Slicing by planes"), mt::ePS_Planes); + cb_pot_slic_type->setItemData(0, tr("Standard potential slicing approach by automatic identification of planes ")+ + tr("perpedincular to the beam direction"), Qt::ToolTipRole); + cb_pot_slic_type->addItem(tr("Slicing by dz"), mt::ePS_dz_Proj); + cb_pot_slic_type->setItemData(1, tr("Standard potential slicing approach using the given slice thickness"), Qt::ToolTipRole); + cb_pot_slic_type->addItem(tr("Subslicing by dz"), mt::ePS_dz_Sub); + cb_pot_slic_type->setItemData(2, tr("3d potential subslicing using the given slice thickness"), Qt::ToolTipRole); + cb_pot_slic_type->addItem(tr("Auto"), mt::ePS_Auto); + cb_pot_slic_type->setItemData(3, tr("Automatic potential slicing"), Qt::ToolTipRole); + + disable_item_QComboBox(cb_pot_slic_type, 3); + + lb_pot_slic_thick = new QLabel(tr("dz [Å]")); + + le_pot_slic_thick = new QLineEdit; + le_pot_slic_thick->setStatusTip(tr("Slice thickness")); + le_pot_slic_thick->setValidator(new QDoubleValidator(0, double_lim, 4)); + le_pot_slic_thick->setText("2.0000"); + + pb_pot_slic_view = new QPushButton(QIcon(":/images/view.png"), ""); + pb_pot_slic_view->setStatusTip(tr("Show specimen slicing")); + pb_pot_slic_view->setMaximumSize(22, 22); + pb_pot_slic_view->setEnabled(false); + + gbg_potential_slic = new MGroupBox_G(tr("Potential slicing")); + gbg_potential_slic->setContentsMargins(1, 2, 1, 0); + gbg_potential_slic->addWidget(cb_pot_slic_type, 0, 0); + gbg_potential_slic->addWidget(lb_pot_slic_thick, 0, 1); + gbg_potential_slic->addWidget(le_pot_slic_thick, 0, 2); + gbg_potential_slic->addWidget(pb_pot_slic_view, 0, 3); + + fr_specimen->layout->addWidget(gbg_potential_slic); + + connect(cb_pot_slic_type, SIGNAL(currentIndexChanged(int)), SLOT(cb_pot_slic_type_currentIndexChanged(int))); + cb_pot_slic_type->setCurrentIndex(0); + cb_pot_slic_type_currentIndexChanged(0); + + connect(le_pot_slic_thick, SIGNAL(editingFinished()), SLOT(le_pot_slic_thick_editingFinished())); + + connect(pb_spec_load, SIGNAL(released()), SLOT(pb_spec_load_released())); + + /*******************************************************/ + /********************** xy sampling ********************/ + /*******************************************************/ + lb_samp_nx = new QLabel(tr(x_sub_to_qba("N", "x"))); + + le_samp_nx = new QLineEdit; + le_samp_nx->setStatusTip(tr("Number of pixels in the x direction")); + le_samp_nx->setValidator(new QIntValidator(32, int_lim)); + le_samp_nx->setText("1024"); + + lb_samp_ny = new QLabel(tr(x_sub_to_qba("N", "y"))); + + le_samp_ny = new QLineEdit; + le_samp_ny->setStatusTip(tr("Number of pixels in the y direction")); + le_samp_ny->setValidator(new QIntValidator(32, int_lim)); + le_samp_ny->setText("1024"); + + ckb_samp_bandwidth = new QCheckBox(tr("bwl")); + ckb_samp_bandwidth->setStatusTip(tr("Symmetrically bandwidth limit the wave function")); + + gbg_samp = new MGroupBox_G(tr("Box sampling")); + gbg_samp->layout->setVerticalSpacing(1); + gbg_samp->layout->setHorizontalSpacing(3); + + gbg_samp->addWidget(lb_samp_nx, 0, 0); + gbg_samp->addWidget(le_samp_nx, 0, 1); + gbg_samp->addWidget(lb_samp_ny, 0, 2); + gbg_samp->addWidget(le_samp_ny, 0, 3); + gbg_samp->addWidget(ckb_samp_bandwidth, 0, 4); + + fr_specimen->layout->addWidget(gbg_samp); + fr_specimen->layout->addStretch(1); + + /*******************************************************/ + connect(le_samp_nx, &QLineEdit::editingFinished, + [this]() + { + mt::Prime_Num pn; + auto nx = le_samp_nx->text().toInt(); + nx = pn(nx, mt::eDST_Closest); + le_samp_nx->setText(QString::number(nx)); + }); + + connect(le_samp_ny, &QLineEdit::editingFinished, + [this]() + { + mt::Prime_Num pn; + auto ny = le_samp_ny->text().toInt(); + ny = pn(ny, mt::eDST_Closest); + le_samp_ny->setText(QString::number(ny)); + }); + + ////////////////////////////////////////////// + dw_specimen = new QDockWidget(tr("Specimen"), this); + dw_specimen->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + dw_specimen->setFeatures(QDockWidget::NoDockWidgetFeatures); + dw_specimen->setWidget(fr_specimen); + addDockWidget(Qt::LeftDockWidgetArea, dw_specimen); } void MainWindow::create_experiment_dock_widget() { - ////////////////////////////////////////////// - auto *fr_experiment = new MFrame_G; - fr_experiment->layout->setVerticalSpacing(0); - fr_experiment->setStyleSheet("QFrame { background: "+ QColor("#D8D8D8").name() +" }"); - - lb_sim_type = new QLabel(tr("Select simulation type")); - lb_sim_type->setAlignment(Qt::AlignCenter); - // lb_sim_type->setFrameStyle(QFrame::Box | QFrame::Sunken); - - cb_sim_type = new QComboBox; - cb_sim_type->setStatusTip(tr("Select simulation type")); - - cb_sim_type->addItem(tr("STEM"), mt::eTEMST_STEM); - cb_sim_type->setItemData(0, tr("Scanning transmission electron microscopy"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("ISTEM"), mt::eTEMST_ISTEM); - cb_sim_type->setItemData(1, tr("Imaging scanning transmission electron microscopy"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("CBED"), mt::eTEMST_CBED); - cb_sim_type->setItemData(2, tr("Convergent beam electron diffraction"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("CBEI"), mt::eTEMST_CBEI); - cb_sim_type->setItemData(3, tr("Convergent beam electron imaging"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("ED"), mt::eTEMST_ED); - cb_sim_type->setItemData(4, tr("Electron diffraction"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("HRTEM"), mt::eTEMST_HRTEM); - cb_sim_type->setItemData(5, tr("High resolution transmission electron microscopy"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("PED"), mt::eTEMST_PED); - cb_sim_type->setItemData(6, tr("Precession electron diffraction"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("HCTEM"), mt::eTEMST_HCTEM); - cb_sim_type->setItemData(7, tr("Hollow cone transmission electron microscopy"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("EWFS"), mt::eTEMST_EWFS); - cb_sim_type->setItemData(8, tr("Exit wave in Fourier space"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("EWRS"), mt::eTEMST_EWRS); - cb_sim_type->setItemData(9, tr("Exit wave in real space"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("STEM_EELS"), mt::eTEMST_EELS); - cb_sim_type->setItemData(10, tr("STEM electron energy loss spectroscopy"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("EFTEM"), mt::eTEMST_EFTEM); - cb_sim_type->setItemData(11, tr("Energy filtered transmission electron microscopy"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("IWFS"), mt::eTEMST_IWFS); - cb_sim_type->setItemData(12, tr("Incident wave in Fourier space"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("IWRS"), mt::eTEMST_IWRS); - cb_sim_type->setItemData(13, tr("Incident wave in real space"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("PPFS"), mt::eTEMST_PPFS); - cb_sim_type->setItemData(14, tr("Projected potential in the Fourier space"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("PPRS"), mt::eTEMST_PPRS); - cb_sim_type->setItemData(15, tr("Projected potential in real space"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("TFFS"), mt::eTEMST_TFFS); - cb_sim_type->setItemData(16, tr("Transmission function in Fourier space"), Qt::ToolTipRole); - cb_sim_type->addItem(tr("TFRS"), mt::eTEMST_TFRS); - cb_sim_type->setItemData(17, tr("Transmission function in real space"), Qt::ToolTipRole); - cb_sim_type->setCurrentIndex(-1); - - disable_item_QComboBox(cb_sim_type, 12); - disable_item_QComboBox(cb_sim_type, 14); - disable_item_QComboBox(cb_sim_type, 16); - - auto lyh_experiment = new QHBoxLayout; - lyh_experiment->setContentsMargins(2, 0, 1, 0); - lyh_experiment->addWidget(lb_sim_type); - lyh_experiment->addWidget(cb_sim_type); - - create_iw_widget(); - create_stem_widget(); - create_pcs_widget(); - create_eels_widget(); - create_pptf_widget(); - - fr_experiment->layout->addLayout(lyh_experiment, 0, 0); - fr_experiment->layout->addWidget(wg_iw, 1, 0); - fr_experiment->layout->addWidget(wg_stem, 2, 0); - fr_experiment->layout->addWidget(wg_pcs, 2, 0); - fr_experiment->layout->addWidget(wg_eels, 2, 0); - fr_experiment->layout->addWidget(wg_pptf, 2, 0); - fr_experiment->layout->setRowStretch(3, 1); - - ////////////////////////////////////////////// - dw_simulation = new QDockWidget(tr("Experiment"), this); - dw_simulation->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - dw_simulation->setFeatures(QDockWidget::NoDockWidgetFeatures); - dw_simulation->setWidget(fr_experiment); - addDockWidget(Qt::RightDockWidgetArea, dw_simulation); + ////////////////////////////////////////////// + auto *fr_experiment = new MFrame_G; + fr_experiment->layout->setVerticalSpacing(0); + fr_experiment->setStyleSheet("QFrame { background: "+ QColor("#D8D8D8").name() +" }"); + + lb_sim_type = new QLabel(tr("Select simulation type")); + lb_sim_type->setAlignment(Qt::AlignCenter); + // lb_sim_type->setFrameStyle(QFrame::Box | QFrame::Sunken); + + cb_sim_type = new QComboBox; + cb_sim_type->setStatusTip(tr("Select simulation type")); + + cb_sim_type->addItem(tr("STEM"), mt::eTEMST_STEM); + cb_sim_type->setItemData(0, tr("Scanning transmission electron microscopy"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("ISTEM"), mt::eTEMST_ISTEM); + cb_sim_type->setItemData(1, tr("Imaging scanning transmission electron microscopy"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("CBED"), mt::eTEMST_CBED); + cb_sim_type->setItemData(2, tr("Convergent beam electron diffraction"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("CBEI"), mt::eTEMST_CBEI); + cb_sim_type->setItemData(3, tr("Convergent beam electron imaging"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("ED"), mt::eTEMST_ED); + cb_sim_type->setItemData(4, tr("Electron diffraction"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("HRTEM"), mt::eTEMST_HRTEM); + cb_sim_type->setItemData(5, tr("High resolution transmission electron microscopy"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("PED"), mt::eTEMST_PED); + cb_sim_type->setItemData(6, tr("Precession electron diffraction"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("HCTEM"), mt::eTEMST_HCTEM); + cb_sim_type->setItemData(7, tr("Hollow cone transmission electron microscopy"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("EWFS"), mt::eTEMST_EWFS); + cb_sim_type->setItemData(8, tr("Exit wave in Fourier space"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("EWRS"), mt::eTEMST_EWRS); + cb_sim_type->setItemData(9, tr("Exit wave in real space"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("STEM_EELS"), mt::eTEMST_EELS); + cb_sim_type->setItemData(10, tr("STEM electron energy loss spectroscopy"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("EFTEM"), mt::eTEMST_EFTEM); + cb_sim_type->setItemData(11, tr("Energy filtered transmission electron microscopy"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("IWFS"), mt::eTEMST_IWFS); + cb_sim_type->setItemData(12, tr("Incident wave in Fourier space"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("IWRS"), mt::eTEMST_IWRS); + cb_sim_type->setItemData(13, tr("Incident wave in real space"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("PPFS"), mt::eTEMST_PPFS); + cb_sim_type->setItemData(14, tr("Projected potential in the Fourier space"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("PPRS"), mt::eTEMST_PPRS); + cb_sim_type->setItemData(15, tr("Projected potential in real space"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("TFFS"), mt::eTEMST_TFFS); + cb_sim_type->setItemData(16, tr("Transmission function in Fourier space"), Qt::ToolTipRole); + cb_sim_type->addItem(tr("TFRS"), mt::eTEMST_TFRS); + cb_sim_type->setItemData(17, tr("Transmission function in real space"), Qt::ToolTipRole); + cb_sim_type->setCurrentIndex(-1); + + disable_item_QComboBox(cb_sim_type, 12); + disable_item_QComboBox(cb_sim_type, 14); + disable_item_QComboBox(cb_sim_type, 16); + + auto lyh_experiment = new QHBoxLayout; + lyh_experiment->setContentsMargins(2, 0, 1, 0); + lyh_experiment->addWidget(lb_sim_type); + lyh_experiment->addWidget(cb_sim_type); + + create_iw_widget(); + create_stem_widget(); + create_pcs_widget(); + create_eels_widget(); + create_pptf_widget(); + + fr_experiment->layout->addLayout(lyh_experiment, 0, 0); + fr_experiment->layout->addWidget(wg_iw, 1, 0); + fr_experiment->layout->addWidget(wg_stem, 2, 0); + fr_experiment->layout->addWidget(wg_pcs, 2, 0); + fr_experiment->layout->addWidget(wg_eels, 2, 0); + fr_experiment->layout->addWidget(wg_pptf, 2, 0); + fr_experiment->layout->setRowStretch(3, 1); + + ////////////////////////////////////////////// + dw_simulation = new QDockWidget(tr("Experiment"), this); + dw_simulation->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + dw_simulation->setFeatures(QDockWidget::NoDockWidgetFeatures); + dw_simulation->setWidget(fr_experiment); + addDockWidget(Qt::RightDockWidgetArea, dw_simulation); } void MainWindow::create_microscope_dock_widget() { - ////////////////////////////////////////////// - auto *fr_microscope = new MFrame_V; - fr_microscope->layout->setSpacing(1); - fr_microscope->setStyleSheet("QFrame { background: "+ QColor("#D8D8D8").name() +" }"); - - /*******************************************************/ - /**********************Microscope***********************/ - /*******************************************************/ - lb_mic_name = new QLabel(tr("Microscope")); - - cb_mic_name = new QComboBox; - cb_mic_name->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - - cb_mic_name->setStatusTip(tr("Microscope name")); - cb_mic_name->addItem(tr("Titan")); - cb_mic_name->setCurrentIndex(0); - - lb_mic_acc_vol = new QLabel(tr("E0 [kV]")); - - le_mic_acc_vol = new QLineEdit; - le_mic_acc_vol->setStatusTip(tr("Acceleration voltage")); - le_mic_acc_vol->setValidator(new QDoubleValidator(0, 5000, 1)); - le_mic_acc_vol->setText("300.0"); - - pb_mic_view = new QPushButton(QIcon(":/images/view.png"), ""); - pb_mic_view->setStatusTip(tr("Add or edit microscope parameters")); - pb_mic_view->setMaximumSize(22, 22); - pb_mic_view->setEnabled(false); - - auto lyh_mic = new QHBoxLayout; - lyh_mic->setSpacing(3); - lyh_mic->setContentsMargins(2, 0, 1, 0); - - lyh_mic->addWidget(lb_mic_name); - lyh_mic->addWidget(cb_mic_name); - lyh_mic->addWidget(lb_mic_acc_vol); - lyh_mic->addWidget(le_mic_acc_vol); - lyh_mic->addWidget(pb_mic_view); - - fr_microscope->layout->addLayout(lyh_mic); - - /*******************************************************/ - /*******************Illumination model******************/ - /*******************************************************/ - lb_tilt_theta = new QLabel(tr("q [°]")); - lb_tilt_theta->setAlignment(Qt::AlignCenter); - - le_tilt_theta = new QLineEdit; - le_tilt_theta->setStatusTip(tr("Tilt illumination polar angle")); - le_tilt_theta->setValidator(new QDoubleValidator(0, 180, 3)); - le_tilt_theta->setText("0.000"); - - /*******************************************************/ - lb_tilt_phi = new QLabel(tr("j [°]")); - - le_tilt_phi = new QLineEdit; - le_tilt_phi->setStatusTip(tr("Tilt illumination azimuthal angle")); - le_tilt_phi->setValidator(new QDoubleValidator(0, 360, 3)); - le_tilt_phi->setText("0.000"); - - /*******************************************************/ - lb_illu_model = new QLabel(tr("Illum. mode")); - - cb_illu_model = new QComboBox; - cb_illu_model->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - - cb_illu_model->setStatusTip(tr("Illumination mode")); - cb_illu_model->addItem(tr("Coherence mode"), enum_to_QVar(mt::eIM_Coherent)); - cb_illu_model->setItemData(0, tr("Coherence mode illumination"), Qt::ToolTipRole); - cb_illu_model->addItem(tr("Part. coherence mode"), enum_to_QVar(mt::eIM_Partial_Coherent)); - cb_illu_model->setItemData(1, tr("Partially coherence mode illumination"), Qt::ToolTipRole); - cb_illu_model->addItem(tr("Trans. cross Coef."), enum_to_QVar(mt::eIM_Trans_Cross_Coef)); - cb_illu_model->setItemData(2, tr("Transmission cross coefficient"), Qt::ToolTipRole); - cb_illu_model->addItem(tr("Incoh. numerical int."), enum_to_QVar(mt::eIM_Full_Integration)); - cb_illu_model->setItemData(3, tr("Incoherent illumination using numerical integration"), Qt::ToolTipRole); - - disable_item_QComboBox(cb_illu_model, 2, true); - - /*******************************************************/ - lb_illu_beta = new QLabel(tr("b [mrad]")); - lb_illu_beta->setAlignment(Qt::AlignCenter); - - le_illu_beta = new QLineEdit; - le_illu_beta->setStatusTip(tr("Semi-divergence angle")); - le_illu_beta->setValidator(new QDoubleValidator(0, std::numeric_limits::max(), 3)); - le_illu_beta->setText("0.100"); - - /*******************************************************/ - lb_illu_nbeta = new QLabel(tr("Nb")); - lb_illu_nbeta->setAlignment(Qt::AlignCenter); - - le_illu_nbeta = new QLineEdit; - le_illu_nbeta->setStatusTip(tr("Number of integration points")); - le_illu_nbeta->setValidator(new QIntValidator(4, int_lim)); - le_illu_nbeta->setText("8"); - - /*******************************************************/ - gbg_illu = new MGroupBox_G(); - gbg_illu->layout->setVerticalSpacing(1); - gbg_illu->layout->setContentsMargins(2, 3, 1, 0); - - gbg_illu->addWidget(lb_tilt_theta, 0, 0); - gbg_illu->addWidget(le_tilt_theta, 0, 1); - gbg_illu->addWidget(lb_tilt_phi, 0, 2); - gbg_illu->addWidget(le_tilt_phi, 0, 3); - - gbg_illu->addWidget(lb_illu_model, 1, 0); - gbg_illu->addWidget(cb_illu_model, 1, 1, 1, 3); - - gbg_illu->addWidget(lb_illu_beta, 2, 0); - gbg_illu->addWidget(le_illu_beta, 2, 1); - gbg_illu->addWidget(lb_illu_nbeta, 2, 2); - gbg_illu->addWidget(le_illu_nbeta, 2, 3); - - fr_microscope->layout->addWidget(gbg_illu); - - /*******************************************************/ - create_condenser_lens_tab(wg_cond_lens); - create_objective_lens_tab(wg_obj_lens); - - tb_lens = new QTabWidget; - tb_lens->addTab(wg_cond_lens, tr("Condenser Lens")); - tb_lens->addTab(wg_obj_lens, tr("Objective Lens")); - - fr_microscope->layout->addWidget(tb_lens); - fr_microscope->layout->addStretch(1); - - ////////////////////////////////////////////// - dw_microscope = new QDockWidget(tr("Microscope settings"), this); - dw_microscope->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - dw_microscope->setFeatures(QDockWidget::NoDockWidgetFeatures); - dw_microscope->setWidget(fr_microscope); - addDockWidget(Qt::RightDockWidgetArea, dw_microscope); - - // signal to slot - connect(cb_illu_model, SIGNAL(currentIndexChanged(int)), SLOT(cb_illu_model_currentIndexChanged(int))); - - cb_illu_model_currentIndexChanged(cb_illu_model->findData(mt::eIM_Coherent)); + ////////////////////////////////////////////// + auto *fr_microscope = new MFrame_V; + fr_microscope->layout->setSpacing(1); + fr_microscope->setStyleSheet("QFrame { background: "+ QColor("#D8D8D8").name() +" }"); + + /*******************************************************/ + /**********************Microscope***********************/ + /*******************************************************/ + lb_mic_name = new QLabel(tr("Microscope")); + + cb_mic_name = new QComboBox; + cb_mic_name->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + + cb_mic_name->setStatusTip(tr("Microscope name")); + cb_mic_name->addItem(tr("Titan")); + cb_mic_name->setCurrentIndex(0); + + lb_mic_acc_vol = new QLabel(tr("E0 [kV]")); + + le_mic_acc_vol = new QLineEdit; + le_mic_acc_vol->setStatusTip(tr("Acceleration voltage")); + le_mic_acc_vol->setValidator(new QDoubleValidator(0, 5000, 1)); + le_mic_acc_vol->setText("300.0"); + + pb_mic_view = new QPushButton(QIcon(":/images/view.png"), ""); + pb_mic_view->setStatusTip(tr("Add or edit microscope parameters")); + pb_mic_view->setMaximumSize(22, 22); + pb_mic_view->setEnabled(false); + + auto lyh_mic = new QHBoxLayout; + lyh_mic->setSpacing(3); + lyh_mic->setContentsMargins(2, 0, 1, 0); + + lyh_mic->addWidget(lb_mic_name); + lyh_mic->addWidget(cb_mic_name); + lyh_mic->addWidget(lb_mic_acc_vol); + lyh_mic->addWidget(le_mic_acc_vol); + lyh_mic->addWidget(pb_mic_view); + + fr_microscope->layout->addLayout(lyh_mic); + + /*******************************************************/ + /*******************Illumination model******************/ + /*******************************************************/ + lb_tilt_theta = new QLabel(tr("q [°]")); + lb_tilt_theta->setAlignment(Qt::AlignCenter); + + le_tilt_theta = new QLineEdit; + le_tilt_theta->setStatusTip(tr("Tilt illumination polar angle")); + le_tilt_theta->setValidator(new QDoubleValidator(0, 180, 3)); + le_tilt_theta->setText("0.000"); + + /*******************************************************/ + lb_tilt_phi = new QLabel(tr("j [°]")); + + le_tilt_phi = new QLineEdit; + le_tilt_phi->setStatusTip(tr("Tilt illumination azimuthal angle")); + le_tilt_phi->setValidator(new QDoubleValidator(0, 360, 3)); + le_tilt_phi->setText("0.000"); + + /*******************************************************/ + lb_illu_model = new QLabel(tr("Illum. mode")); + + cb_illu_model = new QComboBox; + cb_illu_model->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + + cb_illu_model->setStatusTip(tr("Illumination mode")); + cb_illu_model->addItem(tr("Coherence mode"), enum_to_QVar(mt::eIM_Coherent)); + cb_illu_model->setItemData(0, tr("Coherence mode illumination"), Qt::ToolTipRole); + cb_illu_model->addItem(tr("Part. coherence mode"), enum_to_QVar(mt::eIM_Partial_Coherent)); + cb_illu_model->setItemData(1, tr("Partially coherence mode illumination"), Qt::ToolTipRole); + cb_illu_model->addItem(tr("Trans. cross Coef."), enum_to_QVar(mt::eIM_Trans_Cross_Coef)); + cb_illu_model->setItemData(2, tr("Transmission cross coefficient"), Qt::ToolTipRole); + cb_illu_model->addItem(tr("Incoh. numerical int."), enum_to_QVar(mt::eIM_Full_Integration)); + cb_illu_model->setItemData(3, tr("Incoherent illumination using numerical integration"), Qt::ToolTipRole); + + disable_item_QComboBox(cb_illu_model, 2, true); + + /*******************************************************/ + lb_illu_beta = new QLabel(tr("b [mrad]")); + lb_illu_beta->setAlignment(Qt::AlignCenter); + + le_illu_beta = new QLineEdit; + le_illu_beta->setStatusTip(tr("Semi-divergence angle")); + le_illu_beta->setValidator(new QDoubleValidator(0, std::numeric_limits::max(), 3)); + le_illu_beta->setText("0.100"); + + /*******************************************************/ + lb_illu_nbeta = new QLabel(tr("Nb")); + lb_illu_nbeta->setAlignment(Qt::AlignCenter); + + le_illu_nbeta = new QLineEdit; + le_illu_nbeta->setStatusTip(tr("Number of integration points")); + le_illu_nbeta->setValidator(new QIntValidator(4, int_lim)); + le_illu_nbeta->setText("8"); + + /*******************************************************/ + gbg_illu = new MGroupBox_G(); + gbg_illu->layout->setVerticalSpacing(1); + gbg_illu->layout->setContentsMargins(2, 3, 1, 0); + + gbg_illu->addWidget(lb_tilt_theta, 0, 0); + gbg_illu->addWidget(le_tilt_theta, 0, 1); + gbg_illu->addWidget(lb_tilt_phi, 0, 2); + gbg_illu->addWidget(le_tilt_phi, 0, 3); + + gbg_illu->addWidget(lb_illu_model, 1, 0); + gbg_illu->addWidget(cb_illu_model, 1, 1, 1, 3); + + gbg_illu->addWidget(lb_illu_beta, 2, 0); + gbg_illu->addWidget(le_illu_beta, 2, 1); + gbg_illu->addWidget(lb_illu_nbeta, 2, 2); + gbg_illu->addWidget(le_illu_nbeta, 2, 3); + + fr_microscope->layout->addWidget(gbg_illu); + + /*******************************************************/ + create_condenser_lens_tab(wg_cond_lens); + create_objective_lens_tab(wg_obj_lens); + + tb_lens = new QTabWidget; + tb_lens->addTab(wg_cond_lens, tr("Condenser Lens")); + tb_lens->addTab(wg_obj_lens, tr("Objective Lens")); + + fr_microscope->layout->addWidget(tb_lens); + fr_microscope->layout->addStretch(1); + + ////////////////////////////////////////////// + dw_microscope = new QDockWidget(tr("Microscope settings"), this); + dw_microscope->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + dw_microscope->setFeatures(QDockWidget::NoDockWidgetFeatures); + dw_microscope->setWidget(fr_microscope); + addDockWidget(Qt::RightDockWidgetArea, dw_microscope); + + // signal to slot + connect(cb_illu_model, SIGNAL(currentIndexChanged(int)), SLOT(cb_illu_model_currentIndexChanged(int))); + + cb_illu_model_currentIndexChanged(cb_illu_model->findData(mt::eIM_Coherent)); } diff --git a/gui_multem/mainwindow.h b/gui_multem/mainwindow.h index 012af3cb..11a948c1 100644 --- a/gui_multem/mainwindow.h +++ b/gui_multem/mainwindow.h @@ -47,557 +47,557 @@ class PB_Timer; /************************************************/ class MainWindow : public QMainWindow { - Q_OBJECT + Q_OBJECT public: - MainWindow(); + MainWindow(); - RS_Thread *rs_thread; - PB_Timer *pb_timer; + RS_Thread *rs_thread; + PB_Timer *pb_timer; - void run_sim(); + void run_sim(); //public signals: -// void close_childs(); +// void close_childs(); private slots: - void open_sim(); - void save_sim(); - void save_as_sim(); - void exit(); - void about(); - void default_sim(); - void start_sim(); - void stop_sim(); + void open_sim(); + void save_sim(); + void save_as_sim(); + void exit(); + void about(); + void default_sim(); + void start_sim(); + void stop_sim(); public slots: - void progress_run_update(); - void show_data(); + void progress_run_update(); + void show_data(); - void cb_device_currentIndexChanged(int index); - void cb_elec_spec_int_model_currentIndexChanged(int index); + void cb_device_currentIndexChanged(int index); + void cb_elec_spec_int_model_currentIndexChanged(int index); - void pb_spec_load_released(); + void pb_spec_load_released(); - void le_spec_lx_ly_textChanged(const QString &); - void pb_spec_recenter_released(); - void cb_spec_rot_center_type_currentIndexChanged(int index); - void cb_pot_slic_type_currentIndexChanged(int index); - void cb_thk_type_currentIndexChanged(int index); - void le_pot_slic_thick_editingFinished(); + void le_spec_lx_ly_textChanged(const QString &); + void pb_spec_recenter_released(); + void cb_spec_rot_center_type_currentIndexChanged(int index); + void cb_pot_slic_type_currentIndexChanged(int index); + void cb_thk_type_currentIndexChanged(int index); + void le_pot_slic_thick_editingFinished(); - void cb_sim_type_currentIndexChanged(int index); + void cb_sim_type_currentIndexChanged(int index); - void cb_iw_type_currentIndexChanged(int index); - void pb_iw_load_released(); + void cb_iw_type_currentIndexChanged(int index); + void pb_iw_load_released(); - void cb_stem_det_type_currentIndexChanged(int index); - void le_stem_det_n_det_editingFinished(); - void cb_stem_det_k_det_currentIndexChanged(int index); - void le_stem_det_ideal_editingFinished(); - void pb_stem_det_exp_load_released(); + void cb_stem_det_type_currentIndexChanged(int index); + void le_stem_det_n_det_editingFinished(); + void cb_stem_det_k_det_currentIndexChanged(int index); + void le_stem_det_ideal_editingFinished(); + void pb_stem_det_exp_load_released(); - void cb_eels_element_currentIndexChanged(int index); + void cb_eels_element_currentIndexChanged(int index); - void cb_illu_model_currentIndexChanged(int index); - void cb_cl_sa_c_10_zero_currentIndexChanged(int index); - void cb_ol_sa_c_10_zero_currentIndexChanged(int index); - void pb_cl_sa_c_10_opt_released(); - void pb_ol_sa_c_10_opt_released(); + void cb_illu_model_currentIndexChanged(int index); + void cb_cl_sa_c_10_zero_currentIndexChanged(int index); + void cb_ol_sa_c_10_zero_currentIndexChanged(int index); + void pb_cl_sa_c_10_opt_released(); + void pb_ol_sa_c_10_opt_released(); private: - void create_menubar(); - - QLabel *central_widget; - QMenu *file_menu; - QAction *act_open_sim; - QAction *act_save_sim; - QAction *act_save_as_sim; - QAction *act_exit; - QAction *act_default_sim; - QAction *act_start_sim; - QAction *act_stop_sim; - - QProgressBar *pb_progress_run; - /****************General*****************/ - MGroupBox_G *gbg_device; - QComboBox *cb_device; - - QLabel *lb_precision; - QComboBox *cb_precision; - - QLabel *lb_gpu_card; - QComboBox *cb_gpu_card; - - QLabel *lb_nthreads; - QSpinBox *sb_nthreads; - - MGroupBox_G *gbg_elec_spec_int_model; - QComboBox *cb_elec_spec_int_model; - QLabel *lb_potential_type; - QComboBox *cb_potential_type; - - MGroupBox_G *gbg_elec_phonon_int_model; - QComboBox *cb_pn_model; - QCheckBox *ckb_pn_coh_contrib; - QLabel *lb_pn_dim; - QComboBox *cb_pn_dim; - QLabel *lb_pn_nconf; - QLineEdit *le_pn_nconf; - QCheckBox *ckb_pn_single_conf; - QLabel *lb_pn_seed; - QLineEdit *le_pn_seed; - QCheckBox *ckb_pn_auto_seed; - QWidget *wg_electron_phonon; - - QDockWidget *dw_general; - - /***********************Specimen**********************/ - QLabel *lb_spec_file; - QLineEdit *le_spec_file; - QPushButton *pb_spec_load; - QPushButton *pb_spec_show; - - MGroupBox_G *gbg_spec_info; - - QLabel *lb_spec_n_atom_types; - QLabel *lb_spec_lx; - QLineEdit *le_spec_lx; - QLabel *lb_spec_ly; - QLineEdit *le_spec_ly; - QPushButton *pb_spec_recenter; - - MGroupBox_G *gbg_spec_rot; - - QLabel *lb_spec_rot_theta; - QLineEdit *le_spec_rot_theta; - QLabel *lb_spec_rot_u; - QLineEdit *le_spec_rot_ux; - QLineEdit *le_spec_rot_uy; - QLineEdit *le_spec_rot_uz; - QLabel *lb_spec_rot_center_type; - QComboBox *cb_spec_rot_center_type; - QLabel *lb_spec_rot_center_p; - QLineEdit *le_spec_rot_center_px; - QLineEdit *le_spec_rot_center_py; - QLineEdit *le_spec_rot_center_pz; - - /*****************************************************/ - MGroupBox_G *gbg_thk; - QLabel *lb_thk_type; - QComboBox *cb_thk_type; - - QLabel *lb_thk_0; - QLineEdit *le_thk_0; - QLabel *lb_thk_d; - QLineEdit *le_thk_d; - QLabel *lb_thk_e; - QLineEdit *le_thk_e; - - MGroupBox_G *gbg_potential_slic; - - QComboBox *cb_pot_slic_type; - QLabel *lb_pot_slic_thick; - QLineEdit *le_pot_slic_thick; - QPushButton *pb_pot_slic_view; - - MGroupBox_G *gbg_samp; - - QLabel *lb_samp_nx; - QLineEdit *le_samp_nx; - QLabel *lb_samp_ny; - QLineEdit *le_samp_ny; - QCheckBox *ckb_samp_bandwidth; - - QDockWidget *dw_specimen; - - /****************Incident wave*****************/ - QLabel *lb_iw_type; - QComboBox *cb_iw_type; + void create_menubar(); + + QLabel *central_widget; + QMenu *file_menu; + QAction *act_open_sim; + QAction *act_save_sim; + QAction *act_save_as_sim; + QAction *act_exit; + QAction *act_default_sim; + QAction *act_start_sim; + QAction *act_stop_sim; + + QProgressBar *pb_progress_run; + /****************General*****************/ + MGroupBox_G *gbg_device; + QComboBox *cb_device; + + QLabel *lb_precision; + QComboBox *cb_precision; + + QLabel *lb_gpu_card; + QComboBox *cb_gpu_card; + + QLabel *lb_nthreads; + QSpinBox *sb_nthreads; + + MGroupBox_G *gbg_elec_spec_int_model; + QComboBox *cb_elec_spec_int_model; + QLabel *lb_potential_type; + QComboBox *cb_potential_type; + + MGroupBox_G *gbg_elec_phonon_int_model; + QComboBox *cb_pn_model; + QCheckBox *ckb_pn_coh_contrib; + QLabel *lb_pn_dim; + QComboBox *cb_pn_dim; + QLabel *lb_pn_nconf; + QLineEdit *le_pn_nconf; + QCheckBox *ckb_pn_single_conf; + QLabel *lb_pn_seed; + QLineEdit *le_pn_seed; + QCheckBox *ckb_pn_auto_seed; + QWidget *wg_electron_phonon; + + QDockWidget *dw_general; + + /***********************Specimen**********************/ + QLabel *lb_spec_file; + QLineEdit *le_spec_file; + QPushButton *pb_spec_load; + QPushButton *pb_spec_show; + + MGroupBox_G *gbg_spec_info; + + QLabel *lb_spec_n_atom_types; + QLabel *lb_spec_lx; + QLineEdit *le_spec_lx; + QLabel *lb_spec_ly; + QLineEdit *le_spec_ly; + QPushButton *pb_spec_recenter; + + MGroupBox_G *gbg_spec_rot; + + QLabel *lb_spec_rot_theta; + QLineEdit *le_spec_rot_theta; + QLabel *lb_spec_rot_u; + QLineEdit *le_spec_rot_ux; + QLineEdit *le_spec_rot_uy; + QLineEdit *le_spec_rot_uz; + QLabel *lb_spec_rot_center_type; + QComboBox *cb_spec_rot_center_type; + QLabel *lb_spec_rot_center_p; + QLineEdit *le_spec_rot_center_px; + QLineEdit *le_spec_rot_center_py; + QLineEdit *le_spec_rot_center_pz; + + /*****************************************************/ + MGroupBox_G *gbg_thk; + QLabel *lb_thk_type; + QComboBox *cb_thk_type; + + QLabel *lb_thk_0; + QLineEdit *le_thk_0; + QLabel *lb_thk_d; + QLineEdit *le_thk_d; + QLabel *lb_thk_e; + QLineEdit *le_thk_e; + + MGroupBox_G *gbg_potential_slic; + + QComboBox *cb_pot_slic_type; + QLabel *lb_pot_slic_thick; + QLineEdit *le_pot_slic_thick; + QPushButton *pb_pot_slic_view; + + MGroupBox_G *gbg_samp; + + QLabel *lb_samp_nx; + QLineEdit *le_samp_nx; + QLabel *lb_samp_ny; + QLineEdit *le_samp_ny; + QCheckBox *ckb_samp_bandwidth; + + QDockWidget *dw_specimen; + + /****************Incident wave*****************/ + QLabel *lb_iw_type; + QComboBox *cb_iw_type; - QLabel *lb_iw_file; - QLineEdit *le_iw_file; - QPushButton *pb_iw_load; + QLabel *lb_iw_file; + QLineEdit *le_iw_file; + QPushButton *pb_iw_load; - QLabel *lb_iw_x; - QLineEdit *le_iw_x; - QLabel *lb_iw_y; - QLineEdit *le_iw_y; + QLabel *lb_iw_x; + QLineEdit *le_iw_x; + QLabel *lb_iw_y; + QLineEdit *le_iw_y; - QPushButton *pb_iw_p; + QPushButton *pb_iw_p; - MGroupBox_G *gbg_iw; + MGroupBox_G *gbg_iw; - QWidget *wg_iw; - - /*********************stem**********************/ - QLabel *lb_stem_sc_type; - QComboBox *cb_stem_sc_type; - QCheckBox *ckb_stem_sc_incl_last_point; - - QLabel *lb_stem_sc_n_points; - QLineEdit *le_stem_sc_n_points; - QLabel *lb_stem_sc_np_assign; - QComboBox *cb_stem_sc_np_assign; - - QLabel *lb_stem_sc_px_0; - QLineEdit *le_stem_sc_px_0; - QLabel *lb_stem_sc_py_0; - QLineEdit *le_stem_sc_py_0; - QPushButton *pb_stem_sc_p_0; + QWidget *wg_iw; + + /*********************stem**********************/ + QLabel *lb_stem_sc_type; + QComboBox *cb_stem_sc_type; + QCheckBox *ckb_stem_sc_incl_last_point; + + QLabel *lb_stem_sc_n_points; + QLineEdit *le_stem_sc_n_points; + QLabel *lb_stem_sc_np_assign; + QComboBox *cb_stem_sc_np_assign; + + QLabel *lb_stem_sc_px_0; + QLineEdit *le_stem_sc_px_0; + QLabel *lb_stem_sc_py_0; + QLineEdit *le_stem_sc_py_0; + QPushButton *pb_stem_sc_p_0; - QLabel *lb_stem_sc_px_e; - QLineEdit *le_stem_sc_px_e; - QLabel *lb_stem_sc_py_e; - QLineEdit *le_stem_sc_py_e; - QPushButton *pb_stem_sc_p_e; + QLabel *lb_stem_sc_px_e; + QLineEdit *le_stem_sc_px_e; + QLabel *lb_stem_sc_py_e; + QLineEdit *le_stem_sc_py_e; + QPushButton *pb_stem_sc_p_e; - MGroupBox_G *gbg_stem_scanning; + MGroupBox_G *gbg_stem_scanning; - QComboBox *cb_stem_det_type; - QLabel *lb_stem_det_n_det; - QLineEdit *le_stem_det_n_det; - QLabel *lb_stem_det_k_det; - QComboBox *cb_stem_det_k_det; - QPushButton *pb_stem_det_view; - - MGroupBox_G *gbg_stem_detector; - - QFrame *fr_stem_detector_ideal; - QLabel *lb_stem_det_ideal_inner_angle; - QLineEdit *le_stem_det_ideal_inner_angle; - QLabel *lb_stem_det_ideal_outer_angle; - QLineEdit *le_stem_det_ideal_outer_angle; + QComboBox *cb_stem_det_type; + QLabel *lb_stem_det_n_det; + QLineEdit *le_stem_det_n_det; + QLabel *lb_stem_det_k_det; + QComboBox *cb_stem_det_k_det; + QPushButton *pb_stem_det_view; + + MGroupBox_G *gbg_stem_detector; + + QFrame *fr_stem_detector_ideal; + QLabel *lb_stem_det_ideal_inner_angle; + QLineEdit *le_stem_det_ideal_inner_angle; + QLabel *lb_stem_det_ideal_outer_angle; + QLineEdit *le_stem_det_ideal_outer_angle; - QFrame *fr_stem_detector_exp; - QLabel *lb_stem_det_exp_file; - QLineEdit *le_stem_det_exp_file; - QPushButton *pb_stem_det_exp_load; + QFrame *fr_stem_detector_exp; + QLabel *lb_stem_det_exp_file; + QLineEdit *le_stem_det_exp_file; + QPushButton *pb_stem_det_exp_load; - QWidget *wg_stem; + QWidget *wg_stem; - /*************PED/HCTEM**************/ - QLabel *lb_pcs_tilt_angle; - QLineEdit *le_pcs_tilt_angle; + /*************PED/HCTEM**************/ + QLabel *lb_pcs_tilt_angle; + QLineEdit *le_pcs_tilt_angle; - QLabel *lb_pcs_n_rotation; - QLineEdit *le_pcs_n_rotation; + QLabel *lb_pcs_n_rotation; + QLineEdit *le_pcs_n_rotation; - MGroupBox_G *gbg_pcs; + MGroupBox_G *gbg_pcs; - QWidget *wg_pcs; + QWidget *wg_pcs; - /*********************EFTEM/EELS***********************/ - QLabel *lb_eels_element; - QComboBox *cb_eels_element; + /*********************EFTEM/EELS***********************/ + QLabel *lb_eels_element; + QComboBox *cb_eels_element; - QLabel *lb_eels_energy; - QComboBox *cb_eels_energy; + QLabel *lb_eels_energy; + QComboBox *cb_eels_energy; - QLabel *lb_eels_coll_angle; - QLineEdit *le_eels_coll_angle; - - QLabel *lb_eels_m_selection; - QComboBox *cb_eels_m_selection; - - QLabel *lb_eels_channelling_type; - QComboBox *cb_eels_channelling_type; - - MGroupBox_G *gbg_eels; - - QWidget *wg_eels; - - /*************************PP/TF************************/ - QLabel *lb_pptf_n_slices; - - QLabel *lb_pptf_slice; - QComboBox *cb_pptf_slice; - - MGroupBox_H *gbh_pptf; - - QWidget *wg_pptf; - - /*******************************************************/ - MGroupBox_G *gbg_simulation; - - QLabel *lb_sim_type; - QComboBox *cb_sim_type; - QDockWidget *dw_simulation; - - /************Microscope parameters**************/ - QLabel *lb_mic_name; - QComboBox *cb_mic_name; - QLabel *lb_mic_acc_vol; - QLineEdit *le_mic_acc_vol; - QPushButton *pb_mic_view; - - /**********************************************/ - QLabel *lb_tilt_theta; - QLineEdit *le_tilt_theta; - QLabel *lb_tilt_phi; - QLineEdit *le_tilt_phi; - - /**********************************************/ - QLabel *lb_illu_model; - QComboBox *cb_illu_model; - - QLabel *lb_illu_beta; - QLineEdit *le_illu_beta; - QLabel *lb_illu_nbeta; - QLineEdit *le_illu_nbeta; - - MGroupBox_G *gbg_illu; - - /*************Condenser lens***************/ - QLabel *lb_cl_sa_c_30; - QLineEdit *le_cl_sa_c_30; - QLabel *lb_cl_sa_c_50; - QLineEdit *le_cl_sa_c_50; - QLabel *lb_cl_sa_m; - QLineEdit *le_cl_sa_m; - - QLabel *lb_cl_sa_c_10; - QLineEdit *le_cl_sa_c_10; - QPushButton *pb_cl_sa_c_10_opt; - QLabel *lb_cl_sa_c_10_zero; - QComboBox *cb_cl_sa_c_10_zero; - QLabel *lb_cl_sa_c_10_z; - QLineEdit *le_cl_sa_c_10_z; - - QLabel *lb_cl_sa_delta; - QLineEdit *le_cl_sa_delta; - QLabel *lb_cl_sa_ndelta; - QComboBox *cb_cl_sa_ndelta; - - MGroupBox_GE *gbge_cl_nsa; - - QLabel *lb_cl_c_12; - QLineEdit *le_cl_c_12; - QLabel *lb_cl_phi_12; - QLineEdit *le_cl_phi_12; - - QLabel *lb_cl_c_21; - QLineEdit *le_cl_c_21; - QLabel *lb_cl_phi_21; - QLineEdit *le_cl_phi_21; - QLabel *lb_cl_c_23; - QLineEdit *le_cl_c_23; - QLabel *lb_cl_phi_23; - QLineEdit *le_cl_phi_23; - - QLabel *lb_cl_c_32; - QLineEdit *le_cl_c_32; - QLabel *lb_cl_phi_32; - QLineEdit *le_cl_phi_32; - QLabel *lb_cl_c_34; - QLineEdit *le_cl_c_34; - QLabel *lb_cl_phi_34; - QLineEdit *le_cl_phi_34; - - QLabel *lb_cl_c_41; - QLineEdit *le_cl_c_41; - QLabel *lb_cl_phi_41; - QLineEdit *le_cl_phi_41; - QLabel *lb_cl_c_43; - QLineEdit *le_cl_c_43; - QLabel *lb_cl_phi_43; - QLineEdit *le_cl_phi_43; - QLabel *lb_cl_c_45; - QLineEdit *le_cl_c_45; - QLabel *lb_cl_phi_45; - QLineEdit *le_cl_phi_45; - - QLabel *lb_cl_c_52; - QLineEdit *le_cl_c_52; - QLabel *lb_cl_phi_52; - QLineEdit *le_cl_phi_52; - QLabel *lb_cl_c_54; - QLineEdit *le_cl_c_54; - QLabel *lb_cl_phi_54; - QLineEdit *le_cl_phi_54; - QLabel *lb_cl_c_56; - QLineEdit *le_cl_c_56; - QLabel *lb_cl_phi_56; - QLineEdit *le_cl_phi_56; - - MGroupBox_H *gbh_cl_ar; - QLabel *lb_cl_ar_min; - QLineEdit *le_cl_ar_min; - QLabel *lb_cl_ar_max; - QLineEdit *le_cl_ar_max; - - /*************Objective lens***************/ - QLabel *lb_ol_sa_c_30; - QLineEdit *le_ol_sa_c_30; - QLabel *lb_ol_sa_c_50; - QLineEdit *le_ol_sa_c_50; - QLabel *lb_ol_sa_m; - QLineEdit *le_ol_sa_m; - - QLabel *lb_ol_sa_c_10; - QLineEdit *le_ol_sa_c_10; - QPushButton *pb_ol_sa_c_10_opt; - QLabel *lb_ol_sa_c_10_zero; - QComboBox *cb_ol_sa_c_10_zero; - QLabel *lb_ol_sa_c_10_z; - QLineEdit *le_ol_sa_c_10_z; - - QLabel *lb_ol_sa_delta; - QLineEdit *le_ol_sa_delta; - QLabel *lb_ol_sa_ndelta; - QComboBox *cb_ol_sa_ndelta; - - MGroupBox_GE *gbge_ol_nsa; - - QLabel *lb_ol_c_12; - QLineEdit *le_ol_c_12; - QLabel *lb_ol_phi_12; - QLineEdit *le_ol_phi_12; - - QLabel *lb_ol_c_21; - QLineEdit *le_ol_c_21; - QLabel *lb_ol_phi_21; - QLineEdit *le_ol_phi_21; - QLabel *lb_ol_c_23; - QLineEdit *le_ol_c_23; - QLabel *lb_ol_phi_23; - QLineEdit *le_ol_phi_23; - - QLabel *lb_ol_c_32; - QLineEdit *le_ol_c_32; - QLabel *lb_ol_phi_32; - QLineEdit *le_ol_phi_32; - QLabel *lb_ol_c_34; - QLineEdit *le_ol_c_34; - QLabel *lb_ol_phi_34; - QLineEdit *le_ol_phi_34; - - QLabel *lb_ol_c_41; - QLineEdit *le_ol_c_41; - QLabel *lb_ol_phi_41; - QLineEdit *le_ol_phi_41; - QLabel *lb_ol_c_43; - QLineEdit *le_ol_c_43; - QLabel *lb_ol_phi_43; - QLineEdit *le_ol_phi_43; - QLabel *lb_ol_c_45; - QLineEdit *le_ol_c_45; - QLabel *lb_ol_phi_45; - QLineEdit *le_ol_phi_45; - - QLabel *lb_ol_c_52; - QLineEdit *le_ol_c_52; - QLabel *lb_ol_phi_52; - QLineEdit *le_ol_phi_52; - QLabel *lb_ol_c_54; - QLineEdit *le_ol_c_54; - QLabel *lb_ol_phi_54; - QLineEdit *le_ol_phi_54; - QLabel *lb_ol_c_56; - QLineEdit *le_ol_c_56; - QLabel *lb_ol_phi_56; - QLineEdit *le_ol_phi_56; - - MGroupBox_H *gbh_ol_ar; - QLabel *lb_ol_ar_min; - QLineEdit *le_ol_ar_min; - QLabel *lb_ol_ar_max; - QLineEdit *le_ol_ar_max; - - QWidget *wg_cond_lens; - QWidget *wg_obj_lens; - QTabWidget *tb_lens; - - QDockWidget *dw_microscope; - - /*******************************************************/ - mt::System_Configuration system_conf; - - mt::Atom_Data atoms; - - mt::Vector, mt::e_host> iw_psi; - mt::Grid_2d grid_2d_iw_psi; - - mt::Detector stem_detector; - - mt::Atomic_Data atomic_data; - - void read_system_configuration(); - - mt::Output_Multislice output_multislice_float; - mt::Output_Multislice output_multislice_double; - - template - void read_input_multislice(mt::Input_Multislice &input_multislice); - - /*******************************************************/ - void set_enable_running_simulation(bool enable); - - void set_objective_lens_tab_enable(boolean enable); - - /*******************************************************/ - void default_general_dock_widget(); - - void default_specimen_dock_widget(); - - void default_iw_widget(); - void default_stem_widget(); - void default_pcs_widget(); - void default_eels_widget(); - void default_pptf_widget(); - void default_experiment_dock_widget(); - - void default_condenser_lens_tab(); - void default_objective_lens_tab(); - void default_microscope_dock_widget(); - - /*******************************************************/ - void create_iw_widget(); - void create_stem_widget(); - void create_pcs_widget(); - void create_eels_widget(); - void create_pptf_widget(); - void create_condenser_lens_tab(QWidget *&lens); - void create_objective_lens_tab(QWidget *&lens); - - /*******************************************************/ - void create_general_dock_widget(); - void create_specimen_dock_widget(); - void create_experiment_dock_widget(); - void create_microscope_dock_widget(); - - /*******************************************************/ - void set_specimen_enable(bool enable); - - /*******************************************************/ - void disable_item_cb_iw_type(mt::eIncident_Wave_Type iwt, bool disabled=true); - void disable_item_cb_illu_model(mt::eIllumination_Model ill_model, bool disabled=true); - - /*******************************************************/ - void set_cb_iw_type_using_eTEM_Sim_Type(mt::eTEM_Sim_Type sim_type); - void set_cb_illu_model_using_eTEM_Sim_Type(mt::eTEM_Sim_Type sim_type); + QLabel *lb_eels_coll_angle; + QLineEdit *le_eels_coll_angle; + + QLabel *lb_eels_m_selection; + QComboBox *cb_eels_m_selection; + + QLabel *lb_eels_channelling_type; + QComboBox *cb_eels_channelling_type; + + MGroupBox_G *gbg_eels; + + QWidget *wg_eels; + + /*************************PP/TF************************/ + QLabel *lb_pptf_n_slices; + + QLabel *lb_pptf_slice; + QComboBox *cb_pptf_slice; + + MGroupBox_H *gbh_pptf; + + QWidget *wg_pptf; + + /*******************************************************/ + MGroupBox_G *gbg_simulation; + + QLabel *lb_sim_type; + QComboBox *cb_sim_type; + QDockWidget *dw_simulation; + + /************Microscope parameters**************/ + QLabel *lb_mic_name; + QComboBox *cb_mic_name; + QLabel *lb_mic_acc_vol; + QLineEdit *le_mic_acc_vol; + QPushButton *pb_mic_view; + + /**********************************************/ + QLabel *lb_tilt_theta; + QLineEdit *le_tilt_theta; + QLabel *lb_tilt_phi; + QLineEdit *le_tilt_phi; + + /**********************************************/ + QLabel *lb_illu_model; + QComboBox *cb_illu_model; + + QLabel *lb_illu_beta; + QLineEdit *le_illu_beta; + QLabel *lb_illu_nbeta; + QLineEdit *le_illu_nbeta; + + MGroupBox_G *gbg_illu; + + /*************Condenser lens***************/ + QLabel *lb_cl_sa_c_30; + QLineEdit *le_cl_sa_c_30; + QLabel *lb_cl_sa_c_50; + QLineEdit *le_cl_sa_c_50; + QLabel *lb_cl_sa_m; + QLineEdit *le_cl_sa_m; + + QLabel *lb_cl_sa_c_10; + QLineEdit *le_cl_sa_c_10; + QPushButton *pb_cl_sa_c_10_opt; + QLabel *lb_cl_sa_c_10_zero; + QComboBox *cb_cl_sa_c_10_zero; + QLabel *lb_cl_sa_c_10_z; + QLineEdit *le_cl_sa_c_10_z; + + QLabel *lb_cl_sa_delta; + QLineEdit *le_cl_sa_delta; + QLabel *lb_cl_sa_ndelta; + QComboBox *cb_cl_sa_ndelta; + + MGroupBox_GE *gbge_cl_nsa; + + QLabel *lb_cl_c_12; + QLineEdit *le_cl_c_12; + QLabel *lb_cl_phi_12; + QLineEdit *le_cl_phi_12; + + QLabel *lb_cl_c_21; + QLineEdit *le_cl_c_21; + QLabel *lb_cl_phi_21; + QLineEdit *le_cl_phi_21; + QLabel *lb_cl_c_23; + QLineEdit *le_cl_c_23; + QLabel *lb_cl_phi_23; + QLineEdit *le_cl_phi_23; + + QLabel *lb_cl_c_32; + QLineEdit *le_cl_c_32; + QLabel *lb_cl_phi_32; + QLineEdit *le_cl_phi_32; + QLabel *lb_cl_c_34; + QLineEdit *le_cl_c_34; + QLabel *lb_cl_phi_34; + QLineEdit *le_cl_phi_34; + + QLabel *lb_cl_c_41; + QLineEdit *le_cl_c_41; + QLabel *lb_cl_phi_41; + QLineEdit *le_cl_phi_41; + QLabel *lb_cl_c_43; + QLineEdit *le_cl_c_43; + QLabel *lb_cl_phi_43; + QLineEdit *le_cl_phi_43; + QLabel *lb_cl_c_45; + QLineEdit *le_cl_c_45; + QLabel *lb_cl_phi_45; + QLineEdit *le_cl_phi_45; + + QLabel *lb_cl_c_52; + QLineEdit *le_cl_c_52; + QLabel *lb_cl_phi_52; + QLineEdit *le_cl_phi_52; + QLabel *lb_cl_c_54; + QLineEdit *le_cl_c_54; + QLabel *lb_cl_phi_54; + QLineEdit *le_cl_phi_54; + QLabel *lb_cl_c_56; + QLineEdit *le_cl_c_56; + QLabel *lb_cl_phi_56; + QLineEdit *le_cl_phi_56; + + MGroupBox_H *gbh_cl_ar; + QLabel *lb_cl_ar_min; + QLineEdit *le_cl_ar_min; + QLabel *lb_cl_ar_max; + QLineEdit *le_cl_ar_max; + + /*************Objective lens***************/ + QLabel *lb_ol_sa_c_30; + QLineEdit *le_ol_sa_c_30; + QLabel *lb_ol_sa_c_50; + QLineEdit *le_ol_sa_c_50; + QLabel *lb_ol_sa_m; + QLineEdit *le_ol_sa_m; + + QLabel *lb_ol_sa_c_10; + QLineEdit *le_ol_sa_c_10; + QPushButton *pb_ol_sa_c_10_opt; + QLabel *lb_ol_sa_c_10_zero; + QComboBox *cb_ol_sa_c_10_zero; + QLabel *lb_ol_sa_c_10_z; + QLineEdit *le_ol_sa_c_10_z; + + QLabel *lb_ol_sa_delta; + QLineEdit *le_ol_sa_delta; + QLabel *lb_ol_sa_ndelta; + QComboBox *cb_ol_sa_ndelta; + + MGroupBox_GE *gbge_ol_nsa; + + QLabel *lb_ol_c_12; + QLineEdit *le_ol_c_12; + QLabel *lb_ol_phi_12; + QLineEdit *le_ol_phi_12; + + QLabel *lb_ol_c_21; + QLineEdit *le_ol_c_21; + QLabel *lb_ol_phi_21; + QLineEdit *le_ol_phi_21; + QLabel *lb_ol_c_23; + QLineEdit *le_ol_c_23; + QLabel *lb_ol_phi_23; + QLineEdit *le_ol_phi_23; + + QLabel *lb_ol_c_32; + QLineEdit *le_ol_c_32; + QLabel *lb_ol_phi_32; + QLineEdit *le_ol_phi_32; + QLabel *lb_ol_c_34; + QLineEdit *le_ol_c_34; + QLabel *lb_ol_phi_34; + QLineEdit *le_ol_phi_34; + + QLabel *lb_ol_c_41; + QLineEdit *le_ol_c_41; + QLabel *lb_ol_phi_41; + QLineEdit *le_ol_phi_41; + QLabel *lb_ol_c_43; + QLineEdit *le_ol_c_43; + QLabel *lb_ol_phi_43; + QLineEdit *le_ol_phi_43; + QLabel *lb_ol_c_45; + QLineEdit *le_ol_c_45; + QLabel *lb_ol_phi_45; + QLineEdit *le_ol_phi_45; + + QLabel *lb_ol_c_52; + QLineEdit *le_ol_c_52; + QLabel *lb_ol_phi_52; + QLineEdit *le_ol_phi_52; + QLabel *lb_ol_c_54; + QLineEdit *le_ol_c_54; + QLabel *lb_ol_phi_54; + QLineEdit *le_ol_phi_54; + QLabel *lb_ol_c_56; + QLineEdit *le_ol_c_56; + QLabel *lb_ol_phi_56; + QLineEdit *le_ol_phi_56; + + MGroupBox_H *gbh_ol_ar; + QLabel *lb_ol_ar_min; + QLineEdit *le_ol_ar_min; + QLabel *lb_ol_ar_max; + QLineEdit *le_ol_ar_max; + + QWidget *wg_cond_lens; + QWidget *wg_obj_lens; + QTabWidget *tb_lens; + + QDockWidget *dw_microscope; + + /*******************************************************/ + mt::System_Configuration system_conf; + + mt::Atom_Data atoms; + + mt::Vector, mt::e_host> iw_psi; + mt::Grid_2d grid_2d_iw_psi; + + mt::Detector stem_detector; + + mt::Atomic_Data atomic_data; + + void read_system_configuration(); + + mt::Output_Multislice output_multislice_float; + mt::Output_Multislice output_multislice_double; + + template + void read_input_multislice(mt::Input_Multislice &input_multislice); + + /*******************************************************/ + void set_enable_running_simulation(bool enable); + + void set_objective_lens_tab_enable(boolean enable); + + /*******************************************************/ + void default_general_dock_widget(); + + void default_specimen_dock_widget(); + + void default_iw_widget(); + void default_stem_widget(); + void default_pcs_widget(); + void default_eels_widget(); + void default_pptf_widget(); + void default_experiment_dock_widget(); + + void default_condenser_lens_tab(); + void default_objective_lens_tab(); + void default_microscope_dock_widget(); + + /*******************************************************/ + void create_iw_widget(); + void create_stem_widget(); + void create_pcs_widget(); + void create_eels_widget(); + void create_pptf_widget(); + void create_condenser_lens_tab(QWidget *&lens); + void create_objective_lens_tab(QWidget *&lens); + + /*******************************************************/ + void create_general_dock_widget(); + void create_specimen_dock_widget(); + void create_experiment_dock_widget(); + void create_microscope_dock_widget(); + + /*******************************************************/ + void set_specimen_enable(bool enable); + + /*******************************************************/ + void disable_item_cb_iw_type(mt::eIncident_Wave_Type iwt, bool disabled=true); + void disable_item_cb_illu_model(mt::eIllumination_Model ill_model, bool disabled=true); + + /*******************************************************/ + void set_cb_iw_type_using_eTEM_Sim_Type(mt::eTEM_Sim_Type sim_type); + void set_cb_illu_model_using_eTEM_Sim_Type(mt::eTEM_Sim_Type sim_type); }; /************************************************/ class RS_Thread : public QThread { - Q_OBJECT + Q_OBJECT public: - RS_Thread(MainWindow *main_i): main(main_i){} + RS_Thread(MainWindow *main_i): main(main_i){} signals: - void resultReady(); + void resultReady(); protected: - void run() - { - main->run_sim(); - emit resultReady(); - } + void run() + { + main->run_sim(); + emit resultReady(); + } private: - MainWindow *main; + MainWindow *main; }; class PB_Timer : public QObject @@ -605,29 +605,29 @@ class PB_Timer : public QObject Q_OBJECT public: - PB_Timer(MainWindow *main_i): main(main_i) - { - connect(&timer, SIGNAL (timeout()), this, SLOT (doWork())); - timer.setInterval(500); - } - - void start() - { - timer.start(); - } - - void stop() - { - timer.stop(); - } + PB_Timer(MainWindow *main_i): main(main_i) + { + connect(&timer, SIGNAL (timeout()), this, SLOT (doWork())); + timer.setInterval(500); + } + + void start() + { + timer.start(); + } + + void stop() + { + timer.stop(); + } private slots: - void doWork() - { - main->progress_run_update(); - } + void doWork() + { + main->progress_run_update(); + } private: - MainWindow *main; - QTimer timer; + MainWindow *main; + QTimer timer; }; #endif // MAINWINDOW_H diff --git a/gui_multem/multem.cu b/gui_multem/multem.cu index f34b0f96..293f7049 100644 --- a/gui_multem/multem.cu +++ b/gui_multem/multem.cu @@ -28,15 +28,15 @@ template void mt_run_multislice(mt::System_Configuration &system_conf, mt::Input_Multislice &input_multislice, mt::Output_Multislice &output_multislice) { - mt::Stream stream(system_conf.nstream); - mt::FFT fft_2d; - fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); + mt::Stream stream(system_conf.nstream); + mt::FFT fft_2d; + fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); if(input_multislice.is_IWFS_IWRS()) { mt::Incident_Wave incident_wave; incident_wave.set_input_data(&input_multislice, &stream, &fft_2d); - auto space = (input_multislice.is_IWRS())?mt::eS_Real:mt::eS_Reciprocal; + auto space = (input_multislice.is_IWRS())?mt::eS_Real:mt::eS_Reciprocal; incident_wave(space, output_multislice); } else @@ -48,8 +48,8 @@ void mt_run_multislice(mt::System_Configuration &system_conf, multislice(output_multislice); } - stream.synchronize(); - fft_2d.cleanup(); + stream.synchronize(); + fft_2d.cleanup(); } inline @@ -139,6 +139,6 @@ int mt_iter(mt::System_Configuration &system_conf) inline void mt_init() { - mt::Stream stream; - mt::FFT fft_2d; -} + mt::Stream stream; + mt::FFT fft_2d; +} \ No newline at end of file diff --git a/gui_multem/multem.cuh b/gui_multem/multem.cuh index 4d7a36a4..35682de8 100644 --- a/gui_multem/multem.cuh +++ b/gui_multem/multem.cuh @@ -30,19 +30,19 @@ void run_multislice(mt::System_Configuration &system_conf, mt::Input_Multislice &input_multislice, mt::Output_Multislice &output_multislice) { - mt::Input_Multislice input_multislice; - read_input_multislice(input_multislice); + mt::Input_Multislice input_multislice; + read_input_multislice(input_multislice); - output_multislice.set_input_data(&input_multislice); + output_multislice.set_input_data(&input_multislice); - mt::Stream stream(system_conf.nstream); - mt::FFT fft_2d; - fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); + mt::Stream stream(system_conf.nstream); + mt::FFT fft_2d; + fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - mt::Multislice multislice; - multislice.set_input_data(&input_multislice, &stream, &fft_2d); - multislice(output_multislice); + mt::Multislice multislice; + multislice.set_input_data(&input_multislice, &stream, &fft_2d); + multislice(output_multislice); - stream.synchronize(); - fft_2d.cleanup(); + stream.synchronize(); + fft_2d.cleanup(); } \ No newline at end of file diff --git a/gui_multem/multem.pro.user b/gui_multem/multem.pro.user index 6366be26..0be8e525 100644 --- a/gui_multem/multem.pro.user +++ b/gui_multem/multem.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -62,7 +62,7 @@ Desktop Qt 5.9.0 MSVC2015 64bit Desktop Qt 5.9.0 MSVC2015 64bit qt.59.win64_msvc2015_64_kit - 1 + 0 0 0 @@ -292,7 +292,7 @@ multem.pro false - D:/MULTEM/build-multem-Desktop_Qt_5_9_0_MSVC2015_64bit-Release/executable + D:/MULTEM/build-multem-Desktop_Qt_5_9_0_MSVC2015_64bit-Debug/executable 3768 false true diff --git a/gui_multem/q_colormap.h b/gui_multem/q_colormap.h index 1e91dddb..591280f7 100644 --- a/gui_multem/q_colormap.h +++ b/gui_multem/q_colormap.h @@ -10,209 +10,209 @@ class Colormap { public: - Colormap(const eColormap &colormap) - { - points.resize(128); - map.resize(256); - - set_colormap(colormap); - } - - Colormap() - { - points.resize(128); - map.resize(256); - - clear(); - } - - ~Colormap(){} - - void set_colormap(const eColormap &colormap) - { - const int m = 256; - int ri, gi, bi; - - clear(); - - switch(colormap) - { - case eCM_Gray: - { - for(auto ik=0; ik points; - std::vector map; - - void clear() - { - std::fill(points.begin(), points.end(), qRgba(0, 0, 0, 0)); - std::fill(map.begin(), map.end(), qRgba(0, 0, 0, 0)); - } - - void getLinearmap() - { - if(points.empty()) return; - - int ipoints; - int r, g, b; - QVector3D V0, V1, u0; - int idx0, idx1, idx; - - // get initial point - idx0 = qAlpha(points[0]); - V0.setX(qRed(points[0])); - V0.setY(qGreen(points[0])); - V0.setZ(qBlue(points[0])); - - for(ipoints=1; ipoints points; + std::vector map; + + void clear() + { + std::fill(points.begin(), points.end(), qRgba(0, 0, 0, 0)); + std::fill(map.begin(), map.end(), qRgba(0, 0, 0, 0)); + } + + void getLinearmap() + { + if(points.empty()) return; + + int ipoints; + int r, g, b; + QVector3D V0, V1, u0; + int idx0, idx1, idx; + + // get initial point + idx0 = qAlpha(points[0]); + V0.setX(qRed(points[0])); + V0.setY(qGreen(points[0])); + V0.setZ(qBlue(points[0])); + + for(ipoints=1; ipoints - explicit Data_Viewer(TOutput_Multislice &output_multislice_i, QDialog *parent = Q_NULLPTR): QDialog(parent) - { - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - MouSetPos = QPoint(0,0); + template + explicit Data_Viewer(TOutput_Multislice &output_multislice_i, QDialog *parent = Q_NULLPTR): QDialog(parent) + { + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + MouSetPos = QPoint(0,0); - QDesktopWidget *desktopWidget = QApplication::desktop(); - const QRect screenGeometry = desktopWidget->screenGeometry(desktopWidget->primaryScreen()); - window_size = screenGeometry.size()*3/5; - auto side_min = qMin(window_size.width(), window_size.height()); - window_size.setWidth(side_min); - window_size.setHeight(side_min); + QDesktopWidget *desktopWidget = QApplication::desktop(); + const QRect screenGeometry = desktopWidget->screenGeometry(desktopWidget->primaryScreen()); + window_size = screenGeometry.size()*3/5; + auto side_min = qMin(window_size.width(), window_size.height()); + window_size.setWidth(side_min); + window_size.setHeight(side_min); - /******************************************************/ - create_wigets(); + /******************************************************/ + create_wigets(); - /******************************************************/ - output_multislice = output_multislice_i; + /******************************************************/ + output_multislice = output_multislice_i; - image->set_data_size(output_multislice.nx, output_multislice.ny); - image->set_window_size(window_size); + image->set_data_size(output_multislice.nx, output_multislice.ny); + image->set_window_size(window_size); - /******************************************************/ - sl_thickness->setMinimum(1); - sl_thickness->setMaximum(output_multislice.thick.size()); - sl_thickness->setValue(1); + /******************************************************/ + sl_thickness->setMinimum(1); + sl_thickness->setMaximum(output_multislice.thick.size()); + sl_thickness->setValue(1); - if(is_thickness_available()) - { - lb_thickness_value->setText(thk_value_qstr(output_multislice.thick[0])); - } + if(is_thickness_available()) + { + lb_thickness_value->setText(thk_value_qstr(output_multislice.thick[0])); + } - /******************************************************/ - sl_detector->setMinimum(1); - sl_detector->setMaximum(output_multislice.ndetector); - sl_detector->setValue(1); + /******************************************************/ + sl_detector->setMinimum(1); + sl_detector->setMaximum(output_multislice.ndetector); + sl_detector->setValue(1); - if(output_multislice.is_STEM()) - { - auto lambda = mt::get_lambda(output_multislice.E_0); - auto g_inner = output_multislice.detector.g_inner[0]; - auto g_outer = output_multislice.detector.g_outer[0]; + if(output_multislice.is_STEM()) + { + auto lambda = mt::get_lambda(output_multislice.E_0); + auto g_inner = output_multislice.detector.g_inner[0]; + auto g_outer = output_multislice.detector.g_outer[0]; - lb_detector_value->setText(det_value_qstr(lambda, g_inner, g_outer)); - } + lb_detector_value->setText(det_value_qstr(lambda, g_inner, g_outer)); + } - /******************************************************/ - activate_options(); + /******************************************************/ + activate_options(); - /******************************************************/ - connect(image, SIGNAL(mouseDoubleClick()), this, SLOT(set_normalSize())); + /******************************************************/ + connect(image, SIGNAL(mouseDoubleClick()), this, SLOT(set_normalSize())); -// connect(image_tot, SIGNAL(mouseMove(QPoint)), this, SLOT(qt_image_mouseMoveEvent(QPoint))); -// connect(image_tot, SIGNAL(mousePress(QPoint)), this, SLOT(qt_image_mousePressEvent(QPoint))); -// connect(image_tot, SIGNAL(mouseReleaseEvent(QPoint)), this, SLOT(qt_image_mouseReleaseEvent(QPoint))); -// connect(cb_colormap, SIGNAL(currentIndexChanged(int)), this, SLOT(on_cb_ColorMap_currentIndexChanged(int))); +// connect(image_tot, SIGNAL(mouseMove(QPoint)), this, SLOT(qt_image_mouseMoveEvent(QPoint))); +// connect(image_tot, SIGNAL(mousePress(QPoint)), this, SLOT(qt_image_mousePressEvent(QPoint))); +// connect(image_tot, SIGNAL(mouseReleaseEvent(QPoint)), this, SLOT(qt_image_mouseReleaseEvent(QPoint))); +// connect(cb_colormap, SIGNAL(currentIndexChanged(int)), this, SLOT(on_cb_ColorMap_currentIndexChanged(int))); - connect(cb_show_ctype, SIGNAL(currentIndexChanged(int)), SLOT(cb_show_ctype_currentIndexChanged(int))); - connect(cb_colormap, SIGNAL(currentIndexChanged(int)), SLOT(cb_colormap_currentIndexChanged(int))); + connect(cb_show_ctype, SIGNAL(currentIndexChanged(int)), SLOT(cb_show_ctype_currentIndexChanged(int))); + connect(cb_colormap, SIGNAL(currentIndexChanged(int)), SLOT(cb_colormap_currentIndexChanged(int))); - connect(cb_scale, SIGNAL(currentIndexChanged(int)), SLOT(cb_scale_currentIndexChanged(int))); + connect(cb_scale, SIGNAL(currentIndexChanged(int)), SLOT(cb_scale_currentIndexChanged(int))); - connect(ckb_block_g0, SIGNAL(stateChanged(int)), SLOT(ckb_block_g0_stateChanged(int))); + connect(ckb_block_g0, SIGNAL(stateChanged(int)), SLOT(ckb_block_g0_stateChanged(int))); - connect(le_scale, SIGNAL(editingFinished()), SLOT(le_scale_editingFinished())); - connect(le_scale, SIGNAL(returnPressed()), SLOT(le_scale_editingFinished())); + connect(le_scale, SIGNAL(editingFinished()), SLOT(le_scale_editingFinished())); + connect(le_scale, SIGNAL(returnPressed()), SLOT(le_scale_editingFinished())); - connect(sl_thickness, SIGNAL(valueChanged(int)), SLOT(sl_thickness_valueChanged(int))); - connect(sl_detector, SIGNAL(valueChanged(int)), SLOT(sl_detector_valueChanged(int))); - connect(ckb_show_coh, SIGNAL(stateChanged(int)), SLOT(ckb_show_coh_stateChanged(int))); + connect(sl_thickness, SIGNAL(valueChanged(int)), SLOT(sl_thickness_valueChanged(int))); + connect(sl_detector, SIGNAL(valueChanged(int)), SLOT(sl_detector_valueChanged(int))); + connect(ckb_show_coh, SIGNAL(stateChanged(int)), SLOT(ckb_show_coh_stateChanged(int))); - connect(le_rep_x, SIGNAL(textChanged(QString)), SLOT(le_rep_xy_textChanged(QString))); - connect(le_rep_y, SIGNAL(textChanged(QString)), SLOT(le_rep_xy_textChanged(QString))); + connect(le_rep_x, SIGNAL(textChanged(QString)), SLOT(le_rep_xy_textChanged(QString))); + connect(le_rep_y, SIGNAL(textChanged(QString)), SLOT(le_rep_xy_textChanged(QString))); - connect(image, SIGNAL(sg_save_as_binary()), this, SLOT(save_as_binary())); - /******************************************************/ - draw_current_settings(); - } + connect(image, SIGNAL(sg_save_as_binary()), this, SLOT(save_as_binary())); + /******************************************************/ + draw_current_settings(); + } public slots: - void save_as_binary() - { - QString FileName = QFileDialog::getSaveFileName(0,"Save file", QDir::currentPath(), - "Binary file (*.bin );Binary (*.bin)", - new QString("Binary file (*.bin )")); - - if (!FileName.isEmpty()) - { - //mt::Grid_2d grid(output_multislice.nx, output_multislice.grid_2d.ny); - //mt::write_mat_binary_matrix(FileName, grid, data); - } - } - - void set_normalSize() - { - adjustSize(); - } - - void qt_image_mouseMoveEvent(QPoint Point) - { -// lb_Pos->setText(QString(" Position: X = %1, Y = %2").arg(Point.rx()).arg(Point.ry())); -// lb_Rel_Pos->setText(QString(" Position: X = %1, Y = %2").arg(Point.rx()-MouSetPos.rx()).arg(Point.ry()-MouSetPos.ry())); - } - - void qt_image_mousePressEvent(QPoint Point) - { -// lb_Rel_Ori->setText(QString(" Position: X = %1, Y = %2").arg(Point.rx()).arg(Point.ry())); -// MouSetPos = Point; - } - - void qt_image_mouseReleaseEvent(QPoint Point) - { - - } - - void cb_colormap_currentIndexChanged(int index) - { - auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); - auto colormap = QVar_to_enum(cb_colormap->itemData(index)); - auto scale_type = QVar_to_enum(cb_scale->currentData()); - double scale_factor = le_scale->text().toDouble(); - - int ithk = sl_thickness->value()-1; - int idet = sl_detector->value()-1; - - draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); - } - - void cb_show_ctype_currentIndexChanged(int index) - { - auto show_cdata = QVar_to_enum(cb_show_ctype->itemData(index)); - auto colormap = QVar_to_enum(cb_colormap->currentData()); - - if(!(show_cdata==mt::eSCD_CMod)) - { - cb_scale->setCurrentIndex(0); - } - auto scale_type = QVar_to_enum(cb_scale->currentData()); - double scale_factor = le_scale->text().toDouble(); - - int ithk = sl_thickness->value()-1; - int idet = sl_detector->value()-1; - - draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); - } - - void cb_scale_currentIndexChanged(int index) - { - auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); - auto colormap = QVar_to_enum(cb_colormap->currentData()); - auto scale_type = QVar_to_enum(cb_scale->itemData(index)); - double scale_factor = le_scale->text().toDouble(); - - auto b_st = (scale_type==eSLT_Power); - le_scale->setVisible(b_st); - - int ithk = sl_thickness->value()-1; - int idet = sl_detector->value()-1; - - draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); - } - - void le_scale_editingFinished() - { - auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); - auto colormap = QVar_to_enum(cb_colormap->currentData()); - auto scale_type = QVar_to_enum(cb_scale->currentData()); - double scale_factor = le_scale->text().toDouble(); - - int ithk = sl_thickness->value()-1; - int idet = sl_detector->value()-1; - - draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); - } - - void le_rep_xy_textChanged(const QString &) - { - auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); - auto colormap = QVar_to_enum(cb_colormap->currentData()); - auto scale_type = QVar_to_enum(cb_scale->currentData()); - double scale_factor = le_scale->text().toDouble(); - - int ithk = sl_thickness->value()-1; - int idet = sl_detector->value()-1; - - int rep_nx = le_rep_x->text().toInt(); - int rep_ny = le_rep_y->text().toInt(); - - auto pmo = (ckb_show_coh->isChecked())?mt::eFMO_Coherent:mt::eFMO_Total; - data = output_multislice.extract_data(pmo, show_cdata, ithk, idet); - data = replicate(rep_nx, rep_ny, data); - - image->set_data_size(rep_nx*output_multislice.nx, rep_ny*output_multislice.ny); - image->draw(&data, colormap, scale_type, scale_factor); - } - - void ckb_block_g0_stateChanged(int state) - { - draw_current_settings(); - } - - void ckb_show_coh_stateChanged(int state) - { - if(state==Qt::Checked) - { - if(output_multislice.is_ot_m2psi_tot_psi_coh()) - { - lb_show_ctype->setVisible(true); - cb_show_ctype->setVisible(true); - } - } - else - { - auto bb_complex = is_output_complex_alone(); - lb_show_ctype->setVisible(bb_complex); - cb_show_ctype->setVisible(bb_complex); - } - draw_current_settings(); - } - - void sl_thickness_valueChanged(int value) - { - if(value>output_multislice.thick.size()) return; - - auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); - auto colormap = QVar_to_enum(cb_colormap->currentData()); - auto scale_type = QVar_to_enum(cb_scale->currentData()); - double scale_factor = le_scale->text().toDouble(); - - int ithk = value-1; - int idet = sl_detector->value()-1; - - lb_thickness_value->setText(thk_value_qstr(output_multislice.thick[ithk])); - - draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); - } - - void sl_detector_valueChanged(int value) - { - if(value>output_multislice.ndetector) return; - - auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); - auto colormap = QVar_to_enum(cb_colormap->currentData()); - auto scale_type = QVar_to_enum(cb_scale->currentData()); - double scale_factor = le_scale->text().toDouble(); - - int ithk = sl_thickness->value()-1; - int idet = value-1; - - auto lambda = mt::get_lambda(output_multislice.E_0); - auto g_inner = output_multislice.detector.g_inner[idet]; - auto g_outer = output_multislice.detector.g_outer[idet]; - - lb_detector_value->setText(det_value_qstr(lambda, g_inner, g_outer)); - - int rep_nx = le_rep_x->text().toInt(); - int rep_ny = le_rep_y->text().toInt(); - - auto pmo = (ckb_show_coh->isChecked())?mt::eFMO_Coherent:mt::eFMO_Total; - data = output_multislice.extract_data(pmo, show_cdata, ithk, idet); - data = replicate(rep_nx, rep_ny, data); - - image->set_data_size(rep_nx*output_multislice.nx, rep_ny*output_multislice.ny); - image->draw(&data, colormap, scale_type, scale_factor); - } - - void draw_current_settings() - { - auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); - auto colormap = QVar_to_enum(cb_colormap->currentData()); - auto scale_type = QVar_to_enum(cb_scale->currentData()); - double scale_factor = le_scale->text().toDouble(); - - int ithk = sl_thickness->value()-1; - int idet = sl_detector->value()-1; - - draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); - } + void save_as_binary() + { + QString FileName = QFileDialog::getSaveFileName(0,"Save file", QDir::currentPath(), + "Binary file (*.bin );Binary (*.bin)", + new QString("Binary file (*.bin )")); + + if (!FileName.isEmpty()) + { + //mt::Grid_2d grid(output_multislice.nx, output_multislice.grid_2d.ny); + //mt::write_mat_binary_matrix(FileName, grid, data); + } + } + + void set_normalSize() + { + adjustSize(); + } + + void qt_image_mouseMoveEvent(QPoint Point) + { +// lb_Pos->setText(QString(" Position: X = %1, Y = %2").arg(Point.rx()).arg(Point.ry())); +// lb_Rel_Pos->setText(QString(" Position: X = %1, Y = %2").arg(Point.rx()-MouSetPos.rx()).arg(Point.ry()-MouSetPos.ry())); + } + + void qt_image_mousePressEvent(QPoint Point) + { +// lb_Rel_Ori->setText(QString(" Position: X = %1, Y = %2").arg(Point.rx()).arg(Point.ry())); +// MouSetPos = Point; + } + + void qt_image_mouseReleaseEvent(QPoint Point) + { + + } + + void cb_colormap_currentIndexChanged(int index) + { + auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); + auto colormap = QVar_to_enum(cb_colormap->itemData(index)); + auto scale_type = QVar_to_enum(cb_scale->currentData()); + double scale_factor = le_scale->text().toDouble(); + + int ithk = sl_thickness->value()-1; + int idet = sl_detector->value()-1; + + draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); + } + + void cb_show_ctype_currentIndexChanged(int index) + { + auto show_cdata = QVar_to_enum(cb_show_ctype->itemData(index)); + auto colormap = QVar_to_enum(cb_colormap->currentData()); + + if(!(show_cdata==mt::eSCD_CMod)) + { + cb_scale->setCurrentIndex(0); + } + auto scale_type = QVar_to_enum(cb_scale->currentData()); + double scale_factor = le_scale->text().toDouble(); + + int ithk = sl_thickness->value()-1; + int idet = sl_detector->value()-1; + + draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); + } + + void cb_scale_currentIndexChanged(int index) + { + auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); + auto colormap = QVar_to_enum(cb_colormap->currentData()); + auto scale_type = QVar_to_enum(cb_scale->itemData(index)); + double scale_factor = le_scale->text().toDouble(); + + auto b_st = (scale_type==eSLT_Power); + le_scale->setVisible(b_st); + + int ithk = sl_thickness->value()-1; + int idet = sl_detector->value()-1; + + draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); + } + + void le_scale_editingFinished() + { + auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); + auto colormap = QVar_to_enum(cb_colormap->currentData()); + auto scale_type = QVar_to_enum(cb_scale->currentData()); + double scale_factor = le_scale->text().toDouble(); + + int ithk = sl_thickness->value()-1; + int idet = sl_detector->value()-1; + + draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); + } + + void le_rep_xy_textChanged(const QString &) + { + auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); + auto colormap = QVar_to_enum(cb_colormap->currentData()); + auto scale_type = QVar_to_enum(cb_scale->currentData()); + double scale_factor = le_scale->text().toDouble(); + + int ithk = sl_thickness->value()-1; + int idet = sl_detector->value()-1; + + int rep_nx = le_rep_x->text().toInt(); + int rep_ny = le_rep_y->text().toInt(); + + auto pmo = (ckb_show_coh->isChecked())?mt::eFMO_Coherent:mt::eFMO_Total; + data = output_multislice.extract_data(pmo, show_cdata, ithk, idet); + data = replicate(rep_nx, rep_ny, data); + + image->set_data_size(rep_nx*output_multislice.nx, rep_ny*output_multislice.ny); + image->draw(&data, colormap, scale_type, scale_factor); + } + + void ckb_block_g0_stateChanged(int state) + { + draw_current_settings(); + } + + void ckb_show_coh_stateChanged(int state) + { + if(state==Qt::Checked) + { + if(output_multislice.is_ot_m2psi_tot_psi_coh()) + { + lb_show_ctype->setVisible(true); + cb_show_ctype->setVisible(true); + } + } + else + { + auto bb_complex = is_output_complex_alone(); + lb_show_ctype->setVisible(bb_complex); + cb_show_ctype->setVisible(bb_complex); + } + draw_current_settings(); + } + + void sl_thickness_valueChanged(int value) + { + if(value>output_multislice.thick.size()) return; + + auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); + auto colormap = QVar_to_enum(cb_colormap->currentData()); + auto scale_type = QVar_to_enum(cb_scale->currentData()); + double scale_factor = le_scale->text().toDouble(); + + int ithk = value-1; + int idet = sl_detector->value()-1; + + lb_thickness_value->setText(thk_value_qstr(output_multislice.thick[ithk])); + + draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); + } + + void sl_detector_valueChanged(int value) + { + if(value>output_multislice.ndetector) return; + + auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); + auto colormap = QVar_to_enum(cb_colormap->currentData()); + auto scale_type = QVar_to_enum(cb_scale->currentData()); + double scale_factor = le_scale->text().toDouble(); + + int ithk = sl_thickness->value()-1; + int idet = value-1; + + auto lambda = mt::get_lambda(output_multislice.E_0); + auto g_inner = output_multislice.detector.g_inner[idet]; + auto g_outer = output_multislice.detector.g_outer[idet]; + + lb_detector_value->setText(det_value_qstr(lambda, g_inner, g_outer)); + + int rep_nx = le_rep_x->text().toInt(); + int rep_ny = le_rep_y->text().toInt(); + + auto pmo = (ckb_show_coh->isChecked())?mt::eFMO_Coherent:mt::eFMO_Total; + data = output_multislice.extract_data(pmo, show_cdata, ithk, idet); + data = replicate(rep_nx, rep_ny, data); + + image->set_data_size(rep_nx*output_multislice.nx, rep_ny*output_multislice.ny); + image->draw(&data, colormap, scale_type, scale_factor); + } + + void draw_current_settings() + { + auto show_cdata = QVar_to_enum(cb_show_ctype->currentData()); + auto colormap = QVar_to_enum(cb_colormap->currentData()); + auto scale_type = QVar_to_enum(cb_scale->currentData()); + double scale_factor = le_scale->text().toDouble(); + + int ithk = sl_thickness->value()-1; + int idet = sl_detector->value()-1; + + draw(show_cdata, colormap, scale_type, scale_factor, ithk, idet); + } private: - /****************************************************/ - QLabel *lb_colormap; - QComboBox *cb_colormap; - - QCheckBox *ckb_show_coh; - - QLabel *lb_scale; - QComboBox *cb_scale; - QLineEdit *le_scale; - - QLabel *lb_show_ctype; - QComboBox *cb_show_ctype; - - QCheckBox *ckb_block_g0; - - QLabel *lb_thickness; - QSlider *sl_thickness; - QLabel *lb_thickness_value; - - QLabel *lb_detector; - QSlider *sl_detector; - QLabel *lb_detector_value; - - /****************************************************/ - QLabel *lb_rep_x; - QLineEdit *le_rep_x; - QLabel *lb_rep_y; - QLineEdit *le_rep_y; - - QLabel *lb_source_size; - QLineEdit *le_source_size; - - QLabel *lb_pos_pixel; - QLabel *lb_pos_real; - - /****************************************************/ - Data_Image *image; - - QPoint MouSetPos; - - QSize window_size; - - /****************************************************/ - mt::Output_Multislice output_multislice; - - host_vector data; - - void set_title() - { - auto sim_type = output_multislice.simulation_type; - - switch(sim_type) - { - case mt::eTEMST_STEM: - setWindowTitle(tr("Scanning transmission electron microscopy")); - break; - case mt::eTEMST_ISTEM: - setWindowTitle(tr("Imaging scanning transmission electron microscopy")); - break; - case mt::eTEMST_CBED: - setWindowTitle(tr("Convergent beam electron diffraction")); - break; - case mt::eTEMST_CBEI: - setWindowTitle(tr("Convergent beam electron imaging")); - break; - case mt::eTEMST_HRTEM: - setWindowTitle(tr("High resolution transmission electron microscopy")); - break; - case mt::eTEMST_ED: - setWindowTitle(tr("Electron diffraction")); - break; - case mt::eTEMST_PED: - setWindowTitle(tr("Precession electron diffraction")); - break; - case mt::eTEMST_HCTEM: - setWindowTitle(tr("Hollow cone TEM")); - break; - case mt::eTEMST_EWFS: - setWindowTitle(tr("Exit wave in Fourier space")); - break; - case mt::eTEMST_EWRS: - setWindowTitle(tr("Exit wave in real space")); - break; - case mt::eTEMST_EELS: - setWindowTitle(tr("STEM electron energy loss spectroscopy")); - break; - case mt::eTEMST_EFTEM: - setWindowTitle(tr("Energy filtered TEM")); - break; - case mt::eTEMST_IWFS: - setWindowTitle(tr("Incident wave in real space")); - break; - case mt::eTEMST_IWRS: - setWindowTitle(tr("Incident wave in Fourier space")); - break; - case mt::eTEMST_PPRS: - setWindowTitle(tr("Projected potential in real space")); - break; - case mt::eTEMST_TFRS: - setWindowTitle(tr("Transmission function in real space")); - break; - } - } - - void create_wigets() - { - lb_colormap = new QLabel(tr("Colormap")); - - cb_colormap = new QComboBox(); - cb_colormap->addItem("Gray", QVariant(eCM_Gray)); - cb_colormap->addItem("Hot", QVariant(eCM_Hot)); - cb_colormap->addItem("Cool", QVariant(eCM_Cool)); - cb_colormap->addItem("Jet", QVariant(eCM_Jet)); - cb_colormap->addItem("Copper", QVariant(eCM_Copper)); - cb_colormap->addItem("Summer", QVariant(eCM_Summer)); - cb_colormap->addItem("Autumn", QVariant(eCM_Autumn)); - cb_colormap->addItem("Winter", QVariant(eCM_Winter)); - - /***************************************************/ - ckb_show_coh = new QCheckBox(tr("Show Coherent wave")); - ckb_show_coh->setStatusTip(tr("Show Coherent wave")); - - /***************************************************/ - lb_scale = new QLabel(tr("Scale")); - - cb_scale = new QComboBox(); - cb_scale->addItem("Linear", QVariant(eSLT_Linear)); - cb_scale->addItem("Power", QVariant(eSLT_Power)); - cb_scale->addItem("Log", QVariant(eSLT_Log)); - - le_scale = new QLineEdit; - le_scale->setStatusTip(tr("Scaling factor [0-1]")); - le_scale->setMaximumWidth(70); - le_scale->setValidator(new QDoubleValidator(0, 1.0, 3)); - le_scale->setText("0.500"); - - /***************************************************/ - lb_show_ctype = new QLabel(tr("Complex")); - - cb_show_ctype = new QComboBox(); - cb_show_ctype->addItem("Module", QVariant(mt::eSCD_CMod)); - cb_show_ctype->addItem("Phase", QVariant(mt::eSCD_CPhase)); - cb_show_ctype->addItem("Real", QVariant(mt::eSCD_CReal)); - cb_show_ctype->addItem("Imag", QVariant(mt::eSCD_CImag)); - - /***************************************************/ - ckb_block_g0 = new QCheckBox(tr("Block g(0))")); - ckb_block_g0->setStatusTip(tr("Block g(0)")); - - /***************************************************/ - lb_thickness = new QLabel(tr(" Thickness ")); - lb_thickness->setFrameStyle(QFrame::Box | QFrame::Sunken); - lb_thickness->setAlignment(Qt::AlignCenter); - - sl_thickness = new QSlider(Qt::Horizontal); - sl_thickness->setMinimumWidth(25); - - lb_thickness_value = new QLabel(thk_value_qstr(0)); - lb_thickness_value->setFrameStyle(QFrame::Box | QFrame::Sunken); - lb_thickness_value->setAlignment(Qt::AlignCenter); - - /***************************************************/ - lb_detector = new QLabel(tr(" Detector ")); - lb_detector->setFrameStyle(QFrame::Box | QFrame::Sunken); - lb_detector->setAlignment(Qt::AlignCenter); - - sl_detector = new QSlider(Qt::Horizontal); - sl_detector->setMinimumWidth(25); - - lb_detector_value = new QLabel(det_value_qstr(0.019, 0, 0)); - lb_detector_value->setFrameStyle(QFrame::Box | QFrame::Sunken); - lb_detector_value->setAlignment(Qt::AlignCenter); - - /***************************************************/ - /***************************************************/ - auto lyh_top = new QHBoxLayout; - lyh_top->setContentsMargins(0, 0, 0, 0); - lyh_top->setSizeConstraint(QLayout::SetMinimumSize); - lyh_top->addWidget(lb_colormap); - lyh_top->addWidget(cb_colormap); - lyh_top->addWidget(lb_scale); - lyh_top->addWidget(cb_scale); - lyh_top->addWidget(le_scale); - lyh_top->addWidget(ckb_show_coh); - lyh_top->addWidget(lb_show_ctype); - lyh_top->addWidget(cb_show_ctype); - lyh_top->addWidget(ckb_block_g0); - lyh_top->addWidget(lb_thickness); - lyh_top->addWidget(sl_thickness); - lyh_top->addWidget(lb_thickness_value); - lyh_top->addWidget(lb_detector); - lyh_top->addWidget(sl_detector); - lyh_top->addWidget(lb_detector_value); - lyh_top->addStretch(); - - auto gb_top = new QGroupBox; - gb_top->setMouseTracking(true); - gb_top->setLayout(lyh_top); - gb_top->setStyleSheet("QGroupBox{border: 1px solid gray; \n border-radius: 2px; \n margin-top: 0px;}"); - gb_top->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - - /***************************************************/ - lb_rep_x = new QLabel("Rep. x"); - - le_rep_x = new QLineEdit; - le_rep_x->setStatusTip(tr("Replicate along x")); - le_rep_x->setMaximumWidth(70); - le_rep_x->setValidator(new QIntValidator(0, 50)); - le_rep_x->setText("1"); - - /***************************************************/ - lb_rep_y = new QLabel("Rep. y"); - - le_rep_y = new QLineEdit; - le_rep_y->setStatusTip(tr("Replicate along x")); - le_rep_y->setMaximumWidth(70); - le_rep_y->setValidator(new QIntValidator(0, 50)); - le_rep_y->setText("1"); - - /***************************************************/ - lb_source_size = new QLabel("Source Size [Å]"); - - le_source_size = new QLineEdit; - le_source_size->setStatusTip(tr("Source size (FWHM)")); - le_source_size->setMaximumWidth(70); - le_source_size->setValidator(new QDoubleValidator(0, 100, 3)); - le_source_size->setText("0.800"); - le_source_size->setVisible(false); - - /***************************************************/ - lb_pos_pixel = new QLabel(" (0, 0) Pixels"); - lb_pos_real = new QLabel(" (0, 0) [Å]"); - - /***************************************************/ - /***************************************************/ - auto lyh_bottom = new QHBoxLayout; - lyh_bottom->setContentsMargins(0, 0, 0, 0); - lyh_bottom->setSizeConstraint(QLayout::SetMinimumSize); - lyh_bottom->addWidget(lb_rep_x); - lyh_bottom->addWidget(le_rep_x); - lyh_bottom->addWidget(lb_rep_y); - lyh_bottom->addWidget(le_rep_y); - lyh_bottom->addWidget(lb_source_size); - lyh_bottom->addWidget(le_source_size); - lyh_bottom->addStretch(); - lyh_bottom->addWidget(lb_pos_pixel); - lyh_bottom->addWidget(lb_pos_real); - - auto gb_bottom = new QGroupBox; - gb_bottom->setMouseTracking(true); - gb_bottom->setLayout(lyh_bottom); - gb_bottom->setStyleSheet("QGroupBox{border: 1px solid gray; \n border-radius: 2px; \n margin-top: 0px;}"); - gb_bottom->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - - /***************************************************/ - image = new Data_Image; - image->setMouseTracking(true); - image->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - /***************************************************/ - auto lyv_main = new QVBoxLayout; - lyv_main->setSpacing(0); - lyv_main->setMargin(0); - lyv_main->setContentsMargins(0, 0, 0, 0); - lyv_main->addWidget(gb_top); - lyv_main->addWidget(image); - lyv_main->addWidget(gb_bottom); - setLayout(lyv_main); - -// connect(q_image, SIGNAL(Signal_NormalSize(QSize)), this, SLOT(qt_image_NormalSize(QSize))); -// connect(q_image, SIGNAL(Signal_mouseMoveEvent(QPoint)), this, SLOT(qt_image_mouseMoveEvent(QPoint))); -// connect(q_image, SIGNAL(Signal_mousePressEvent(QPoint)), this, SLOT(qt_image_mousePressEvent(QPoint))); -// connect(q_image, SIGNAL(Signal_mouseReleaseEvent(QPoint)), this, SLOT(qt_image_mouseReleaseEvent(QPoint))); -// connect(cb_colormap, SIGNAL(currentIndexChanged(int)), this, SLOT(on_cb_colormap_currentIndexChanged(int))); - } - - void activate_options() - { - auto b_complex = is_output_complex_alone(); - - lb_show_ctype->setVisible(b_complex); - cb_show_ctype->setVisible(b_complex); - - auto b_pwr = output_multislice.is_CBED_ED_EWFS_PED(); - le_scale->setVisible(b_pwr); - - if(b_pwr) - { - cb_scale->setCurrentIndex(1); - le_scale->setText(QString::number(0.25, 'f', 3)); - } - else - { - cb_scale->setCurrentIndex(0); - } - - ckb_show_coh->setVisible(is_two_ouputs_present()); - - auto b_g0 = (output_multislice.is_ED() || output_multislice.is_EWFS() || output_multislice.is_PED()) && output_multislice.is_plane_wave(); - - ckb_block_g0->setChecked(true); - ckb_block_g0->setVisible(b_g0); - - auto b_thk_sl = (output_multislice.thick.size()>1); - sl_thickness->setVisible(b_thk_sl); - - auto b_thk_val = is_thickness_available(); - lb_thickness->setVisible(b_thk_val); - lb_thickness_value->setVisible(b_thk_val); - - /**************************************************************/ - auto b_stem = output_multislice.is_STEM(); - - lb_rep_x->setVisible(b_stem); - le_rep_x->setVisible(b_stem); - lb_rep_y->setVisible(b_stem); - le_rep_y->setVisible(b_stem); - lb_source_size->setVisible(false); - le_source_size->setVisible(false); - - auto b_det_sl = b_stem && (output_multislice.ndetector>1); - sl_detector->setVisible(b_det_sl); - - auto b_det_val = b_stem; - lb_detector->setVisible(b_det_val); - lb_detector_value->setVisible(b_det_val); - } - - bool is_two_ouputs_present() - { - bool b = output_multislice.is_ot_image_tot_coh()||output_multislice.is_ot_m2psi_tot_coh(); - b = b || output_multislice.is_ot_m2psi_tot_psi_coh(); - - return b; - } - - bool is_output_complex_alone() - { - bool b = output_multislice.is_ot_psi_coh()||output_multislice.is_ot_psi_0(); - b = b || output_multislice.is_ot_trans(); - - return b; - } - - bool is_thickness_available() - { - bool bb = output_multislice.is_IWFS_IWRS() || output_multislice.is_PPFS_PPRS(); - bb = bb || output_multislice.is_TFFS_TFRS() || output_multislice.is_PropFS_PropRS(); - - return !bb; - } - - host_vector replicate(int nx_r, int ny_r, host_vector &data) - { - int nx = output_multislice.nx; - int ny = output_multislice.ny; - - int nx_t = nx_r*nx; - int ny_t = ny_r*ny; - - host_vector data_t(nx_t*ny_t); - - int ix_t = 0; - for(auto ix_r=0; ix_risChecked())?mt::eFMO_Coherent:mt::eFMO_Total; - data = output_multislice.extract_data(pmo, show_cdata, ithk, idet); - - - auto b_g0 = (output_multislice.is_ED() || output_multislice.is_EWFS() || output_multislice.is_PED()) && output_multislice.is_plane_wave(); - if(b_g0 && ckb_block_g0->isChecked()) - { - int ix = output_multislice.nx/2; - int iy = output_multislice.ny/2; - int ny = output_multislice.ny; - - data[ix*ny+iy] = 0; - } - - image->draw(&data, colormap, scale_type, scale_factor); - } + /****************************************************/ + QLabel *lb_colormap; + QComboBox *cb_colormap; + + QCheckBox *ckb_show_coh; + + QLabel *lb_scale; + QComboBox *cb_scale; + QLineEdit *le_scale; + + QLabel *lb_show_ctype; + QComboBox *cb_show_ctype; + + QCheckBox *ckb_block_g0; + + QLabel *lb_thickness; + QSlider *sl_thickness; + QLabel *lb_thickness_value; + + QLabel *lb_detector; + QSlider *sl_detector; + QLabel *lb_detector_value; + + /****************************************************/ + QLabel *lb_rep_x; + QLineEdit *le_rep_x; + QLabel *lb_rep_y; + QLineEdit *le_rep_y; + + QLabel *lb_source_size; + QLineEdit *le_source_size; + + QLabel *lb_pos_pixel; + QLabel *lb_pos_real; + + /****************************************************/ + Data_Image *image; + + QPoint MouSetPos; + + QSize window_size; + + /****************************************************/ + mt::Output_Multislice output_multislice; + + host_vector data; + + void set_title() + { + auto sim_type = output_multislice.simulation_type; + + switch(sim_type) + { + case mt::eTEMST_STEM: + setWindowTitle(tr("Scanning transmission electron microscopy")); + break; + case mt::eTEMST_ISTEM: + setWindowTitle(tr("Imaging scanning transmission electron microscopy")); + break; + case mt::eTEMST_CBED: + setWindowTitle(tr("Convergent beam electron diffraction")); + break; + case mt::eTEMST_CBEI: + setWindowTitle(tr("Convergent beam electron imaging")); + break; + case mt::eTEMST_HRTEM: + setWindowTitle(tr("High resolution transmission electron microscopy")); + break; + case mt::eTEMST_ED: + setWindowTitle(tr("Electron diffraction")); + break; + case mt::eTEMST_PED: + setWindowTitle(tr("Precession electron diffraction")); + break; + case mt::eTEMST_HCTEM: + setWindowTitle(tr("Hollow cone TEM")); + break; + case mt::eTEMST_EWFS: + setWindowTitle(tr("Exit wave in Fourier space")); + break; + case mt::eTEMST_EWRS: + setWindowTitle(tr("Exit wave in real space")); + break; + case mt::eTEMST_EELS: + setWindowTitle(tr("STEM electron energy loss spectroscopy")); + break; + case mt::eTEMST_EFTEM: + setWindowTitle(tr("Energy filtered TEM")); + break; + case mt::eTEMST_IWFS: + setWindowTitle(tr("Incident wave in real space")); + break; + case mt::eTEMST_IWRS: + setWindowTitle(tr("Incident wave in Fourier space")); + break; + case mt::eTEMST_PPRS: + setWindowTitle(tr("Projected potential in real space")); + break; + case mt::eTEMST_TFRS: + setWindowTitle(tr("Transmission function in real space")); + break; + } + } + + void create_wigets() + { + lb_colormap = new QLabel(tr("Colormap")); + + cb_colormap = new QComboBox(); + cb_colormap->addItem("Gray", QVariant(eCM_Gray)); + cb_colormap->addItem("Hot", QVariant(eCM_Hot)); + cb_colormap->addItem("Cool", QVariant(eCM_Cool)); + cb_colormap->addItem("Jet", QVariant(eCM_Jet)); + cb_colormap->addItem("Copper", QVariant(eCM_Copper)); + cb_colormap->addItem("Summer", QVariant(eCM_Summer)); + cb_colormap->addItem("Autumn", QVariant(eCM_Autumn)); + cb_colormap->addItem("Winter", QVariant(eCM_Winter)); + + /***************************************************/ + ckb_show_coh = new QCheckBox(tr("Show Coherent wave")); + ckb_show_coh->setStatusTip(tr("Show Coherent wave")); + + /***************************************************/ + lb_scale = new QLabel(tr("Scale")); + + cb_scale = new QComboBox(); + cb_scale->addItem("Linear", QVariant(eSLT_Linear)); + cb_scale->addItem("Power", QVariant(eSLT_Power)); + cb_scale->addItem("Log", QVariant(eSLT_Log)); + + le_scale = new QLineEdit; + le_scale->setStatusTip(tr("Scaling factor [0-1]")); + le_scale->setMaximumWidth(70); + le_scale->setValidator(new QDoubleValidator(0, 1.0, 3)); + le_scale->setText("0.500"); + + /***************************************************/ + lb_show_ctype = new QLabel(tr("Complex")); + + cb_show_ctype = new QComboBox(); + cb_show_ctype->addItem("Module", QVariant(mt::eSCD_CMod)); + cb_show_ctype->addItem("Phase", QVariant(mt::eSCD_CPhase)); + cb_show_ctype->addItem("Real", QVariant(mt::eSCD_CReal)); + cb_show_ctype->addItem("Imag", QVariant(mt::eSCD_CImag)); + + /***************************************************/ + ckb_block_g0 = new QCheckBox(tr("Block g(0))")); + ckb_block_g0->setStatusTip(tr("Block g(0)")); + + /***************************************************/ + lb_thickness = new QLabel(tr(" Thickness ")); + lb_thickness->setFrameStyle(QFrame::Box | QFrame::Sunken); + lb_thickness->setAlignment(Qt::AlignCenter); + + sl_thickness = new QSlider(Qt::Horizontal); + sl_thickness->setMinimumWidth(25); + + lb_thickness_value = new QLabel(thk_value_qstr(0)); + lb_thickness_value->setFrameStyle(QFrame::Box | QFrame::Sunken); + lb_thickness_value->setAlignment(Qt::AlignCenter); + + /***************************************************/ + lb_detector = new QLabel(tr(" Detector ")); + lb_detector->setFrameStyle(QFrame::Box | QFrame::Sunken); + lb_detector->setAlignment(Qt::AlignCenter); + + sl_detector = new QSlider(Qt::Horizontal); + sl_detector->setMinimumWidth(25); + + lb_detector_value = new QLabel(det_value_qstr(0.019, 0, 0)); + lb_detector_value->setFrameStyle(QFrame::Box | QFrame::Sunken); + lb_detector_value->setAlignment(Qt::AlignCenter); + + /***************************************************/ + /***************************************************/ + auto lyh_top = new QHBoxLayout; + lyh_top->setContentsMargins(0, 0, 0, 0); + lyh_top->setSizeConstraint(QLayout::SetMinimumSize); + lyh_top->addWidget(lb_colormap); + lyh_top->addWidget(cb_colormap); + lyh_top->addWidget(lb_scale); + lyh_top->addWidget(cb_scale); + lyh_top->addWidget(le_scale); + lyh_top->addWidget(ckb_show_coh); + lyh_top->addWidget(lb_show_ctype); + lyh_top->addWidget(cb_show_ctype); + lyh_top->addWidget(ckb_block_g0); + lyh_top->addWidget(lb_thickness); + lyh_top->addWidget(sl_thickness); + lyh_top->addWidget(lb_thickness_value); + lyh_top->addWidget(lb_detector); + lyh_top->addWidget(sl_detector); + lyh_top->addWidget(lb_detector_value); + lyh_top->addStretch(); + + auto gb_top = new QGroupBox; + gb_top->setMouseTracking(true); + gb_top->setLayout(lyh_top); + gb_top->setStyleSheet("QGroupBox{border: 1px solid gray; \n border-radius: 2px; \n margin-top: 0px;}"); + gb_top->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + + /***************************************************/ + lb_rep_x = new QLabel("Rep. x"); + + le_rep_x = new QLineEdit; + le_rep_x->setStatusTip(tr("Replicate along x")); + le_rep_x->setMaximumWidth(70); + le_rep_x->setValidator(new QIntValidator(0, 50)); + le_rep_x->setText("1"); + + /***************************************************/ + lb_rep_y = new QLabel("Rep. y"); + + le_rep_y = new QLineEdit; + le_rep_y->setStatusTip(tr("Replicate along x")); + le_rep_y->setMaximumWidth(70); + le_rep_y->setValidator(new QIntValidator(0, 50)); + le_rep_y->setText("1"); + + /***************************************************/ + lb_source_size = new QLabel("Source Size [Å]"); + + le_source_size = new QLineEdit; + le_source_size->setStatusTip(tr("Source size (FWHM)")); + le_source_size->setMaximumWidth(70); + le_source_size->setValidator(new QDoubleValidator(0, 100, 3)); + le_source_size->setText("0.800"); + le_source_size->setVisible(false); + + /***************************************************/ + lb_pos_pixel = new QLabel(" (0, 0) Pixels"); + lb_pos_real = new QLabel(" (0, 0) [Å]"); + + /***************************************************/ + /***************************************************/ + auto lyh_bottom = new QHBoxLayout; + lyh_bottom->setContentsMargins(0, 0, 0, 0); + lyh_bottom->setSizeConstraint(QLayout::SetMinimumSize); + lyh_bottom->addWidget(lb_rep_x); + lyh_bottom->addWidget(le_rep_x); + lyh_bottom->addWidget(lb_rep_y); + lyh_bottom->addWidget(le_rep_y); + lyh_bottom->addWidget(lb_source_size); + lyh_bottom->addWidget(le_source_size); + lyh_bottom->addStretch(); + lyh_bottom->addWidget(lb_pos_pixel); + lyh_bottom->addWidget(lb_pos_real); + + auto gb_bottom = new QGroupBox; + gb_bottom->setMouseTracking(true); + gb_bottom->setLayout(lyh_bottom); + gb_bottom->setStyleSheet("QGroupBox{border: 1px solid gray; \n border-radius: 2px; \n margin-top: 0px;}"); + gb_bottom->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + + /***************************************************/ + image = new Data_Image; + image->setMouseTracking(true); + image->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + /***************************************************/ + auto lyv_main = new QVBoxLayout; + lyv_main->setSpacing(0); + lyv_main->setMargin(0); + lyv_main->setContentsMargins(0, 0, 0, 0); + lyv_main->addWidget(gb_top); + lyv_main->addWidget(image); + lyv_main->addWidget(gb_bottom); + setLayout(lyv_main); + +// connect(q_image, SIGNAL(Signal_NormalSize(QSize)), this, SLOT(qt_image_NormalSize(QSize))); +// connect(q_image, SIGNAL(Signal_mouseMoveEvent(QPoint)), this, SLOT(qt_image_mouseMoveEvent(QPoint))); +// connect(q_image, SIGNAL(Signal_mousePressEvent(QPoint)), this, SLOT(qt_image_mousePressEvent(QPoint))); +// connect(q_image, SIGNAL(Signal_mouseReleaseEvent(QPoint)), this, SLOT(qt_image_mouseReleaseEvent(QPoint))); +// connect(cb_colormap, SIGNAL(currentIndexChanged(int)), this, SLOT(on_cb_colormap_currentIndexChanged(int))); + } + + void activate_options() + { + auto b_complex = is_output_complex_alone(); + + lb_show_ctype->setVisible(b_complex); + cb_show_ctype->setVisible(b_complex); + + auto b_pwr = output_multislice.is_CBED_ED_EWFS_PED(); + le_scale->setVisible(b_pwr); + + if(b_pwr) + { + cb_scale->setCurrentIndex(1); + le_scale->setText(QString::number(0.25, 'f', 3)); + } + else + { + cb_scale->setCurrentIndex(0); + } + + ckb_show_coh->setVisible(is_two_ouputs_present()); + + auto b_g0 = (output_multislice.is_ED() || output_multislice.is_EWFS() || output_multislice.is_PED()) && output_multislice.is_plane_wave(); + + ckb_block_g0->setChecked(true); + ckb_block_g0->setVisible(b_g0); + + auto b_thk_sl = (output_multislice.thick.size()>1); + sl_thickness->setVisible(b_thk_sl); + + auto b_thk_val = is_thickness_available(); + lb_thickness->setVisible(b_thk_val); + lb_thickness_value->setVisible(b_thk_val); + + /**************************************************************/ + auto b_stem = output_multislice.is_STEM(); + + lb_rep_x->setVisible(b_stem); + le_rep_x->setVisible(b_stem); + lb_rep_y->setVisible(b_stem); + le_rep_y->setVisible(b_stem); + lb_source_size->setVisible(false); + le_source_size->setVisible(false); + + auto b_det_sl = b_stem && (output_multislice.ndetector>1); + sl_detector->setVisible(b_det_sl); + + auto b_det_val = b_stem; + lb_detector->setVisible(b_det_val); + lb_detector_value->setVisible(b_det_val); + } + + bool is_two_ouputs_present() + { + bool b = output_multislice.is_ot_image_tot_coh()||output_multislice.is_ot_m2psi_tot_coh(); + b = b || output_multislice.is_ot_m2psi_tot_psi_coh(); + + return b; + } + + bool is_output_complex_alone() + { + bool b = output_multislice.is_ot_psi_coh()||output_multislice.is_ot_psi_0(); + b = b || output_multislice.is_ot_trans(); + + return b; + } + + bool is_thickness_available() + { + bool bb = output_multislice.is_IWFS_IWRS() || output_multislice.is_PPFS_PPRS(); + bb = bb || output_multislice.is_TFFS_TFRS() || output_multislice.is_PropFS_PropRS(); + + return !bb; + } + + host_vector replicate(int nx_r, int ny_r, host_vector &data) + { + int nx = output_multislice.nx; + int ny = output_multislice.ny; + + int nx_t = nx_r*nx; + int ny_t = ny_r*ny; + + host_vector data_t(nx_t*ny_t); + + int ix_t = 0; + for(auto ix_r=0; ix_risChecked())?mt::eFMO_Coherent:mt::eFMO_Total; + data = output_multislice.extract_data(pmo, show_cdata, ithk, idet); + + + auto b_g0 = (output_multislice.is_ED() || output_multislice.is_EWFS() || output_multislice.is_PED()) && output_multislice.is_plane_wave(); + if(b_g0 && ckb_block_g0->isChecked()) + { + int ix = output_multislice.nx/2; + int iy = output_multislice.ny/2; + int ny = output_multislice.ny; + + data[ix*ny+iy] = 0; + } + + image->draw(&data, colormap, scale_type, scale_factor); + } //protected: -// void closeEvent(QCloseEvent *event); +// void closeEvent(QCloseEvent *event); //signals: -// void Signal_CloseWindow(QString name); +// void Signal_CloseWindow(QString name); }; diff --git a/gui_multem/q_image.h b/gui_multem/q_image.h index 8800704b..fc3aa129 100644 --- a/gui_multem/q_image.h +++ b/gui_multem/q_image.h @@ -10,305 +10,305 @@ class Data_Image : public QWidget { - Q_OBJECT + Q_OBJECT public: - using TVector_s = thrust::host_vector; + using TVector_s = thrust::host_vector; - explicit Data_Image(QWidget *parent = Q_NULLPTR) - : QWidget(parent), nx(0), ny(0), nxy(0), image(nullptr), - im_zoom_0(1.0), im_zoom(1.0), im_zoom_d(1.25) - { - im_zoom_min = 0.1*im_zoom_0; - im_zoom_max = 20.0*im_zoom_0; + explicit Data_Image(QWidget *parent = Q_NULLPTR) + : QWidget(parent), nx(0), ny(0), nxy(0), image(nullptr), + im_zoom_0(1.0), im_zoom(1.0), im_zoom_d(1.25) + { + im_zoom_min = 0.1*im_zoom_0; + im_zoom_max = 20.0*im_zoom_0; - im_pos = QPointF(0, 0); - im_pos_press = im_pos; - window_size = QSize(0, 0); + im_pos = QPointF(0, 0); + im_pos_press = im_pos; + window_size = QSize(0, 0); - FileName = ""; + FileName = ""; - setContextMenuPolicy(Qt::CustomContextMenu); + setContextMenuPolicy(Qt::CustomContextMenu); - mn_Contex = new QMenu(); - act_save_as_image = mn_Contex->addAction("Save as image"); - act_save_as_binary = mn_Contex->addAction("Save as Binary"); + mn_Contex = new QMenu(); + act_save_as_image = mn_Contex->addAction("Save as image"); + act_save_as_binary = mn_Contex->addAction("Save as Binary"); - connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),SLOT(custom_context_menu(const QPoint &))); - connect(act_save_as_image, SIGNAL(triggered()),SLOT(save_as_tif())); - connect(act_save_as_binary, SIGNAL(triggered()),SLOT(save_as_binary())); - } + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),SLOT(custom_context_menu(const QPoint &))); + connect(act_save_as_image, SIGNAL(triggered()),SLOT(save_as_tif())); + connect(act_save_as_binary, SIGNAL(triggered()),SLOT(save_as_binary())); + } - ~Data_Image(){} - - QSize minimumSizeHint() const Q_DECL_OVERRIDE - { - return sizeHint()/4; - } - - QSize sizeHint() const Q_DECL_OVERRIDE - { - auto size_xy = qRound(max(im_zoom_0*nx, im_zoom_0*ny)); - return QSize(size_xy, size_xy); - } - - QSize data_size() - { - return QSize(nx, ny); - } - - void set_data_size(int nx_i, int ny_i) - { - nx = nx_i; - ny = ny_i; - nxy = nx*ny; - - delete image; - image = new QImage(nx, ny, QImage::Format_RGB32); - - set_default_zoom_pos(); - } - - void set_window_size(QSize ws) - { - window_size = ws; - set_default_zoom_pos(); - } - - void set_default_zoom_pos() - { - auto data_size_f = QPointF(data_size().width(), data_size().height()); - im_zoom_0 = qreal(window_size.height())/qreal(max(data_size_f.rx(), data_size_f.ry())); - im_zoom = im_zoom_0; - im_zoom_min = 0.1*im_zoom_0; - im_zoom_max = 20.0*im_zoom_0; - - im_pos.setX(0.5*(window_size.width() - im_zoom_0*data_size_f.rx())); - im_pos.setY(0.5*(window_size.height() - im_zoom_0*data_size_f.ry())); - } - - void scale(qreal factor) - { - im_zoom = factor; - update(); - } - - void pos_scale(QPointF pos, qreal factor) - { - im_pos = pos; - im_zoom = factor; - update(); - } - - void draw(TVector_s *data, eColormap colormap, eScale_Type scale_type, double scale_factor) - { - Colormap map(colormap); - - TVector_s &data_s = *data; - auto data_s_minmax = std::minmax_element(data_s.begin(), data_s.end()); - double data_s_min = *(data_s_minmax.first); - double data_s_max = *(data_s_minmax.second); - - switch(scale_type) - { - case eSLT_Linear: - { - double vs_min = data_s_min; - double vs_max = data_s_max; - double y_m = 255/(vs_max-vs_min); - - for(auto iy = 0; iyscanLine(iy)); - for(auto ix = 0; ixscanLine(iy)); - for(auto ix = 0; ixscanLine(iy)); - for(auto ix = 0; ixscanLine(iy)); + for(auto ix = 0; ixscanLine(iy)); + for(auto ix = 0; ixscanLine(iy)); + for(auto ix = 0; ixpopup(mapToGlobal(point)); - } - - void save_data(QString name) - { - image->save(name); - } - - void save_as_tif() - { - FileName = QFileDialog::getSaveFileName(0,"Save file", QDir::currentPath(), - "PNG - Portable Network Graphics (*.png);TIF - TIFF Bitmap (*.tif)", - new QString("PNG - Portable Network Graphics (*.png)")); - - if (!FileName.isEmpty()) - { - image->save(FileName); - } - } - - void save_as_binary() - { - emit sg_save_as_binary(); - } + void set_normalSize() + { + set_default_zoom_pos(); + update(); + } + + void custom_context_menu(const QPoint &point) + { + mn_Contex->popup(mapToGlobal(point)); + } + + void save_data(QString name) + { + image->save(name); + } + + void save_as_tif() + { + FileName = QFileDialog::getSaveFileName(0,"Save file", QDir::currentPath(), + "PNG - Portable Network Graphics (*.png);TIF - TIFF Bitmap (*.tif)", + new QString("PNG - Portable Network Graphics (*.png)")); + + if (!FileName.isEmpty()) + { + image->save(FileName); + } + } + + void save_as_binary() + { + emit sg_save_as_binary(); + } protected: - void paintEvent(QPaintEvent * /*event*/) Q_DECL_OVERRIDE - { - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing, false); - painter.setRenderHint(QPainter::SmoothPixmapTransform, false); - painter.setRenderHint(QPainter::HighQualityAntialiasing, false); - painter.translate(im_pos); - painter.scale(im_zoom, im_zoom); - painter.drawImage(QPointF(0, 0), *image); - } + void paintEvent(QPaintEvent * /*event*/) Q_DECL_OVERRIDE + { + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, false); + painter.setRenderHint(QPainter::SmoothPixmapTransform, false); + painter.setRenderHint(QPainter::HighQualityAntialiasing, false); + painter.translate(im_pos); + painter.scale(im_zoom, im_zoom); + painter.drawImage(QPointF(0, 0), *image); + } - void wheelEvent(QWheelEvent * event) Q_DECL_OVERRIDE - { - qreal delta = (event->delta()<0)?1.0/im_zoom_d:im_zoom_d; - auto zoom_t = im_zoom*delta; - - if((im_zoom_minposF(); - im_zoom *= delta; - } - - update(); - } + void wheelEvent(QWheelEvent * event) Q_DECL_OVERRIDE + { + qreal delta = (event->delta()<0)?1.0/im_zoom_d:im_zoom_d; + auto zoom_t = im_zoom*delta; + + if((im_zoom_minposF(); + im_zoom *= delta; + } + + update(); + } - void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE - { - event->accept(); -// if(event->buttons()==Qt::LeftButton) -// { -// im_pos = im_pos + (event->pos() - im_pos_press)*im_zoom; -// update(); -// } - emit mouseMove(event->pos()); - } + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE + { + event->accept(); +// if(event->buttons()==Qt::LeftButton) +// { +// im_pos = im_pos + (event->pos() - im_pos_press)*im_zoom; +// update(); +// } + emit mouseMove(event->pos()); + } - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE - { - event->accept(); - im_pos_press = event->pos(); - emit mousePress(event->pos()); - } + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE + { + event->accept(); + im_pos_press = event->pos(); + emit mousePress(event->pos()); + } - void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE - { - event->accept(); - im_pos_press = QPointF(0, 0); - emit mouseRelease(event->pos()); - } - - void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE - { - event->accept(); - set_normalSize(); - emit mouseDoubleClick(); - } + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE + { + event->accept(); + im_pos_press = QPointF(0, 0); + emit mouseRelease(event->pos()); + } + + void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE + { + event->accept(); + set_normalSize(); + emit mouseDoubleClick(); + } signals: - void mouseDoubleClick(); - void mouseMove(QPoint Point); - void mousePress(QPoint Point); - void mouseRelease(QPoint Point); + void mouseDoubleClick(); + void mouseMove(QPoint Point); + void mousePress(QPoint Point); + void mouseRelease(QPoint Point); private: - QString FileName; - - double log_scale(double x) - { - const double ee = 1e-6; - return log(ee+x); - } - - double power_scale(double x, double factor) - { - return pow(x, factor); - } - - uchar real_2_uchar(double x, double x_min, double y_m) - { - auto v = (uchar)(y_m*(x-x_min)); - return qBound(0, v, 255); - } - - int nx; - int ny; - int nxy; - - QImage *image; - QSize window_size; - - qreal im_zoom_0; // Initial zoom factor - qreal im_zoom; // zoom factor - qreal im_zoom_min; // zoom factor - qreal im_zoom_max; // zoom factor - qreal im_zoom_d; // step - QPointF im_pos; // - QPointF im_pos_press; // - - QMenu *mn_Contex; - QAction *act_save_as_image; - QAction *act_save_as_binary; + QString FileName; + + double log_scale(double x) + { + const double ee = 1e-6; + return log(ee+x); + } + + double power_scale(double x, double factor) + { + return pow(x, factor); + } + + uchar real_2_uchar(double x, double x_min, double y_m) + { + auto v = (uchar)(y_m*(x-x_min)); + return qBound(0, v, 255); + } + + int nx; + int ny; + int nxy; + + QImage *image; + QSize window_size; + + qreal im_zoom_0; // Initial zoom factor + qreal im_zoom; // zoom factor + qreal im_zoom_min; // zoom factor + qreal im_zoom_max; // zoom factor + qreal im_zoom_d; // step + QPointF im_pos; // + QPointF im_pos_press; // + + QMenu *mn_Contex; + QAction *act_save_as_image; + QAction *act_save_as_binary; }; #endif // Q_IMAGE_H diff --git a/gui_multem/q_load_specimen.h b/gui_multem/q_load_specimen.h index 4214ea76..6e5f9430 100644 --- a/gui_multem/q_load_specimen.h +++ b/gui_multem/q_load_specimen.h @@ -9,82 +9,82 @@ template class Load_Specimen { public: - Load_Specimen(){} - ~Load_Specimen(){} + Load_Specimen(){} + ~Load_Specimen(){} - bool operator()(QString filename, mt::Atom_Data &atoms) - { - QFileInfo file(filename); - QString ext = file.suffix(); + bool operator()(QString filename, mt::Atom_Data &atoms) + { + QFileInfo file(filename); + QString ext = file.suffix(); - bool result = false; - if(ext.compare("txt", Qt::CaseInsensitive)==0) - { - result = read_txt(filename, atoms); - } + bool result = false; + if(ext.compare("txt", Qt::CaseInsensitive)==0) + { + result = read_txt(filename, atoms); + } - return result; - } + return result; + } private: - bool read_txt(QString filename, mt::Atom_Data &atoms) - { - QFile file(filename); - - if(!file.open(QFile::ReadOnly | QFile::Text)) return false; - - QTextStream text_stream(&file); - - QRegExp sep("(\\ |\\t)"); - // read first line whihc contains simulation box information - QString line_string = text_stream.readLine().simplified(); - QStringList line_list = line_string.split(sep, QString::SkipEmptyParts); - atoms.l_x = line_list[0].toDouble(); - atoms.l_y = line_list[1].toDouble(); - atoms.l_z = 0; - atoms.dz = max(line_list[2].toDouble(), 0.5); - - // count number of atoms - int n_atoms = 0; - line_string = text_stream.readLine(); - while(!line_string.isNull()) - { - n_atoms++; - line_string = text_stream.readLine(); - } - text_stream.seek(0); - - // read data - atoms.resize(n_atoms); - int iatoms_c = 0; - // skip first line - line_string = text_stream.readLine(); - // read second line - line_string = text_stream.readLine(); - do - { - line_list = line_string.split(sep, QString::SkipEmptyParts); - auto n_cols = line_list.count(); - - atoms.Z[iatoms_c] = line_list[0].toDouble(); - atoms.x[iatoms_c] = line_list[1].toDouble(); - atoms.y[iatoms_c] = line_list[2].toDouble(); - atoms.z[iatoms_c] = line_list[3].toDouble(); - atoms.sigma[iatoms_c] = (n_cols>4)?line_list[4].toDouble():0.085; - atoms.occ[iatoms_c] = (n_cols>5)?line_list[5].toDouble():1.0; - atoms.region[iatoms_c] = (n_cols>6)?line_list[6].toDouble():0; - atoms.charge[iatoms_c] = (n_cols>7)?line_list[7].toDouble():0; - iatoms_c++; - - line_string = text_stream.readLine().simplified(); - } while(!line_string.isNull()); - - file.close(); - - atoms.get_statistic(); - - return true; - } + bool read_txt(QString filename, mt::Atom_Data &atoms) + { + QFile file(filename); + + if(!file.open(QFile::ReadOnly | QFile::Text)) return false; + + QTextStream text_stream(&file); + + QRegExp sep("(\\ |\\t)"); + // read first line whihc contains simulation box information + QString line_string = text_stream.readLine().simplified(); + QStringList line_list = line_string.split(sep, QString::SkipEmptyParts); + atoms.l_x = line_list[0].toDouble(); + atoms.l_y = line_list[1].toDouble(); + atoms.l_z = 0; + atoms.dz = max(line_list[2].toDouble(), 0.5); + + // count number of atoms + int n_atoms = 0; + line_string = text_stream.readLine(); + while(!line_string.isNull()) + { + n_atoms++; + line_string = text_stream.readLine(); + } + text_stream.seek(0); + + // read data + atoms.resize(n_atoms); + int iatoms_c = 0; + // skip first line + line_string = text_stream.readLine(); + // read second line + line_string = text_stream.readLine(); + do + { + line_list = line_string.split(sep, QString::SkipEmptyParts); + auto n_cols = line_list.count(); + + atoms.Z[iatoms_c] = line_list[0].toDouble(); + atoms.x[iatoms_c] = line_list[1].toDouble(); + atoms.y[iatoms_c] = line_list[2].toDouble(); + atoms.z[iatoms_c] = line_list[3].toDouble(); + atoms.sigma[iatoms_c] = (n_cols>4)?line_list[4].toDouble():0.085; + atoms.occ[iatoms_c] = (n_cols>5)?line_list[5].toDouble():1.0; + atoms.region[iatoms_c] = (n_cols>6)?line_list[6].toDouble():0; + atoms.charge[iatoms_c] = (n_cols>7)?line_list[7].toDouble():0; + iatoms_c++; + + line_string = text_stream.readLine().simplified(); + } while(!line_string.isNull()); + + file.close(); + + atoms.get_statistic(); + + return true; + } }; #endif // QT_LOAD_SPECIMEN_H diff --git a/gui_multem/q_types.h b/gui_multem/q_types.h index 232b73d1..25e10c0d 100644 --- a/gui_multem/q_types.h +++ b/gui_multem/q_types.h @@ -13,20 +13,20 @@ class QWidget; /************************Input File*******************************/ enum eInput_File { - eIF_txt = 1, eIF_pdb = 2 + eIF_txt = 1, eIF_pdb = 2 }; /************************Color map*******************************/ enum eColormap { - eCM_Gray = 1, eCM_Hot = 2, eCM_Cool = 3, eCM_Jet = 4, - eCM_Copper = 5, eCM_Summer = 6, eCM_Autumn = 7, eCM_Winter = 8 + eCM_Gray = 1, eCM_Hot = 2, eCM_Cool = 3, eCM_Jet = 4, + eCM_Copper = 5, eCM_Summer = 6, eCM_Autumn = 7, eCM_Winter = 8 }; /**************************Scale*********************************/ enum eScale_Type { - eSLT_Linear = 1, eSLT_Power = 2, eSLT_Log = 3 + eSLT_Linear = 1, eSLT_Power = 2, eSLT_Log = 3 }; @@ -39,98 +39,98 @@ const double int_lim = std::numeric_limits::max()/2; inline QString sups_mone() { - return QString::fromWCharArray(L"\x207B\x00B9"); + return QString::fromWCharArray(L"\x207B\x00B9"); } inline QByteArray c_nm_to_qba(int nm, const char *units) { - QString str = "C"; - str += QString::number(nm) + "" + QString::fromUtf8(units); - return str.toUtf8(); + QString str = "C"; + str += QString::number(nm) + "" + QString::fromUtf8(units); + return str.toUtf8(); } inline QByteArray phi_nm_to_qba(int nm, const char *units) { - QString str = "f"; - str += QString::number(nm) + "" + QString::fromUtf8(units); - return str.toUtf8(); + QString str = "f"; + str += QString::number(nm) + "" + QString::fromUtf8(units); + return str.toUtf8(); } inline QByteArray x_sub_to_qba(const char *x, const char *s, QString fs="large") { - QString str = QString::fromUtf8(x) + ""; - str += QString::fromUtf8(s) + ""; - return str.toUtf8(); + QString str = QString::fromUtf8(x) + ""; + str += QString::fromUtf8(s) + ""; + return str.toUtf8(); } inline QByteArray n_atoms_types_qba(int na, int nt) { - QString str_natoms = "Natoms = " + QString::number(na); - QString str_ntypes = "Natom types = " + QString::number(nt); - QString str = str_natoms + " - " + str_ntypes; - return str.toUtf8(); + QString str_natoms = "Natoms = " + QString::number(na); + QString str_ntypes = "Natom types = " + QString::number(nt); + QString str = str_natoms + " - " + str_ntypes; + return str.toUtf8(); } inline QByteArray n_slices_qba(int na) { - QString str_nslices = "Nslices = " + QString::number(na); - return str_nslices.toUtf8(); + QString str_nslices = "Nslices = " + QString::number(na); + return str_nslices.toUtf8(); } inline QString thk_value_qstr(double value) { - QString str_thk = " " + QString::number(value, 'f', 4) + " " + Ags + " "; - return str_thk; + QString str_thk = " " + QString::number(value, 'f', 4) + " " + Ags + " "; + return str_thk; } inline QString det_value_qstr(double lambda, double g_inner, double g_outer) { - g_inner = 1000*asin(lambda*g_inner); - g_outer = 1000*asin(lambda*g_outer); - QString str_det = " [" + QString::number(g_inner, 'f', 3) + " - " + QString::number(g_outer, 'f', 3) + "] mrad "; - return str_det; + g_inner = 1000*asin(lambda*g_inner); + g_outer = 1000*asin(lambda*g_outer); + QString str_det = " [" + QString::number(g_inner, 'f', 3) + " - " + QString::number(g_outer, 'f', 3) + "] mrad "; + return str_det; } template QVariant enum_to_QVar(const T &data) { - return QVariant(static_cast(data)); + return QVariant(static_cast(data)); } template T QVar_to_enum(const QVariant &data) { - return static_cast(data.toInt()); + return static_cast(data.toInt()); } inline void disable_item_QComboBox(QComboBox *cb, int index, bool disabled=true) { - QStandardItemModel *model = qobject_cast(cb->model()); - QStandardItem *item = model->item(index); - item->setFlags(disabled? item->flags() & ~Qt::ItemIsEnabled: - item->flags() | Qt::ItemIsEnabled); + QStandardItemModel *model = qobject_cast(cb->model()); + QStandardItem *item = model->item(index); + item->setFlags(disabled? item->flags() & ~Qt::ItemIsEnabled: + item->flags() | Qt::ItemIsEnabled); } inline void set_non_editable_QLineEdit(QLineEdit *le) { - le->setReadOnly(true); - le->setEnabled(false); + le->setReadOnly(true); + le->setEnabled(false); -// auto palette = new QPalette(); -// palette->setColor(QPalette::Base,Qt::gray); -// palette->setColor(QPalette::Text,Qt::darkGray); +// auto palette = new QPalette(); +// palette->setColor(QPalette::Base,Qt::gray); +// palette->setColor(QPalette::Text,Qt::darkGray); -// le->setReadOnly(true); -// le->setPalette(*palette); +// le->setReadOnly(true); +// le->setPalette(*palette); } #endif // QT_TYPES_H diff --git a/gui_multem/q_widget.cpp b/gui_multem/q_widget.cpp index 7ff7b17a..41526150 100644 --- a/gui_multem/q_widget.cpp +++ b/gui_multem/q_widget.cpp @@ -22,206 +22,206 @@ QColor from_string_to_color(const QString &name) { - if (name == "Black") - return QColor("#D8D8D8"); - if (name == "White") - return QColor("#F1F1F1"); - if (name == "Red") - return QColor("#F1D8D8"); - if (name == "Green") - return QColor("#D8E4D8"); - if (name == "Blue") - return QColor("#D8D8F1"); - if (name == "Yellow") - return QColor("#F1F0D8"); - - return QColor(name).light(110); + if (name == "Black") + return QColor("#D8D8D8"); + if (name == "White") + return QColor("#F1F1F1"); + if (name == "Red") + return QColor("#F1D8D8"); + if (name == "Green") + return QColor("#D8E4D8"); + if (name == "Blue") + return QColor("#D8D8F1"); + if (name == "Yellow") + return QColor("#F1F0D8"); + + return QColor(name).light(110); } /*************************** MColorMap ****************************/ void MColorMap::set(Spec color_map_i) { - colormap = color_map_i; - - int v_max = qint32(map.size())-1; - - std::fill(map.begin(), map.end(), qRgba(0, 0, 0, 0)); - - auto to_int = [&v_max](const qreal &v_n) - { - return qBound(0, qRound(v_max*v_n), v_max); - }; - - switch(colormap) - { - case eCM_Gray: - { - for(auto iv=0; iv(1.0, 1.250*t); - auto g = qMin(1.0, 0.7812*t); - auto b = qMin(1.0, 0.4975*t); - - auto r_i = to_int(r); - auto g_i = to_int(g); - auto b_i = to_int(b); - - map[iv] = qRgb(r_i, g_i, b_i); - } - } - break; - case eCM_Summer: - { - for(auto iv=0; iv(0, qRound(v_max*v_n), v_max); + }; + + switch(colormap) + { + case eCM_Gray: + { + for(auto iv=0; iv(1.0, 1.250*t); + auto g = qMin(1.0, 0.7812*t); + auto b = qMin(1.0, 0.4975*t); + + auto r_i = to_int(r); + auto g_i = to_int(g); + auto b_i = to_int(b); + + map[iv] = qRgb(r_i, g_i, b_i); + } + } + break; + case eCM_Summer: + { + for(auto iv=0; ivsetAlignment(Qt::AlignHCenter); - header_title->setFlat(true); - header_title->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); - - expand_buttom = new QToolButton; - expand_buttom->setStyleSheet("QToolButton { border: none; }"); - expand_buttom->setToolButtonStyle(Qt::ToolButtonIconOnly); - expand_buttom->setArrowType(Qt::ArrowType::LeftArrow); - expand_buttom->setCheckable(true); - expand_buttom->setChecked(false); - - /********************************************************/ - content_frame = new QFrame; - - main_layout = new QGridLayout; - main_layout->setVerticalSpacing(0); - main_layout->setContentsMargins(0, 0, 0, 0); - main_layout->addWidget(header_title, 0, 0); - main_layout->addWidget(expand_buttom, 0, 1, 1, 1, Qt::AlignRight); - main_layout->addWidget(content_frame, 1, 0, 1, 2); - - setLayout(main_layout); - - QObject::connect(expand_buttom, &QToolButton::toggled, [this](const bool checked) { - expand_buttom->setArrowType(checked ? Qt::ArrowType::DownArrow : Qt::ArrowType::LeftArrow); - content_frame->setVisible(checked); - }); - content_frame->setVisible(expand_buttom->isChecked()); + header_title = new QGroupBox(title); + header_title->setAlignment(Qt::AlignHCenter); + header_title->setFlat(true); + header_title->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); + + expand_buttom = new QToolButton; + expand_buttom->setStyleSheet("QToolButton { border: none; }"); + expand_buttom->setToolButtonStyle(Qt::ToolButtonIconOnly); + expand_buttom->setArrowType(Qt::ArrowType::LeftArrow); + expand_buttom->setCheckable(true); + expand_buttom->setChecked(false); + + /********************************************************/ + content_frame = new QFrame; + + main_layout = new QGridLayout; + main_layout->setVerticalSpacing(0); + main_layout->setContentsMargins(0, 0, 0, 0); + main_layout->addWidget(header_title, 0, 0); + main_layout->addWidget(expand_buttom, 0, 1, 1, 1, Qt::AlignRight); + main_layout->addWidget(content_frame, 1, 0, 1, 2); + + setLayout(main_layout); + + QObject::connect(expand_buttom, &QToolButton::toggled, [this](const bool checked) { + expand_buttom->setArrowType(checked ? Qt::ArrowType::DownArrow : Qt::ArrowType::LeftArrow); + content_frame->setVisible(checked); + }); + content_frame->setVisible(expand_buttom->isChecked()); } diff --git a/gui_multem/q_widget.h b/gui_multem/q_widget.h index 49c0ef2c..d1d943f0 100644 --- a/gui_multem/q_widget.h +++ b/gui_multem/q_widget.h @@ -16,225 +16,225 @@ class MColorMap { public: - enum Spec - { - eCM_Invalid = 0, eCM_Gray = 1, eCM_Hot = 2, eCM_Cool = 3, eCM_Jet = 4, - eCM_Copper = 5, eCM_Summer = 6, eCM_Autumn = 7, eCM_Winter = 8 - }; - - inline - MColorMap(Spec color_map_i=eCM_Gray):map(256, qRgba(0, 0, 0, 0)) - { - set(color_map_i); - } - - inline - QRgb operator()(const uchar &iv) const - { - return map[iv]; - } - - void set(Spec color_map_i); - - inline - Spec get() const - { - return colormap; - } + enum Spec + { + eCM_Invalid = 0, eCM_Gray = 1, eCM_Hot = 2, eCM_Cool = 3, eCM_Jet = 4, + eCM_Copper = 5, eCM_Summer = 6, eCM_Autumn = 7, eCM_Winter = 8 + }; + + inline + MColorMap(Spec color_map_i=eCM_Gray):map(256, qRgba(0, 0, 0, 0)) + { + set(color_map_i); + } + + inline + QRgb operator()(const uchar &iv) const + { + return map[iv]; + } + + void set(Spec color_map_i); + + inline + Spec get() const + { + return colormap; + } private: - std::vector map; - Spec colormap; + std::vector map; + Spec colormap; }; /***************************** MLine_H *****************************/ class MLine_H: public QFrame { - Q_OBJECT + Q_OBJECT public: - explicit MLine_H(QWidget *parent = Q_NULLPTR): QFrame(parent) - { - setFrameStyle(QFrame::HLine | QFrame::Sunken); - setLineWidth(1); - } + explicit MLine_H(QWidget *parent = Q_NULLPTR): QFrame(parent) + { + setFrameStyle(QFrame::HLine | QFrame::Sunken); + setLineWidth(1); + } }; /***************************** MFrame_V *****************************/ class MFrame_V: public QFrame { - Q_OBJECT + Q_OBJECT public: - explicit MFrame_V(QWidget *parent = Q_NULLPTR) - : QFrame(parent), layout(new QVBoxLayout), - szHint(-1, -1), minSzHint(50, 50) - { - setFrameStyle(QFrame::Box | QFrame::Sunken); - setLineWidth(1); - setMidLineWidth(1); - layout->setContentsMargins(1, 2, 1, 0); - //layout->setVerticalSpacing(2); - layout->setSizeConstraint(QLayout::SetMinimumSize); - setLayout(layout); - } - - QSize sizeHint() const Q_DECL_OVERRIDE - { - return szHint; - } - - QSize minimumSizeHint() const Q_DECL_OVERRIDE - { - return minSzHint; - } - - QVBoxLayout *layout; + explicit MFrame_V(QWidget *parent = Q_NULLPTR) + : QFrame(parent), layout(new QVBoxLayout), + szHint(-1, -1), minSzHint(50, 50) + { + setFrameStyle(QFrame::Box | QFrame::Sunken); + setLineWidth(1); + setMidLineWidth(1); + layout->setContentsMargins(1, 2, 1, 0); + //layout->setVerticalSpacing(2); + layout->setSizeConstraint(QLayout::SetMinimumSize); + setLayout(layout); + } + + QSize sizeHint() const Q_DECL_OVERRIDE + { + return szHint; + } + + QSize minimumSizeHint() const Q_DECL_OVERRIDE + { + return minSzHint; + } + + QVBoxLayout *layout; private: - QSize szHint; - QSize minSzHint; + QSize szHint; + QSize minSzHint; }; /***************************** MFrame_G *****************************/ class MFrame_G: public QFrame { - Q_OBJECT + Q_OBJECT public: - explicit MFrame_G(QWidget *parent = Q_NULLPTR) - : QFrame(parent), layout(new QGridLayout) - , szHint(-1, -1), minSzHint(50, 50) - { - setFrameStyle(QFrame::Box | QFrame::Sunken); - setLineWidth(1); - setMidLineWidth(1); - - layout->setContentsMargins(1, 2, 1, 0); - layout->setVerticalSpacing(2); - layout->setSizeConstraint(QLayout::SetMinimumSize); - setLayout(layout); - } - - QSize sizeHint() const Q_DECL_OVERRIDE - { - return szHint; - } - - QSize minimumSizeHint() const Q_DECL_OVERRIDE - { - return minSzHint; - } - - QGridLayout *layout; + explicit MFrame_G(QWidget *parent = Q_NULLPTR) + : QFrame(parent), layout(new QGridLayout) + , szHint(-1, -1), minSzHint(50, 50) + { + setFrameStyle(QFrame::Box | QFrame::Sunken); + setLineWidth(1); + setMidLineWidth(1); + + layout->setContentsMargins(1, 2, 1, 0); + layout->setVerticalSpacing(2); + layout->setSizeConstraint(QLayout::SetMinimumSize); + setLayout(layout); + } + + QSize sizeHint() const Q_DECL_OVERRIDE + { + return szHint; + } + + QSize minimumSizeHint() const Q_DECL_OVERRIDE + { + return minSzHint; + } + + QGridLayout *layout; private: - QSize szHint; - QSize minSzHint; + QSize szHint; + QSize minSzHint; }; /***************************** MGroupBox_BE *****************************/ class MGroupBox_BE : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit MGroupBox_BE(const QString & title = "", QWidget *parent = Q_NULLPTR); + explicit MGroupBox_BE(const QString & title = "", QWidget *parent = Q_NULLPTR); - void setExpand(bool expand) - { - expand_buttom->setChecked(expand); - } + void setExpand(bool expand) + { + expand_buttom->setChecked(expand); + } protected: - QGridLayout *main_layout; - QGroupBox *header_title; - QToolButton *expand_buttom; - QFrame *content_frame; + QGridLayout *main_layout; + QGroupBox *header_title; + QToolButton *expand_buttom; + QFrame *content_frame; }; /***************************** MGroupBox_HE *****************************/ class MGroupBox_HE : public MGroupBox_BE { - Q_OBJECT + Q_OBJECT public: - explicit MGroupBox_HE(const QString & title = "", QWidget *parent = Q_NULLPTR) - :MGroupBox_BE::MGroupBox_BE(title, parent), layout(new QHBoxLayout) - { - layout->setContentsMargins(2, 1, 1, 0); - this->content_frame->setLayout(layout); - } - - void addWidget(QWidget *widget) - { - layout->addWidget(widget); - } - - template - void addWidget(QWidget *widget, TArgs... args) - { - layout->addWidget(widget); - addWidget(args...); - } - - QHBoxLayout *layout; + explicit MGroupBox_HE(const QString & title = "", QWidget *parent = Q_NULLPTR) + :MGroupBox_BE::MGroupBox_BE(title, parent), layout(new QHBoxLayout) + { + layout->setContentsMargins(2, 1, 1, 0); + this->content_frame->setLayout(layout); + } + + void addWidget(QWidget *widget) + { + layout->addWidget(widget); + } + + template + void addWidget(QWidget *widget, TArgs... args) + { + layout->addWidget(widget); + addWidget(args...); + } + + QHBoxLayout *layout; }; /***************************** MGroupBox_VE *****************************/ class MGroupBox_VE : public MGroupBox_BE { - Q_OBJECT + Q_OBJECT public: - explicit MGroupBox_VE(const QString & title = "", QWidget *parent = Q_NULLPTR) - :MGroupBox_BE::MGroupBox_BE(title, parent), layout(new QVBoxLayout) - { - layout->setSpacing(0); - layout->setContentsMargins(2, 1, 1, 0); - content_frame->setLayout(layout); - } - - void addWidget(QWidget *widget) - { - layout->addWidget(widget); - } - - template - void addWidget(QWidget *widget, TArgs... args) - { - layout->addWidget(widget); - addWidget(args...); - } - - QVBoxLayout *layout; + explicit MGroupBox_VE(const QString & title = "", QWidget *parent = Q_NULLPTR) + :MGroupBox_BE::MGroupBox_BE(title, parent), layout(new QVBoxLayout) + { + layout->setSpacing(0); + layout->setContentsMargins(2, 1, 1, 0); + content_frame->setLayout(layout); + } + + void addWidget(QWidget *widget) + { + layout->addWidget(widget); + } + + template + void addWidget(QWidget *widget, TArgs... args) + { + layout->addWidget(widget); + addWidget(args...); + } + + QVBoxLayout *layout; }; /***************************** MGroupBox_GE *****************************/ class MGroupBox_GE : public MGroupBox_BE { - Q_OBJECT + Q_OBJECT public: - explicit MGroupBox_GE(const QString & title = "", QWidget *parent = Q_NULLPTR) - :MGroupBox_BE::MGroupBox_BE(title, parent), layout(new QGridLayout) - { - layout->setVerticalSpacing(1); - layout->setHorizontalSpacing(2); - layout->setContentsMargins(2, 1, 1, 0); - this->content_frame->setLayout(layout); - } - - void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment = Qt::Alignment()) - { - layout->addWidget(widget, row, column, alignment); - } - - void addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = Qt::Alignment()) - { - layout->addWidget(widget, fromRow, fromColumn, rowSpan, columnSpan, alignment); - } - - QGridLayout *layout; + explicit MGroupBox_GE(const QString & title = "", QWidget *parent = Q_NULLPTR) + :MGroupBox_BE::MGroupBox_BE(title, parent), layout(new QGridLayout) + { + layout->setVerticalSpacing(1); + layout->setHorizontalSpacing(2); + layout->setContentsMargins(2, 1, 1, 0); + this->content_frame->setLayout(layout); + } + + void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment = Qt::Alignment()) + { + layout->addWidget(widget, row, column, alignment); + } + + void addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = Qt::Alignment()) + { + layout->addWidget(widget, fromRow, fromColumn, rowSpan, columnSpan, alignment); + } + + QGridLayout *layout; }; @@ -242,92 +242,92 @@ class MGroupBox_GE : public MGroupBox_BE class MGroupBox_H: public QGroupBox { - Q_OBJECT + Q_OBJECT public: - explicit MGroupBox_H(const QString &title = "", QWidget *parent = Q_NULLPTR) - : QGroupBox(title, parent), layout(new QHBoxLayout) - { - setAlignment(Qt::AlignHCenter); - setFlat(true); - layout->setSpacing(1); - layout->setContentsMargins(1, 2, 1, 2); - setLayout(layout); - } - - void addWidget(QWidget *widget) - { - layout->addWidget(widget); - } - - template - void addWidget(QWidget *widget, TArgs... args) - { - layout->addWidget(widget); - addWidget(args...); - } - - QHBoxLayout *layout; + explicit MGroupBox_H(const QString &title = "", QWidget *parent = Q_NULLPTR) + : QGroupBox(title, parent), layout(new QHBoxLayout) + { + setAlignment(Qt::AlignHCenter); + setFlat(true); + layout->setSpacing(1); + layout->setContentsMargins(1, 2, 1, 2); + setLayout(layout); + } + + void addWidget(QWidget *widget) + { + layout->addWidget(widget); + } + + template + void addWidget(QWidget *widget, TArgs... args) + { + layout->addWidget(widget); + addWidget(args...); + } + + QHBoxLayout *layout; }; /***************************** MGroupBox_V *****************************/ class MGroupBox_V: public QGroupBox { - Q_OBJECT + Q_OBJECT public: - explicit MGroupBox_V(const QString &title = "", QWidget *parent = Q_NULLPTR) - : QGroupBox(title, parent), layout(new QVBoxLayout) - { - setAlignment(Qt::AlignHCenter); - setFlat(true); - layout->setSpacing(1); - layout->setContentsMargins(1, 2, 1, 2); - setLayout(layout); - } - - void addWidget(QWidget *widget) - { - layout->addWidget(widget); - } - - template - void addWidget(QWidget *widget, TArgs... args) - { - layout->addWidget(widget); - addWidget(args...); - } - - QVBoxLayout *layout; + explicit MGroupBox_V(const QString &title = "", QWidget *parent = Q_NULLPTR) + : QGroupBox(title, parent), layout(new QVBoxLayout) + { + setAlignment(Qt::AlignHCenter); + setFlat(true); + layout->setSpacing(1); + layout->setContentsMargins(1, 2, 1, 2); + setLayout(layout); + } + + void addWidget(QWidget *widget) + { + layout->addWidget(widget); + } + + template + void addWidget(QWidget *widget, TArgs... args) + { + layout->addWidget(widget); + addWidget(args...); + } + + QVBoxLayout *layout; }; /***************************** MGroupBox_G *****************************/ class MGroupBox_G: public QGroupBox { - Q_OBJECT + Q_OBJECT public: - explicit MGroupBox_G(const QString &title = "", QWidget *parent = Q_NULLPTR) - : QGroupBox(title, parent), layout(new QGridLayout) - { - setAlignment(Qt::AlignHCenter); - setFlat(true); - layout->setVerticalSpacing(0); - layout->setHorizontalSpacing(2); - layout->setContentsMargins(1, 2, 1, 2); - setLayout(layout); - } - - void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment = Qt::Alignment()) - { - layout->addWidget(widget, row, column, alignment); - } - - void addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = Qt::Alignment()) - { - layout->addWidget(widget, fromRow, fromColumn, rowSpan, columnSpan, alignment); - } - - QGridLayout *layout; + explicit MGroupBox_G(const QString &title = "", QWidget *parent = Q_NULLPTR) + : QGroupBox(title, parent), layout(new QGridLayout) + { + setAlignment(Qt::AlignHCenter); + setFlat(true); + layout->setVerticalSpacing(0); + layout->setHorizontalSpacing(2); + layout->setContentsMargins(1, 2, 1, 2); + setLayout(layout); + } + + void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment = Qt::Alignment()) + { + layout->addWidget(widget, row, column, alignment); + } + + void addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = Qt::Alignment()) + { + layout->addWidget(widget, fromRow, fromColumn, rowSpan, columnSpan, alignment); + } + + QGridLayout *layout; }; #endif // MWIDGET_H diff --git a/matlab_functions/MEX.m b/matlab_functions/MEX.m index a90549c2..f89b4a39 100644 --- a/matlab_functions/MEX.m +++ b/matlab_functions/MEX.m @@ -1,54 +1,135 @@ function [] = MEX(option, m_file, src, varargin) -nVarargs = length(varargin); -for k = 1:nVarargs - varargin{k} = strcat(src, filesep, char(varargin{k})); -end - -CUDA_PATH = getenv('CUDA_PATH'); -if(isempty(CUDA_PATH)) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%% Format input data %%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if(strcmp('../', src(1:3))) + [pathstr,~,~] = fileparts(pwd); + src = [pathstr, filesep, src(4:end)]; + end + + nVarargs = length(varargin); + for k = 1:nVarargs + varargin{k} = strcat(src, filesep, char(varargin{k})); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%% set cuda path %%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + CUDA_PATH = getenv('CUDA_PATH'); + if(isempty(CUDA_PATH)) + if(ispc) + CUDA_PATH = 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0'; + elseif(ismac) + CUDA_PATH = '/Developer/NVIDIA/CUDA-8.0'; + else + CUDA_PATH = '/usr/local/cuda-8.0'; + end + end + + if(~exist(CUDA_PATH,'dir')) + disp(['Cuda path not found']) + end + + CUDA_BIN_PATH = [CUDA_PATH, filesep, 'bin']; + CUDA_INC_PATH = [CUDA_PATH, filesep, 'include']; if(ispc) - setenv('CUDA_PATH', 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0'); + CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib', filesep, 'x64']; elseif(ismac) - setenv('CUDA_PATH', '/Developer/NVIDIA/CUDA-8.0'); + CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; else - setenv('CUDA_PATH', '/usr/local/cuda-8.0'); - end -end -CUDA_INC_BIN = [CUDA_PATH, filesep, 'bin']; -CUDA_INC_PATH = [CUDA_PATH, filesep, 'include']; + CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; + end + CUDA_LIBS = '-lcudart -lcufft -lcublas'; + + %%%%%%%%%%%%%%% set NVCC compiler location %%%%%%%%%%%%%%%%%% + setenv('CUDA_PATH', CUDA_PATH); + setenv('CUDA_BIN_PATH', CUDA_BIN_PATH); + setenv('CUDA_LIB_PATH', CUDA_LIB_PATH); + setenv('MW_NVCC_PATH', CUDA_BIN_PATH); -% NVCC compiler location -setenv('MW_NVCC_PATH', CUDA_INC_BIN); + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%% https://developer.nvidia.com/cuda-gpus %%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %%%%%%%%%%%%%%%% set card architecture %%%%%%%%%%%%%%%%%% + SINGLE_CARD="-gencode=arch=compute_60,code=\"sm_60,compute_60\""; + MULTI_CARD=['-gencode=arch=compute_20,code=sm_20 -gencode=arch=compute_30,code=sm_30'... + ' -gencode=arch=compute_35,code=\"sm_35,compute_35\"'... + ' -gencode=arch=compute_50,code=\"sm_50,compute_50\"'... + ' -gencode=arch=compute_60,code=\"sm_60,compute_60\"']; -if(ispc) - FFTW_LIB = ['-L"',src,'" -lfftw3f-3 -lfftw3-3']; - LAPACK_LIB = ['-lblas -llapack']; - CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib', filesep, 'x64']; -elseif(ismac) - FFTW_LIB = ' -lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; - LAPACK_LIB = ' -lblas -llapack'; - CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; -else - % scientific linux -% FFTW_LIB = '-L"/opt/local/lib" -lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; -% LAPACK_LIB = '-L"/opt/local/lib" -lblas -llapack'; - % ubuntu - FFTW_LIB = '-L"/usr/lib/x86_64-linux-gnu" -lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; - LAPACK_LIB = '-L"/usr/lib" -lblas -llapack'; - CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; -end + ARCH_FLAGS = MULTI_CARD; -INCLUDE = ['-I"',CUDA_INC_PATH,'" -I"', src, '"']; -LIBRARY = ['-L"',CUDA_LIB_PATH,'" -lcudart -lcufft -lcublas ', FFTW_LIB, ' ', LAPACK_LIB]; + if(ispc) + mex_cuda_filename = 'mex_CUDA_win64.xml'; + elseif(ismac) + mex_cuda_filename = 'mex_CUDA_maci64.xml'; + else + mex_cuda_filename = 'mex_CUDA_glnxa64.xml'; + end + + %%%%%%%%%%%%% read template mex_cuda file %%%%%%%%%%%%%%% + mex_cuda_file_in = [pathstr, filesep, 'matlab_functions', filesep, mex_cuda_filename]; + mex_cuda = fileread(mex_cuda_file_in); + mex_cuda = strrep(mex_cuda, 'XXX_ARCH_FLAGS', ARCH_FLAGS); + + %%%%%%%%%%%%%%%%% save mex_cuda file %%%%%%%%%%%%%%%%%%%% + mex_cuda_file_out = [pwd, filesep, mex_cuda_filename]; + fid = fopen(mex_cuda_file_out, 'wt'); + fwrite(fid, mex_cuda); + fclose(fid); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%% set library path %%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if(ispc) + % OS = Windows 10 + FFTW_LIB_PATH = src; + FFTW_LIBS = '-lfftw3f-3 -lfftw3-3'; + BLAS_LAPACK_LIB_PATH = src; + BLAS_LAPACK_LIBS = '-lblas -llapack'; + elseif(ismac) + % OS = Windows 10 + FFTW_LIB_PATH = []; + FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; + BLAS_LAPACK_LIB_PATH = []; + BLAS_LAPACK_LIBS = '-lblas -llapack'; + else + % OS = scientific linux +% FFTW_LIB = '-/opt/local/lib'; +% FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; +% LAPACK_LIB = '/opt/local/lib'; +% BLAS_LAPACK_LIBS = '-lblas -llapack'; -if (strcmpi(option, 'release')) - mex_comand = 'mex -v -largeArrayDims'; -else - mex_comand = 'mex -v -g -largeArrayDims'; -end + % OS = ubuntu + FFTW_LIB_PATH = '/usr/lib/x86_64-linux-gnu'; + FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; + BLAS_LAPACK_LIB_PATH = '/usr/lib'; + BLAS_LAPACK_LIBS = '-lblas -llapack'; + end + + if(~exist(FFTW_LIB_PATH,'dir')) + disp(['FFTW path not found']) + end + + if(~exist(BLAS_LAPACK_LIB_PATH,'dir')) + disp(['Blas and Lapack paths not found']) + end + + INCLUDE = ['-I"',CUDA_INC_PATH,'" -I"', src, '"']; + LIBRARY = ['-L"',CUDA_LIB_PATH,'" ',CUDA_LIBS,' -L"',FFTW_LIB_PATH,'" ',FFTW_LIBS,' -L"',BLAS_LAPACK_LIB_PATH,'" ',BLAS_LAPACK_LIBS]; + + if (strcmpi(option, 'release')) + mex_comand = 'mex -v -largeArrayDims'; + else + mex_comand = 'mex -v -g -largeArrayDims'; + end -OUTDIR = ['-outdir ..', filesep, 'mex_bin']; + OUTDIR = ['-outdir ..', filesep, 'mex_bin']; -textcommands = strjoin({mex_comand, OUTDIR, INCLUDE, LIBRARY, m_file, strjoin(varargin)}); -disp(textcommands); -eval(textcommands); \ No newline at end of file + textcommands = strjoin({mex_comand, OUTDIR, INCLUDE, LIBRARY, m_file, strjoin(varargin)}); + disp(textcommands); + eval(textcommands); + + delete(mex_cuda_file_out); +end \ No newline at end of file diff --git a/matlab_functions/getMemorySize.m b/matlab_functions/getMemorySize.m deleted file mode 100644 index 0e59b5f6..00000000 --- a/matlab_functions/getMemorySize.m +++ /dev/null @@ -1,3 +0,0 @@ -function [gamma] = getMemorySize(type, ) -emass = 510.99906; % electron rest mass in keV -gamma = (1.0 + E_0/emass); \ No newline at end of file diff --git a/matlab_functions/ilm_compile.m b/matlab_functions/ilm_compile.m new file mode 100644 index 00000000..c1e0eed3 --- /dev/null +++ b/matlab_functions/ilm_compile.m @@ -0,0 +1,140 @@ +function ilm_compile(option, m_file, src) + if(strcmp('../', src(1:3))) + src = [pwd, filesep, src(4:end)]; + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%% set cuda path %%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + CUDA_PATH = getenv('CUDA_PATH'); + if(isempty(CUDA_PATH)) + if(ispc) + CUDA_PATH = 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0'; + elseif(ismac) + CUDA_PATH = '/Developer/NVIDIA/CUDA-8.0'; + else + CUDA_PATH = '/usr/local/cuda-8.0'; + end + end + + CUDA_BIN_PATH = [CUDA_PATH, filesep, 'bin']; + CUDA_INC_PATH = [CUDA_PATH, filesep, 'include']; + if(ispc) + CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib', filesep, 'x64']; + elseif(ismac) + CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; + else + CUDA_LIB_PATH = [CUDA_PATH, filesep, 'lib64']; + end + CUDA_LIBS = '-lcudart -lcufft -lcublas'; + + % NVCC compiler location + setenv('CUDA_PATH', CUDA_PATH); + setenv('CUDA_BIN_PATH', CUDA_BIN_PATH); + setenv('CUDA_LIB_PATH', CUDA_LIB_PATH); + setenv('MW_NVCC_PATH', CUDA_BIN_PATH); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%% set library path %%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if(ispc) + FFTW_LIB_PATH = src; + FFTW_LIBS = '-lfftw3f-3 -lfftw3-3'; + BLAS_LAPACK_LIB_PATH = src; + BLAS_LAPACK_LIBS = '-lblas -llapack'; + elseif(ismac) + FFTW_LIB_PATH = []; + FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; + BLAS_LAPACK_LIB_PATH = []; + BLAS_LAPACK_LIBS = '-lblas -llapack'; + + else + % scientific linux +% FFTW_LIB = '-/opt/local/lib'; +% FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; +% LAPACK_LIB = '/opt/local/lib'; +% BLAS_LAPACK_LIBS = '-lblas -llapack'; + + % ubuntu + FFTW_LIB_PATH = '/usr/lib/x86_64-linux-gnu'; + FFTW_LIBS = '-lfftw3f -lfftw3 -lfftw3f_threads -lfftw3_threads'; + BLAS_LAPACK_LIB_PATH = '/usr/lib'; + BLAS_LAPACK_LIBS = '-lblas -llapack'; + end + + INCLUDE = ['-I"',CUDA_INC_PATH,'" -I"', src, '"']; + LIBRARY = ['-L"',CUDA_LIB_PATH,'" ',CUDA_LIBS,' -L"',FFTW_LIB_PATH,'" ',FFTW_LIBS,' -L"',BLAS_LAPACK_LIB_PATH,'" ',BLAS_LAPACK_LIBS]; + + if (strcmpi(option, 'release')) + mex_comand = 'mex -v -largeArrayDims'; + else + mex_comand = 'mex -v -g -largeArrayDims'; + end + + OUTDIR = ['-outdir ..', filesep, 'mex_bin']; + + CARD_20 = '-gencode arch=compute_20,code=sm_20'; + CARD_30 = '-gencode arch=compute_30,code=sm_30'; + CARD_35 = '-gencode arch=compute_35,code=sm_35'; + CARD_50 = '-gencode arch=compute_50,code=sm_50'; + CARD_60 = '-gencode arch=compute_60,code=sm_60'; + CARD_MULT = [CARD_20, ' ', CARD_30, ' ', CARD_35, ' ', CARD_50, ' ', CARD_60]; + ARCH_FLAGS = CARD_60; + + NVCC_FLAGS='-std=c++11 --default-stream legacy'; + COMP_FLAGS='--compiler-options=/Zp8,/GR,/W3,/EHs,/nologo,/MD'; + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%% compilation %%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + cmd1 = [CUDA_BIN_PATH, filsep, 'nvcc -c --compiler-options=/D_CRT_SECURE_NO_DEPRECATE,/D_SCL_SECURE_NO_DEPRECATE,/D_SECURE_SCL=0,/DMATLAB_MEX_FILE' ... + ' ', INCLUDE,... + ' -I"',matlabroot,'/extern/include"',... + ' ', ARCH_FLAGS,... + ' ', NVCC_FLAGS,... + ' -std=c++11 --compiler-options=-ansi,-fexceptions,-fPIC,-fno-omit-frame-pointer,-lcufft,-lcufftw,-pthread -O -DNDEBUG' ... + ' ' files{k} '.cu -o ' files{k} '.o']; + + cmd2 = ['/usr/bin/g++ -pthread -Wl,--no-undefined -Wl,--no-as-needed -shared -O' ... + ' -Wl,--version-script,"/usr/local/MATLAB/R2016b/extern/lib/glnxa64/mexFunction.map"' ... + ' ' strcat(files{k},'.o') ' -ldl' ... + ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcusparse.so' ... % -lcusparse + ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcublas_static.a' ... % -lcublas_static + ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcusparse_static.a' ... % -lcusparse_static + ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libculibos.a' ... % -lculibos' + ' -L/usr/local/cuda-8.0/lib64 -Wl,-rpath-link,/usr/local/MATLAB/R2016b/bin/glnxa64' ... + ' -L"/usr/local/MATLAB/R2016b/bin/glnxa64" -lmx -lmex -lmat -lm -lstdc++ -lmwgpu -lcufft -lcufftw' ... + ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcudart.so' ... % /usr/local/MATLAB/R2016a/bin/glnxa64/libcudart.so.7.5 + ' -o ' files{k} '.mexa64']; + + cmd3 = ['rm -f ' files{k} '.o']; + + +% cmd1 = ['/usr/local/cuda-8.0/bin/nvcc -c --compiler-options=-D_GNU_SOURCE,-DMATLAB_MEX_FILE' ... +% ' -I"/usr/local/cuda-8.0/include"' ... +% ' -I"/usr/local/MATLAB/R2016b/extern/include"' ... +% ' -I"/usr/local/MATLAB/R2016b/simulink/include"' ... +% ' -I"/usr/local/MATLAB/R2016b/toolbox/distcomp/gpu/extern/include/"' ... +% ' -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=sm_50' ... +% ' -std=c++11 --compiler-options=-ansi,-fexceptions,-fPIC,-fno-omit-frame-pointer,-lcufft,-lcufftw,-pthread -O -DNDEBUG' ... +% ' ' files{k} '.cu -o ' files{k} '.o']; +% +% cmd2 = ['/usr/bin/g++ -pthread -Wl,--no-undefined -Wl,--no-as-needed -shared -O' ... +% ' -Wl,--version-script,"/usr/local/MATLAB/R2016b/extern/lib/glnxa64/mexFunction.map"' ... +% ' ' strcat(files{k},'.o') ' -ldl' ... +% ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcusparse.so' ... % -lcusparse +% ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcublas_static.a' ... % -lcublas_static +% ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcusparse_static.a' ... % -lcusparse_static +% ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libculibos.a' ... % -lculibos' +% ' -L/usr/local/cuda-8.0/lib64 -Wl,-rpath-link,/usr/local/MATLAB/R2016b/bin/glnxa64' ... +% ' -L"/usr/local/MATLAB/R2016b/bin/glnxa64" -lmx -lmex -lmat -lm -lstdc++ -lmwgpu -lcufft -lcufftw' ... +% ' /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcudart.so' ... % /usr/local/MATLAB/R2016a/bin/glnxa64/libcudart.so.7.5 +% ' -o ' files{k} '.mexa64']; +% +% cmd3 = ['rm -f ' files{k} '.o']; + + disp([files{k} '.cu']) + if system(cmd1); error('%s failed step 1',files{k}); end + if system(cmd2); error('%s failed step 2',files{k}); end + if system(cmd3); error('%s failed step 3',files{k}); end + disp('MEX completed successfully.') +end \ No newline at end of file diff --git a/matlab_functions/ilm_find_closest_xy_pos.m b/matlab_functions/ilm_find_closest_xy_pos.m new file mode 100644 index 00000000..135f0442 --- /dev/null +++ b/matlab_functions/ilm_find_closest_xy_pos.m @@ -0,0 +1,5 @@ +function[x_c, y_c]=ilm_find_closest_xy_pos(atoms, x_c, y_c) + [~, ii] = sort((atoms(:, 2)-x_c).^2+(atoms(:, 3)-y_c).^2); + x_c = atoms(ii(1), 2); + y_c = atoms(ii(1), 3); +end \ No newline at end of file diff --git a/matlab_functions/ilm_geom_center_cp.m b/matlab_functions/ilm_geom_center_cp.m new file mode 100644 index 00000000..cc27f6ba --- /dev/null +++ b/matlab_functions/ilm_geom_center_cp.m @@ -0,0 +1,5 @@ +function[p0]=ilm_geom_center_cp(atoms) + p0 = mean(atoms); % rotation point + [~, ii] = sort(sqrt(sum((atoms-p0).^2, 2))); + p0 = atoms(ii(1), :); +end \ No newline at end of file diff --git a/matlab_functions/ilm_mean_image.m b/matlab_functions/ilm_mean_image.m new file mode 100644 index 00000000..9eacda28 --- /dev/null +++ b/matlab_functions/ilm_mean_image.m @@ -0,0 +1,9 @@ +function[image_av]=ilm_mean_image(data) + +n_images = length(data); +[ny, nx] = size(data(1).image); +image_av = zeros(ny, nx); +for i = 1:n_images + image_av = image_av + data(i).image; +end +image_av = image_av/n_images; \ No newline at end of file diff --git a/matlab_functions/ilm_min_max.m b/matlab_functions/ilm_min_max.m new file mode 100644 index 00000000..11bc7b22 --- /dev/null +++ b/matlab_functions/ilm_min_max.m @@ -0,0 +1,4 @@ +function[im_min, im_max]=ilm_min_max(im_i) + im_min = min(im_i(:)); + im_max = max(im_i(:)); +end \ No newline at end of file diff --git a/matlab_functions/ilm_minmax_norm_image.m b/matlab_functions/ilm_minmax_norm_image.m index e4ad76ac..1f78e184 100644 --- a/matlab_functions/ilm_minmax_norm_image.m +++ b/matlab_functions/ilm_minmax_norm_image.m @@ -1,4 +1,4 @@ function [im_o] = ilm_minmax_norm_image(im_i) - [im_min, im_max] = get_min_max(im_i); + [im_min, im_max] = ilm_min_max(im_i); im_o = (im_i-im_min)/(im_max-im_min); end \ No newline at end of file diff --git a/matlab_functions/ilm_rand.m b/matlab_functions/ilm_rand.m index ec85b699..0933c526 100644 --- a/matlab_functions/ilm_rand.m +++ b/matlab_functions/ilm_rand.m @@ -1,3 +1,10 @@ -function [x] = ilm_rand(x_min, x_max) - x = x_min+(x_max-x_min)*rand(); +function [x] = ilm_rand(x_min, x_max, nr, nc) + if(nargin<4) + nc = 1; + end + if(nargin<3) + nr = 1; + end + + x = x_min+(x_max-x_min)*rand(nr, nc); end \ No newline at end of file diff --git a/matlab_functions/ilm_select_atoms.m b/matlab_functions/ilm_select_atoms.m new file mode 100644 index 00000000..b9dde046 --- /dev/null +++ b/matlab_functions/ilm_select_atoms.m @@ -0,0 +1,5 @@ +function[atoms]=ilm_select_atoms(atoms, x_min, x_max, y_min, y_max) + x = atoms(:, 2); + y = atoms(:, 3); + atoms = atoms((x_min<=x)&(x + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mex_files_multem/mex_CUDA_maci64.xml b/matlab_functions/mex_CUDA_maci64.xml similarity index 94% rename from mex_files_multem/mex_CUDA_maci64.xml rename to matlab_functions/mex_CUDA_maci64.xml index a19cc9ad..7ccd9638 100644 --- a/mex_files_multem/mex_CUDA_maci64.xml +++ b/matlab_functions/mex_CUDA_maci64.xml @@ -1,5 +1,4 @@ - - - @@ -124,48 +121,88 @@ - + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/matlab_functions/multem_default_values.m b/matlab_functions/multem_default_values.m index 88485666..cfea0ffa 100644 --- a/matlab_functions/multem_default_values.m +++ b/matlab_functions/multem_default_values.m @@ -58,7 +58,7 @@ %%%%%%%%%%%%%%%%%%%%%%%% Simulation type %%%%%%%%%%%%%%%%%%%%%%%%%%% % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, -% eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, +% eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, % eTEMST_EWFS=51, eTEMST_EWRS=52, eTEMST_EELS=61, eTEMST_EFTEM=62, % eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82, % eTEMST_TFFS=91, eTEMST_TFRS=92 @@ -70,14 +70,14 @@ input_multislice.iw_x = 0.0; % x position input_multislice.iw_y = 0.0; % y position -%%%%%%%%%%%%%%%%%%%% Microscope paramters %%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.E_0 = 300; % Acceleration Voltage (keV) input_multislice.theta = 0.0; % Polar angle (º) input_multislice.phi = 0.0; % Azimuthal angle (º) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.illumination_model = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multislice.temporal_spatial_incoh = 1; % 1: Spatial and temporal, 2: Temporal, 3: Spatial +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % On the optimun probe in aberration corrected ADF-STEM @@ -121,12 +121,15 @@ input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % # integration steps for the divergence semi-angle. It will be only used if illumination_model=4 +%%%%%%%%%% source spread function %%%%%%%%%%%% +input_multislice.cond_lens_ssf_sigma = 0.0072; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 8; % # of integration points. It will be only used if illumination_model=4 -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % # integration steps for the defocus Spread. It will be only used if illumination_model=4 +%%%%%%%%% defocus spread function %%%%%%%%%%%% +input_multislice.cond_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +%%%%%%%%% zero defocus reference %%%%%%%%%%%% input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; % It will be only used if cond_lens_zero_defocus_type = eZDT_User_Define @@ -176,21 +179,14 @@ input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) -input_multislice.obj_lens_sf = 32; % Defocus Spread (Å) -input_multislice.obj_lens_nsf = 10; % # integration steps for the defocus Spread. It will be only used if illumination_model=4 +%%%%%%%%% defocus spread function %%%%%%%%%%%% +input_multislice.obj_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.obj_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +%%%%%%%%% zero defocus reference %%%%%%%%%%%% input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define -%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ISTEM/STEM %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.scanning_type = 1; % eST_Line = 1, eST_Area = 2 -input_multislice.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) -input_multislice.scanning_ns = 10; % number of sampling points -input_multislice.scanning_x0 = 0.0; % x-starting point (Å) -input_multislice.scanning_y0 = 0.0; % y-starting point (Å) -input_multislice.scanning_xe = 4.078; % x-final point (Å) -input_multislice.scanning_ye = 4.078; % y-final point (Å) - %%%%%%%%%%%%%%%%%%%%%%%%%% STEM Detector %%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.detector.type = 1; % eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 @@ -203,21 +199,43 @@ input_multislice.detector.matrix(1).R = 0; % 2D detector angle(mrad) input_multislice.detector.matrix(1).fR = 0; % 2D sensitivity value -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PED %%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%% Scanning area for ISTEM/STEM/EELS %%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.scanning_type = 1; % eST_Line = 1, eST_Area = 2 +input_multislice.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) +input_multislice.scanning_ns = 10; % number of sampling points +input_multislice.scanning_x0 = 0.0; % x-starting point (Å) +input_multislice.scanning_y0 = 0.0; % y-starting point (Å) +input_multislice.scanning_xe = 4.078; % x-final point (Å) +input_multislice.scanning_ye = 4.078; % y-final point (Å) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%PED %%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.ped_nrot = 360; % Number of orientations input_multislice.ped_theta = 3.0; % Precession angle (degrees) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% HCI %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%HCI %%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.hci_nrot = 360; % number of orientations input_multislice.hci_theta = 3.0; % Precession angle (degrees) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EELS %%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%EELS %%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.eels_Z = 79; % atomic type input_multislice.eels_E_loss = 80; % Energy loss (eV) input_multislice.eels_collection_angle = 100; % Collection half angle (mrad) input_multislice.eels_m_selection = 3; % selection rule input_multislice.eels_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EFTEM %%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%EFTEM %%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.eftem_Z = 79; % atomic type input_multislice.eftem_E_loss = 80; % Energy loss (eV) input_multislice.eftem_collection_angle = 100; % Collection half angle (mrad) input_multislice.eftem_m_selection = 3; % selection rule -input_multislice.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 \ No newline at end of file +input_multislice.eftem_channelling_type = 1; % eCT_Single_Channelling = 1, eCT_Mixed_Channelling = 2, eCT_Double_Channelling = 3 + +%%%%%%%%%%%%%%%%%%%%%%% OUTPUT REGION %%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% This option is not use for eTEMST_STEM and eTEMST_EELS %%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.output_area_ix_0 = 1; % x-starting in pixel +input_multislice.output_area_iy_0 = 1; % y-starting in pixel +input_multislice.output_area_ix_e = 1; % x-final in pixel +input_multislice.output_area_iy_e = 1; % y-final in pixel \ No newline at end of file diff --git a/matlab_functions/xy_projected.mat b/matlab_functions/xy_projected.mat new file mode 100644 index 00000000..2ccd32b5 Binary files /dev/null and b/matlab_functions/xy_projected.mat differ diff --git a/mex_examples_multem/example_MULTEM_CBED.m b/mex_examples_multem/example_MULTEM_CBED.m index c226922f..bd341799 100644 --- a/mex_examples_multem/example_MULTEM_CBED.m +++ b/mex_examples_multem/example_MULTEM_CBED.m @@ -8,48 +8,59 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 - -system_conf.cpu_ncores = 1; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 4; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 21; -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.pn_coh_contrib = 0; -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 100; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% na = 8; nb = 8; nc = 40; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = Si001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 4096; -input_multislice.ny = 4096; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = 0; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; +input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 100; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.illumination_model = 4; % 1: coherente mode, 4: Numerical integration -input_multislice.temporal_spatial_incoh = 2; % 1: Spatial and temporal, 2: Temporal, 3: Spatial +input_multislice.illumination_model = 1; % 1: coherente mode, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto @@ -58,50 +69,48 @@ input_multislice.iw_y = input_multislice.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_m = 0; % Vortex momentum -input_multislice.cond_lens_c_10 = 1110; % Defocus (Å) -input_multislice.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) -input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 8; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle -input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multislice.cond_lens_m = 0; % Vortex momentum +input_multislice.cond_lens_c_10 = 1110; % Defocus (Å) +input_multislice.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) +input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multislice.cond_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; -input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = [10, 20, 30, 50, 70, 90]; % Array of thickes (Å) - clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; +c = 1e5; figure(1); clf; -for i=1:length(output_multislice.data) - c = 1e5; -% m2psi_tot = output_multislice.data(i).m2psi_tot; - m2psi_tot = log(1+c*output_multislice.data(i).m2psi_tot/max(output_multislice.data(i).m2psi_tot(:))); -% m2psi_coh = log(1+c*output_multislice.data(i).m2psi_coh/max(output_multislice.data(i).m2psi_tot(:))); +for i=1:length(output_multislice.data) + m2psi_tot = output_multislice.data(i).m2psi_tot; + m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); I_min = min(m2psi_tot(:)); I_max = max(m2psi_tot(:)); -% subplot(1, 2, 1); imagesc(output_multislice.x, output_multislice.y, m2psi_tot, [I_min I_max]); - title(strcat('Total intensity - Thick = ', num2str(i))); + title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); axis image; - colormap hot; -% subplot(1, 2, 2); -% imagesc(output_multislice.x, output_multislice.y, m2psi_coh, [I_min I_max]); -% title(strcat('Total intensity - Thick = ', num2str(i))); -% axis image; -% colormap hot; - pause(1); + colormap hot; + pause(0.5); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_CBEI.m b/mex_examples_multem/example_MULTEM_CBEI.m index 0c7aad2a..d33d9122 100644 --- a/mex_examples_multem/example_MULTEM_CBEI.m +++ b/mex_examples_multem/example_MULTEM_CBEI.m @@ -1,6 +1,6 @@ % output_multislice = il_MULTEM(system_conf, input_multislice) perform TEM simulation % -% Convergent beam electron Imaging (CBEI) simulation +% Convergent beam electron image (CBEI) simulation % % All parameters of the input_multislice structure are explained in multem_default_values() % @@ -8,104 +8,120 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 22; -input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 10; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.illumination_model = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient -input_multislice.temporal_spatial_incoh = 1; % 1: Spatial and temporal, 2: Temporal, 3: Spatial +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.bwl = 0; - -input_multislice.E_0 = 100; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% na = 8; nb = 8; nc = 40; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = Si001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = 0; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 100; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.illumination_model = 1; % 1: coherente mode, 4: Numerical integration -input_multislice.temporal_spatial_incoh = 2; % 1: Spatial and temporal, 2: Temporal, 3: Spatial +input_multislice.illumination_model = 1; % 1: coherente mode, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multislice.iw_psi = 0; % user define incident wave -input_multislice.iw_x = input_multislice.spec_lx/2; % x position -input_multislice.iw_y = input_multislice.spec_ly/2; % y position +input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multislice.iw_psi = read_psi_0_multem(input_multislice.nx, input_multislice.ny); % user define incident wave +input_multislice.iw_x = input_multislice.spec_lx/2; % x position +input_multislice.iw_y = input_multislice.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_m = 0; % Vortex momentum -input_multislice.cond_lens_c_10 = 1110; % Defocus (Å) -input_multislice.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) +input_multislice.cond_lens_m = 0; % Vortex momentum +input_multislice.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multislice.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle -input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multislice.cond_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.obj_lens_m = 0; % Vortex momentum -input_multislice.obj_lens_c_10 = 0; % Defocus (Å) -input_multislice.obj_lens_c_30 = 0.00; % Third order spherical aberration (mm) -input_multislice.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) -input_multislice.obj_lens_sf = 0; % Defocus Spread (Å) -input_multislice.obj_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multislice.obj_lens_m = 0; % Vortex momentum +input_multislice.obj_lens_c_10 = 0; % Defocus (Å) +input_multislice.obj_lens_c_30 = 0.00; % Third order spherical aberration (mm) +input_multislice.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multislice.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) +%%%%%%%%% defocus spread function %%%%%%%%%%%% +input_multislice.obj_lens_dsf_sigma = 0; % standard deviation (Å) +input_multislice.obj_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; -input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:4*c:1000; % Array of thickes - clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; -clear il_MULTEM; figure(1); for i=1:length(output_multislice.data) imagesc(output_multislice.data(i).m2psi_tot); - title(strcat('Total intensity - Thick = ', num2str(i))); + title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); axis image; - colormap gray; + colormap hot; pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_ED.m b/mex_examples_multem/example_MULTEM_ED.m index a13ceceb..28f3073a 100644 --- a/mex_examples_multem/example_MULTEM_ED.m +++ b/mex_examples_multem/example_MULTEM_ED.m @@ -1,6 +1,6 @@ % output_multislice = il_MULTEM(system_conf, input_multislice) perform TEM simulation % -% electron diffraction (ED) simulation +% Convergent beam electron diffraction (CBED) simulation % % All parameters of the input_multislice structure are explained in multem_default_values() % @@ -8,56 +8,66 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 31; -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.pn_dim = 110; -input_multislice.pn_seed = 300183; -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 10; +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% na = 8; nb = 8; nc = 40; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = Cu001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false -input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:c:1000; % Array of thickes +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; -clear il_MULTEM; +c = 1e6; figure(1); for i=1:length(output_multislice.data) - c = 1e6; - m2psi_tot = log(1+c*output_multislice.data(i).m2psi_tot/max(output_multislice.data(i).m2psi_tot(:))); + m2psi_tot = output_multislice.data(i).m2psi_tot; + m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); I_min = min(m2psi_tot(:)); I_max = max(m2psi_tot(:)); diff --git a/mex_examples_multem/example_MULTEM_EELS.m b/mex_examples_multem/example_MULTEM_EELS.m index 3ea84a4f..d5c5ad12 100644 --- a/mex_examples_multem/example_MULTEM_EELS.m +++ b/mex_examples_multem/example_MULTEM_EELS.m @@ -4,10 +4,8 @@ system_conf.precision = 1; % eP_Float = 1, eP_double = 2 system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; system_conf.cpu_nthread = 4; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; % eST_STEM=11, eST_ISTEM=12, eST_CBED=21, eST_CBEI=22, eST_ED=31, eST_HRTEM=32, eST_PED=41, eST_HCI=42, eST_EWFS=51, eST_EWRS=52, % eST_EELS=61, eST_EFTEM=62, eST_ProbeFS=71, eST_ProbeRS=72, eST_PPFS=81, eST_PPRS=82,eST_TFFS=91, eST_TFRS=92 @@ -54,12 +52,12 @@ input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle +input_multislice.cond_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +input_multislice.cond_lens_ssf_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 8; % # of integration points. It will be only used if illumination_model=4 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.scanning_type = 1; % eST_Line = 1, eST_Area = 2 input_multislice.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) input_multislice.scanning_ns = 10; % number of sampling points diff --git a/mex_examples_multem/example_MULTEM_EFTEM.m b/mex_examples_multem/example_MULTEM_EFTEM.m index a9262b0d..09edb182 100644 --- a/mex_examples_multem/example_MULTEM_EFTEM.m +++ b/mex_examples_multem/example_MULTEM_EFTEM.m @@ -8,52 +8,65 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multislice.simulation_type = 62; % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, eTEMST_EELS=61, eTEMST_EFTEM=62 -input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 +input_multislice.simulation_type = 62; -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 5; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 5; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -na = 8; nb = 8; nc = 3; ncu = 2; rms3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8; nb = 8; nc = 5; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = SrTiO3001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = 0; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) %%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multislice.temporal_spatial_incoh = 1; % 1: Spatial and temporal, 2: Temporal, 3: Spatial +input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multislice.iw_psi = 0; % user define incident wave -input_multislice.iw_x = input_multislice.spec_lx/2; % x position -input_multislice.iw_y = input_multislice.spec_ly/2; % y position +input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multislice.iw_psi = 0; % user define incident wave +input_multislice.iw_x = input_multislice.spec_lx/2; % x position +input_multislice.iw_y = input_multislice.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% input_multislice.cond_lens_m = 0; % Vortex momentum @@ -66,11 +79,19 @@ input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle -input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_mrad_2_sigma(input_multislice.E_0, 0.02); % mrad to standard deviation +input_multislice.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% @@ -84,8 +105,8 @@ input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) -input_multislice.obj_lens_sf = 32; % Defocus Spread (Å) -input_multislice.obj_lens_nsf = 10; % # integration steps for the defocus Spread. It will be only used if illumination_model=4 +input_multislice.obj_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.obj_lens_dsf_npoints = 10; % # integration steps for the defocus Spread. It will be only used if illumination_model=4 input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define @@ -111,36 +132,12 @@ tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; -clear il_MULTEM; figure(1); for i=1:length(output_multislice.data) imagesc(output_multislice.data(i).m2psi_tot); - title(strcat('Total intensity - Thick = ', num2str(i))); + title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); axis image; colormap gray; pause(0.25); -end - -% cc = [1 0 1; 1 0 0; 0 0 1; 0 0 0]; -% for i=1:4 -% input_multislice.eftem_channelling_type = i; -% clear il_MULTEM; -% tic; -% [m2psi_tot] = il_MULTEM(system_conf, input_multislice); -% toc; -% figure(1); -% subplot(2, 1, 1); -% hold on; -% plot(m2psi_tot(129, :), 'color', cc(i, :)); -% subplot(2, 1, 2); -% hold on; -% plot(m2psi_tot(257, :), 'color', cc(i, :)); -% -% figure(2); -% subplot(2, 2, i); -% imagesc(m2psi_tot); -% title('Total intensity'); -% axis image; -% colormap gray; -% end \ No newline at end of file +end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_EWFS.m b/mex_examples_multem/example_MULTEM_EWFS.m index 3b3a1146..624bfd87 100644 --- a/mex_examples_multem/example_MULTEM_EWFS.m +++ b/mex_examples_multem/example_MULTEM_EWFS.m @@ -1,6 +1,6 @@ % output_multislice = il_MULTEM(system_conf, input_multislice) perform TEM simulation % -% Exit wave Fourier space (EWFS) simulation +% Exit wave real space (EWRS) simulation % % All parameters of the input_multislice structure are explained in multem_default_values() % @@ -8,105 +8,130 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 51; -input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 20; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% na = 8; nb = 8; nc = 40; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = SrTiO3001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multislice.iw_psi = 0; % user define incident wave +input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multislice.iw_psi = 0; % user define incident wave input_multislice.iw_x = input_multislice.spec_lx/2; % x position input_multislice.iw_y = input_multislice.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_m = 0; % Vortex momentum -input_multislice.cond_lens_c_10 = 1110; % Defocus (Å) -input_multislice.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) +input_multislice.cond_lens_m = 0; % Vortex momentum +input_multislice.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multislice.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle -input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multislice.cond_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% zero defocus reference %%%%%%%%%%%% input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define -input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:c:1000; % Array of thickes - clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; +c = 1e6; figure(1); for i=1:length(output_multislice.data) - c = 1e6; - - m2psi_coh = abs(output_multislice.data(i).psi_coh).^2; - m2psi_coh = log(1+c*m2psi_coh/max(m2psi_coh(:))); - + m2psi_coh = abs(output_multislice.data(i).psi_coh).^2; if(isfield(output_multislice.data, 'm2psi_tot')) - m2psi_tot = log(1+c*output_multislice.data(i).m2psi_tot/max(output_multislice.data(i).m2psi_tot(:))); + m2psi_tot = output_multislice.data(i).m2psi_tot; else m2psi_tot = m2psi_coh; - end - - I_min = min([min(m2psi_tot(:)), min(m2psi_coh(:))]); - I_max = max([max(m2psi_tot(:)), max(m2psi_coh(:))]); - + end + + m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); + m2psi_coh = log(1+c*m2psi_coh/max(m2psi_coh(:))); + + I_min = min([min(m2psi_coh(:)), min(m2psi_tot(:))]); + I_max = max([max(m2psi_coh(:)), max(m2psi_tot(:))]); + subplot(1, 2, 1); imagesc(m2psi_tot, [I_min I_max]); - title(strcat('Total intensity - Thick = ', num2str(i))); + title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); axis image; colormap gray; + colorbar subplot(1, 2, 2); imagesc(m2psi_coh, [I_min I_max]); - title(strcat('Coherent intensity - Thick = ', num2str(i))); + title(strcat('Coherent intensity - Thick = ', num2str(output_multislice.thick(i)))); axis image; colormap gray; + colorbar pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_EWFS_till_illumination.m b/mex_examples_multem/example_MULTEM_EWFS_till_illumination.m index 40355785..4fac1c1a 100644 --- a/mex_examples_multem/example_MULTEM_EWFS_till_illumination.m +++ b/mex_examples_multem/example_MULTEM_EWFS_till_illumination.m @@ -1,6 +1,6 @@ % output_multislice = il_MULTEM(system_conf, input_multislice) perform TEM simulation % -% Exit wave Fourier space (EWFS) simulation using till illumination +% Exit wave real space (EWRS) simulation % % All parameters of the input_multislice structure are explained in multem_default_values() % @@ -8,105 +8,130 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 51; -input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 5; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 3.0; % Till ilumination (º) -input_multislice.phi = 0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -na = 8; nb = 8; nc = 20; ncu = 2; rms3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8; nb = 8; nc = 40; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = SrTiO3001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 3.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multislice.iw_psi = 0; % user define incident wave +input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multislice.iw_psi = 0; % user define incident wave input_multislice.iw_x = input_multislice.spec_lx/2; % x position input_multislice.iw_y = input_multislice.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_m = 0; % Vortex momentum -input_multislice.cond_lens_c_10 = 1110; % Defocus (Å) -input_multislice.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) +input_multislice.cond_lens_m = 0; % Vortex momentum +input_multislice.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multislice.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle -input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multislice.cond_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% zero defocus reference %%%%%%%%%%%% input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define -input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:c:1000; % Array of thickes - clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; +c = 1e6; figure(1); for i=1:length(output_multislice.data) - c = 1e6; - - m2psi_coh = abs(output_multislice.data(i).psi_coh).^2; - m2psi_coh = log(1+c*m2psi_coh/max(m2psi_coh(:))); - + m2psi_coh = abs(output_multislice.data(i).psi_coh).^2; if(isfield(output_multislice.data, 'm2psi_tot')) - m2psi_tot = log(1+c*output_multislice.data(i).m2psi_tot/max(output_multislice.data(i).m2psi_tot(:))); + m2psi_tot = output_multislice.data(i).m2psi_tot; else m2psi_tot = m2psi_coh; - end - - I_min = min([min(m2psi_tot(:)), min(m2psi_coh(:))]); - I_max = max([max(m2psi_tot(:)), max(m2psi_coh(:))]); - + end + + m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); + m2psi_coh = log(1+c*m2psi_coh/max(m2psi_coh(:))); + + I_min = min([min(m2psi_coh(:)), min(m2psi_tot(:))]); + I_max = max([max(m2psi_coh(:)), max(m2psi_tot(:))]); + subplot(1, 2, 1); imagesc(m2psi_tot, [I_min I_max]); - title(strcat('Total intensity - Thick = ', num2str(i))); + title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); axis image; colormap gray; + colorbar subplot(1, 2, 2); imagesc(m2psi_coh, [I_min I_max]); - title(strcat('Coherent intensity - Thick = ', num2str(i))); + title(strcat('Coherent intensity - Thick = ', num2str(output_multislice.thick(i)))); axis image; colormap gray; + colorbar pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_EWRS.m b/mex_examples_multem/example_MULTEM_EWRS.m index 5bb30ad6..86d69006 100644 --- a/mex_examples_multem/example_MULTEM_EWRS.m +++ b/mex_examples_multem/example_MULTEM_EWRS.m @@ -8,77 +8,97 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multislice.simulation_type = 52; -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 +input_multislice.simulation_type = 52; -input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 10; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% na = 8; nb = 8; nc = 10; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = SrTiO3001Crystal(na, nb, nc, ncu, rms3d); -show_crystal(1, input_multislice.spec_atoms); -view([0 0 1]); +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multislice.iw_psi = read_psi_0_multem(input_multislice.nx, input_multislice.ny); % user define incident wave +input_multislice.iw_psi = 0; % user define incident wave input_multislice.iw_x = input_multislice.spec_lx/2; % x position input_multislice.iw_y = input_multislice.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_m = 0; % Vortex momentum -input_multislice.cond_lens_c_10 = 1110; % Defocus (Å) -input_multislice.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) +input_multislice.cond_lens_m = 0; % Vortex momentum +input_multislice.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multislice.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle -input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multislice.cond_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% zero defocus reference %%%%%%%%%%%% input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define -input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:2*c:1000; % Array of thickes - clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); @@ -91,17 +111,22 @@ m2psi_tot = output_multislice.data(i).m2psi_tot; else m2psi_tot = m2psi_coh; - end + end + I_min = min([min(m2psi_coh(:)), min(m2psi_tot(:))]); + I_max = max([max(m2psi_coh(:)), max(m2psi_tot(:))]); + subplot(1, 2, 1); - imagesc(m2psi_tot); + imagesc(m2psi_tot, [I_min I_max]); title(strcat('Total intensity - Thick = ', num2str(i))); axis image; colormap gray; + colorbar subplot(1, 2, 2); - imagesc(m2psi_coh); + imagesc(m2psi_coh, [I_min I_max]); title(strcat('Coherent intensity - Thick = ', num2str(i))); axis image; colormap gray; + colorbar pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_EWRS_till_illumination.m b/mex_examples_multem/example_MULTEM_EWRS_till_illumination.m index 2a88e9e6..ef7ac5ce 100644 --- a/mex_examples_multem/example_MULTEM_EWRS_till_illumination.m +++ b/mex_examples_multem/example_MULTEM_EWRS_till_illumination.m @@ -1,6 +1,6 @@ % output_multislice = il_MULTEM(system_conf, input_multislice) perform TEM simulation % -% Exit wave real space (EWRS) simulation using till illumination +% Exit wave real space (EWRS) simulation % % All parameters of the input_multislice structure are explained in multem_default_values() % @@ -8,74 +8,97 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 52; -input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 10; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 3.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -na = 4; nb = 4; nc = 15; ncu = 2; rms3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8; nb = 8; nc = 10; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... -, a, b, c, input_multislice.spec_dz] = Cu001Crystal(na, nb, nc, ncu, rms3d); +, a, b, c, input_multislice.spec_dz] = SrTiO3001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 3.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multislice.iw_psi = 0; % user define incident wave +input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multislice.iw_psi = 0; % user define incident wave input_multislice.iw_x = input_multislice.spec_lx/2; % x position input_multislice.iw_y = input_multislice.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_m = 0; % Vortex momentum -input_multislice.cond_lens_c_10 = 1110; % Defocus (Å) -input_multislice.cond_lens_c_30 = 3.3; % Third order spherical aberration (mm) +input_multislice.cond_lens_m = 0; % Vortex momentum +input_multislice.cond_lens_c_10 = 140.0312; % Defocus (Å) +input_multislice.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle -input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multislice.cond_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% zero defocus reference %%%%%%%%%%%% input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define -input_multislice.thick_type = 3; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:2*c:1000; % Array of thickes - clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); @@ -94,11 +117,13 @@ title(strcat('Total intensity - Thick = ', num2str(i))); axis image; colormap gray; + colorbar subplot(1, 2, 2); imagesc(m2psi_coh); title(strcat('Coherent intensity - Thick = ', num2str(i))); axis image; colormap gray; + colorbar pause(0.25); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_HCI.m b/mex_examples_multem/example_MULTEM_HCI.m deleted file mode 100644 index 2d311cfa..00000000 --- a/mex_examples_multem/example_MULTEM_HCI.m +++ /dev/null @@ -1,88 +0,0 @@ -% output_multislice = il_MULTEM(system_conf, input_multislice) perform TEM simulation -% -% Hollow cone illumination (HCI) simulation -% -% All parameters of the input_multislice structure are explained in multem_default_values() -% -% Copyright 2017 Ivan Lobato - -clear all; clc; - -input_multislice = multem_default_values(); % Load default values; - -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; -system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; - -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, -% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multislice.simulation_type = 42; -input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 - -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 5; % true: phonon configuration, false: number of frozen phonon configurations - -input_multislice.illumination_model = 2; % 1: coherente mode, 4: Numerical integration -input_multislice.temporal_spatial_incoh = 1; % 1: Spatial and temporal, 2: Temporal, 3: Spatial - -input_multislice.bwl = 0; - -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) - -na = 8; nb = 8; nc = 10; ncu = 2; rms3d = 0.085; - -[input_multislice.spec_atoms, input_multislice.spec_lx... -, input_multislice.spec_ly, input_multislice.spec_lz... -, a, b, c, input_multislice.spec_dz] = Cu001Crystal(na, nb, nc, ncu, rms3d); - -input_multislice.nx = 1024; -input_multislice.ny = 1024; - -%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.obj_lens_m = 0; % Vortex momentum -input_multislice.obj_lens_c_10 = +10; % Defocus (Å) -input_multislice.obj_lens_c_30 = 0.04; % Third order spherical aberration (mm) -input_multislice.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.obj_lens_outer_aper_ang = 21; % Outer aperture (mrad) -input_multislice.obj_lens_sf = 32; % Defocus Spread (Å) -input_multislice.obj_lens_nsf = 16; % Number of integration steps for the defocus Spread -input_multislice.obj_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.obj_lens_nbeta = 8; % Number of integration steps for the divergence semi-angle -input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 -input_multislice.obj_lens_zero_defocus_plane = 0; - -input_multislice.hci_nrot = 30; % number of orientations -input_multislice.hci_theta = 3.0; % Precession angle (degrees) - -input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:c:1000; % Array of thickes - -clear il_MULTEM; -tic; -output_multislice = il_MULTEM(system_conf, input_multislice); -toc; -clear il_MULTEM; - -figure(1); -for i=1:length(output_multislice.data) - imagesc(output_multislice.data(i).m2psi_tot); - title(strcat('Total intensity - Thick = ', num2str(i))); - axis image; - colormap gray; - pause(0.25); -end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_HCTEM.m b/mex_examples_multem/example_MULTEM_HCTEM.m new file mode 100644 index 00000000..1de0dbcf --- /dev/null +++ b/mex_examples_multem/example_MULTEM_HCTEM.m @@ -0,0 +1,104 @@ +% output_multislice = il_MULTEM(system_conf, input_multislice) perform TEM simulation +% +% Hollow cone transmission electron microscopy (HCTEM) simulation +% +% All parameters of the input_multislice structure are explained in multem_default_values() +% +% Copyright 2017 Ivan Lobato + +clear all; clc; + +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; + +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; +system_conf.gpu_device = 0; + +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 +input_multislice.simulation_type = 42; + +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 + +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 + +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) + +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 16; nb = 16; nc = 20; ncu = 2; rms3d = 0.085; + +[input_multislice.spec_atoms, input_multislice.spec_lx... +, input_multislice.spec_ly, input_multislice.spec_lz... +, a, b, c, input_multislice.spec_dz] = Cu001Crystal(na, nb, nc, ncu, rms3d); + +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; +input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_mrad_2_sigma(input_multislice.E_0, 0.02); % mrad to standard deviation +input_multislice.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.obj_lens_m = 0; % Vortex momentum +input_multislice.obj_lens_c_10 = 20; % Defocus (Å) +input_multislice.obj_lens_c_30 = 0.04; % Third order spherical aberration (mm) +input_multislice.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multislice.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.obj_lens_outer_aper_ang = 25.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.obj_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.obj_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%HCI %%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.hci_nrot = 30; % number of orientations +input_multislice.hci_theta = 3.0; % Precession angle (degrees) + +clear il_MULTEM; +tic; +output_multislice = il_MULTEM(system_conf, input_multislice); +toc; + +figure(1); +for i=1:length(output_multislice.data) + imagesc(output_multislice.data(i).m2psi_tot); + title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); + axis image; + colormap gray; + pause(0.25); +end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_HRTEM.m b/mex_examples_multem/example_MULTEM_HRTEM.m index 726765c8..a66a0195 100644 --- a/mex_examples_multem/example_MULTEM_HRTEM.m +++ b/mex_examples_multem/example_MULTEM_HRTEM.m @@ -8,80 +8,96 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 32; -input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_dim = 110; -input_multislice.pn_seed = 300183; -input_multislice.pn_single_conf = 0; % 1: true, 0:false -input_multislice.pn_nconf = 10; +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multislice.temporal_spatial_incoh = 1; % 1: Spatial and temporal, 2: Temporal, 3: Spatial - -input_multislice.bwl = 0; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -na = 27; nb = 27; nc = 13; ncu = 2; rms3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 16; nb = 16; nc = 20; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = Cu001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle + %%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_mrad_2_sigma(input_multislice.E_0, 0.02); % mrad to standard deviation +input_multislice.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.obj_lens_m = 0; % Vortex momentum -input_multislice.obj_lens_c_10 = 20; % Defocus (Å) +input_multislice.obj_lens_m = 0; % Vortex momentum +input_multislice.obj_lens_c_10 = 20; % Defocus (Å) input_multislice.obj_lens_c_30 = 0.04; % Third order spherical aberration (mm) input_multislice.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) -input_multislice.obj_lens_sf = 32; % Defocus Spread (Å) -input_multislice.obj_lens_nsf = 16; % Number of integration steps for the defocus Spread -input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multislice.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.obj_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.obj_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.obj_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.obj_lens_zero_defocus_plane = 0; -input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:c:1000; % Array of thickes - clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; -clear il_MULTEM; figure(1); for i=1:length(output_multislice.data) imagesc(output_multislice.data(i).m2psi_tot); - title(strcat('Total intensity - Thick = ', num2str(i))); + title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); axis image; colormap gray; pause(0.25); diff --git a/mex_examples_multem/example_MULTEM_ISTEM.m b/mex_examples_multem/example_MULTEM_ISTEM.m index 41f39d92..b836b0b3 100644 --- a/mex_examples_multem/example_MULTEM_ISTEM.m +++ b/mex_examples_multem/example_MULTEM_ISTEM.m @@ -8,99 +8,122 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 -input_multislice.simulation_type = 12; -input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 +input_multislice.simulation_type = 12; -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 5; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 200; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -na = 4; nb = 4; nc = 10; ncu = 2; rms3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8; nb = 8; nc = 5; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = Au001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 200; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 1; % 1: coherente mode, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% input_multislice.cond_lens_m = 0; % Vortex momentum -input_multislice.cond_lens_c_10 = 15.836; % Defocus (Å) -input_multislice.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) -input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multislice.cond_lens_c_10 = 15.836; % Defocus (Å) +input_multislice.cond_lens_c_30 = 1e-03; % Third order spherical aberration (mm) +input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle -input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multislice.cond_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.obj_lens_m = 0; % Vortex momentum -input_multislice.obj_lens_c_10 = 0; % Defocus (Å) +input_multislice.obj_lens_m = 0; % Vortex momentum +input_multislice.obj_lens_c_10 = 0; % Defocus (Å) input_multislice.obj_lens_c_30 = 0; % Third order spherical aberration (mm) input_multislice.obj_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) -input_multislice.obj_lens_sf = 0; % Defocus Spread (Å) -input_multislice.obj_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 +input_multislice.obj_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.obj_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.obj_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) +%%%%%%%%% defocus spread function %%%%%%%%%%%% +input_multislice.obj_lens_dsf_sigma = 0; % standard deviation (Å) +input_multislice.obj_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.scanning_type = 2; % eST_Line = 1, eST_Area = 2 input_multislice.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) input_multislice.scanning_ns = 10; -input_multislice.scanning_x0 = 2*a; -input_multislice.scanning_y0 = 2*b; -input_multislice.scanning_xe = 3*a; -input_multislice.scanning_ye = 3*b; - -input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:2*c:1000; % Array of thickes +input_multislice.scanning_x0 = 3*a; +input_multislice.scanning_y0 = 3*b; +input_multislice.scanning_xe = 4*a; +input_multislice.scanning_ye = 4*b; clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; -clear il_MULTEM; figure(1); for i=1:length(output_multislice.data) imagesc(output_multislice.data(i).m2psi_tot); - title(strcat('Total intensity - Thick = ', num2str(i))); + title(strcat('Total intensity - Thick = ', num2str(output_multislice.thick(i)))); axis image; colormap gray; pause(0.25); diff --git a/mex_examples_multem/example_MULTEM_PED.m b/mex_examples_multem/example_MULTEM_PED.m index 7d24c1c4..3a3cff5c 100644 --- a/mex_examples_multem/example_MULTEM_PED.m +++ b/mex_examples_multem/example_MULTEM_PED.m @@ -8,70 +8,92 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 41; -input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 5; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.illumination_model = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multislice.temporal_spatial_incoh = 1; % 1: Spatial and temporal, 2: Temporal, 3: Spatial - -input_multislice.bwl = 1; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -na = 8; nb = 8; nc = 10; ncu = 2; rms3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 16; nb = 16; nc = 30; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = Cu001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 1024; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial + +%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_mrad_2_sigma(input_multislice.E_0, 0.02); % mrad to standard deviation +input_multislice.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%% aperture radius %%%%%%%%%%%%%%%%% +input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.obj_lens_outer_aper_ang = 0.0; % Outer aperture (mrad) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PED %%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.ped_nrot = 30; % number of orientations input_multislice.ped_theta = 3.0; % Precession angle (degrees) -input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = 0:c:1000; % Array of thickes - clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; -clear il_MULTEM; +c = 1e7; figure(1); for i=1:length(output_multislice.data) - c = 1e6; - m2psi_tot = log(1+c*output_multislice.data(i).m2psi_tot/max(output_multislice.data(i).m2psi_tot(:))); + m2psi_tot = output_multislice.data(i).m2psi_tot; + m2psi_tot = log(1+c*m2psi_tot/max(m2psi_tot(:))); I_min = min(m2psi_tot(:)); I_max = max(m2psi_tot(:)); - imagesc(m2psi_tot, [I_min I_max]); + imagesc(output_multislice.x, output_multislice.y, m2psi_tot, [I_min I_max]); title(strcat('Total intensity - Thick = ', num2str(i))); axis image; colormap gray; - pause(0.25); + pause(0.5); end \ No newline at end of file diff --git a/mex_examples_multem/example_MULTEM_STEM.m b/mex_examples_multem/example_MULTEM_STEM.m index 3716e557..4b8039b4 100644 --- a/mex_examples_multem/example_MULTEM_STEM.m +++ b/mex_examples_multem/example_MULTEM_STEM.m @@ -8,42 +8,59 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 11; -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 10; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 10; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -na = 8; nb = 8; nc = 25; ncu = 2; rms3d = 0.0942; % 0.085; +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8; nb = 8; nc = 5; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = Au001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 4096; -input_multislice.ny = 4096; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = c:c:1000; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; +input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 1; % 1: coherente mode, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% input_multislice.cond_lens_m = 0; % Vortex momentum @@ -56,14 +73,22 @@ input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle -input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multislice.cond_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.scanning_type = 2; % eST_Line = 1, eST_Area = 2 input_multislice.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) input_multislice.scanning_ns = 20; @@ -72,26 +97,17 @@ input_multislice.scanning_xe = 4*a; input_multislice.scanning_ye = 4*b; -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Detector %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Detector %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.detector.type = 1; % eDT_Circular = 1, eDT_Radial = 2, eDT_Matrix = 3 input_multislice.detector.cir(1).inner_ang = 40; % Inner angle(mrad) input_multislice.detector.cir(1).outer_ang = 160; % Outer angle(mrad) input_multislice.detector.cir(2).inner_ang = 80; % Inner angle(mrad) input_multislice.detector.cir(2).outer_ang = 160; % Outer angle(mrad) -input_multislice.detector.radial(1).x = 0; % radial detector angle(mrad) -input_multislice.detector.radial(1).fx = 0; % radial sensitivity value -input_multislice.detector.matrix(1).R = 0; % 2D detector angle(mrad) -input_multislice.detector.matrix(1).fR = 0; % 2D sensitivity value - -input_multislice.thick_type = 2; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 -input_multislice.thick = c:c:1000; % Array of thickes - clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; -clear il_MULTEM; figure(1); for i=1:length(output_multislice.data) @@ -99,7 +115,7 @@ for j=1:ndet subplot(1, ndet, j); imagesc(output_multislice.data(i).image_tot(j).image); - title(strcat('Thk = ', num2str(i), ', det = ', num2str(j))); + title(strcat('Thk = ', num2str(i), ', det = ', num2str(output_multislice.thick(j)))); axis image; colormap jet; end diff --git a/mex_examples_multem/example_MULTEM_STEM_EELS.m b/mex_examples_multem/example_MULTEM_STEM_EELS.m index 008c03ec..754728c2 100644 --- a/mex_examples_multem/example_MULTEM_STEM_EELS.m +++ b/mex_examples_multem/example_MULTEM_STEM_EELS.m @@ -8,66 +8,93 @@ clear all; clc; -input_multislice = multem_default_values(); % Load default values; +%%%%%%%%%%%%%%%%%% Load multem default parameter %%%%%%%%$$%%%%%%%%% +input_multislice = multem_default_values(); % Load default values; -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; +%%%%%%%%%%%%%%%%%%%%% Set system configuration %%%%%%%%%%%%%%%%%%%%% +system_conf.precision = 1; % eP_Float = 1, eP_double = 2 +system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 +system_conf.cpu_nthread = 1; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +%%%%%%%%%%%%%%%%%%%% Set simulation experiment %%%%%%%%%%%%%%%%%%%%% +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 61; -input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 -input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 -input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.pn_dim = 110; % phonon dimensions (xyz) -input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) -input_multislice.pn_nconf = 5; % true: phonon configuration, false: number of frozen phonon configurations +%%%%%%%%%%%%%% Electron-Specimen interaction model %%%%%%%%%%%%%%%%% +input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 +input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 -input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false +%%%%%%%%%%%%%%%%%%%%%%% Potential slicing %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; % Till ilumination (º) -input_multislice.phi = 0.0; % Till ilumination (º) +%%%%%%%%%%%%%%% Electron-Phonon interaction model %%%%%%%%%%%%%%%%%% +input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 +input_multislice.pn_coh_contrib = 0; +input_multislice.pn_single_conf = 0; % 1: true, 0:false (extract single configuration) +input_multislice.pn_nconf = 5; % true: specific phonon configuration, false: number of frozen phonon configurations +input_multislice.pn_dim = 110; % phonon dimensions (xyz) +input_multislice.pn_seed = 300183; % Random seed(frozen phonon) -na = 4; nb = 4; nc = 10; ncu = 2; rms3d = 0.085; +%%%%%%%%%%%%%%%%%%%%%%% Specimen information %%%%%%%%%%%%%%%%%%%%%%% +na = 8; nb = 8; nc = 5; ncu = 2; rms3d = 0.085; [input_multislice.spec_atoms, input_multislice.spec_lx... , input_multislice.spec_ly, input_multislice.spec_lz... , a, b, c, input_multislice.spec_dz] = SrTiO3001Crystal(na, nb, nc, ncu, rms3d); -input_multislice.nx = 512; -input_multislice.ny = 512; +%%%%%%%%%%%%%%%%%%%%%% Specimen thickness %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.thick_type = 1; % eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 +input_multislice.thick = 0; % Array of thickes (Å) + +%%%%%%%%%%%%%%%%%%%%%% x-y sampling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.nx = 1024; +input_multislice.ny = 1024; +input_multislice.bwl = 0; % Band-width limit, 1: true, 0:false + +%%%%%%%%%%%%%%%%%%%% Microscope parameters %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.E_0 = 300; % Acceleration Voltage (keV) +input_multislice.theta = 0.0; % Till ilumination (º) +input_multislice.phi = 0.0; % Till ilumination (º) + +%%%%%%%%%%%%%%%%%%%%%% Illumination model %%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.illumination_model = 1; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multislice.iw_psi = 0; % user define incident wave +input_multislice.iw_type = 4; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multislice.iw_psi = 0; % user define incident wave input_multislice.iw_x = input_multislice.spec_lx/2; % x position input_multislice.iw_y = input_multislice.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_m = 0; % Vortex momentum -input_multislice.cond_lens_c_10 = 88.7414; % Defocus (Å) -input_multislice.cond_lens_c_30 = 0.04; % Third order spherical aberration (mm) -input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) -input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) -input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STEM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +input_multislice.cond_lens_m = 0; % Vortex momentum +input_multislice.cond_lens_c_10 = 88.7414; % Defocus (Å) +input_multislice.cond_lens_c_30 = 0.04; % Third order spherical aberration (mm) +input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) +input_multislice.cond_lens_c_12 = 0.0; % Twofold astigmatism (Å) +input_multislice.cond_lens_phi_12 = 0.0; % Azimuthal angle of the twofold astigmatism (º) +input_multislice.cond_lens_c_23 = 0.0; % Threefold astigmatism (Å) +input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) +input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) +input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) + +%%%%%%%%% defocus spread function %%%%%%%%%%%% +dsf_sigma = il_iehwgd_2_sigma(32); % from defocus spread to standard deviation +input_multislice.cond_lens_dsf_sigma = dsf_sigma; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 5; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%%% source spread function %%%%%%%%%%%% +ssf_sigma = il_hwhm_2_sigma(0.45); % half width at half maximum to standard deviation +input_multislice.obj_lens_ssf_sigma = ssf_sigma; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.obj_lens_ssf_npoints = 4; % # of integration points. It will be only used if illumination_model=4 + +%%%%%%%%% zero defocus reference %%%%%%%%%%%% +input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 +input_multislice.cond_lens_zero_defocus_plane = 0; + +%%%%%%%%%%%%%%%%%%%%%%%%%% scanning area %%%%%%%%%%%%%%%%%%%%%%%%%%%% input_multislice.scanning_type = 1; % eST_Line = 1, eST_Area = 2 input_multislice.scanning_periodic = 1; % 1: true, 0:false (periodic boundary conditions) input_multislice.scanning_ns = 10; % number of sampling points @@ -98,25 +125,10 @@ tic; output_multislice = il_MULTEM(system_conf, input_multislice); toc; -clear il_MULTEM; -figure(1); +figure(1); clf; for i=1:length(output_multislice.data) - imagesc(output_multislice.data(i).image_tot(1).image); - title(strcat('Thk = ', num2str(i), ', det = ', num2str(j))); - axis image; - colormap gray; + plot(output_multislice.data(i).image_tot(1).image); + title(strcat('Thk = ', num2str(output_multislice.thick(i)))); pause(0.25); -end - -% cc = [1 0 1; 1 0 0; 0 0 1; 0 0 0]; -% for i=1:4 -% input_multislice.eels_channelling_type = i; -% clear il_MULTEM; -% tic; -% [eels] = il_MULTEM(system_conf, input_multislice); -% toc; -% figure(1); -% hold on; -% plot(eels, 'color', cc(i, :)); -% end \ No newline at end of file +end \ No newline at end of file diff --git a/mex_examples_multem/example_feg.m b/mex_examples_multem/example_feg.m index 60fcc80c..fc629b28 100644 --- a/mex_examples_multem/example_feg.m +++ b/mex_examples_multem/example_feg.m @@ -1,6 +1,6 @@ clear all; clc; -Z = 6; +Z = 78; occ = 1; region = 0; charge = 0; diff --git a/mex_examples_multem/example_incident_wave_1.m b/mex_examples_multem/example_incident_wave_1.m index 745e85b5..87c591ea 100644 --- a/mex_examples_multem/example_incident_wave_1.m +++ b/mex_examples_multem/example_incident_wave_1.m @@ -4,10 +4,8 @@ system_conf.precision = 1; % eP_Float = 1, eP_double = 2 system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; system_conf.cpu_nthread = 4; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; input_multislice.E_0 = 300; % Acceleration Voltage (keV) input_multislice.theta = 0.0; @@ -36,10 +34,10 @@ input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle +input_multislice.cond_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +input_multislice.cond_lens_ssf_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 8; % # of integration points. It will be only used if illumination_model=4 input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; diff --git a/mex_examples_multem/example_incident_wave_2.m b/mex_examples_multem/example_incident_wave_2.m index b8b5926c..a2d38428 100644 --- a/mex_examples_multem/example_incident_wave_2.m +++ b/mex_examples_multem/example_incident_wave_2.m @@ -4,10 +4,8 @@ system_conf.precision = 1; % eP_Float = 1, eP_double = 2 system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; system_conf.cpu_nthread = 4; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; input_multislice.E_0 = 200; % Acceleration Voltage (keV) input_multislice.theta = 0.0; @@ -36,10 +34,10 @@ input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle +input_multislice.cond_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +input_multislice.cond_lens_ssf_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 8; % # of integration points. It will be only used if illumination_model=4 for x = (0.4:0.025:0.6)*input_multislice.spec_lx for y = (0.4:0.025:0.6)*input_multislice.spec_ly diff --git a/mex_examples_multem/example_incident_wave_3.m b/mex_examples_multem/example_incident_wave_3.m index 8c4a77c1..98e2b471 100644 --- a/mex_examples_multem/example_incident_wave_3.m +++ b/mex_examples_multem/example_incident_wave_3.m @@ -4,10 +4,8 @@ system_conf.precision = 1; % eP_Float = 1, eP_double = 2 system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; system_conf.cpu_nthread = 4; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; input_multislice.E_0 = 200; % Acceleration Voltage (keV) input_multislice.theta = 0.00; @@ -20,7 +18,7 @@ input_multislice.ny = 1024; %%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.iw_type = 3; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto +input_multislice.iw_type = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto input_multislice.iw_psi = read_psi_0_multem(input_multislice.nx, input_multislice.ny); % user define incident wave sum(abs(input_multislice.iw_psi(:)).^2) input_multislice.iw_x = 0.0; % x position @@ -37,10 +35,10 @@ input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle +input_multislice.cond_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +input_multislice.cond_lens_ssf_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 8; % # of integration points. It will be only used if illumination_model=4 input_multislice.iw_x = 0.5*input_multislice.spec_lx; input_multislice.iw_y = 0.5*input_multislice.spec_ly; @@ -48,7 +46,7 @@ df0 = -15.836; ax = 0:input_multislice.spec_lx/input_multislice.nx:input_multislice.spec_lx; ay = 0:input_multislice.spec_ly/input_multislice.ny:input_multislice.spec_ly; -for df = 0 +for df = 20 input_multislice.cond_lens_c_10 = df; %Angs tic; diff --git a/mex_examples_multem/example_incident_wave_4.m b/mex_examples_multem/example_incident_wave_4.m index 42fe9085..b8bda679 100644 --- a/mex_examples_multem/example_incident_wave_4.m +++ b/mex_examples_multem/example_incident_wave_4.m @@ -7,7 +7,6 @@ system_conf.cpu_ncores = 1; % Number of Cores CPU (It will be used in the future) system_conf.cpu_nthread = 4; % Number of CPU threads system_conf.gpu_device = 0; % GPU device (i.e. 0, 1, 2, ... ) -system_conf.gpu_nstream = 1; % Number of streams input_multislice.E_0 = 300; % Acceleration Voltage (keV) input_multislice.theta = 0.0; @@ -39,10 +38,10 @@ input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.cond_lens_inner_aper_ang = 0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle +input_multislice.cond_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +input_multislice.cond_lens_ssf_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 8; % # of integration points. It will be only used if illumination_model=4 input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; input_multislice.cond_lens_c_10 = il_scherzer_defocus(input_multislice.E_0, input_multislice.cond_lens_c_30); diff --git a/mex_examples_multem/example_microscope_aberrations.m b/mex_examples_multem/example_microscope_aberrations.m index fc8f6f46..a8e2a977 100644 --- a/mex_examples_multem/example_microscope_aberrations.m +++ b/mex_examples_multem/example_microscope_aberrations.m @@ -4,12 +4,10 @@ system_conf.precision = 1; % eP_Float = 1, eP_double = 2 system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; system_conf.cpu_nthread = 4; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 52; input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 @@ -23,7 +21,7 @@ input_multislice.pn_nconf = 5; input_multislice.illumination_model = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multislice.temporal_spatial_incoh = 1; % 1: Spatial and temporal, 2: Temporal, 3: Spatial +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial input_multislice.bwl = 0; @@ -47,7 +45,7 @@ input_multislice.iw_y = input_multislice.spec_ly/2; % y position %%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) +input_multislice.cond_lens_ssf_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) %%%%%%%%%%%%%%%%%%%%%%%% Objective lens %%%%%%%%%%%%%%%%%%%%%%%% input_multislice.obj_lens_m = 0; % Vortex momentum @@ -60,12 +58,12 @@ input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) -input_multislice.obj_lens_sf = 32; % Defocus Spread (Å) -input_multislice.obj_lens_nsf = 10; % # integration steps for the defocus Spread. It will be only used if illumination_model=4 +input_multislice.obj_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.obj_lens_dsf_npoints = 10; % # integration steps for the defocus Spread. It will be only used if illumination_model=4 input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; % It will be only used if obj_lens_zero_defocus_type = eZDT_User_Define -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 52; clear il_MULTEM; @@ -73,7 +71,7 @@ output_multislice_0 = il_MULTEM(system_conf, input_multislice); toc; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 32; clear il_MULTEM; diff --git a/mex_examples_multem/example_probe_dependence.m b/mex_examples_multem/example_probe_dependence.m deleted file mode 100644 index da0c1e3d..00000000 --- a/mex_examples_multem/example_probe_dependence.m +++ /dev/null @@ -1,119 +0,0 @@ -clear all; clc; - -input_multislice = multem_default_values(); % Load default values; - -system_conf.precision = 1; % eP_Float = 1, eP_double = 2 -system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; -system_conf.cpu_nthread = 4; -system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; - -input_multislice.E_0 = 300; % Acceleration Voltage (keV) -input_multislice.theta = 0.0; -input_multislice.phi = 0.0; - -input_multislice.spec_lx = 100; -input_multislice.spec_ly = 100; - -input_multislice.nx = 1024; -input_multislice.ny = 1024; - -%%%%%%%%%%%%%%%%%%%%%%%%%%% Incident wave %%%%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.iw_type = 2; % 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto -input_multislice.iw_psi = read_psi_0_multem(input_multislice.nx, input_multislice.ny); % user define incident wave -input_multislice.iw_x = 0.0; % x position -input_multislice.iw_y = 0.0; % y position - -%%%%%%%%%%%%%%%%%%%%%%%% condenser lens %%%%%%%%%%%%%%%%%%%%%%%% -input_multislice.cond_lens_m = 0; % Vortex momentum -input_multislice.cond_lens_c_10 = 0; % Defocus (Å) -input_multislice.cond_lens_c_30 = 0.001; % Third order spherical aberration (mm) -input_multislice.cond_lens_c_50 = 0.00; % Fifth order spherical aberration (mm) -input_multislice.cond_lens_c_12 = 0; % Twofold astigmatism (Å) -input_multislice.cond_lens_phi_12 = 0; % Azimuthal angle of the twofold astigmatism (º) -input_multislice.cond_lens_c_23 = 0; % Threefold astigmatism (Å) -input_multislice.cond_lens_phi_23 = 0; % Azimuthal angle of the threefold astigmatism (º) -input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) -input_multislice.cond_lens_outer_aper_ang = 21.0; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle - -input_multislice.iw_x = 0.5*input_multislice.spec_lx; -input_multislice.iw_y = 0.5*input_multislice.spec_ly; - - -df = input_multislice.cond_lens_c_10; -% ax = 0:input_multislice.spec_lx/input_multislice.nx:input_multislice.spec_lx; -% ay = 0:input_multislice.spec_ly/input_multislice.ny:input_multislice.spec_ly; - -figure(2); -subplot(1, 2, 1); -input_multislice.cond_lens_c_10 = -100; -output_incident_wave = il_incident_wave(system_conf, input_multislice); -imagesc(abs(output_incident_wave.psi_0).^2); -axis image; -subplot(1, 2, 2); -input_multislice.cond_lens_c_10 = 100; -output_incident_wave = il_incident_wave(system_conf, input_multislice); -imagesc(abs(output_incident_wave.psi_0).^2); -axis image; - -xyr = 1.5; -af = -4:0.05:4; -dx = input_multislice.spec_lx/input_multislice.nx; -ax = (0:1:(input_multislice.nx/2-1))*dx; - -yc = input_multislice.ny/2+1; -xc = input_multislice.nx/2+1; -clear legend_info; -im = zeros(length(af), input_multislice.nx/2); -figure(1); clf; -ic = 1; -disp(il_scherzer_defocus(300, input_multislice.cond_lens_c_30)); -% input_multislice.cond_lens_outer_aper_ang = il_scherzer_aperture(300, input_multislice.cond_lens_c_30); -% input_multislice.cond_lens_outer_aper_ang = 35; -y_s = zeros(length(af), 1); -for f = af - input_multislice.cond_lens_c_10 = f; -% tic; - output_incident_wave = il_incident_wave(system_conf, input_multislice); -% toc; - y_s(ic) = max(abs(output_incident_wave.psi_0(:))); - y = abs(output_incident_wave.psi_0(yc, xc:end)); - im(ic, :) = y; -% hold all; -% plot(abs(y)); -% legend_info{ic} = ['defocus = ', num2str(f, '%5.2f')]; - ic = ic + 1; -end -% xlim([0 100]); -% xlabel('position (Å)'); -% ylabel('Defocus'); -% set(gca,'FontSize',12,'LineWidth',1.5,'PlotBoxAspectRatio',[xyr 1 1]); -% legend(legend_info); - -figure(1); clf; -subplot(1, 2, 1); -imagesc(ax, af, im); -colormap jet; -xlim([0 2]); -subplot(1, 2, 2); -plot(af, y_s, '-*r'); -% psi_0 = flipud(output_incident_wave.psi_0); -% -% figure(2); -% subplot(1, 2, 1); -% imagesc(ax, ay, abs(psi_0).^2); -% title(strcat('intensity - df = ', num2str(df))); -% axis image; -% colormap gray; -% -% subplot(1, 2, 2); -% imagesc(ax, ay, angle(psi_0)); -% title(strcat('phase - df = ', num2str(df))); -% axis image; -% colormap gray; -% pause(0.1); \ No newline at end of file diff --git a/mex_examples_multem/example_projected_potential.m b/mex_examples_multem/example_projected_potential.m index 8b591cb4..078bf92b 100644 --- a/mex_examples_multem/example_projected_potential.m +++ b/mex_examples_multem/example_projected_potential.m @@ -4,10 +4,8 @@ system_conf.precision = 1; % eP_Float = 1, eP_double = 2 system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; system_conf.cpu_nthread = 4; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; input_multislice.pn_model = 3; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 diff --git a/mex_examples_multem/example_propagate.m b/mex_examples_multem/example_propagate.m index dbc6b7bd..662a2638 100644 --- a/mex_examples_multem/example_propagate.m +++ b/mex_examples_multem/example_propagate.m @@ -4,12 +4,10 @@ system_conf.precision = 1; % eP_Float = 1, eP_double = 2 system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; system_conf.cpu_nthread = 4; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 52; input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 @@ -23,7 +21,7 @@ input_multislice.pn_nconf = 5; input_multislice.illumination_model = 2; % 1: coherente mode, 2: Partial coherente mode, 3: transmission cross coefficient, 4: Numerical integration -input_multislice.temporal_spatial_incoh = 1; % 1: Spatial and temporal, 2: Temporal, 3: Spatial +input_multislice.temporal_spatial_incoh = 1; % 1: Temporal and Spatial, 2: Temporal, 3: Spatial input_multislice.bwl = 0; @@ -46,7 +44,7 @@ input_multislice.iw_x = input_multislice.spec_lx/2; % x position input_multislice.iw_y = input_multislice.spec_ly/2; % y position -input_multislice.simulation_type = 52; % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, eTEMST_EELS=61, eTEMST_EFTEM=62 +input_multislice.simulation_type = 52; % eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, eTEMST_EELS=61, eTEMST_EFTEM=62 clear il_MULTEM; tic; output_multislice = il_MULTEM(system_conf, input_multislice); diff --git a/mex_examples_multem/example_specimen_rotation.m b/mex_examples_multem/example_specimen_rotation.m index 4daabb2b..daba4e05 100644 --- a/mex_examples_multem/example_specimen_rotation.m +++ b/mex_examples_multem/example_specimen_rotation.m @@ -20,13 +20,9 @@ theta = 45; % angle (º) u0 = [1 1 0]; % unitary vector -rot_point_type = 0; % 1: geometric center, 2: User define +rot_point_type = 1; % 1: geometric center, 2: User define p0 = [0 0 0]; % rotation point -% p0 = mean(atoms(:,2:4)); -% [~, ii] = sort(sqrt(sum((atoms(:,2:4)-p0).^2, 2))); -% p0 = atoms(ii(1), 2:4); - % rotate specimen atoms_r = il_spec_rot(atoms, theta, u0, rot_point_type, p0); figure(1); clf; diff --git a/mex_examples_multem/example_specimen_slicing_rotation.m b/mex_examples_multem/example_specimen_slicing_rotation.m index baebe067..af130821 100644 --- a/mex_examples_multem/example_specimen_slicing_rotation.m +++ b/mex_examples_multem/example_specimen_slicing_rotation.m @@ -12,12 +12,10 @@ system_conf.precision = 1; % eP_Float = 1, eP_double = 2 system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; system_conf.cpu_nthread = 4; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; -% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCI=42, eTEMST_EWFS=51, eTEMST_EWRS=52, +% eTEMST_STEM=11, eTEMST_ISTEM=12, eTEMST_CBED=21, eTEMST_CBEI=22, eTEMST_ED=31, eTEMST_HRTEM=32, eTEMST_PED=41, eTEMST_HCTEM=42, eTEMST_EWFS=51, eTEMST_EWRS=52, % eTEMST_EELS=61, eTEMST_EFTEM=62, eTEMST_ProbeFS=71, eTEMST_ProbeRS=72, eTEMST_PPFS=81, eTEMST_PPRS=82,eTEMST_TFFS=91, eTEMST_TFRS=92 input_multislice.simulation_type = 52; input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 diff --git a/mex_examples_multem/example_transmission_function.m b/mex_examples_multem/example_transmission_function.m index ec1423ab..5af55f0d 100644 --- a/mex_examples_multem/example_transmission_function.m +++ b/mex_examples_multem/example_transmission_function.m @@ -7,7 +7,6 @@ system_conf.cpu_ncores = 1; % Number of Cores CPU (It will be used in the future) system_conf.cpu_nthread = 4; % Number of CPU threads system_conf.gpu_device = 0; % GPU device (i.e. 0, 1, 2, ... ) -system_conf.gpu_nstream = 1; % Number of streams input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 diff --git a/mex_examples_multem/example_wave_function.m b/mex_examples_multem/example_wave_function.m index d90773ea..5fb3bbb8 100644 --- a/mex_examples_multem/example_wave_function.m +++ b/mex_examples_multem/example_wave_function.m @@ -4,15 +4,14 @@ system_conf.precision = 1; % eP_Float = 1, eP_double = 2 system_conf.device = 2; % eD_CPU = 1, eD_GPU = 2 -system_conf.cpu_ncores = 1; system_conf.cpu_nthread = 4; system_conf.gpu_device = 0; -system_conf.gpu_nstream = 1; % eTEMST_EWFS=51, eTEMST_EWRS=52 input_multislice.simulation_type = 52; input_multislice.interaction_model = 1; % eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 input_multislice.potential_slicing = 1; % ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 + input_multislice.potential_type = 6; % ePT_Doyle_0_4 = 1, ePT_Peng_0_4 = 2, ePT_Peng_0_12 = 3, ePT_Kirkland_0_12 = 4, ePT_Weickenmeier_0_12 = 5, ePT_Lobato_0_12 = 6 input_multislice.pn_model = 1; % ePM_Still_Atom = 1, ePM_Absorptive = 2, ePM_Frozen_Phonon = 3 @@ -59,10 +58,10 @@ input_multislice.cond_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.cond_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.cond_lens_outer_aper_ang = 7.50; % Outer aperture (mrad) -input_multislice.cond_lens_sf = 32; % Defocus Spread (Å) -input_multislice.cond_lens_nsf = 10; % Number of integration steps for the defocus Spread -input_multislice.cond_lens_beta = 0.2; % Divergence semi-angle (mrad) -input_multislice.cond_lens_nbeta = 10; % Number of integration steps for the divergence semi-angle +input_multislice.cond_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.cond_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 +input_multislice.cond_lens_ssf_sigma = 0.2; % standard deviation: For parallel ilumination(Å^-1); otherwise (Å) +input_multislice.cond_lens_ssf_npoints = 8; % # of integration points. It will be only used if illumination_model=4 input_multislice.cond_lens_zero_defocus_type = 1; % eZDT_First = 1, eZDT_User_Define = 2 input_multislice.cond_lens_zero_defocus_plane = 0; @@ -77,11 +76,16 @@ input_multislice.obj_lens_phi_23 = 0.0; % Azimuthal angle of the threefold astigmatism (º) input_multislice.obj_lens_inner_aper_ang = 0.0; % Inner aperture (mrad) input_multislice.obj_lens_outer_aper_ang = 24.0; % Outer aperture (mrad) -input_multislice.obj_lens_sf = 32; % Defocus Spread (Å) -input_multislice.obj_lens_nsf = 10; % Number of integration steps for the defocus Spread +input_multislice.obj_lens_dsf_sigma = 32; % standard deviation (Å) +input_multislice.obj_lens_dsf_npoints = 10; % # of integration points. It will be only used if illumination_model=4 input_multislice.obj_lens_zero_defocus_type = 3; % eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 input_multislice.obj_lens_zero_defocus_plane = 0; +input_multislice.output_area_ix_0 = 1; % x-starting pixel +input_multislice.output_area_iy_0 = 1; % y-starting pixel +input_multislice.output_area_ix_e = 1; % x-final pixel +input_multislice.output_area_iy_e = 1; % y-final pixel + clear il_wave_function; tic; ouput_multislice = il_wave_function(system_conf, input_multislice); diff --git a/mex_files_multem/il_MULTEM.cu b/mex_files_multem/il_MULTEM.cu index 82dbcaba..c916f6d7 100644 --- a/mex_files_multem/il_MULTEM.cu +++ b/mex_files_multem/il_MULTEM.cu @@ -7,7 +7,7 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * MULTEM is distributed in the hope that it will be useful, + * MULTEM 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. @@ -26,6 +26,7 @@ #include "output_multislice.hpp" #include "atom_data.hpp" #include "multislice.cuh" +#include "timing.cuh" #include #include "matlab_mex.cuh" @@ -39,8 +40,8 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice using T_r = mt::Value_type; /************************ simulation type **************************/ - input_multislice.simulation_type = mx_get_scalar_field(mx_input_multislice, "simulation_type"); - + input_multislice.simulation_type = mx_get_scalar_field(mx_input_multislice, "simulation_type"); + /*******************************************************************/ input_multislice.interaction_model = mx_get_scalar_field(mx_input_multislice, "interaction_model"); input_multislice.potential_type = mx_get_scalar_field(mx_input_multislice, "potential_type"); @@ -50,7 +51,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.reverse_multislice = mx_get_scalar_field(mx_input_multislice, "reverse_multislice"); /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); + input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); input_multislice.pn_coh_contrib = mx_get_scalar_field(mx_input_multislice, "pn_coh_contrib"); input_multislice.pn_single_conf = mx_get_scalar_field(mx_input_multislice, "pn_single_conf"); input_multislice.pn_nconf = mx_get_scalar_field(mx_input_multislice, "pn_nconf"); @@ -62,9 +63,9 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); auto lz = mx_get_scalar_field(mx_input_multislice, "spec_lz"); auto dz = mx_get_scalar_field(mx_input_multislice, "spec_dz"); - bool pbc_xy = true; + bool pbc_xy = true; - if(input_multislice.is_specimen_required()) + if (input_multislice.is_specimen_required()) { auto atoms = mx_get_matrix_field(mx_input_multislice, "spec_atoms"); @@ -79,14 +80,14 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice auto mx_spec_amorp = mxGetField(mx_input_multislice, 0, "spec_amorp"); mt::Vector, mt::e_host> amorp_lay_info(mxGetN(mx_spec_amorp)); - for(auto i = 0; i(mx_spec_amorp, i, "z_0"); amorp_lay_info[i].z_e = mx_get_scalar_field(mx_spec_amorp, i, "z_e"); amorp_lay_info[i].dz = mx_get_scalar_field(mx_spec_amorp, i, "dz"); } - if(full) + if (full) { input_multislice.atoms.set_crystal_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); input_multislice.atoms.set_amorphous_parameters(amorp_lay_info); @@ -96,17 +97,17 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice /************************ Specimen rotation *************************/ input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); - input_multislice.spec_rot_u0.normalized(); + input_multislice.spec_rot_u0.normalized(); input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); /************************ Specimen thickness ***********************/ input_multislice.thick_type = mx_get_scalar_field(mx_input_multislice, "thick_type"); - if(!input_multislice.is_whole_spec() && full) + if (!input_multislice.is_whole_spec() && full) { auto thick = mx_get_matrix_field(mx_input_multislice, "thick"); mt::assign(thick, input_multislice.thick); - } + } /************************ Potential slicing ************************/ input_multislice.potential_slicing = mx_get_scalar_field(mx_input_multislice, "potential_slicing"); @@ -123,7 +124,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice auto iw_type = mx_get_scalar_field(mx_input_multislice, "iw_type"); input_multislice.set_incident_wave_type(iw_type); - if(input_multislice.is_user_define_wave() && full) + if (input_multislice.is_user_define_wave() && full) { auto iw_psi = mx_get_matrix_field(mx_input_multislice, "iw_psi"); mt::assign(iw_psi, input_multislice.iw_psi); @@ -132,10 +133,10 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice // read iw_x and iw_y auto iw_x = mx_get_matrix_field(mx_input_multislice, "iw_x"); auto iw_y = mx_get_matrix_field(mx_input_multislice, "iw_y"); - - int n_iw_xy = min(iw_x.size(), iw_y.size()); - input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin()+n_iw_xy); - input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin()+n_iw_xy); + + int n_iw_xy = min(iw_x.size(), iw_y.size()); + input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin() + n_iw_xy); + input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin() + n_iw_xy); /********************* Microscope parameter ***********************/ input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); @@ -181,15 +182,18 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.cond_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) input_multislice.cond_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - input_multislice.cond_lens.sf = mx_get_scalar_field(mx_input_multislice, "cond_lens_sf"); // Defocus spread (Angstrom) - input_multislice.cond_lens.nsf = mx_get_scalar_field(mx_input_multislice, "cond_lens_nsf"); // Number of integration steps for the defocus Spread - - input_multislice.cond_lens.beta = mx_get_scalar_field(mx_input_multislice, "cond_lens_beta")*mt::c_mrad_2_rad; // divergence semi-angle (mrad-->rad) - input_multislice.cond_lens.nbeta = mx_get_scalar_field(mx_input_multislice, "cond_lens_nbeta"); // Number of integration steps for the divergence semi-angle - + /********************* defocus spread function ********************/ + input_multislice.cond_lens.dsf_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_dsf_sigma"); // standard deviation (Angstrom) + input_multislice.cond_lens.dsf_npoints = mx_get_scalar_field(mx_input_multislice, "cond_lens_dsf_npoints"); // # of integration points + + /********************* source spread function *********************/ + input_multislice.cond_lens.ssf_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_ssf_sigma"); // standard deviation: For parallel ilumination(Å^-1); otherwise (Å) + input_multislice.cond_lens.ssf_npoints = mx_get_scalar_field(mx_input_multislice, "cond_lens_ssf_npoints"); // # of integration points + + /********************* zero defocus reference ********************/ /********************* zero defocus reference ********************/ input_multislice.cond_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "cond_lens_zero_defocus_type"); // Zero defocus type input_multislice.cond_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "cond_lens_zero_defocus_plane"); // Zero defocus position - + input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); /*********************** Objective lens ***************************/ @@ -223,23 +227,26 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.obj_lens.phi_54 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration(degrees-->rad) input_multislice.obj_lens.c_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_56"); // 6-fold astigmatism (Angstrom) input_multislice.obj_lens.phi_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - + input_multislice.obj_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) input_multislice.obj_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - - input_multislice.obj_lens.sf = mx_get_scalar_field(mx_input_multislice, "obj_lens_sf"); // defocus spread (Angstrom) - input_multislice.obj_lens.nsf = mx_get_scalar_field(mx_input_multislice, "obj_lens_nsf"); // Number of integration steps for the defocus Spread - - input_multislice.obj_lens.beta = input_multislice.cond_lens.beta; // divergence semi-angle (mrad-->rad) - input_multislice.obj_lens.nbeta = input_multislice.cond_lens.nbeta; // Number of integration steps for the divergence semi-angle - + + /********************* defocus spread function ********************/ + input_multislice.obj_lens.dsf_sigma = mx_get_scalar_field(mx_input_multislice, "obj_lens_dsf_sigma"); // standard deviation (Angstrom) + input_multislice.obj_lens.dsf_npoints = mx_get_scalar_field(mx_input_multislice, "obj_lens_dsf_npoints"); // # of integration points + + /********************* source spread function *********************/ + input_multislice.obj_lens.ssf_sigma = input_multislice.cond_lens.ssf_sigma; // standard deviation: For parallel ilumination(Å^-1); otherwise (Å) + input_multislice.obj_lens.ssf_npoints = input_multislice.cond_lens.ssf_npoints; // # of integration points + + /********************* zero defocus reference ********************/ input_multislice.obj_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_type"); // Zero defocus type input_multislice.obj_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_plane"); // Zero defocus position - + input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); - /************************* ISTEM/STEM *****************************/ - if(input_multislice.is_scanning()) + /************************** ISTEM/STEM ***************************/ + if (input_multislice.is_scanning()) { input_multislice.scanning.type = mx_get_scalar_field(mx_input_multislice, "scanning_type"); input_multislice.scanning.pbc = mx_get_scalar_field(mx_input_multislice, "scanning_periodic"); @@ -251,7 +258,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.scanning.set_grid(); } - if(input_multislice.is_STEM()) + if (input_multislice.is_STEM()) { T_r lambda = mt::get_lambda(input_multislice.E_0); mxArray *mx_detector = mxGetField(mx_input_multislice, 0, "detector"); @@ -259,62 +266,62 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice switch (input_multislice.detector.type) { - case mt::eDT_Circular: + case mt::eDT_Circular: + { + mx_detector = mxGetField(mx_detector, 0, "cir"); + int ndetector = mxGetN(mx_detector); + if (ndetector > 0) { - mx_detector = mxGetField(mx_detector, 0, "cir"); - int ndetector = mxGetN(mx_detector); - if(ndetector>0) + input_multislice.detector.resize(ndetector); + for (auto i = 0; i < input_multislice.detector.size(); i++) { - input_multislice.detector.resize(ndetector); - for(auto i = 0; i(mx_detector, i, "inner_ang")*mt::c_mrad_2_rad; - input_multislice.detector.g_inner[i] = sin(inner_ang)/lambda; - auto outer_ang = mx_get_scalar_field(mx_detector, i, "outer_ang")*mt::c_mrad_2_rad; - input_multislice.detector.g_outer[i] = sin(outer_ang)/lambda; - } + auto inner_ang = mx_get_scalar_field(mx_detector, i, "inner_ang")*mt::c_mrad_2_rad; + input_multislice.detector.g_inner[i] = sin(inner_ang) / lambda; + auto outer_ang = mx_get_scalar_field(mx_detector, i, "outer_ang")*mt::c_mrad_2_rad; + input_multislice.detector.g_outer[i] = sin(outer_ang) / lambda; } } - break; - case mt::eDT_Radial: + } + break; + case mt::eDT_Radial: + { + mx_detector = mxGetField(mx_detector, 0, "radial"); + int ndetector = mxGetN(mx_detector); + if (ndetector > 0) { - mx_detector = mxGetField(mx_detector, 0, "radial"); - int ndetector = mxGetN(mx_detector); - if(ndetector>0) + input_multislice.detector.resize(ndetector); + for (auto i = 0; i < input_multislice.detector.size(); i++) { - input_multislice.detector.resize(ndetector); - for(auto i = 0; i(mx_detector, i, "x"); - // mt::assign(x, input_multislice.detector.x[i]); - // mt::scale(input_multislice.detector.x[i], 1.0/lambda); - - auto fx = mx_get_matrix_field(mx_detector, i, "fx"); - mt::assign(fx, input_multislice.detector.fx[i]); - } + // auto x = mx_get_matrix_field(mx_detector, i, "x"); + // mt::assign(x, input_multislice.detector.x[i]); + // mt::scale(input_multislice.detector.x[i], 1.0/lambda); + + auto fx = mx_get_matrix_field(mx_detector, i, "fx"); + mt::assign(fx, input_multislice.detector.fx[i]); } } - break; - case mt::eDT_Matrix: + } + break; + case mt::eDT_Matrix: + { + mx_detector = mxGetField(mx_detector, 0, "matrix"); + int ndetector = mxGetN(mx_detector); + if (ndetector > 0) { - mx_detector = mxGetField(mx_detector, 0, "matrix"); - int ndetector = mxGetN(mx_detector); - if(ndetector>0) + input_multislice.detector.resize(ndetector); + for (auto i = 0; i < input_multislice.detector.size(); i++) { - input_multislice.detector.resize(ndetector); - for(auto i = 0; i(mx_detector, i, "x"); - // mt::assign(R, input_multislice.detector.R[i]); - // mt::scale(input_multislice.detector.R[i], 1.0/lambda); - // mt::fft2_shift(input_multislice.grid_2d, input_multislice.detector.R[i]); - - auto fR = mx_get_matrix_field(mx_detector, i, "fR"); - mt::assign(fR, input_multislice.detector.fR[i]); - } + // auto R = mx_get_matrix_field(mx_detector, i, "x"); + // mt::assign(R, input_multislice.detector.R[i]); + // mt::scale(input_multislice.detector.R[i], 1.0/lambda); + // mt::fft2_shift(input_multislice.grid_2d, input_multislice.detector.R[i]); + + auto fR = mx_get_matrix_field(mx_detector, i, "fR"); + mt::assign(fR, input_multislice.detector.fR[i]); } } - break; + } + break; } } else if (input_multislice.is_PED()) @@ -350,8 +357,15 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.eels_fr.set_input_data(space, input_multislice.E_0, E_loss, m_selection, collection_angle, channelling_type, Z); } + /********************* select output region *************************/ + input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; + input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; + input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; + input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; + + /********************* validate parameters *************************/ input_multislice.validate_parameters(); - } +} template void set_struct_multislice(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) @@ -368,64 +382,64 @@ void set_struct_multislice(TOutput_Multislice &output_multislice, mxArray *&mx_o mx_create_set_matrix_field(mx_output_multislice, "y", 1, output_multislice.y.size(), output_multislice.y); mx_create_set_matrix_field(mx_output_multislice, "thick", 1, output_multislice.thick.size(), output_multislice.thick); - if(output_multislice.is_STEM() || output_multislice.is_EELS()) + if (output_multislice.is_STEM() || output_multislice.is_EELS()) { mxArray *mx_field_data; - const char *field_names_data_full[] = {"image_tot", "image_coh"}; - const char *field_names_data_partial[] = {"image_tot"}; - const char **field_names_data = (output_multislice.pn_coh_contrib)?field_names_data_full:field_names_data_partial; - int number_of_fields_data = (output_multislice.pn_coh_contrib)?2:1; - mwSize dims_data[2] = {1, output_multislice.thick.size()}; + const char *field_names_data_full[] = { "image_tot", "image_coh" }; + const char *field_names_data_partial[] = { "image_tot" }; + const char **field_names_data = (output_multislice.pn_coh_contrib) ? field_names_data_full : field_names_data_partial; + int number_of_fields_data = (output_multislice.pn_coh_contrib) ? 2 : 1; + mwSize dims_data[2] = { 1, output_multislice.thick.size() }; mx_field_data = mxCreateStructArray(2, dims_data, number_of_fields_data, field_names_data); mxSetField(mx_output_multislice, 0, "data", mx_field_data); mxArray *mx_field_detector_tot; mxArray *mx_field_detector_coh; - const char *field_names_detector[] = {"image"}; + const char *field_names_detector[] = { "image" }; int number_of_fields_detector = 1; // mwSize dims_detector[2] = {1, output_multislice.ndetector}; mwSize dims_detector[2]; dims_detector[0] = 1; dims_detector[1] = output_multislice.ndetector; - int nx = (output_multislice.scanning.is_line())?1:output_multislice.nx; + int nx = (output_multislice.scanning.is_line()) ? 1 : output_multislice.nx; int ny = output_multislice.ny; - for(auto ithk = 0; ithk(mx_field_detector_tot, iDet, "image", ny, nx, output_multislice.image_tot[ithk].image[iDet]); - if(output_multislice.pn_coh_contrib) + if (output_multislice.pn_coh_contrib) { mx_create_set_matrix_field(mx_field_detector_coh, iDet, "image", ny, nx, output_multislice.image_coh[ithk].image[iDet]); } } } } - else if(output_multislice.is_EWFS_EWRS()) + else if (output_multislice.is_EWFS_EWRS()) { mxArray *mx_field_data; - const char *field_names_data_full[] = {"m2psi_tot", "psi_coh"}; - const char *field_names_data_partial[] = {"psi_coh"}; - const char **field_names_data = (!output_multislice.is_EWFS_EWRS_SC())?field_names_data_full:field_names_data_partial; - int number_of_fields_data = (!output_multislice.is_EWFS_EWRS_SC())?2:1; - mwSize dims_data[2] = {1, output_multislice.thick.size()}; + const char *field_names_data_full[] = { "m2psi_tot", "psi_coh" }; + const char *field_names_data_partial[] = { "psi_coh" }; + const char **field_names_data = (!output_multislice.is_EWFS_EWRS_SC()) ? field_names_data_full : field_names_data_partial; + int number_of_fields_data = (!output_multislice.is_EWFS_EWRS_SC()) ? 2 : 1; + mwSize dims_data[2] = { 1, output_multislice.thick.size() }; mx_field_data = mxCreateStructArray(2, dims_data, number_of_fields_data, field_names_data); mxSetField(mx_output_multislice, 0, "data", mx_field_data); - for(auto ithk = 0; ithk(mx_field_data, ithk, "m2psi_tot", output_multislice.ny, output_multislice.nx, output_multislice.m2psi_tot[ithk]); } @@ -435,19 +449,19 @@ void set_struct_multislice(TOutput_Multislice &output_multislice, mxArray *&mx_o else { mxArray *mx_field_data; - const char *field_names_data_full[] = {"m2psi_tot", "m2psi_coh"}; - const char *field_names_data_partial[] = {"m2psi_tot"}; - const char **field_names_data = (output_multislice.pn_coh_contrib)?field_names_data_full:field_names_data_partial; - int number_of_fields_data = (output_multislice.pn_coh_contrib)?2:1; - mwSize dims_data[2] = {1, output_multislice.thick.size()}; + const char *field_names_data_full[] = { "m2psi_tot", "m2psi_coh" }; + const char *field_names_data_partial[] = { "m2psi_tot" }; + const char **field_names_data = (output_multislice.pn_coh_contrib) ? field_names_data_full : field_names_data_partial; + int number_of_fields_data = (output_multislice.pn_coh_contrib) ? 2 : 1; + mwSize dims_data[2] = { 1, output_multislice.thick.size() }; mx_field_data = mxCreateStructArray(2, dims_data, number_of_fields_data, field_names_data); mxSetField(mx_output_multislice, 0, "data", mx_field_data); - for(auto ithk = 0; ithk(mx_field_data, ithk, "m2psi_tot", output_multislice.ny, output_multislice.nx, output_multislice.m2psi_tot[ithk]); - if(output_multislice.pn_coh_contrib) + if (output_multislice.pn_coh_contrib) { mx_create_set_matrix_field(mx_field_data, ithk, "m2psi_coh", output_multislice.ny, output_multislice.nx, output_multislice.m2psi_coh[ithk]); } @@ -456,26 +470,40 @@ void set_struct_multislice(TOutput_Multislice &output_multislice, mxArray *&mx_o } template -void run_multislice(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, mxArray *&mx_output_multislice) +void run_multislice(mt::System_Configuration &system_conf, const mxArray *mx_input_multislice, +mxArray *&mx_output_multislice) { mt::Input_Multislice input_multislice; read_input_multislice(mx_input_multislice, input_multislice); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); + input_multislice.system_conf = system_conf; mt::Stream stream(system_conf.nstream); + mt::FFT fft_2d; fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - + mt::Multislice multislice; multislice.set_input_data(&input_multislice, &stream, &fft_2d); - multislice(output_multislice); + mt::Output_Multislice output_multislice; + output_multislice.set_input_data(&input_multislice); + + multislice(output_multislice); stream.synchronize(); + + output_multislice.gather(); + output_multislice.clean_temporal(); fft_2d.cleanup(); set_struct_multislice(output_multislice, mx_output_multislice); + + auto err = cudaGetLastError(); + if (err != cudaSuccess) { + mexPrintf("CUDA error: %s\n", cudaGetErrorString(err)); + } + //auto t3 = time.elapsed_ms(); + //mexPrintf("creation, execution, phase grating, deleting time = %7.5f, %7.5f, %7.5f, %7.5f\n", t1, t2, tx, t3); + //mexPrintf("send device = %d, get device = %d\n", system_conf.gpu_device, system_conf.get_device()); } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) @@ -483,26 +511,25 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) auto system_conf = mt::read_system_conf(prhs[0]); int idx_0 = (system_conf.active)?1:0; - if(system_conf.is_float_host()) + if (system_conf.is_float_host()) { - mexPrintf("cpu float"); + //mexPrintf("cpu - float precision calculation\n"); run_multislice(system_conf, prhs[idx_0], plhs[0]); } - else if(system_conf.is_double_host()) + else if (system_conf.is_double_host()) { - mexPrintf("cpu double"); + //mexPrintf("cpu - double precision calculation\n"); run_multislice(system_conf, prhs[idx_0], plhs[0]); } - if(system_conf.is_float_device()) + if (system_conf.is_float_device()) { - mexPrintf("gpu float"); + //mexPrintf("gpu - float precision calculation\n"); run_multislice(system_conf, prhs[idx_0], plhs[0]); } - else if(system_conf.is_double_device()) + else if (system_conf.is_double_device()) { - mexPrintf("gpu double"); + //mexPrintf("gpu - double precision calculation\n"); run_multislice(system_conf, prhs[idx_0], plhs[0]); } - //cudaDeviceReset(); } \ No newline at end of file diff --git a/mex_files_multem/il_fwhm_2_sigma.cpp b/mex_files_multem/il_fwhm_2_sigma.cpp new file mode 100644 index 00000000..c712cb20 --- /dev/null +++ b/mex_files_multem/il_fwhm_2_sigma.cpp @@ -0,0 +1,35 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM 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 3 of the License, or + * (at your option) any later version. + * + * MULTEM 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 MULTEM. If not, see . + */ + +#include "matlab_types.cuh" +#include "host_device_functions.cuh" + +#include +#include "matlab_mex.cuh" + +using mt::rmatrix_r; + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + auto val = mx_get_scalar(prhs[0]); + + /******************************************************************/ + auto rAgs = mx_create_scalar(plhs[0]); + + rAgs[0] = mt::fwhm_2_sigma(val); +} \ No newline at end of file diff --git a/mex_files_multem/il_gmax.cpp b/mex_files_multem/il_gmax.cpp index 0600cbf4..3e0f8e16 100644 --- a/mex_files_multem/il_gmax.cpp +++ b/mex_files_multem/il_gmax.cpp @@ -7,7 +7,7 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * MULTEM is distributed in the hope that it will be useful, + * MULTEM 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. @@ -27,11 +27,11 @@ using mt::rmatrix_r; void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { auto lx = mx_get_scalar(prhs[0]); - auto nx = mx_get_scalar(prhs[1]); - auto ly = (nrhs > 2)?mx_get_scalar(prhs[2]):lx; - auto ny = (nrhs > 3)?mx_get_scalar(prhs[3]):nx; + auto nx = mx_get_scalar(prhs[1]); + auto ly = (nrhs > 2) ? mx_get_scalar(prhs[2]) : lx; + auto ny = (nrhs > 3) ? mx_get_scalar(prhs[3]) : nx; - auto g_max = 0.5*min(nx/lx, ny/ly); + auto g_max = 0.5*min(nx / lx, ny / ly); /******************************************************************/ auto rg_max = mx_create_scalar(plhs[0]); diff --git a/mex_files_multem/il_hwhm_2_sigma.cpp b/mex_files_multem/il_hwhm_2_sigma.cpp new file mode 100644 index 00000000..3183abff --- /dev/null +++ b/mex_files_multem/il_hwhm_2_sigma.cpp @@ -0,0 +1,35 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM 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 3 of the License, or + * (at your option) any later version. + * + * MULTEM 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 MULTEM. If not, see . + */ + +#include "matlab_types.cuh" +#include "host_device_functions.cuh" + +#include +#include "matlab_mex.cuh" + +using mt::rmatrix_r; + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + auto val = mx_get_scalar(prhs[0]); + + /******************************************************************/ + auto rAgs = mx_create_scalar(plhs[0]); + + rAgs[0] = mt::hwhm_2_sigma(val); +} \ No newline at end of file diff --git a/mex_files_multem/il_iehwgd_2_sigma.cpp b/mex_files_multem/il_iehwgd_2_sigma.cpp new file mode 100644 index 00000000..9c6cb464 --- /dev/null +++ b/mex_files_multem/il_iehwgd_2_sigma.cpp @@ -0,0 +1,35 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM 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 3 of the License, or + * (at your option) any later version. + * + * MULTEM 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 MULTEM. If not, see . + */ + +#include "matlab_types.cuh" +#include "host_device_functions.cuh" + +#include +#include "matlab_mex.cuh" + +using mt::rmatrix_r; + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + auto val = mx_get_scalar(prhs[0]); + + /******************************************************************/ + auto rAgs = mx_create_scalar(plhs[0]); + + rAgs[0] = mt::iehwgd_2_sigma(val); +} \ No newline at end of file diff --git a/mex_files_multem/il_incident_wave.cu b/mex_files_multem/il_incident_wave.cu index 7eb8105a..6e0c00d6 100644 --- a/mex_files_multem/il_incident_wave.cu +++ b/mex_files_multem/il_incident_wave.cu @@ -113,6 +113,13 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); + /********************* select output region *************************/ + input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; + input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; + input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; + input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; + + /********************* validate parameters *************************/ input_multislice.validate_parameters(); } @@ -138,9 +145,7 @@ void run_incident_wave(mt::System_Configuration &system_conf, const mxArray *mx_ { mt::Input_Multislice input_multislice; read_input_multislice(mx_input_multislice, input_multislice); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); + input_multislice.system_conf = system_conf; mt::Stream stream(system_conf.nstream); mt::FFT fft_2d; @@ -148,9 +153,16 @@ void run_incident_wave(mt::System_Configuration &system_conf, const mxArray *mx_ mt::Incident_Wave incident_wave; incident_wave.set_input_data(&input_multislice, &stream, &fft_2d); + + mt::Output_Multislice output_multislice; + output_multislice.set_input_data(&input_multislice); + incident_wave(mt::eS_Real, output_multislice); stream.synchronize(); + + output_multislice.gather(); + output_multislice.clean_temporal(); fft_2d.cleanup(); set_struct_incident_wave(output_multislice, mx_output_multislice); diff --git a/mex_files_multem/il_microscope_aberrations.cu b/mex_files_multem/il_microscope_aberrations.cu index 23f26a93..3f2502e8 100644 --- a/mex_files_multem/il_microscope_aberrations.cu +++ b/mex_files_multem/il_microscope_aberrations.cu @@ -7,7 +7,7 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * MULTEM is distributed in the hope that it will be useful, + * MULTEM 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. @@ -45,7 +45,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); T_r lz = 0; T_r dz = 0.25; - bool pbc_xy = true; + bool pbc_xy = true; /************************** xy sampling ****************************/ auto nx = mx_get_scalar_field(mx_input_multislice, "nx"); @@ -58,7 +58,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice auto iw_type = mx_get_scalar_field(mx_input_multislice, "iw_type"); input_multislice.set_incident_wave_type(iw_type); - if(input_multislice.is_user_define_wave() && full) + if (input_multislice.is_user_define_wave() && full) { auto iw_psi = mx_get_matrix_field(mx_input_multislice, "iw_psi"); mt::assign(iw_psi, input_multislice.iw_psi); @@ -67,10 +67,10 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice // read iw_x and iw_y auto iw_x = mx_get_matrix_field(mx_input_multislice, "iw_x"); auto iw_y = mx_get_matrix_field(mx_input_multislice, "iw_y"); - - int n_iw_xy = min(iw_x.size(), iw_y.size()); - input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin()+n_iw_xy); - input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin()+n_iw_xy); + + int n_iw_xy = min(iw_x.size(), iw_y.size()); + input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin() + n_iw_xy); + input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin() + n_iw_xy); /********************* Microscope parameter ***********************/ input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); @@ -81,10 +81,10 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.illumination_model = mx_get_scalar_field(mx_input_multislice, "illumination_model"); input_multislice.temporal_spatial_incoh = mx_get_scalar_field(mx_input_multislice, "temporal_spatial_incoh"); - /****************************** Condenser lens ********************************/ - input_multislice.cond_lens.beta = mx_get_scalar_field(mx_input_multislice, "cond_lens_beta")*mt::c_mrad_2_rad; // divergence semi-angle(mrad-->rad) - input_multislice.cond_lens.nbeta = mx_get_scalar_field(mx_input_multislice, "cond_lens_nbeta"); // Number of integration steps for the divergence semi-angle - + /********************* source spread function *********************/ + input_multislice.cond_lens.ssf_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_ssf_sigma"); // standard deviation: For parallel ilumination(Å^-1); otherwise (Å) + input_multislice.cond_lens.ssf_npoints = mx_get_scalar_field(mx_input_multislice, "cond_lens_ssf_npoints"); // # of integration points + input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); /************************ Objective lens **************************/ @@ -118,31 +118,40 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.obj_lens.phi_54 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_54")*mt::c_deg_2_rad; // Azimuthal angle of 5th order rosette aberration(degrees-->rad) input_multislice.obj_lens.c_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_c_56"); // 6-fold astigmatism (Angstrom) input_multislice.obj_lens.phi_56 = mx_get_scalar_field(mx_input_multislice, "obj_lens_phi_56")*mt::c_deg_2_rad; // Azimuthal angle of 6-fold astigmatism (degrees-->rad) - + input_multislice.obj_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) input_multislice.obj_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "obj_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - - input_multislice.obj_lens.sf = mx_get_scalar_field(mx_input_multislice, "obj_lens_sf"); // defocus spread (Angstrom) - input_multislice.obj_lens.nsf = mx_get_scalar_field(mx_input_multislice, "obj_lens_nsf"); // Number of integration steps for the defocus Spread - - input_multislice.obj_lens.beta = input_multislice.cond_lens.beta; // divergence semi-angle (mrad-->rad) - input_multislice.obj_lens.nbeta = input_multislice.cond_lens.nbeta; // Number of integration steps for the divergence semi-angle - - + + /********************* defocus spread function ********************/ + input_multislice.obj_lens.dsf_sigma = mx_get_scalar_field(mx_input_multislice, "obj_lens_dsf_sigma"); // standard deviation (Angstrom) + input_multislice.obj_lens.dsf_npoints = mx_get_scalar_field(mx_input_multislice, "obj_lens_dsf_npoints"); // # of integration points + + /********************* source spread function *********************/ + input_multislice.obj_lens.ssf_sigma = input_multislice.cond_lens.ssf_sigma; // standard deviation: For parallel ilumination(Å^-1); otherwise (Å) + input_multislice.obj_lens.ssf_npoints = input_multislice.cond_lens.ssf_npoints; // # of integration points // # of integration points + + /********************* zero defocus reference ********************/ input_multislice.obj_lens.zero_defocus_type = mt::eZDT_Last; - input_multislice.obj_lens.zero_defocus_plane = 0.0; - + input_multislice.obj_lens.zero_defocus_plane = 0.0; + input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); + /********************* select output region *************************/ + input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; + input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; + input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; + input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; + + /********************* validate parameters *************************/ input_multislice.validate_parameters(); - } +} template void set_struct_microscope_aberrations(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) { - const char *field_names_output_multislice[] = {"dx", "dy", "x", "y", "thick", "m2psi"}; + const char *field_names_output_multislice[] = { "dx", "dy", "x", "y", "thick", "m2psi" }; int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = {1, 1}; + mwSize dims_output_multislice[2] = { 1, 1 }; mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); @@ -159,9 +168,7 @@ void run_microscope_aberrations(mt::System_Configuration &system_conf, const mxA { mt::Input_Multislice input_multislice; read_input_multislice(mx_input_multislice, input_multislice); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); + input_multislice.system_conf = system_conf; mt::Stream stream(system_conf.nstream); mt::FFT fft_2d; @@ -169,9 +176,16 @@ void run_microscope_aberrations(mt::System_Configuration &system_conf, const mxA mt::Microscope_Effects microscope_effects; microscope_effects.set_input_data(&input_multislice, &stream, &fft_2d); + + mt::Output_Multislice output_multislice; + output_multislice.set_input_data(&input_multislice); + microscope_effects(output_multislice); stream.synchronize(); + + output_multislice.gather(); + output_multislice.clean_temporal(); fft_2d.cleanup(); set_struct_microscope_aberrations(output_multislice, mx_output_multislice); @@ -180,21 +194,21 @@ void run_microscope_aberrations(mt::System_Configuration &system_conf, const mxA void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active)?1:0; + int idx_0 = (system_conf.active) ? 1 : 0; - if(system_conf.is_float_host()) + if (system_conf.is_float_host()) { run_microscope_aberrations(system_conf, prhs[idx_0], plhs[0]); } - else if(system_conf.is_double_host()) + else if (system_conf.is_double_host()) { run_microscope_aberrations(system_conf, prhs[idx_0], plhs[0]); } - else if(system_conf.is_float_device()) + else if (system_conf.is_float_device()) { run_microscope_aberrations(system_conf, prhs[idx_0], plhs[0]); } - else if(system_conf.is_double_device()) + else if (system_conf.is_double_device()) { run_microscope_aberrations(system_conf, prhs[idx_0], plhs[0]); } diff --git a/mex_files_multem/il_min_spl.cpp b/mex_files_multem/il_min_spl.cpp index c824eaac..b47aeb0d 100644 --- a/mex_files_multem/il_min_spl.cpp +++ b/mex_files_multem/il_min_spl.cpp @@ -29,12 +29,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) auto E0 = mx_get_scalar(prhs[0]); auto lx = mx_get_scalar(prhs[1]); auto ly = (nrhs > 3)?mx_get_scalar(prhs[2]):lx; - int idx_theta = (nrhs==3)?2:3; + int idx_theta = (nrhs==3)?2:3; auto theta = mx_get_scalar(prhs[idx_theta])*mt::c_mrad_2_rad; - auto g_req = mt::rad_2_rAngs(E0, theta); - auto nx = static_cast(round(2*lx*g_req)); - auto ny = static_cast(round(2*ly*g_req)); + auto g_req = mt::rad_2_rAngs(E0, theta); + auto nx = static_cast(round(2*lx*g_req)); + auto ny = static_cast(round(2*ly*g_req)); mt::Prime_Num pm; nx = pm(nx, mt::eDST_Closest); @@ -42,10 +42,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) /******************************************************************/ auto rnx = mx_create_scalar(plhs[0]); - rnx[0] = nx; - if(nlhs>1) - { - auto rny = mx_create_scalar(plhs[1]); - rny[0] = ny; - } + rnx[0] = nx; + if(nlhs>1) + { + auto rny = mx_create_scalar(plhs[1]); + rny[0] = ny; + } } \ No newline at end of file diff --git a/mex_files_multem/il_mrad_2_sigma.cpp b/mex_files_multem/il_mrad_2_sigma.cpp new file mode 100644 index 00000000..72ab47d8 --- /dev/null +++ b/mex_files_multem/il_mrad_2_sigma.cpp @@ -0,0 +1,36 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM 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 3 of the License, or + * (at your option) any later version. + * + * MULTEM 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 MULTEM. If not, see . + */ + +#include "matlab_types.cuh" +#include "host_device_functions.cuh" + +#include +#include "matlab_mex.cuh" + +using mt::rmatrix_r; + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + auto E0 = mx_get_scalar(prhs[0]); + auto theta = mx_get_scalar(prhs[1])*mt::c_mrad_2_rad; + + /******************************************************************/ + auto rAgs = mx_create_scalar(plhs[0]); + + rAgs[0] = mt::rad_2_sigma(E0, theta); +} \ No newline at end of file diff --git a/mex_files_multem/il_projected_potential.cu b/mex_files_multem/il_projected_potential.cu index 24b496b1..295a0a49 100644 --- a/mex_files_multem/il_projected_potential.cu +++ b/mex_files_multem/il_projected_potential.cu @@ -89,7 +89,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); + input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); /************************ Potential slicing ************************/ @@ -105,6 +105,13 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice /************************ simulation type **************************/ input_multislice.islice = mx_get_scalar_field(mx_input_multislice, "islice")-1; + /********************* select output region *************************/ + input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; + input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; + input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; + input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; + + /********************* validate parameters *************************/ input_multislice.validate_parameters(); } @@ -130,35 +137,23 @@ void run_projected_potential(mt::System_Configuration &system_conf, const mxArra { mt::Input_Multislice input_multislice; read_input_multislice(mx_input_multislice, input_multislice); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); + input_multislice.system_conf = system_conf; mt::Stream stream(system_conf.nstream); mt::Projected_Potential projected_potential; projected_potential.set_input_data(&input_multislice, &stream); - projected_potential.move_atoms(input_multislice.pn_nconf); - //cudaEvent_t start, stop; - //cudaEventCreate(&start); - //cudaEventCreate(&stop); - - //cudaEventRecord(start, 0); + mt::Output_Multislice output_multislice; + output_multislice.set_input_data(&input_multislice); + projected_potential.move_atoms(input_multislice.pn_nconf); projected_potential(input_multislice.islice, output_multislice); - //cudaEventRecord(stop, 0); - //cudaEventSynchronize(stop); - - //float elapsedTime = 0; - //cudaEventElapsedTime(&elapsedTime, start, stop); - //mexPrintf("Elapsed time = %8.3f ms\n", elapsedTime); - - //cudaEventDestroy(start); - //cudaEventDestroy(stop); - stream.synchronize(); + output_multislice.gather(); + output_multislice.clean_temporal(); + set_struct_projected_potential(output_multislice, mx_output_multislice); } diff --git a/mex_files_multem/il_propagate.cu b/mex_files_multem/il_propagate.cu index 007992c4..90692ab7 100644 --- a/mex_files_multem/il_propagate.cu +++ b/mex_files_multem/il_propagate.cu @@ -77,9 +77,16 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.phi = mx_get_scalar_field(mx_input_multislice, "phi")*mt::c_deg_2_rad; /************************ Objective lens **************************/ - input_multislice.obj_lens.c_10 = mx_get_scalar_field(mx_input_multislice, "obj_lens_f"); // defocus(Angstrom) + input_multislice.obj_lens.c_10 = mx_get_scalar_field(mx_input_multislice, "obj_lens_f"); // defocus(Angstrom) input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); + + /********************* select output region *************************/ + input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; + input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; + input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; + input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; + /********************* validate parameters *************************/ input_multislice.validate_parameters(); } @@ -105,9 +112,7 @@ void run_propagate(mt::System_Configuration &system_conf, const mxArray *mx_inpu { mt::Input_Multislice input_multislice; read_input_multislice(mx_input_multislice, input_multislice); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); + input_multislice.system_conf = system_conf; mt::Stream stream(system_conf.nstream); mt::FFT fft_2d; @@ -115,9 +120,16 @@ void run_propagate(mt::System_Configuration &system_conf, const mxArray *mx_inpu mt::Propagator propagator; propagator.set_input_data(&input_multislice, &stream, &fft_2d); + + mt::Output_Multislice output_multislice; + output_multislice.set_input_data(&input_multislice); + propagator(mt::eS_Real, input_multislice.gx_0(), input_multislice.gy_0(), input_multislice.obj_lens.c_10 , output_multislice); stream.synchronize(); + + output_multislice.gather(); + output_multislice.clean_temporal(); fft_2d.cleanup(); set_struct_propagate(output_multislice, mx_output_multislice); diff --git a/mex_files_multem/il_spec_planes.cpp b/mex_files_multem/il_spec_planes.cpp index 3d5f32bd..3cbfebee 100644 --- a/mex_files_multem/il_spec_planes.cpp +++ b/mex_files_multem/il_spec_planes.cpp @@ -79,7 +79,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); + input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); /************************ Potential slicing ************************/ diff --git a/mex_files_multem/il_spec_slicing.cpp b/mex_files_multem/il_spec_slicing.cpp index 9de6a56f..46f08218 100644 --- a/mex_files_multem/il_spec_slicing.cpp +++ b/mex_files_multem/il_spec_slicing.cpp @@ -79,7 +79,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); + input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); /************************ Potential slicing ************************/ diff --git a/mex_files_multem/il_transmission_function.cu b/mex_files_multem/il_transmission_function.cu index b50b8fad..a4aec257 100644 --- a/mex_files_multem/il_transmission_function.cu +++ b/mex_files_multem/il_transmission_function.cu @@ -91,7 +91,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); + input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); /************************ Potential slicing ************************/ @@ -111,6 +111,13 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.islice = mx_get_scalar_field(mx_input_multislice, "islice")-1; + /********************* select output region *************************/ + input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; + input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; + input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; + input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; + + /********************* validate parameters *************************/ input_multislice.validate_parameters(); } @@ -136,9 +143,7 @@ void run_transmission_function(mt::System_Configuration &system_conf, const mxAr { mt::Input_Multislice input_multislice; read_input_multislice(mx_input_multislice, input_multislice); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); + input_multislice.system_conf = system_conf; mt::Stream stream(system_conf.nstream); mt::FFT fft_2d; @@ -146,10 +151,17 @@ void run_transmission_function(mt::System_Configuration &system_conf, const mxAr mt::Transmission_Function transmission_function; transmission_function.set_input_data(&input_multislice, &stream, &fft_2d); + + mt::Output_Multislice output_multislice; + output_multislice.set_input_data(&input_multislice); + transmission_function.move_atoms(input_multislice.pn_nconf); transmission_function.trans(input_multislice.islice, output_multislice); stream.synchronize(); + + output_multislice.gather(); + output_multislice.clean_temporal(); fft_2d.cleanup(); set_struct_transmission_function(output_multislice, mx_output_multislice); diff --git a/mex_files_multem/il_wave_function.cu b/mex_files_multem/il_wave_function.cu index a1122136..6c41a304 100644 --- a/mex_files_multem/il_wave_function.cu +++ b/mex_files_multem/il_wave_function.cu @@ -7,7 +7,7 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * MULTEM is distributed in the hope that it will be useful, + * MULTEM 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. @@ -42,14 +42,14 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice using T_r = mt::Value_type; /************************ simulation type **************************/ - input_multislice.simulation_type = mx_get_scalar_field(mx_input_multislice, "simulation_type"); - input_multislice.simulation_type = (input_multislice.is_EWRS())?mt::eTEMST_EWRS:mt::eTEMST_EWFS; + input_multislice.simulation_type = mx_get_scalar_field(mx_input_multislice, "simulation_type"); + input_multislice.simulation_type = (input_multislice.is_EWRS()) ? mt::eTEMST_EWRS : mt::eTEMST_EWFS; input_multislice.interaction_model = mx_get_scalar_field(mx_input_multislice, "interaction_model"); input_multislice.potential_type = mx_get_scalar_field(mx_input_multislice, "potential_type"); /************** Electron-Phonon interaction model ******************/ - input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); + input_multislice.pn_model = mx_get_scalar_field(mx_input_multislice, "pn_model"); input_multislice.pn_coh_contrib = true; input_multislice.pn_single_conf = true; input_multislice.pn_nconf = mx_get_scalar_field(mx_input_multislice, "pn_nconf"); @@ -63,7 +63,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice auto ly = mx_get_scalar_field(mx_input_multislice, "spec_ly"); auto lz = mx_get_scalar_field(mx_input_multislice, "spec_lz"); auto dz = mx_get_scalar_field(mx_input_multislice, "spec_dz"); - bool pbc_xy = true; + bool pbc_xy = true; auto ct_na = mx_get_scalar_field(mx_input_multislice, "spec_cryst_na"); auto ct_nb = mx_get_scalar_field(mx_input_multislice, "spec_cryst_nb"); @@ -76,14 +76,14 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice auto mx_spec_amorp = mxGetField(mx_input_multislice, 0, "spec_amorp"); mt::Vector, mt::e_host> amorp_lay_info(mxGetN(mx_spec_amorp)); - for(auto i = 0; i(mx_spec_amorp, i, "z_0"); amorp_lay_info[i].z_e = mx_get_scalar_field(mx_spec_amorp, i, "z_e"); amorp_lay_info[i].dz = mx_get_scalar_field(mx_spec_amorp, i, "dz"); } - if(full) + if (full) { input_multislice.atoms.set_crystal_parameters(ct_na, ct_nb, ct_nc, ct_a, ct_b, ct_c, ct_x0, ct_y0); input_multislice.atoms.set_amorphous_parameters(amorp_lay_info); @@ -94,12 +94,12 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.spec_rot_theta = mx_get_scalar_field(mx_input_multislice, "spec_rot_theta")*mt::c_deg_2_rad; input_multislice.spec_rot_u0 = mx_get_r3d_field(mx_input_multislice, "spec_rot_u0"); input_multislice.spec_rot_u0.normalized(); - input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); + input_multislice.spec_rot_center_type = mx_get_scalar_field(mx_input_multislice, "spec_rot_center_type"); input_multislice.spec_rot_center_p = mx_get_r3d_field(mx_input_multislice, "spec_rot_center_p"); /************************ Specimen thickness ***********************/ input_multislice.thick_type = mx_get_scalar_field(mx_input_multislice, "thick_type"); - if(!input_multislice.is_whole_spec() && full) + if (!input_multislice.is_whole_spec() && full) { auto thick = mx_get_matrix_field(mx_input_multislice, "thick"); mt::assign(thick, input_multislice.thick); @@ -119,7 +119,7 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice auto iw_type = mx_get_scalar_field(mx_input_multislice, "iw_type"); input_multislice.set_incident_wave_type(iw_type); - if(input_multislice.is_user_define_wave() && full) + if (input_multislice.is_user_define_wave() && full) { auto iw_psi = mx_get_matrix_field(mx_input_multislice, "iw_psi"); mt::assign(iw_psi, input_multislice.iw_psi); @@ -128,11 +128,11 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice // read iw_x and iw_y auto iw_x = mx_get_matrix_field(mx_input_multislice, "iw_x"); auto iw_y = mx_get_matrix_field(mx_input_multislice, "iw_y"); - - int n_iw_xy = min(iw_x.size(), iw_y.size()); - input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin()+n_iw_xy); - input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin()+n_iw_xy); - + + int n_iw_xy = min(iw_x.size(), iw_y.size()); + input_multislice.iw_x.assign(iw_x.begin(), iw_x.begin() + n_iw_xy); + input_multislice.iw_y.assign(iw_y.begin(), iw_y.begin() + n_iw_xy); + /********************* Microscope parameter ***********************/ input_multislice.E_0 = mx_get_scalar_field(mx_input_multislice, "E_0"); input_multislice.theta = mx_get_scalar_field(mx_input_multislice, "theta")*mt::c_deg_2_rad; @@ -177,37 +177,47 @@ void read_input_multislice(const mxArray *mx_input_multislice, TInput_Multislice input_multislice.cond_lens.inner_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_inner_aper_ang")*mt::c_mrad_2_rad; // inner aperture (mrad-->rad) input_multislice.cond_lens.outer_aper_ang = mx_get_scalar_field(mx_input_multislice, "cond_lens_outer_aper_ang")*mt::c_mrad_2_rad; // outer aperture (mrad-->rad) - input_multislice.cond_lens.sf = mx_get_scalar_field(mx_input_multislice, "cond_lens_sf"); // Defocus spread (Angstrom) - input_multislice.cond_lens.nsf = mx_get_scalar_field(mx_input_multislice, "cond_lens_nsf"); // Number of integration steps for the defocus Spread - - input_multislice.cond_lens.beta = mx_get_scalar_field(mx_input_multislice, "cond_lens_beta")*mt::c_mrad_2_rad; // divergence semi-angle (mrad-->rad) - input_multislice.cond_lens.nbeta = mx_get_scalar_field(mx_input_multislice, "cond_lens_nbeta"); // Number of integration steps for the divergence semi-angle - + /********************* defocus spread function ********************/ + input_multislice.cond_lens.dsf_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_dsf_sigma"); // standard deviation (Angstrom) + input_multislice.cond_lens.dsf_npoints = mx_get_scalar_field(mx_input_multislice, "cond_lens_dsf_npoints"); // # of integration points + + /********************* source spread function *********************/ + input_multislice.cond_lens.ssf_sigma = mx_get_scalar_field(mx_input_multislice, "cond_lens_ssf_sigma"); // standard deviation: For parallel ilumination(Å^-1); otherwise (Å) + input_multislice.cond_lens.ssf_npoints = mx_get_scalar_field(mx_input_multislice, "cond_lens_ssf_npoints"); // # of integration points + + /********************* zero defocus reference ********************/ input_multislice.cond_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "cond_lens_zero_defocus_type"); // Zero defocus type input_multislice.cond_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "cond_lens_zero_defocus_plane"); // Zero defocus position - + input_multislice.cond_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); /************************ Objective lens **************************/ input_multislice.obj_lens.zero_defocus_type = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_type"); // Zero defocus type input_multislice.obj_lens.zero_defocus_plane = mx_get_scalar_field(mx_input_multislice, "obj_lens_zero_defocus_plane"); // Zero defocus position - + input_multislice.obj_lens.set_input_data(input_multislice.E_0, input_multislice.grid_2d); + /********************* select output region *************************/ + input_multislice.output_area.ix_0 = mx_get_scalar_field(mx_input_multislice, "output_area_ix_0")-1; + input_multislice.output_area.iy_0 = mx_get_scalar_field(mx_input_multislice, "output_area_iy_0")-1; + input_multislice.output_area.ix_e = mx_get_scalar_field(mx_input_multislice, "output_area_ix_e")-1; + input_multislice.output_area.iy_e = mx_get_scalar_field(mx_input_multislice, "output_area_iy_e")-1; + + /********************* validate parameters *************************/ input_multislice.validate_parameters(); } template void set_struct_wave_function(TOutput_Multislice &output_multislice, mxArray *&mx_output_multislice) { - const char *field_names_output_multislice[] = {"dx", "dy", "x", "y", "thick", "data"}; + const char *field_names_output_multislice[] = { "dx", "dy", "x", "y", "thick", "data" }; int number_of_fields_output_multislice = 6; - mwSize dims_output_multislice[2] = {1, 1}; + mwSize dims_output_multislice[2] = { 1, 1 }; mxArray *mx_field_psi; - const char *field_names_psi[] = {"psi_coh"}; + const char *field_names_psi[] = { "psi_coh" }; int number_of_fields_psi = 1; - mwSize dims_psi[2] = {1, output_multislice.thick.size()}; + mwSize dims_psi[2] = { 1, output_multislice.thick.size() }; mx_output_multislice = mxCreateStructArray(2, dims_output_multislice, number_of_fields_output_multislice, field_names_output_multislice); @@ -220,7 +230,7 @@ void set_struct_wave_function(TOutput_Multislice &output_multislice, mxArray *&m mx_field_psi = mxCreateStructArray(2, dims_psi, number_of_fields_psi, field_names_psi); mxSetField(mx_output_multislice, 0, "data", mx_field_psi); - for(auto ithk = 0; ithk(mx_field_psi, ithk, "psi_coh", output_multislice.ny, output_multislice.nx, output_multislice.psi_coh[ithk]); } @@ -231,24 +241,27 @@ void run_wave_function(mt::System_Configuration &system_conf, const mxArray *mx_ { mt::Input_Multislice input_multislice; read_input_multislice(mx_input_multislice, input_multislice); - - mt::Output_Multislice output_multislice; - output_multislice.set_input_data(&input_multislice); + input_multislice.system_conf = system_conf; mt::Stream stream(system_conf.nstream); mt::FFT fft_2d; fft_2d.create_plan_2d(input_multislice.grid_2d.ny, input_multislice.grid_2d.nx, system_conf.nstream); - + mt::Wave_Function wave_function; wave_function.set_input_data(&input_multislice, &stream, &fft_2d); + + mt::Output_Multislice output_multislice; + output_multislice.set_input_data(&input_multislice); + wave_function.move_atoms(input_multislice.pn_nconf); wave_function.set_incident_wave(wave_function.psi_z); wave_function.psi(1.0, wave_function.psi_z, output_multislice); - output_multislice.shift(); - output_multislice.clear_temporal_data(); - stream.synchronize(); + + output_multislice.gather(); + output_multislice.clean_temporal(); + fft_2d.cleanup(); set_struct_wave_function(output_multislice, mx_output_multislice); @@ -257,22 +270,22 @@ void run_wave_function(mt::System_Configuration &system_conf, const mxArray *mx_ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { auto system_conf = mt::read_system_conf(prhs[0]); - int idx_0 = (system_conf.active)?1:0; + int idx_0 = (system_conf.active) ? 1 : 0; - if(system_conf.is_float_host()) + if (system_conf.is_float_host()) { - run_wave_function(system_conf, prhs[idx_0], plhs[0]); + //run_wave_function(system_conf, prhs[idx_0], plhs[0]); } - else if(system_conf.is_double_host()) + else if (system_conf.is_double_host()) { - run_wave_function(system_conf, prhs[idx_0], plhs[0]); + //run_wave_function(system_conf, prhs[idx_0], plhs[0]); } - else if(system_conf.is_float_device()) + else if (system_conf.is_float_device()) { run_wave_function(system_conf, prhs[idx_0], plhs[0]); } - else if(system_conf.is_double_device()) + else if (system_conf.is_double_device()) { - run_wave_function(system_conf, prhs[idx_0], plhs[0]); + //run_wave_function(system_conf, prhs[idx_0], plhs[0]); } } \ No newline at end of file diff --git a/mex_files_multem/mex_CUDA_glnxa64.xml b/mex_files_multem/mex_CUDA_glnxa64.xml deleted file mode 100644 index e4b5ef8c..00000000 --- a/mex_files_multem/mex_CUDA_glnxa64.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mex_files_multem/mex_data_aug_2d.m b/mex_files_multem/mex_data_aug_2d.m deleted file mode 100644 index 86912683..00000000 --- a/mex_files_multem/mex_data_aug_2d.m +++ /dev/null @@ -1,3 +0,0 @@ -clc; clear all; - -MEX('release', 'il_data_aug_2d.cu', '../src'); \ No newline at end of file diff --git a/mex_files_multem/mex_fwhm_2_sigma.m b/mex_files_multem/mex_fwhm_2_sigma.m new file mode 100644 index 00000000..9e4d8cf9 --- /dev/null +++ b/mex_files_multem/mex_fwhm_2_sigma.m @@ -0,0 +1,3 @@ +clc; clear all; + +MEX('release', 'il_fwhm_2_sigma.cpp', '../src'); diff --git a/mex_files_multem/mex_hwhm_2_sigma.m b/mex_files_multem/mex_hwhm_2_sigma.m new file mode 100644 index 00000000..125d88f3 --- /dev/null +++ b/mex_files_multem/mex_hwhm_2_sigma.m @@ -0,0 +1,3 @@ +clc; clear all; + +MEX('release', 'il_hwhm_2_sigma.cpp', '../src'); diff --git a/mex_files_multem/mex_iehwgd_2_sigma.m b/mex_files_multem/mex_iehwgd_2_sigma.m new file mode 100644 index 00000000..572922bd --- /dev/null +++ b/mex_files_multem/mex_iehwgd_2_sigma.m @@ -0,0 +1,3 @@ +clc; clear all; + +MEX('release', 'il_iehwgd_2_sigma.cpp', '../src'); diff --git a/mex_files_multem/mex_mrad_2_sigma.m b/mex_files_multem/mex_mrad_2_sigma.m new file mode 100644 index 00000000..a90d84ab --- /dev/null +++ b/mex_files_multem/mex_mrad_2_sigma.m @@ -0,0 +1,3 @@ +clc; clear all; + +MEX('release', 'il_mrad_2_sigma.cpp', '../src'); diff --git a/mex_files_multem/mex_wave_function.m b/mex_files_multem/mex_wave_function.m index d3131157..c8510cfb 100644 --- a/mex_files_multem/mex_wave_function.m +++ b/mex_files_multem/mex_wave_function.m @@ -1,3 +1,3 @@ clc; clear all; -MEX('release', 'il_wave_function.cu', '../src'); \ No newline at end of file +MEX('debug', 'il_wave_function.cu', '../src'); \ No newline at end of file diff --git a/src/device_functions.cuh b/src/device_functions.cuh index f71da179..d9479a69 100644 --- a/src/device_functions.cuh +++ b/src/device_functions.cuh @@ -382,6 +382,99 @@ namespace mt } } + /***************************************************************************/ + // Shift matrix respect to (nxh, nyh) + template + __global__ void assign_shift_2d(TGrid grid_2d, rVector M_i, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::fft2_shift(ix, iy, grid_2d, M_i, M_o); + } + } + + // add, scale, crop and shift + template + __global__ void add_scale_shift_2d(TGrid grid_2d, T w, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::add_scale_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); + } + } + + // add, scale, square, crop and shift + template + __global__ void add_scale_square_shift_2d(TGrid grid_2d, T2 w, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::add_scale_square_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); + } + } + + // Assign and crop + template + __global__ void assign_crop(TGrid grid_2d, rVector M_i, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nx)&&(iy < grid_2d.ny)) + { + host_device_detail::assign_crop(ix, iy, grid_2d, M_i, M_o); + } + } + + // crop and shift + template + __global__ void assign_crop_shift_2d(TGrid grid_2d, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::assign_crop_shift_2d(ix, iy, grid_2d, M_i, range, M_o); + } + } + + // add, scale, crop and shift + template + __global__ void add_scale_crop_shift_2d(TGrid grid_2d, T w, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::add_scale_crop_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); + } + } + + // add, scale, square, crop and shift + template + __global__ void add_scale_square_crop_shift_2d(TGrid grid_2d, T2 w, rVector M_i, Range_2d range, rVector M_o) + { + int iy = threadIdx.x + blockIdx.x*blockDim.x; + int ix = threadIdx.y + blockIdx.y*blockDim.y; + + if((ix < grid_2d.nxh)&&(iy < grid_2d.nyh)) + { + host_device_detail::add_scale_square_crop_shift_2d(ix, iy, grid_2d, w, M_i, range, M_o); + } + } + + /***************************************************************************/ // sum over the detector template __global__ void sum_over_Det(TGrid grid_2d, Value_type g2_min, Value_type g2_max, rVector M_i, rVector Mp_o) @@ -1011,14 +1104,14 @@ namespace mt // rotate, scale and shift xy template __global__ void rot_sca_sft_2d(TGrid grid_2d_i, rVector M_i, T theta, r2d p0, - T fxy, r2d ps, T bg, TGrid grid_2d_o, rVector M_o) + T fx, T fy, r2d ps, T bg, TGrid grid_2d_o, rVector M_o) { int iy = threadIdx.x + blockIdx.x*blockDim.x; int ix = threadIdx.y + blockIdx.y*blockDim.y; if((ix < grid_2d_o.nx)&&(iy < grid_2d_o.ny)) { - host_device_detail::rot_sca_sft_2d(ix, iy, grid_2d_i, M_i, theta, p0, fxy, ps, bg, grid_2d_o, M_o); + host_device_detail::rot_sca_sft_2d(ix, iy, grid_2d_i, M_i, theta, p0, fx, fy, ps, bg, grid_2d_o, M_o); } } @@ -1048,7 +1141,7 @@ namespace mt enable_if_device_vector fill(Stream &stream, TVector &M_io, Value_type value_i) { - thrust::fill(thrust::device, M_io.begin(), M_io.end(), value_i); + thrust::fill(M_io.begin(), M_io.end(), value_i); } template @@ -1132,18 +1225,18 @@ namespace mt template enable_if_device_vector_and_device_vector - add_square_scale(Stream &stream, Value_type w1_i, TVector_1 &M1_i, Value_type w2_i, TVector_1 &M2_i, TVector_2 &M_o) + add_scale_square(Stream &stream, Value_type w1_i, TVector_1 &M1_i, Value_type w2_i, TVector_1 &M2_i, TVector_2 &M_o) { using value_type = Value_type; - thrust::transform(M1_i.begin(), M1_i.end(), M2_i.begin(), M_o.begin(), functor::add_square_scale_i(w1_i, w2_i)); + thrust::transform(M1_i.begin(), M1_i.end(), M2_i.begin(), M_o.begin(), functor::add_scale_square_i(w1_i, w2_i)); } template enable_if_device_vector_and_device_vector - add_square_scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_io) + add_scale_square(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_io) { using value_type = Value_type; - thrust::transform(M_i.begin(), M_i.end(), M_io.begin(), M_io.begin(), functor::add_square_scale(w_i)); + thrust::transform(M_i.begin(), M_i.end(), M_io.begin(), M_io.begin(), functor::add_scale_square(w_i)); } template @@ -1441,6 +1534,7 @@ namespace mt device_detail::fft2_shift<<>>(grid_2d, M_io); } + template enable_if_device_vector> sum_over_Det(Stream &stream, TGrid &grid_2d, Value_type g_min, Value_type g_max, TVector &M_i) @@ -1501,7 +1595,6 @@ namespace mt Value_type gxu, Value_type gyu, TVector_c &psi_i, TVector_c &psi_o) { auto grid_bt = grid_2d.cuda_grid(); - device_detail::propagate<<>>(grid_2d, w, gxu, gyu, psi_i, psi_o); } @@ -1670,7 +1763,7 @@ namespace mt template enable_if_device_vector_and_host_vector - add_square_scale_to_host(Stream &stream, Value_type w_i, + add_scale_square_to_host(Stream &stream, Value_type w_i, TVector_i &M_i, TVector_o &M_o, Vector, e_host> *M_i_h = nullptr) { Vector, e_host> M_h; @@ -1679,7 +1772,7 @@ namespace mt // data transfer from GPU to CPU M_i_h->assign(M_i.begin(), M_i.end()); - mt::add_square_scale_to_host(stream, w_i, *M_i_h, M_o); + mt::add_scale_square_to_host(stream, w_i, *M_i_h, M_o); } template @@ -1696,9 +1789,283 @@ namespace mt mt::add_scale_m2psi_psi_to_host(stream, w_i, *psi_i_h, m2psi_o, psi_o); } + /***************************************************************************/ + /*************************** Device to Device ******************************/ + /***************************************************************************/ + template + enable_if_device_vector + assign_shift_2d(TGrid &grid_2d, TVector &M_i, TVector &M_o, + Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::assign_shift_2d<<>>(grid_2d, M_i, M_o); + } + + template + enable_if_device_vector + add_scale_shift_2d(TGrid &grid_2d, Value_type w, + TVector &M_i, TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::add_scale_shift_2d<<>>(grid_2d, w, M_i, M_o); + } + + template + enable_if_device_vector_and_device_vector + add_scale_square_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::add_scale_square_shift_2d<<>>(grid_2d, w, M_i, M_o); + } + + template + enable_if_device_vector + assign_crop(TGrid &grid_2d, TVector &M_i, Range_2d &range, + TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid(); + + device_detail::assign_crop_shift_2d<<>>(grid_2d, M_i, range, M_o); + } + + template + enable_if_device_vector + assign_crop_shift_2d(TGrid &grid_2d, TVector &M_i, Range_2d &range, + TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::assign_crop_shift_2d<<>>(grid_2d, M_i, range, M_o); + } + + template + enable_if_device_vector + add_scale_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector &M_i, Range_2d &range, TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::add_scale_crop_shift_2d<<>>(grid_2d, w, M_i, range, M_o); + } + + template + enable_if_device_vector_and_device_vector + add_scale_square_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + auto grid_bt = grid_2d.cuda_grid_h(); + + device_detail::add_scale_square_crop_shift_2d<<>>(grid_2d, w, M_i, range, M_o); + } + + /***************************************************************************/ + /***************************** Device to Host ******************************/ /***************************************************************************/ + template + enable_if_device_vector_and_host_vector + assign_shift_2d(TGrid &grid_2d, TVector_1 &M_i, TVector_2 &M_o, + Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::assign_shift_2d(grid_2d, *M_i_h, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::add_scale_shift_2d(grid_2d, w, *M_i_h, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_square_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::add_scale_square_shift_2d(grid_2d, w, *M_i_h, M_o); + } + + template + enable_if_device_vector_and_host_vector + assign_crop(TGrid &grid_2d, TVector_1 &M_i, Range_2d &range, + TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::assign_crop(grid_2d, *M_i_h, range, M_o); + } + + template + enable_if_device_vector_and_host_vector + assign_crop_shift_2d(TGrid &grid_2d, TVector_1 &M_i, Range_2d &range, + TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::assign_crop_shift_2d(grid_2d, *M_i_h, range, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::add_scale_crop_shift_2d(grid_2d, w, *M_i_h, range, M_o); + } + + template + enable_if_device_vector_and_host_vector + add_scale_square_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Vector, e_host> M_h; + M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + // data transfer from GPU to CPU + M_i_h->assign(M_i.begin(), M_i.end()); + + mt::add_scale_square_crop_shift_2d(grid_2d, w, *M_i_h, range, M_o); + } + + /***************************************************************************/ + /***************************** Host to Device ******************************/ /***************************************************************************/ + template + enable_if_host_vector_and_device_vector + assign_shift_2d(TGrid &grid_2d, TVector_1 &M_i, TVector_2 &M_o, + Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::assign_shift_2d(grid_2d, *M_i_h, M_o); + } + + template + enable_if_host_vector_and_device_vector + add_scale_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::add_scale_shift_2d(grid_2d, w, *M_i_h, M_o); + } + + template + enable_if_host_vector_and_device_vector + add_scale_square_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::add_scale_square_shift_2d(grid_2d, w, *M_i_h, M_o); + } + + template + enable_if_host_vector_and_device_vector + assign_crop(TGrid &grid_2d, TVector_1 &M_i, Range_2d &range, + TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::assign_crop(grid_2d, *M_i_h, range, M_o); + } + + template + enable_if_host_vector_and_device_vector + assign_crop_shift_2d(TGrid &grid_2d, TVector_1 &M_i, Range_2d &range, + TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::assign_crop_shift_2d(grid_2d, *M_i_h, range, M_o); + } + + template + enable_if_host_vector_and_device_vector + add_scale_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::add_scale_crop_shift_2d(grid_2d, w, *M_i_h, range, M_o); + } + + template + enable_if_host_vector_and_device_vector + add_scale_square_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + //Vector, e_host> M_h; + //M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + + //// data transfer from GPU to CPU + //M_i_h->assign(M_i.begin(), M_i.end()); + + //mt::add_scale_square_crop_shift_2d(grid_2d, w, *M_i_h, range, M_o); + } + + /***************************************************************************/ + /***************************************************************************/ template enable_if_device_vector trs(Stream &stream, const int &nrows, const int &ncols, TVector &M) diff --git a/src/fft.cuh b/src/fft.cuh index 69141a3f..dafba7f6 100644 --- a/src/fft.cuh +++ b/src/fft.cuh @@ -91,29 +91,29 @@ namespace mt fftwf_export_wisdom_to_filename("fftwf_1d.wisdom"); } - void create_plan_1d_bc(const int &ny, const int &nx, int nThread=1) + void create_plan_1d_batch(const int &ny, const int &nx, int nThread=1) { destroy_plan(); - fftwf_import_wisdom_from_filename("fftwf_1d_bc.wisdom"); + fftwf_import_wisdom_from_filename("fftwf_1d_batch.wisdom"); fftwf_plan_with_nthreads(nThread); TVector_c M(nx*ny); - fftwf_complex *V = reinterpret_cast(M.data()); + auto V = reinterpret_cast(M.data()); - int rank = 1; /* not 2: we are computing 1d transforms */ - int n[] = {ny}; /* 1d transforms of length ny*/ - int howmany = nx; - int idist = ny, odist = ny; - int istride = 1, ostride = 1; /* distance between two elements in the same column */ - int *inembed = n, *onembed = n; + int rank = 1; // Dimensionality of the transform (1, 2, or 3). + int n[] = {ny}; // 1d transforms of length nx*ny + int how_many = nx; + int idist = ny, odist = ny; // distance between two successive input elements in the least significant + int istride = 1, ostride = 1; // distance between two elements in the same column + int *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions - plan_forward = fftwf_plan_many_dft(rank, n, howmany, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); - plan_backward = fftwf_plan_many_dft(rank, n, howmany, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + plan_forward = fftwf_plan_many_dft(rank, n, how_many, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_many_dft(rank, n, how_many, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); - fftwf_export_wisdom_to_filename("fftwf_1d_bc.wisdom"); + fftwf_export_wisdom_to_filename("fftwf_1d_batch.wisdom"); } void create_plan_2d(const int &ny, const int &nx, int nThread) @@ -126,7 +126,7 @@ namespace mt TVector_c M(nx*ny); - fftwf_complex *V = reinterpret_cast(M.data()); + auto V = reinterpret_cast(M.data()); plan_forward = fftwf_plan_dft_2d(nx, ny, V, V, FFTW_FORWARD, FFTW_MEASURE); plan_backward = fftwf_plan_dft_2d(nx, ny, V, V, FFTW_BACKWARD, FFTW_MEASURE); @@ -134,6 +134,31 @@ namespace mt fftwf_export_wisdom_to_filename("fftwf_2d.wisdom"); } + void create_plan_2d_batch(const int &ny, const int &nx, const int &nz, int nThread) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftwf_2d_batch.wisdom"); + + fftwf_plan_with_nthreads(nThread); + + TVector_c M(nx*ny*nz); + + auto V = reinterpret_cast(M.data()); + + int rank = 2; // Dimensionality of the transform (1, 2, or 3). + int n[] = {nx, ny}; // 2d transforms of length nx*ny + int how_many = nz; + int idist = nx*ny, odist = nx*ny; // distance between two successive input elements in the least significant + int istride = 1, ostride = 1; // distance between two elements in the same column + int *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftwf_plan_many_dft(rank, n, how_many, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftwf_plan_many_dft(rank, n, how_many, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_2d_batch.wisdom"); + } + template void forward(TVector &M_io) { @@ -219,7 +244,7 @@ namespace mt TVector_c M(nx); - fftw_complex *V = reinterpret_cast(M.data()); + auto V = reinterpret_cast(M.data()); plan_forward = fftw_plan_dft_1d(nx, V, V, FFTW_FORWARD, FFTW_MEASURE); plan_backward = fftw_plan_dft_1d(nx, V, V, FFTW_BACKWARD, FFTW_MEASURE); @@ -227,29 +252,29 @@ namespace mt fftw_export_wisdom_to_filename("fftw_1d.wisdom"); } - void create_plan_1d_bc(const int &ny, const int &nx, int nThread=1) + void create_plan_1d_batch(const int &ny, const int &nx, int nThread=1) { destroy_plan(); - fftw_import_wisdom_from_filename("fftw_1d_bc.wisdom"); + fftw_import_wisdom_from_filename("fftw_1d_batch.wisdom"); fftw_plan_with_nthreads(nThread); TVector_c M(nx*ny); - fftw_complex *V = reinterpret_cast(M.data()); + auto V = reinterpret_cast(M.data()); - int rank = 1; /* not 2: we are computing 1d transforms */ - int n[] = {ny}; /* 1d transforms of length ny*/ - int howmany = nx; - int idist = ny, odist = ny; - int istride = 1, ostride = 1; /* distance between two elements in the same column */ - int *inembed = n, *onembed = n; + int rank = 1; // Dimensionality of the transform (1, 2, or 3). + int n[] = {ny}; // 1d transforms of length nx*ny + int how_many = nx; + int idist = ny, odist = ny; // distance between two successive input elements in the least significant + int istride = 1, ostride = 1; // distance between two elements in the same column + int *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions - plan_forward = fftw_plan_many_dft(rank, n, howmany, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); - plan_backward = fftw_plan_many_dft(rank, n, howmany, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + plan_forward = fftw_plan_many_dft(rank, n, how_many, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_many_dft(rank, n, how_many, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); - fftw_export_wisdom_to_filename("fftw_1d_bc.wisdom"); + fftw_export_wisdom_to_filename("fftw_1d_batch.wisdom"); } void create_plan_2d(const int &ny, const int &nx, int nThread) @@ -262,7 +287,7 @@ namespace mt TVector_c M(nx*ny); - fftw_complex *V = reinterpret_cast(M.data()); + auto V = reinterpret_cast(M.data()); plan_forward = fftw_plan_dft_2d(nx, ny, V, V, FFTW_FORWARD, FFTW_MEASURE); plan_backward = fftw_plan_dft_2d(nx, ny, V, V, FFTW_BACKWARD, FFTW_MEASURE); @@ -270,17 +295,42 @@ namespace mt fftw_export_wisdom_to_filename("fftw_2d.wisdom"); } + void create_plan_2d_batch(const int &ny, const int &nx, const int &nz, int nThread) + { + destroy_plan(); + + fftwf_import_wisdom_from_filename("fftw_2d_batch.wisdom"); + + fftwf_plan_with_nthreads(nThread); + + TVector_c M(nx*ny*nz); + + auto V = reinterpret_cast(M.data()); + + int rank = 2; // Dimensionality of the transform (1, 2, or 3). + int n[] = {nx, ny}; // 2d transforms of length nx*ny + int how_many = nz; + int idist = nx*ny, odist = nx*ny; // distance between two successive input elements in the least significant + int istride = 1, ostride = 1; // distance between two elements in the same column + int *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + plan_forward = fftw_plan_many_dft(rank, n, how_many, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_FORWARD, FFTW_MEASURE); + plan_backward = fftw_plan_many_dft(rank, n, how_many, V, inembed, istride, idist, V, onembed, ostride, odist, FFTW_BACKWARD, FFTW_MEASURE); + + fftwf_export_wisdom_to_filename("fftwf_2d_batch.wisdom"); + } + template void forward(TVector &M_io) { - fftw_complex *V_io = reinterpret_cast(M_io.data()); + auto V_io = reinterpret_cast(M_io.data()); fftw_execute_dft(plan_forward, V_io, V_io); } template void inverse(TVector &M_io) { - fftw_complex *V_io = reinterpret_cast(M_io.data()); + auto V_io = reinterpret_cast(M_io.data()); fftw_execute_dft(plan_backward, V_io, V_io); } @@ -353,18 +403,18 @@ namespace mt plan_backward = plan_forward; } - void create_plan_1d_bc(const int &ny, const int &nx, int nThread=1) + void create_plan_1d_batch(const int &ny, const int &nx, int nThread=1) { destroy_plan(); - int rank = 1; /* not 2: we are computing 1d transforms */ - int n[] = {ny}; /* 1d transforms of length ny*/ - int howmany = nx; - int idist = ny, odist = ny; - int istride = 1, ostride = 1; /* distance between two elements in the same column */ - int *inembed = n, *onembed = n; + int rank = 1; // Dimensionality of the transform (1, 2, or 3). + int n[] = {ny}; // 1d transforms of length nx*ny + int how_many = nx; + int idist = ny, odist = ny; // distance between two successive input elements in the least significant + int istride = 1, ostride = 1; // distance between two elements in the same column + int *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions - cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_C2C, howmany); + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_C2C, how_many); plan_backward = plan_forward; } @@ -378,6 +428,27 @@ namespace mt plan_backward = plan_forward; } + void create_plan_2d_batch(const int &ny, const int &nx, const int &nz, int nThread) + { + destroy_plan(); + + int rank = 2; // Dimensionality of the transform (1, 2, or 3). + int n[] = {nx, ny}; // 2d transforms of length nx*ny + int how_many = nz; + int idist = nx*ny, odist = nx*ny; // distance between two successive input elements in the least significant + int istride = 1, ostride = 1; // distance between two elements in the same column + int *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_C2C, how_many); + + plan_backward = plan_forward; + } + + void setstream(cudaStream_t &stream) + { + cufftSetStream(plan_forward, stream); + } + void forward(TVector_c &M_io) { forward(M_io, M_io); @@ -390,15 +461,15 @@ namespace mt void forward(TVector_c &M_i, TVector_c &M_o) { - cufftComplex *V_i = reinterpret_cast(raw_pointer_cast(M_i.data())); - cufftComplex *V_o = reinterpret_cast(raw_pointer_cast(M_o.data())); + auto V_i = reinterpret_cast(raw_pointer_cast(M_i.data())); + auto V_o = reinterpret_cast(raw_pointer_cast(M_o.data())); cufftExecC2C(plan_forward, V_i, V_o, CUFFT_FORWARD); } void inverse(TVector_c &M_i, TVector_c &M_o) { - cufftComplex *V_i = reinterpret_cast(raw_pointer_cast(M_i.data())); - cufftComplex *V_o = reinterpret_cast(raw_pointer_cast(M_o.data())); + auto V_i = reinterpret_cast(raw_pointer_cast(M_i.data())); + auto V_o = reinterpret_cast(raw_pointer_cast(M_o.data())); cufftExecC2C(plan_backward, V_i, V_o, CUFFT_INVERSE); } private: @@ -449,18 +520,18 @@ namespace mt plan_backward = plan_forward; } - void create_plan_1d_bc(const int &ny, const int &nx, int nThread=1) + void create_plan_1d_batch(const int &ny, const int &nx, int nThread=1) { destroy_plan(); - int rank = 1; /* not 2: we are computing 1d transforms */ - int n[] = {ny}; /* 1d transforms of length ny*/ - int howmany = nx; - int idist = ny, odist = ny; - int istride = 1, ostride = 1; /* distance between two elements in the same column */ - int *inembed = n, *onembed = n; + int rank = 1; // Dimensionality of the transform (1, 2, or 3). + int n[] = {ny}; // 1d transforms of length nx*ny + int how_many = nx; + int idist = ny, odist = ny; // distance between two successive input elements in the least significant + int istride = 1, ostride = 1; // distance between two elements in the same column + int *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions - cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_Z2Z, howmany); + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_Z2Z, how_many); plan_backward = plan_forward; } @@ -474,6 +545,22 @@ namespace mt plan_backward = plan_forward; } + void create_plan_2d_batch(const int &ny, const int &nx, const int &nz, int nThread) + { + destroy_plan(); + + int rank = 2; // Dimensionality of the transform (1, 2, or 3). + int n[] = {nx, ny}; // 2d transforms of length nx*ny + int how_many = nz; + int idist = nx*ny, odist = nx*ny; // distance between two successive input elements in the least significant + int istride = 1, ostride = 1; // distance between two elements in the same column + int *inembed = n, *onembed = n; // Pointer of size rank that indicates the storage dimensions + + cufftPlanMany(&plan_forward, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_Z2Z, how_many); + + plan_backward = plan_forward; + } + void forward(TVector_c &M_io) { forward(M_io, M_io); @@ -486,15 +573,15 @@ namespace mt void forward(TVector_c &M_i, TVector_c &M_o) { - cufftDoubleComplex *V_i = reinterpret_cast(raw_pointer_cast(M_i.data())); - cufftDoubleComplex *V_o = reinterpret_cast(raw_pointer_cast(M_o.data())); + auto V_i = reinterpret_cast(raw_pointer_cast(M_i.data())); + auto V_o = reinterpret_cast(raw_pointer_cast(M_o.data())); cufftExecZ2Z(plan_forward, V_i, V_o, CUFFT_FORWARD); } void inverse(TVector_c &M_i, TVector_c &M_o) { - cufftDoubleComplex *V_i = reinterpret_cast(raw_pointer_cast(M_i.data())); - cufftDoubleComplex *V_o = reinterpret_cast(raw_pointer_cast(M_o.data())); + auto V_i = reinterpret_cast(raw_pointer_cast(M_i.data())); + auto V_o = reinterpret_cast(raw_pointer_cast(M_o.data())); cufftExecZ2Z(plan_backward, V_i, V_o, CUFFT_INVERSE); } private: diff --git a/src/host_device_classes.cuh b/src/host_device_classes.cuh index 2ecc65f6..9828001d 100644 --- a/src/host_device_classes.cuh +++ b/src/host_device_classes.cuh @@ -24,6 +24,7 @@ #include "traits.cuh" #include "stream.cuh" #include "fft.cuh" +#include "random.cuh" #ifdef __CUDACC__ #include @@ -153,7 +154,7 @@ namespace mt void set_fft_plan() { - fft_2d->create_plan_1d_bc(grid_2d.ny, grid_2d.nx, stream->size()); + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); } void operator()(T sigma_r, TVector_c &Im) @@ -428,7 +429,7 @@ namespace mt void set_fft_plan() { - fft_2d->create_plan_1d_bc(grid_2d.ny, grid_2d.nx, stream->size()); + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); } void operator()(T sigma_r, T PSNR, TVector_c &Im) @@ -921,42 +922,37 @@ namespace mt /************************Host************************/ template enable_if_dev_host - operator()(TVector &M_i, T theta, r2d p0, T sxy, r2d ps, TVector &M_o) + operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, TVector &M_o) { // calculate background T bg = mean(*stream, M_i); - int nx_o = get_new_size(grid_2d.nx, sxy); - int ny_o = get_new_size(grid_2d.ny, sxy); + int nx_o = get_new_size(grid_2d.nx, sx); + int ny_o = get_new_size(grid_2d.ny, sy); Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); stream->set_n_act_stream(grid_2d_o.nx); stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); - stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sxy, ps, bg, grid_2d_o, M_o); + stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); } /**********************Device**********************/ #ifdef __CUDACC__ template enable_if_dev_device - operator()(TVector &M_i, T theta, r2d p0, T sxy, r2d ps, TVector &M_o) + operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, TVector &M_o) { - if(isEqual(sxy, T(1))) - { - M_o = M_i; - } - // calculate background T bg = mean(*stream, M_i); - int nx_o = max(int(floor(grid_2d.nx*sxy)), 1); - int ny_o = max(int(floor(grid_2d.ny*sxy)), 1); + int nx_o = max(int(floor(grid_2d.nx*sx)), 1); + int ny_o = max(int(floor(grid_2d.ny*sy)), 1); Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); auto grid_bt = grid_2d_o.cuda_grid(); - device_detail::rot_sca_sft_2d, typename TVector::value_type><<>>(grid_2d, M_i, theta, p0, sxy, ps, bg, grid_2d_o, M_o); + device_detail::rot_sca_sft_2d, typename TVector::value_type><<>>(grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); } #endif @@ -991,7 +987,7 @@ namespace mt /************************Host************************/ template enable_if_dev_host - operator()(TVector &M_i, T theta, r2d p0, T sxy, r2d ps, T sim, + operator()(TVector &M_i, T theta, r2d p0, T sx, T sy, r2d ps, T sim, int nx_o, int ny_o, TVector &M_o) { // calculate maximum @@ -1004,15 +1000,15 @@ namespace mt T bg = 0.6*mean(*stream, M_i); - T Rx_0 = p0.x*sxy-(nx_o/2)*grid_2d.dRx; - T Ry_0 = p0.y*sxy-(ny_o/2)*grid_2d.dRy; + T Rx_0 = p0.x*sx-(nx_o/2)*grid_2d.dRx; + T Ry_0 = p0.y*sy-(ny_o/2)*grid_2d.dRy; Grid_2d grid_2d_o(nx_o, ny_o, nx_o*grid_2d.dRx, ny_o*grid_2d.dRy); grid_2d_o.set_R_0(Rx_0, Ry_0); stream->set_n_act_stream(grid_2d_o.nx); stream->set_grid(grid_2d_o.nx, grid_2d_o.ny); - stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sxy, ps, bg, grid_2d_o, M_o); + stream->exec_matrix(host_device_detail::rot_sca_sft_2d, TVector>, grid_2d, M_i, theta, p0, sx, sy, ps, bg, grid_2d_o, M_o); normalized_data(M_o, M_max); @@ -1216,7 +1212,7 @@ namespace mt void set_fft_plan() { - fft_2d->create_plan_1d_bc(grid_2d.ny, grid_2d.nx, stream->size()); + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); } void operator()(T alpha, TVector_r ys, TVector_c &Im) @@ -1503,8 +1499,8 @@ namespace mt void set_fft_plan() { - fft_2d->create_plan_1d_bc(grid_2d.ny, grid_2d.nx, stream->size()); - fft_2d_e.create_plan_1d_bc(grid_2d_e.ny, grid_2d_e.nx, stream->size()); + fft_2d->create_plan_1d_batch(grid_2d.ny, grid_2d.nx, stream->size()); + fft_2d_e.create_plan_1d_batch(grid_2d_e.ny, grid_2d_e.nx, stream->size()); } void operator()(TVector_r &M_r, TVector_r &M_s, T p, T sigma_g, @@ -2242,7 +2238,7 @@ namespace mt { T ee_f = pow(yr[ix]-ys[ix], 2); T ee_df = pow(yr_n[ix]+yr_b[ix]-2*ys[ix], 2); - T chi2_p = alpha*ee_f + beta*ee_df;; + T chi2_p = alpha*ee_f + beta*ee_df; host_device_detail::kh_sum(chi2, chi2_p, chi2_ee); } chi2_pk[ix_pk] = chi2; diff --git a/src/host_device_functions.cuh b/src/host_device_functions.cuh index 5c98fdc7..42187267 100644 --- a/src/host_device_functions.cuh +++ b/src/host_device_functions.cuh @@ -89,6 +89,49 @@ namespace mt return sin(theta)/get_lambda(E_0); } + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // hwhm: Half width at half maximum + // sigma: Standard deviation + template + DEVICE_CALLABLE FORCE_INLINE + T hwhm_2_sigma(const T &v) + { + T c_hwhm_2_sigma = 0.84932180028801907; // hwhm to sigma 1/(sqrt(2*log(2))) + return v*c_hwhm_2_sigma; + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // fwhm: Full width at half maximum + // sigma: Standard deviation + template + DEVICE_CALLABLE FORCE_INLINE + T fwhm_2_sigma(const T &v) + { + T c_fwhm_2_sigma = 0.42466090014400953; // fwhm to sigma 1/(2*sqrt(2*log(2))) + return v*c_fwhm_2_sigma; + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // iehwgd: e^-1 half-width value of the Gaussian distribution + // sigma: Standard deviation + template + DEVICE_CALLABLE FORCE_INLINE + T iehwgd_2_sigma(const T &v) + { + T c_iehwgd_2_sigma = 0.70710678118654746; // iehwgd to sigma 1/sqrt(2) + return v*c_iehwgd_2_sigma; + } + + // Marc De Graef - Introduction to Conventional Transmission Electron Microscopy page: 608 + // sigma: Standard deviation + template + DEVICE_CALLABLE FORCE_INLINE + T rad_2_sigma(const T &E_0, const T &theta) + { + T q0 = sin(theta)/get_lambda(E_0); + return iehwgd_2_sigma(q0); + } + // E. J. Kirkland - Advanced computing in electron microscopy page: 10-13 // Input: E_0(keV), Output: gamma*lambda/c_Potf template @@ -143,9 +186,9 @@ namespace mt { Vector Rm(9); T alpha = 1-cos(theta); - alpha = (isZero(alpha)?0:alpha); + alpha = (isZero(alpha)?0:alpha); T beta = sin(theta); - beta = (isZero(beta)?0:beta); + beta = (isZero(beta)?0:beta); Rm[0] = 1.0 + alpha*(u0.x*u0.x-1); Rm[1] = u0.y*u0.x*alpha + u0.z*beta; Rm[2] = u0.z*u0.x*alpha - u0.y*beta; @@ -1539,7 +1582,6 @@ namespace mt thrust::swap(M_io[ixy], M_io[ixy_shift]); } - template DEVICE_CALLABLE FORCE_INLINE void fft2_shift(const int &ix, const int &iy, const TGrid &grid_2d, TVector &M_io) @@ -1552,7 +1594,190 @@ namespace mt ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, iy); thrust::swap(M_io[ixy], M_io[ixy_shift]); } + + /***************************************************************************/ + template + DEVICE_CALLABLE FORCE_INLINE + void assign_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, + TVector &M_i, TVector &M_o) + { + int ixy = grid_2d.ind_col(ix, iy); + int ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, grid_2d.nyh+iy); + M_o[ixy] = M_i[ixy_shift]; + M_o[ixy_shift] = M_i[ixy]; + + ixy = grid_2d.ind_col(ix, grid_2d.nyh+iy); + ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, iy); + M_o[ixy] = M_i[ixy_shift]; + M_o[ixy_shift] = M_i[ixy]; + } + + template + DEVICE_CALLABLE FORCE_INLINE + void add_scale_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, + const Value_type &w, TVector &M_i, TVector &M_o) + { + int ixy = grid_2d.ind_col(ix, iy); + int ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, grid_2d.nyh+iy); + + M_o[ixy] += w*M_i[ixy_shift]; + M_o[ixy_shift] += w*M_i[ixy]; + + /***************************************************************************/ + ixy = grid_2d.ind_col(ix, grid_2d.nyh+iy); + ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, iy); + + M_o[ixy] += w*M_i[ixy_shift]; + M_o[ixy_shift] += w*M_i[ixy]; + } + + template + DEVICE_CALLABLE FORCE_INLINE + void add_scale_square_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, + const Value_type &w, TVector_1 &M_i, TVector_2 &M_o) + { + int ixy = grid_2d.ind_col(ix, iy); + int ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, grid_2d.nyh+iy); + + M_o[ixy] += w*::norm(M_i[ixy_shift]); + M_o[ixy_shift] += w*::norm(M_i[ixy]); + + /***************************************************************************/ + ixy = grid_2d.ind_col(ix, grid_2d.nyh+iy); + ixy_shift = grid_2d.ind_col(grid_2d.nxh+ix, iy); + + M_o[ixy] += w*::norm(M_i[ixy_shift]); + M_o[ixy_shift] += w*::norm(M_i[ixy]); + } + + /***************************************************************************/ + template + DEVICE_CALLABLE FORCE_INLINE + void assign_crop(const int &ix, const int &iy, const TGrid &grid_2d, TVector &M_i, Range_2d &range, TVector &M_o) + { + if(range.chk_bound(ix, iy)) + { + M_o[range.ind_col_o(ix, iy)] = M_i[grid_2d.ind_col(ix, iy)]; + } + } + template + DEVICE_CALLABLE FORCE_INLINE + void assign_crop_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, TVector &M_i, Range_2d &range, TVector &M_o) + { + int ix_i = ix; + int iy_i = iy; + + int ix_s = grid_2d.nxh+ix; + int iy_s = grid_2d.nyh+iy; + + if(range.chk_bound(ix_i, iy_i)) + { + M_o[range.ind_col_o(ix_i, iy_i)] = M_i[grid_2d.ind_col(ix_s, iy_s)]; + } + + if(range.chk_bound(ix_s, iy_s)) + { + M_o[range.ind_col_o(ix_s, iy_s)] = M_i[grid_2d.ind_col(ix_i, iy_i)]; + } + + /***************************************************************************/ + ix_i = ix; + iy_i = grid_2d.nyh+iy; + + ix_s = grid_2d.nxh+ix; + iy_s = iy; + + if(range.chk_bound(ix_i, iy_i)) + { + M_o[range.ind_col_o(ix_i, iy_i)] = M_i[grid_2d.ind_col(ix_s, iy_s)]; + } + + if(range.chk_bound(ix_s, iy_s)) + { + M_o[range.ind_col_o(ix_s, iy_s)] = M_i[grid_2d.ind_col(ix_i, iy_i)]; + } + } + + template + DEVICE_CALLABLE FORCE_INLINE + void add_scale_crop_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, + const Value_type &w, TVector &M_i, Range_2d &range, TVector &M_o) + { + int ix_i = ix; + int iy_i = iy; + + int ix_s = grid_2d.nxh+ix; + int iy_s = grid_2d.nyh+iy; + + if(range.chk_bound(ix_i, iy_i)) + { + M_o[range.ind_col_o(ix_i, iy_i)] += w*M_i[grid_2d.ind_col(ix_s, iy_s)]; + } + + if(range.chk_bound(ix_s, iy_s)) + { + M_o[range.ind_col_o(ix_s, iy_s)] += w*M_i[grid_2d.ind_col(ix_i, iy_i)]; + } + + /***************************************************************************/ + ix_i = ix; + iy_i = grid_2d.nyh+iy; + + ix_s = grid_2d.nxh+ix; + iy_s = iy; + + if(range.chk_bound(ix_i, iy_i)) + { + M_o[range.ind_col_o(ix_i, iy_i)] += w*M_i[grid_2d.ind_col(ix_s, iy_s)]; + } + + if(range.chk_bound(ix_s, iy_s)) + { + M_o[range.ind_col_o(ix_s, iy_s)] += w*M_i[grid_2d.ind_col(ix_i, iy_i)]; + } + } + + template + DEVICE_CALLABLE FORCE_INLINE + void add_scale_square_crop_shift_2d(const int &ix, const int &iy, const TGrid &grid_2d, + const Value_type &w, TVector_1 &M_i, Range_2d &range, TVector_2 &M_o) + { + int ix_i = ix; + int iy_i = iy; + + int ix_s = grid_2d.nxh+ix; + int iy_s = grid_2d.nyh+iy; + + if(range.chk_bound(ix_i, iy_i)) + { + M_o[range.ind_col_o(ix_i, iy_i)] += w*::norm(M_i[grid_2d.ind_col(ix_s, iy_s)]); + } + + if(range.chk_bound(ix_s, iy_s)) + { + M_o[range.ind_col_o(ix_s, iy_s)] += w*::norm(M_i[grid_2d.ind_col(ix_i, iy_i)]); + } + + /***************************************************************************/ + ix_i = ix; + iy_i = grid_2d.nyh+iy; + + ix_s = grid_2d.nxh+ix; + iy_s = iy; + + if(range.chk_bound(ix_i, iy_i)) + { + M_o[range.ind_col_o(ix_i, iy_i)] += w*::norm(M_i[grid_2d.ind_col(ix_s, iy_s)]); + } + + if(range.chk_bound(ix_s, iy_s)) + { + M_o[range.ind_col_o(ix_s, iy_s)] += w*::norm(M_i[grid_2d.ind_col(ix_i, iy_i)]); + } + } + + /***************************************************************************/ template DEVICE_CALLABLE FORCE_INLINE void sum_over_Det(const int &ix, const int &iy, const TGrid &grid_2d, @@ -1575,7 +1800,7 @@ namespace mt if((g2_min <= g2)&&(g2 <= g2_max)) { int ixy = grid_2d.ind_col(ix, iy); - sum += norm(M_i[ixy]); + sum += norm(M_i[ixy]); } } @@ -1585,7 +1810,7 @@ namespace mt const TVector_1 &S_i, const TVector_2 &M_i, Value_type &sum) { const int ixy = grid_2d.ind_col(ix, iy); - sum += S_i[ixy]*norm(M_i[ixy]); + sum += S_i[ixy] * norm(M_i[ixy]); } template @@ -1616,7 +1841,7 @@ namespace mt const auto m = grid_2d.bwl_factor_shift(ix, iy)/grid_2d.nxy_r(); const auto theta = w*grid_2d.g2_shift(ix, iy, gx_0, gy_0); - psi_o[ixy] = polar(m, theta)*psi_i[ixy]; + psi_o[ixy] = polar(m, theta)*psi_i[ixy]; } /********************* phase shifts real space **********************/ @@ -1793,18 +2018,18 @@ namespace mt if((lens.g2_min <= g2)&&(g2 < lens.g2_max)) { T_r chi = g2*(lens.c_c_30*g2+lens.c_c_10); - T_r c = c_Pi*lens.beta*lens.sf; + T_r c = c_Pi*lens.ssf_beta*lens.dsf_iehwgd; T_r u = 1.0 + 2*c*c*g2; - c = c_Pi*lens.sf*lens.lambda*g2; + c = c_Pi*lens.dsf_iehwgd*lens.lambda*g2; T_r temp_inc = 0.5*c*c; - c = c_Pi*lens.beta*(lens.c_30*lens.lambda2*g2-lens.c_10); + c = c_Pi*lens.ssf_beta*(lens.c_30*lens.lambda2*g2-lens.c_10); T_r spa_inc = c*c*g2; T_r st_inc = exp(-(spa_inc+temp_inc)/u)/sqrt(u); - fPsi_o[ixy] = fPsi_i[ixy]*polar(st_inc, chi); + fPsi_o[ixy] = fPsi_i[ixy]*polar(st_inc, chi); } else { @@ -2153,11 +2378,12 @@ namespace mt template DEVICE_CALLABLE FORCE_INLINE - r2d af_irot_sca_sft(const T &theta, const r2d &p0, const T &fxy, const r2d &ps, r2d p) + r2d af_irot_sca_sft(const T &theta, const r2d &p0, const T &fx, const T &fy, const r2d &ps, r2d p) { T sin_t, cos_t; sincos(theta, &sin_t, &cos_t); - p = (p-ps)/fxy; + p.x = (p.x-ps.x)/fx; + p.y = (p.y-ps.y)/fy; p -= p0; p = r2d(cos_t*p.x+sin_t*p.y, -sin_t*p.x+cos_t*p.y); p += p0; @@ -2229,13 +2455,13 @@ namespace mt template DEVICE_CALLABLE FORCE_INLINE void rot_sca_sft_2d(const int &ix, const int &iy, const TGrid &grid_2d_i, TVector &M_i, - const Value_type &theta, const r2d> &p0, const Value_type &fxy, + const Value_type &theta, const r2d> &p0, const Value_type &fx, const Value_type &fy, const r2d> &ps, const Value_type &bg, const TGrid &grid_2d_o, TVector &M_o) { using T = Value_type; r2d p(grid_2d_o.Rx(ix), grid_2d_o.Ry(iy)); - p = af_irot_sca_sft(theta, p0, fxy, ps, p); + p = af_irot_sca_sft(theta, p0, fx, fy, ps, p); M_o[grid_2d_o.ind_col(ix, iy)] = (grid_2d_i.ckb_bound(p))?interp_bl_2d(p, grid_2d_i, M_i):bg; }; @@ -2980,10 +3206,10 @@ namespace mt }; template - struct add_square_scale + struct add_scale_square { const T w; - add_square_scale(T w_i = T()): w(w_i){} + add_scale_square(T w_i = T()): w(w_i){} template DEVICE_CALLABLE @@ -2991,11 +3217,11 @@ namespace mt }; template - struct add_square_scale_i + struct add_scale_square_i { const T w1; const T w2; - add_square_scale_i(T w1_i = T(), T w2_i = T()): w1(w1_i), w2(w2_i){} + add_scale_square_i(T w1_i = T(), T w2_i = T()): w1(w1_i), w2(w2_i){} template DEVICE_CALLABLE diff --git a/src/host_functions.hpp b/src/host_functions.hpp index 4f3a46f5..dd8d53ad 100644 --- a/src/host_functions.hpp +++ b/src/host_functions.hpp @@ -7,7 +7,7 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * MULTEM is distributed in the hope that it will be useful, + * MULTEM 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. @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -79,34 +78,34 @@ namespace mt namespace host_detail { - template + template void matrix_iter(const Range_2d &range, TFn &fn, TArg &...arg) { - for(auto ix = range.ix_0; ix < range.ix_e; ix++) + for (auto ix = range.ix_0; ix < range.ix_e; ix++) { - for(auto iy = range.iy_0; iy < range.iy_e; iy++) + for (auto iy = range.iy_0; iy < range.iy_e; iy++) { fn(ix, iy, arg...); } } } - template + template void matrix_iter_yx(const Range_2d &range, TFn &fn, TArg &...arg) { - for(auto iy = range.iy_0; iy < range.iy_e; iy++) + for (auto iy = range.iy_0; iy < range.iy_e; iy++) { - for(auto ix = range.ix_0; ix < range.ix_e; ix++) + for (auto ix = range.ix_0; ix < range.ix_e; ix++) { fn(ix, iy, arg...); } } } - template + template void vector_iter(const Range_2d &range, TFn &fn, TArg &...arg) { - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) + for (auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) { fn(ixy, arg...); } @@ -117,9 +116,9 @@ namespace mt { T sum = 0; - for(auto ix_0 = 0; ix_0 < atom_Ip.ixn; ix_0++) + for (auto ix_0 = 0; ix_0 < atom_Ip.ixn; ix_0++) { - for(auto iy_0 = 0; iy_0 < atom_Ip.iyn; iy_0++) + for (auto iy_0 = 0; iy_0 < atom_Ip.iyn; iy_0++) { int ix = ix_0 + atom_Ip.ix_0; int iy = iy_0 + atom_Ip.iy_0; @@ -130,7 +129,7 @@ namespace mt int ixy = grid_2d.ind_col(ix, iy); T M = M_i[ixy]; const T V = host_device_detail::eval_cubic_poly(R2, atom_Ip); - sum += (V-2*M)*V; + sum += (V - 2 * M)*V; } } } @@ -141,10 +140,10 @@ namespace mt template void subtract_atom(Stream &stream, const Grid_2d &grid_2d, const Atom_Sa &atom_Ip, rVector M_i) { - for(auto ix_0 = 0; ix_0 < atom_Ip.ixn; ix_0++) + for (auto ix_0 = 0; ix_0 < atom_Ip.ixn; ix_0++) { int iyc = 0; - for(auto iy_0 = 0; iy_0 < atom_Ip.iyn; iy_0++) + for (auto iy_0 = 0; iy_0 < atom_Ip.iyn; iy_0++) { int ix = ix_0 + atom_Ip.ix_0; int iy = iy_0 + atom_Ip.iy_0; @@ -163,7 +162,7 @@ namespace mt } stream.stream_mutex.lock(); - for(auto iy_0 = 0; iy_0 < iyc; iy_0++) + for (auto iy_0 = 0; iy_0 < iyc; iy_0++) { M_i.V[atom_Ip.iv[iy_0]] -= atom_Ip.v[iy_0]; } @@ -174,18 +173,18 @@ namespace mt // Linear projected potential: V and zV template void linear_Vz(const Q1, e_host> &qz, TAtom &atom) - { + { using T = Value_type; - for(auto iR = 0; iR < c_nR; iR++) + for (auto iR = 0; iR < c_nR; iR++) { T R2 = atom.R2[iR]; T V = 0; T dVir = 0; - T a = (atom.split)?(-atom.z0h):(atom.zeh-atom.z0h); - T b = (atom.split)?(atom.z0h):(atom.zeh+atom.z0h); - for(auto ix = 0; ix < qz.size(); ix++) + T a = (atom.split) ? (-atom.z0h) : (atom.zeh - atom.z0h); + T b = (atom.split) ? (atom.z0h) : (atom.zeh + atom.z0h); + for (auto ix = 0; ix < qz.size(); ix++) { T z = a*qz.x[ix] + b; T r = sqrt(z*z + R2); @@ -199,7 +198,7 @@ namespace mt { T a = atom.zeh; T b = atom.zeh; - for(auto ix = 0; ix < qz.size(); ix++) + for (auto ix = 0; ix < qz.size(); ix++) { T z = a*qz.x[ix] + b; T r = sqrt(z*z + R2); @@ -221,23 +220,23 @@ namespace mt } // Get Local interpolation coefficients - template + template void cubic_poly_coef(TAtom &atom) { - for(auto iR = 0; iR < c_nR-1; iR++) + for (auto iR = 0; iR < c_nR - 1; iR++) { host_device_detail::cubic_poly_coef(iR, atom); } } // Cubic polynomial evaluation - template + template void eval_cubic_poly(Stream &stream, Grid_2d &grid_2d, Atom_Vp &atom, rVector M_o) - { - for(auto ix_0 = 0; ix_0 < atom.nx; ix_0++) + { + for (auto ix_0 = 0; ix_0 < atom.nx; ix_0++) { int iyc = 0; - for(auto iy_0 = 0; iy_0 < atom.ny; iy_0++) + for (auto iy_0 = 0; iy_0 < atom.ny; iy_0++) { int ix = ix_0 + atom.ix_0; int iy = iy_0 + atom.iy_0; @@ -247,7 +246,7 @@ namespace mt { const T V = atom.occ*host_device_detail::eval_cubic_poly(R2, atom); const int ixy = grid_2d.ind_col_pbc_shift(ix, iy); - + atom.iv[iyc] = ixy; atom.v[iyc] = V; iyc++; @@ -255,7 +254,7 @@ namespace mt } stream.stream_mutex.lock(); - for(auto iy_0 = 0; iy_0 < iyc; iy_0++) + for (auto iy_0 = 0; iy_0 < iyc; iy_0++) { M_o.V[atom.iv[iy_0]] += atom.v[iy_0]; } @@ -264,13 +263,13 @@ namespace mt } // Gaussian evaluation - template + template void gauss_eval(Stream &stream, Grid_2d &grid_2d, Gauss_Sp &gauss, rVector M_o) - { - for(auto ix_0 = 0; ix_0 < gauss.nx; ix_0++) + { + for (auto ix_0 = 0; ix_0 < gauss.nx; ix_0++) { int iyc = 0; - for(auto iy_0 = 0; iy_0 < gauss.ny; iy_0++) + for (auto iy_0 = 0; iy_0 < gauss.ny; iy_0++) { int ix = ix_0 + gauss.ix_0; int iy = iy_0 + gauss.iy_0; @@ -285,7 +284,7 @@ namespace mt } stream.stream_mutex.lock(); - for(auto iy_0 = 0; iy_0 < iyc; iy_0++) + for (auto iy_0 = 0; iy_0 < iyc; iy_0++) { M_o.V[gauss.iv[iy_0]] += gauss.v[iy_0]; } @@ -313,7 +312,7 @@ namespace mt stream.set_grid(grid_2d.nx, grid_2d.ny); stream.exec(thr_Lorentz_factor); - return sqrt(eels.occ)/sum; + return sqrt(eels.occ) / sum; } template @@ -341,19 +340,19 @@ namespace mt sx2y += x2*y; } - T det = sx1x1*sx2x2-sx1x2*sx1x2; - a1 = (sx2x2*sx1y-sx1x2*sx2y)/det; - a0 = (sx1x1*sx2y-sx1x2*sx1y)/det; + T det = sx1x1*sx2x2 - sx1x2*sx1x2; + a1 = (sx2x2*sx1y - sx1x2*sx2y) / det; + a0 = (sx1x1*sx2y - sx1x2*sx1y) / det; } template - void fit_gauss_a_c(const TVector &x2_i, const TVector &y_i, Value_type lambdai, - Value_type sigma, Value_type &a, Value_type &c) + void fit_gauss_a_c(const TVector &x2_i, const TVector &y_i, Value_type lambdai, + Value_type sigma, Value_type &a, Value_type &c) { using T = Value_type; // get a, c - T c_0 = 0.5/pow(sigma, 2); + T c_0 = 0.5 / pow(sigma, 2); T sx1x1 = 0; T sx2x2 = 0; T sx1x2 = 0; @@ -372,13 +371,13 @@ namespace mt sx1y += x1*y; sx2y += x2*y; } - T lambda = lambdai*(sx1x1+sx2x2); + T lambda = lambdai*(sx1x1 + sx2x2); sx1x1 += lambda; sx2x2 += lambda; - T det = sx1x1*sx2x2-sx1x2*sx1x2; - a = (sx2x2*sx1y-sx1x2*sx2y)/det; - c = (sx1x1*sx2y-sx1x2*sx1y)/det; + T det = sx1x1*sx2x2 - sx1x2*sx1x2; + a = (sx2x2*sx1y - sx1x2*sx2y) / det; + c = (sx1x1*sx2y - sx1x2*sx1y) / det; } template @@ -387,7 +386,7 @@ namespace mt using T = Value_type; // get a = sum xy/sum x^2 - T c_0 = 0.5/pow(sigma, 2); + T c_0 = 0.5 / pow(sigma, 2); T sx1x1 = 0; T sx1y = 0; @@ -400,13 +399,13 @@ namespace mt sx1y += x1*y; } - return sx1y/sx1x1; + return sx1y / sx1x1; } template - Value_type fit_gauss_sigma(const TVector &x2_i, const TVector &y_i, Value_type a, - Value_type &sigma, Value_type sigma_min, Value_type sigma_max, - int nit, Value_type d_sigma_error) + Value_type fit_gauss_sigma(const TVector &x2_i, const TVector &y_i, Value_type a, + Value_type &sigma, Value_type sigma_min, Value_type sigma_max, + int nit, Value_type d_sigma_error) { using T = Value_type; @@ -414,43 +413,43 @@ namespace mt // get b = sum xy/sum x^2 for (auto it = 0; it < nit; it++) { - T c_0 = 0.5/pow(sigma, 2); - T c_1 = a/pow(sigma, 3); + T c_0 = 0.5 / pow(sigma, 2); + T c_1 = a / pow(sigma, 3); T sx1x1 = 0; T sx1y = 0; for (auto ix = 0; ix < x2_i.size(); ix++) { T f = exp(-c_0*x2_i[ix]); - T x1 = c_1*x2_i[ix]*f; - T y = y_i[ix]-a*f; + T x1 = c_1*x2_i[ix] * f; + T y = y_i[ix] - a*f; sx1x1 += x1*x1; sx1y += x1*y; } - T d_sigma = sx1y/sx1x1; + T d_sigma = sx1y / sx1x1; sigma += d_sigma; // sigma = min(max(sigma, sigma_min), sigma_max); - if(sigma <= sigma_min) + if (sigma <= sigma_min) { sigma = sigma_min; break; } - if(sigma >= sigma_max) + if (sigma >= sigma_max) { sigma = sigma_max; break; } - if (fabs(d_sigma/sigma) @@ -459,7 +458,7 @@ namespace mt using T = Value_type; // get a = sum xy/sum x^2 - T c_0 = 0.5/pow(sigma, 2); + T c_0 = 0.5 / pow(sigma, 2); T sx1x1 = 0; T sx1y = 0; @@ -474,13 +473,13 @@ namespace mt sx1y += x1*y; } - return sx1y/sx1x1; + return sx1y / sx1x1; } template - Value_type fit_gauss_w_sigma(const TVector &x2_i, const TVector &y_i, Value_type a, - Value_type &sigma, Value_type sigma_min, Value_type sigma_max, - int nit, Value_type d_sigma_error) + Value_type fit_gauss_w_sigma(const TVector &x2_i, const TVector &y_i, Value_type a, + Value_type &sigma, Value_type sigma_min, Value_type sigma_max, + int nit, Value_type d_sigma_error) { using T = Value_type; @@ -488,8 +487,8 @@ namespace mt // get b = sum xy/sum x^2 for (auto it = 0; it < nit; it++) { - T c_0 = 0.5/pow(sigma, 2); - T c_1 = a/pow(sigma, 3); + T c_0 = 0.5 / pow(sigma, 2); + T c_1 = a / pow(sigma, 3); T sx1x1 = 0; T sx1y = 0; @@ -498,34 +497,34 @@ namespace mt // T w = 1/::fmax(x2_i[ix], 0.001); T w = x2_i[ix]; T f = exp(-c_0*x2_i[ix]); - T x1 = c_1*x2_i[ix]*f; - T y = y_i[ix]-a*f; + T x1 = c_1*x2_i[ix] * f; + T y = y_i[ix] - a*f; sx1x1 += w*x1*x1; sx1y += w*x1*y; } - T d_sigma = sx1y/sx1x1; + T d_sigma = sx1y / sx1x1; sigma += d_sigma; - if(sigma <= sigma_min) + if (sigma <= sigma_min) { sigma = sigma_min; break; } - if(sigma >= sigma_max) + if (sigma >= sigma_max) { sigma = sigma_max; break; } - if (fabs(d_sigma/sigma) enable_if_host_vector_and_host_vector - assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) { M_o.assign(M_i.begin(), M_i.end()); } template - typename std::enable_if::value - && is_complex>::value && !std::is_same, Value_type>::value, void>::type - assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + typename std::enable_if::value + && is_complex>::value && !std::is_same, Value_type>::value, void>::type + assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) { Vector, e_host> M_h; - M_i_h = (M_i_h == nullptr)?&M_h:M_i_h; + M_i_h = (M_i_h == nullptr) ? &M_h : M_i_h; // copy data to the same output type assign(M_i, *M_i_h); @@ -556,9 +555,9 @@ namespace mt } template - typename std::enable_if::value - && (!is_complex>::value || std::is_same, Value_type>::value), void>::type - assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + typename std::enable_if::value + && (!is_complex>::value || std::is_same, Value_type>::value), void>::type + assign(TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) { M_o.assign(M_i.begin(), M_i.end()); } @@ -569,7 +568,7 @@ namespace mt { auto thr_fill = [&](const Range_2d &range) { - thrust::fill(M_io.begin()+range.ixy_0, M_io.begin()+range.ixy_e, value_i); + thrust::fill(M_io.begin() + range.ixy_0, M_io.begin() + range.ixy_e, value_i); }; stream.set_n_act_stream(M_io.size()); @@ -584,8 +583,8 @@ namespace mt using value_type = Value_type; auto thr_scale = [&](const Range_2d &range) { - thrust::transform(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e, - M_o.begin()+range.ixy_0, functor::scale(w_i)); + thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, + M_o.begin() + range.ixy_0, functor::scale(w_i)); }; stream.set_n_act_stream(M_o.size()); @@ -607,8 +606,8 @@ namespace mt using value_type = Value_type; auto thr_square = [&](const Range_2d &range) { - thrust::transform(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e, - M_o.begin()+range.ixy_0, functor::square()); + thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, + M_o.begin() + range.ixy_0, functor::square()); }; stream.set_n_act_stream(M_o.size()); @@ -623,8 +622,8 @@ namespace mt using value_type = Value_type; auto thr_square_scale = [&](const Range_2d &range) { - thrust::transform(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e, - M_o.begin()+range.ixy_0, functor::square_scale(w_i)); + thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, + M_o.begin() + range.ixy_0, functor::square_scale(w_i)); }; stream.set_n_act_stream(M_o.size()); @@ -639,8 +638,8 @@ namespace mt using value_type = Value_type; auto thr_add = [&](const Range_2d &range) { - thrust::transform(M1_i.begin()+range.ixy_0, M1_i.begin()+range.ixy_e, - M2_i.begin()+range.ixy_0, M_o.begin()+range.ixy_0, functor::add()); + thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, + M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::add()); }; stream.set_n_act_stream(M_o.size()); @@ -657,14 +656,14 @@ namespace mt template enable_if_host_vector_and_host_vector - add_scale(Stream &stream, Value_type w1_i, TVector_1 &M1_i, + add_scale(Stream &stream, Value_type w1_i, TVector_1 &M1_i, Value_type w2_i, TVector_1 &M2_i, TVector_2 &M_o) { using value_type = Value_type; auto thr_add_scale = [&](const Range_2d &range) { - thrust::transform(M1_i.begin()+range.ixy_0, M1_i.begin()+range.ixy_e, - M2_i.begin()+range.ixy_0, M_o.begin()+range.ixy_0, functor::add_scale_i(w1_i, w2_i)); + thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, + M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::add_scale_i(w1_i, w2_i)); }; stream.set_n_act_stream(M_o.size()); @@ -679,8 +678,8 @@ namespace mt using value_type = Value_type; auto thr_add_scale = [&](const Range_2d &range) { - thrust::transform(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e, - M_io.begin()+range.ixy_0, M_io.begin()+range.ixy_0, functor::add_scale(w_i)); + thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, + M_io.begin() + range.ixy_0, M_io.begin() + range.ixy_0, functor::add_scale(w_i)); }; stream.set_n_act_stream(M_io.size()); @@ -695,8 +694,8 @@ namespace mt using value_type = Value_type; auto thr_add_square = [&](const Range_2d &range) { - thrust::transform(M1_i.begin()+range.ixy_0, M1_i.begin()+range.ixy_e, - M2_i.begin()+range.ixy_0, M_o.begin()+range.ixy_0, functor::add_square_i()); + thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, + M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::add_square_i()); }; stream.set_n_act_stream(M_o.size()); @@ -706,13 +705,13 @@ namespace mt template enable_if_host_vector_and_host_vector - add_square(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) + add_square(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) { using value_type = Value_type; auto thr_add_square = [&](const Range_2d &range) { - thrust::transform(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e, - M_io.begin()+range.ixy_0, M_io.begin()+range.ixy_0, functor::add_square()); + thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, + M_io.begin() + range.ixy_0, M_io.begin() + range.ixy_0, functor::add_square()); }; stream.set_n_act_stream(M_io.size()); @@ -722,45 +721,45 @@ namespace mt template enable_if_host_vector_and_host_vector - add_square_scale(Stream &stream, Value_type w1_i, TVector_1 &M1_i, Value_type w2_i, TVector_1 &M2_i, TVector_2 &M_o) + add_scale_square(Stream &stream, Value_type w1_i, TVector_1 &M1_i, Value_type w2_i, TVector_1 &M2_i, TVector_2 &M_o) { using value_type = Value_type; - auto thr_add_square_scale = [&](const Range_2d &range) + auto thr_add_scale_square = [&](const Range_2d &range) { - thrust::transform(M1_i.begin()+range.ixy_0, M1_i.begin()+range.ixy_e, - M2_i.begin()+range.ixy_0, M_o.begin()+range.ixy_0, functor::add_square_scale_i(w1_i, w2_i)); + thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, + M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::add_scale_square_i(w1_i, w2_i)); }; stream.set_n_act_stream(M_o.size()); stream.set_grid(1, M_o.size()); - stream.exec(thr_add_square_scale); + stream.exec(thr_add_scale_square); } template enable_if_host_vector_and_host_vector - add_square_scale(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_io) + add_scale_square(Stream &stream, Value_type w_i, TVector_1 &M_i, TVector_2 &M_io) { using value_type = Value_type; - auto thr_add_square_scale = [&](const Range_2d &range) + auto thr_add_scale_square = [&](const Range_2d &range) { - thrust::transform(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e, - M_io.begin()+range.ixy_0, M_io.begin()+range.ixy_0, functor::add_square_scale(w_i)); + thrust::transform(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, + M_io.begin() + range.ixy_0, M_io.begin() + range.ixy_0, functor::add_scale_square(w_i)); }; stream.set_n_act_stream(M_io.size()); stream.set_grid(1, M_io.size()); - stream.exec(thr_add_square_scale); + stream.exec(thr_add_scale_square); } template enable_if_host_vector_and_host_vector - multiply(Stream &stream, TVector_1 &M1_i, TVector_1 &M2_i, TVector_2 &M_o) + multiply(Stream &stream, TVector_1 &M1_i, TVector_1 &M2_i, TVector_2 &M_o) { using value_type = Value_type; auto thr_multiply = [&](const Range_2d &range) { - thrust::transform(M1_i.begin()+range.ixy_0, M1_i.begin()+range.ixy_e, - M2_i.begin()+range.ixy_0, M_o.begin()+range.ixy_0, functor::multiply()); + thrust::transform(M1_i.begin() + range.ixy_0, M1_i.begin() + range.ixy_e, + M2_i.begin() + range.ixy_0, M_o.begin() + range.ixy_0, functor::multiply()); }; stream.set_n_act_stream(M_o.size()); @@ -770,14 +769,14 @@ namespace mt template enable_if_host_vector_and_host_vector - multiply(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) + multiply(Stream &stream, TVector_1 &M_i, TVector_2 &M_io) { multiply(stream, M_i, M_io, M_io); } template enable_if_host_vector> - sum(Stream &stream, TVector &M_i) + sum(Stream &stream, TVector &M_i) { using value_type = Value_type; @@ -785,7 +784,7 @@ namespace mt value_type sum_ee = 0; auto thr_sum = [&](const Range_2d &range) { - auto sum_partial = thrust::reduce(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e); + auto sum_partial = thrust::reduce(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e); stream.stream_mutex.lock(); host_device_detail::kh_sum(sum_total, sum_partial, sum_ee); @@ -801,7 +800,7 @@ namespace mt template enable_if_host_vector> - sum_square(Stream &stream, TVector &M_i) + sum_square(Stream &stream, TVector &M_i) { using T_r = Value_type_r; @@ -809,8 +808,8 @@ namespace mt T_r sum_ee = 0; auto thr_sum_square = [&](const Range_2d &range) { - auto sum_partial = thrust::transform_reduce(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e, - functor::square(), T_r(0), functor::add()); + auto sum_partial = thrust::transform_reduce(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, + functor::square(), T_r(0), functor::add()); stream.stream_mutex.lock(); host_device_detail::kh_sum(sum_total, sum_partial, sum_ee); @@ -826,14 +825,14 @@ namespace mt template enable_if_host_vector> - mean(Stream &stream, TVector &M_i) + mean(Stream &stream, TVector &M_i) { - return sum(stream, M_i)/M_i.size(); + return sum(stream, M_i) / M_i.size(); } template enable_if_host_vector - mean_var(Stream &stream, TVector &M_i, Value_type &x_mean, Value_type_r &x_var) + mean_var(Stream &stream, TVector &M_i, Value_type &x_mean, Value_type_r &x_var) { using T = Value_type; using T_r = Value_type_r; @@ -843,8 +842,8 @@ namespace mt x_var = 0; auto thr_var = [&](const Range_2d &range) { - auto x_var_partial = thrust::transform_reduce(M_i.begin()+range.ixy_0, M_i.begin()+range.ixy_e, - functor::square_dif(x_mean), T_r(0), functor::add()); + auto x_var_partial = thrust::transform_reduce(M_i.begin() + range.ixy_0, M_i.begin() + range.ixy_e, + functor::square_dif(x_mean), T_r(0), functor::add()); stream.stream_mutex.lock(); x_var += x_var_partial; @@ -855,12 +854,12 @@ namespace mt stream.set_grid(1, M_i.size()); stream.exec(thr_var); - x_var = x_var/M_i.size(); + x_var = x_var / M_i.size(); } template enable_if_host_vector> - variance(Stream &stream, TVector &M_i) + variance(Stream &stream, TVector &M_i) { using T = Value_type; using T_r = Value_type_r; @@ -875,7 +874,7 @@ namespace mt void rescale_data(const Value_type &x_mean, const Value_type &x_std, TVector &x) { using T = Value_type; - std::for_each(x.begin(), x.end(), [=](T &v){ v = (v-x_mean)/x_std; }); + std::for_each(x.begin(), x.end(), [=](T &v) { v = (v - x_mean) / x_std; }); } template @@ -896,13 +895,13 @@ namespace mt { return ::fmax(max_std_data(x), max_std_data(arg...)); } - + /***********************************************************************/ template enable_if_host_vector - exp_r_factor_1d(TGrid &grid_1d, Value_type gx, TVector_c &fPsi_i, TVector_c &fPsi_o) + exp_r_factor_1d(TGrid &grid_1d, Value_type gx, TVector_c &fPsi_i, TVector_c &fPsi_o) { - for(auto ix = 0; ix < grid_1d.nx; ix++) + for (auto ix = 0; ix < grid_1d.nx; ix++) { host_device_detail::exp_r_factor_1d(ix, grid_1d, gx, fPsi_i, fPsi_o); } @@ -910,8 +909,8 @@ namespace mt template enable_if_host_vector - exp_r_factor_2d_bc(Stream &stream, TGrid &grid_2d, Value_type alpha, - TVector_r &gy, TVector_c &fPsi_i, TVector_c &fPsi_o) + exp_r_factor_2d_bc(Stream &stream, TGrid &grid_2d, Value_type alpha, + TVector_r &gy, TVector_c &fPsi_i, TVector_c &fPsi_o) { stream.set_n_act_stream(grid_2d.nx); stream.set_grid(grid_2d.nx, grid_2d.ny); @@ -920,8 +919,8 @@ namespace mt template enable_if_host_vector - exp_r_factor_2d(Stream &stream, TGrid &grid_2d, Value_type gx, Value_type gy, - TVector_c &fPsi_i, TVector_c &fPsi_o) + exp_r_factor_2d(Stream &stream, TGrid &grid_2d, Value_type gx, Value_type gy, + TVector_c &fPsi_i, TVector_c &fPsi_o) { stream.set_n_act_stream(grid_2d.nx); stream.set_grid(grid_2d.nx, grid_2d.ny); @@ -930,8 +929,8 @@ namespace mt template enable_if_host_vector - mul_exp_r_factor_2d(Stream &stream, TGrid &grid_2d, Vector, e_host> &gx, - Vector, e_host> &gy, TVector_c &fPsi_i, TVector_c &fPsi_o) + mul_exp_r_factor_2d(Stream &stream, TGrid &grid_2d, Vector, e_host> &gx, + Vector, e_host> &gy, TVector_c &fPsi_i, TVector_c &fPsi_o) { using TVector_r = Vector, e_host>; @@ -939,13 +938,13 @@ namespace mt stream.set_grid(grid_2d.nx, grid_2d.ny); stream.exec_matrix(host_device_detail::mul_exp_r_factor_2d, grid_2d, gx, gy, fPsi_i, fPsi_o); } - + /***********************************************************************/ template enable_if_host_vector - exp_g_factor_1d(TGrid &grid_1d, Value_type x, TVector_c &fPsi_i, TVector_c &fPsi_o) + exp_g_factor_1d(TGrid &grid_1d, Value_type x, TVector_c &fPsi_i, TVector_c &fPsi_o) { - for(auto ix = 0; ix < grid_1d.nx; ix++) + for (auto ix = 0; ix < grid_1d.nx; ix++) { host_device_detail::exp_g_factor_1d(ix, grid_1d, x, fPsi_i, fPsi_o); } @@ -953,8 +952,8 @@ namespace mt template enable_if_host_vector - exp_g_factor_2d_bc(Stream &stream, TGrid &grid_2d, Value_type alpha, - TVector_r &y, TVector_c &fPsi_i, TVector_c &fPsi_o) + exp_g_factor_2d_bc(Stream &stream, TGrid &grid_2d, Value_type alpha, + TVector_r &y, TVector_c &fPsi_i, TVector_c &fPsi_o) { stream.set_n_act_stream(grid_2d.nx); stream.set_grid(grid_2d.nx, grid_2d.ny); @@ -963,8 +962,8 @@ namespace mt template enable_if_host_vector - exp_g_factor_2d(Stream &stream, TGrid &grid_2d, Value_type x, Value_type y, - TVector_c &fPsi_i, TVector_c &fPsi_o) + exp_g_factor_2d(Stream &stream, TGrid &grid_2d, Value_type x, Value_type y, + TVector_c &fPsi_i, TVector_c &fPsi_o) { stream.set_n_act_stream(grid_2d.nx); stream.set_grid(grid_2d.nx, grid_2d.ny); @@ -973,8 +972,8 @@ namespace mt template enable_if_host_vector - mul_exp_g_factor_2d(Stream &stream, TGrid &grid_2d, Vector, e_host> &x, - Vector, e_host> &y, TVector_c &fPsi_i, TVector_c &fPsi_o) + mul_exp_g_factor_2d(Stream &stream, TGrid &grid_2d, Vector, e_host> &x, + Vector, e_host> &y, TVector_c &fPsi_i, TVector_c &fPsi_o) { using TVector_r = Vector, e_host>; @@ -986,21 +985,21 @@ namespace mt /***********************************************************************/ template enable_if_host_vector> - atom_cost_function(TGrid &grid_2d, const Atom_Sa> &atom_Ip, TVector_r &M_i) + atom_cost_function(TGrid &grid_2d, const Atom_Sa> &atom_Ip, TVector_r &M_i) { return host_detail::atom_cost_function(grid_2d, atom_Ip, M_i); } template enable_if_host_vector - subtract_atom(Stream &stream, TGrid &grid_2d, Vector>, e_host> &atom_Ip, TVector_r &M_i) + subtract_atom(Stream &stream, TGrid &grid_2d, Vector>, e_host> &atom_Ip, TVector_r &M_i) { - if(stream.n_act_stream<= 0) + if (stream.n_act_stream <= 0) { return; } - for(auto istream = 0; istream < stream.n_act_stream; istream++) + for (auto istream = 0; istream < stream.n_act_stream; istream++) { stream[istream] = std::thread(std::bind(host_detail::subtract_atom, std::ref(stream), std::ref(grid_2d), std::ref(atom_Ip[istream]), std::ref(M_i))); } @@ -1010,95 +1009,95 @@ namespace mt // Linear projected potential: V and zV template enable_if_host - linear_Vz(Stream &stream, ePotential_Type potential_type, TQ1 &qz, TVAtom &vatom) + linear_Vz(Stream &stream, ePotential_Type potential_type, TQ1 &qz, TVAtom &vatom) { using TAtom = Value_type; - if(stream.n_act_stream<= 0) + if (stream.n_act_stream <= 0) { return; } auto thr_linear_Vz = [](const ePotential_Type &potential_type, TQ1 &qz, TAtom &atom) { - if(atom.charge == 0) + if (atom.charge == 0) { - switch(potential_type) + switch (potential_type) { - case ePT_Doyle_0_4: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Peng_0_4: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Peng_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Kirkland_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Weickenmeier_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Lobato_0_12: - host_detail::linear_Vz(qz, atom); - break; + case ePT_Doyle_0_4: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Peng_0_4: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Peng_0_12: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Kirkland_0_12: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Weickenmeier_0_12: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Lobato_0_12: + host_detail::linear_Vz(qz, atom); + break; } } else { - switch(potential_type) + switch (potential_type) { - case ePT_Doyle_0_4: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Peng_0_4: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Peng_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Kirkland_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Weickenmeier_0_12: - host_detail::linear_Vz(qz, atom); - break; - case ePT_Lobato_0_12: - host_detail::linear_Vz(qz, atom); - break; + case ePT_Doyle_0_4: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Peng_0_4: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Peng_0_12: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Kirkland_0_12: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Weickenmeier_0_12: + host_detail::linear_Vz(qz, atom); + break; + case ePT_Lobato_0_12: + host_detail::linear_Vz(qz, atom); + break; } } }; - for(auto istream = 0; istream < stream.n_act_stream-1; istream++) + for (auto istream = 0; istream < stream.n_act_stream - 1; istream++) { stream[istream] = std::thread(std::bind(thr_linear_Vz, potential_type, std::ref(qz), std::ref(vatom[istream]))); } - thr_linear_Vz(potential_type, qz, vatom[stream.n_act_stream-1]); + thr_linear_Vz(potential_type, qz, vatom[stream.n_act_stream - 1]); stream.synchronize(); } // Get Local interpolation coefficients - template + template enable_if_host cubic_poly_coef(Stream &stream, TVAtom &vatom) { using TAtom = Value_type; - if(stream.n_act_stream<= 0) + if (stream.n_act_stream <= 0) { return; } - for(auto istream = 0; istream < stream.n_act_stream-1; istream++) + for (auto istream = 0; istream < stream.n_act_stream - 1; istream++) { stream[istream] = std::thread(std::bind(host_detail::cubic_poly_coef, std::ref(vatom[istream]))); } - host_detail::cubic_poly_coef(vatom[stream.n_act_stream-1]); + host_detail::cubic_poly_coef(vatom[stream.n_act_stream - 1]); stream.synchronize(); } @@ -1107,7 +1106,7 @@ namespace mt enable_if_host_vector fft1_shift(TGrid &grid_1d, TVector &M_io) { - for(auto ix = 0; ix < grid_1d.nxh; ix++) + for (auto ix = 0; ix < grid_1d.nxh; ix++) { host_device_detail::fft1_shift(ix, grid_1d, M_io); } @@ -1161,7 +1160,7 @@ namespace mt template enable_if_host_vector> - sum_square_over_Det(Stream &stream, TGrid &grid_2d, Value_type g_min, Value_type g_max, TVector &M_i) + sum_square_over_Det(Stream &stream, TGrid &grid_2d, Value_type g_min, Value_type g_max, TVector &M_i) { using T_r = Value_type; @@ -1188,7 +1187,7 @@ namespace mt template enable_if_host_vector_and_host_vector> - sum_square_over_Det(Stream &stream, TGrid &grid_2d, TVector_1 &S_i, TVector_2 &M_i) + sum_square_over_Det(Stream &stream, TGrid &grid_2d, TVector_1 &S_i, TVector_2 &M_i) { using T_r = Value_type; @@ -1213,7 +1212,7 @@ namespace mt template enable_if_host_vector - bandwidth_limit(Stream &stream, TGrid &grid_2d, TVector_c &M_io) + bandwidth_limit(Stream &stream, TGrid &grid_2d, TVector_c &M_io) { stream.set_n_act_stream(grid_2d.nx); stream.set_grid(grid_2d.nx, grid_2d.ny); @@ -1222,7 +1221,7 @@ namespace mt template enable_if_host_vector - hard_aperture(Stream &stream, TGrid &grid_2d, Value_type g_max, Value_type w, TVector_c &M_io) + hard_aperture(Stream &stream, TGrid &grid_2d, Value_type g_max, Value_type w, TVector_c &M_io) { auto g2_max = pow(g_max, 2); @@ -1233,8 +1232,8 @@ namespace mt template enable_if_host_vector - propagate(Stream &stream, TGrid &grid_2d, Value_type w, - Value_type gxu, Value_type gyu, TVector_c &psi_i, TVector_c &psi_o) + propagate(Stream &stream, TGrid &grid_2d, Value_type w, + Value_type gxu, Value_type gyu, TVector_c &psi_i, TVector_c &psi_o) { stream.set_n_act_stream(grid_2d.nx); stream.set_grid(grid_2d.nx, grid_2d.ny); @@ -1243,15 +1242,15 @@ namespace mt template enable_if_host_vector_and_host_vector - transmission_function(Stream &stream, TGrid &grid_2d, eElec_Spec_Int_Model elec_spec_int_model, - Value_type w, TVector_1 &V0_i, TVector_2 &Trans_o) - { + transmission_function(Stream &stream, TGrid &grid_2d, eElec_Spec_Int_Model elec_spec_int_model, + Value_type w, TVector_1 &V0_i, TVector_2 &Trans_o) + { using T_r = Value_type; auto thr_transmission_funtion = [&](const Range_2d &range) { - thrust::transform(V0_i.begin()+range.ixy_0, V0_i.begin()+range.ixy_e, - Trans_o.begin()+range.ixy_0, functor::transmission_function(w, elec_spec_int_model)); + thrust::transform(V0_i.begin() + range.ixy_0, V0_i.begin() + range.ixy_e, + Trans_o.begin() + range.ixy_0, functor::transmission_function(w, elec_spec_int_model)); }; stream.set_n_act_stream(grid_2d.nxy()); @@ -1261,20 +1260,20 @@ namespace mt template enable_if_host_vector - probe(Stream &stream, TGrid &grid_2d, Lens> &lens, Value_type x, - Value_type y, Value_type gxu, Value_type gyu, TVector_c &fPsi_o) + probe(Stream &stream, TGrid &grid_2d, Lens> &lens, Value_type x, + Value_type y, Value_type gxu, Value_type gyu, TVector_c &fPsi_o) { stream.set_n_act_stream(grid_2d.nx); stream.set_grid(grid_2d.nx, grid_2d.ny); stream.exec_matrix(host_device_detail::probe, grid_2d, lens, x, y, gxu, gyu, fPsi_o); auto total = sum_square(stream, fPsi_o); - mt::scale(stream, sqrt(1.0/total), fPsi_o); + mt::scale(stream, sqrt(1.0 / total), fPsi_o); } template enable_if_host_vector - apply_CTF(Stream &stream, TGrid &grid_2d, Lens> &lens, Value_type gxu, Value_type gyu, TVector_c &fPsi_i, TVector_c &fPsi_o) + apply_CTF(Stream &stream, TGrid &grid_2d, Lens> &lens, Value_type gxu, Value_type gyu, TVector_c &fPsi_i, TVector_c &fPsi_o) { stream.set_n_act_stream(grid_2d.nx); stream.set_grid(grid_2d.nx, grid_2d.ny); @@ -1283,7 +1282,7 @@ namespace mt template enable_if_host_vector - apply_PCTF(Stream &stream, TGrid &grid_2d, Lens> &lens, TVector_c &fPsi_i, TVector_c &fPsi_o) + apply_PCTF(Stream &stream, TGrid &grid_2d, Lens> &lens, TVector_c &fPsi_i, TVector_c &fPsi_o) { stream.set_n_act_stream(grid_2d.nx); stream.set_grid(grid_2d.nx, grid_2d.ny); @@ -1292,7 +1291,7 @@ namespace mt template enable_if_host_vector - kernel_xyz(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_x, TVector_c &k_y, TVector_c &k_z) + kernel_xyz(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_x, TVector_c &k_y, TVector_c &k_z) { eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); @@ -1304,10 +1303,10 @@ namespace mt fft_2d.inverse(k_y); fft_2d.inverse(k_z); } - + template enable_if_host_vector - kernel_x(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_x) + kernel_x(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_x) { eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); @@ -1317,10 +1316,10 @@ namespace mt fft_2d.inverse(k_x); } - + template enable_if_host_vector - kernel_y(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_y) + kernel_y(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_y) { eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); @@ -1330,10 +1329,10 @@ namespace mt fft_2d.inverse(k_y); } - + template enable_if_host_vector - kernel_z(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_z) + kernel_z(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_z) { eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); @@ -1346,7 +1345,7 @@ namespace mt template enable_if_host_vector - kernel_mn1(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_mn1) + kernel_mn1(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_mn1) { eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); @@ -1359,7 +1358,7 @@ namespace mt template enable_if_host_vector - kernel_mp1(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_mp1) + kernel_mp1(Stream &stream, TGrid &grid_2d, EELS> &eels, FFT, e_host> &fft_2d, TVector_c &k_mp1) { eels.factor = host_detail::Lorentz_factor(stream, grid_2d, eels); @@ -1374,7 +1373,7 @@ namespace mt /***************************************************************************/ template enable_if_host_vector_and_host_vector - copy_to_host(Stream &stream, TVector_i &M_i, TVector_o &M_o, + copy_to_host(Stream &stream, TVector_i &M_i, TVector_o &M_o, TVector_i *M_i_h = nullptr) { mt::assign(M_i, M_o, M_i_h); @@ -1382,7 +1381,7 @@ namespace mt template enable_if_host_vector_and_host_vector - add_scale_to_host(Stream &stream, Value_type w_i, + add_scale_to_host(Stream &stream, Value_type w_i, TVector_i &M_i, TVector_o &M_o, TVector_i *M_i_h = nullptr) { mt::add_scale(stream, w_i, M_i, M_o); @@ -1390,19 +1389,99 @@ namespace mt template enable_if_host_vector_and_host_vector - add_square_scale_to_host(Stream &stream, Value_type w_i, + add_scale_square_to_host(Stream &stream, Value_type w_i, TVector_i &M_i, TVector_o &M_o, TVector_i *M_i_h = nullptr) { - mt::add_square_scale(stream, w_i, M_i, M_o); + mt::add_scale_square(stream, w_i, M_i, M_o); } template enable_if_host_vector_and_host_vector - add_scale_m2psi_psi_to_host(Stream &stream, Value_type w_i, + add_scale_m2psi_psi_to_host(Stream &stream, Value_type w_i, TVector_c_i &psi_i, TVector_r_o &m2psi_o, TVector_c_o &psi_o, TVector_c_i *psi_i_h = nullptr) { mt::add_scale(stream, w_i, psi_i, psi_o); - mt::add_square_scale(stream, w_i, psi_i, m2psi_o); + mt::add_scale_square(stream, w_i, psi_i, m2psi_o); + } + + /***************************************************************************/ + /****************************** Host to Host *******************************/ + /***************************************************************************/ + template + enable_if_host_vector + assign_shift_2d(TGrid &grid_2d, TVector &M_i, TVector &M_o, + Vector, e_host> *M_i_h = nullptr) + { + Stream stream(1); + stream.set_n_act_stream(grid_2d.nxh); + stream.set_grid(grid_2d.nxh, grid_2d.nyh); + stream.exec_matrix(host_device_detail::assign_shift_2d, grid_2d, M_i, M_o); + } + + template + enable_if_host_vector + add_scale_shift_2d(TGrid &grid_2d, Value_type w, + TVector &M_i, TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + Stream stream(1); + stream.set_n_act_stream(grid_2d.nxh); + stream.set_grid(grid_2d.nxh, grid_2d.nyh); + stream.exec_matrix(host_device_detail::add_scale_shift_2d, grid_2d, w, M_i, M_o); + } + + template + enable_if_host_vector_and_host_vector + add_scale_square_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Stream stream(1); + stream.set_n_act_stream(grid_2d.nxh); + stream.set_grid(grid_2d.nxh, grid_2d.nyh); + stream.exec_matrix(host_device_detail::add_scale_square_shift_2d, grid_2d, w, M_i, M_o); + } + + template + enable_if_host_vector + assign_crop(TGrid &grid_2d, TVector &M_i, Range_2d &range, + TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + Stream stream(1); + stream.set_n_act_stream(grid_2d.nx); + stream.set_grid(grid_2d.nx, grid_2d.ny); + stream.exec_matrix(host_device_detail::assign_crop, grid_2d, M_i, range, M_o); + } + + template + enable_if_host_vector + assign_crop_shift_2d(TGrid &grid_2d, TVector &M_i, Range_2d &range, + TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + Stream stream(1); + stream.set_n_act_stream(grid_2d.nxh); + stream.set_grid(grid_2d.nxh, grid_2d.nyh); + stream.exec_matrix(host_device_detail::assign_crop_shift_2d, grid_2d, M_i, range, M_o); + } + + template + enable_if_host_vector + add_scale_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector &M_i, Range_2d &range, TVector &M_o, Vector, e_host> *M_i_h = nullptr) + { + Stream stream(1); + stream.set_n_act_stream(grid_2d.nxh); + stream.set_grid(grid_2d.nxh, grid_2d.nyh); + stream.exec_matrix(host_device_detail::add_scale_crop_shift_2d, grid_2d, w, M_i, range, M_o); + } + + template + enable_if_host_vector_and_host_vector + add_scale_square_crop_shift_2d(TGrid &grid_2d, Value_type w, + TVector_1 &M_i, Range_2d &range, TVector_2 &M_o, Vector, e_host> *M_i_h = nullptr) + { + Stream stream(1); + stream.set_n_act_stream(grid_2d.nxh); + stream.set_grid(grid_2d.nxh, grid_2d.nyh); + stream.exec_matrix(host_device_detail::add_scale_square_crop_shift_2d, grid_2d, w, M_i, range, M_o); } /***************************************************************************/ @@ -1421,28 +1500,28 @@ namespace mt /***********************Temporal and Spatial quadratures*********************/ template - void temporal_spatial_quadratures(Lens &lens, Q1 &qt, Q2 &qs) + void obj_lens_temporal_spatial_quadratures(Lens &lens, Q1 &qt, Q2 &qs) { /*********************Temporal quadrature**********************/ Quadrature quadrature; - quadrature.get(8, lens.nsf, qt); // 8: int_-infty^infty f(x) Exp[-x^2] dx - std::for_each(qt.w.begin(), qt.w.end(), [](T &v){ v = v/c_Pii2; }); + quadrature.get(8, lens.dsf_npoints, qt); // 8: int_-infty^infty f(x) Exp[-x^2] dx + std::for_each(qt.w.begin(), qt.w.end(), [](T &v) { v = v / c_Pii2; }); /*********************Spatial quadrature**********************/ - qs.reserve((2*lens.ngxs+1)*(2*lens.ngys+1)); - int iqs = 0; + qs.reserve((2 * lens.ngxs + 1)*(2 * lens.ngys + 1)); + int iqs = 0; T sum_w = 0; T sum_ee = 0; - T alpha = 0.5/pow(lens.sggs, 2); + T alpha = 0.5 / pow(lens.ssf_sigma, 2); - for(auto ix =-lens.ngxs; ix <= lens.ngxs; ix++) + for (auto ix = -lens.ngxs; ix <= lens.ngxs; ix++) { - for(auto iy =-lens.ngys; iy <= lens.ngys; iy++) + for (auto iy = -lens.ngys; iy <= lens.ngys; iy++) { T gxs = lens.gxs(ix); T gys = lens.gys(iy); T g2s = gxs*gxs + gys*gys; - if(g2s < lens.g2_maxs) + if (g2s < lens.g2_maxs) { qs.x.push_back(gxs); qs.y.push_back(gys); @@ -1453,7 +1532,55 @@ namespace mt } } qs.resize(iqs); - std::for_each(qs.w.begin(), qs.w.end(), [sum_w](T &v){ v = v/sum_w; }); + std::for_each(qs.w.begin(), qs.w.end(), [sum_w](T &v) { v = v / sum_w; }); + } + + template + void cond_lens_temporal_spatial_quadratures(Lens &lens, Q1 &qt, Q2 &qs) + { + /*********************Temporal quadrature**********************/ + + if(lens.dsf_npoints>1) + { + Quadrature quadrature; + quadrature.get(8, lens.dsf_npoints, qt); // 8: int_-infty^infty f(x) Exp[-x^2] dx + std::for_each(qt.w.begin(), qt.w.end(), [](double &v) { v /= c_Pii2; }); + } + else + { + qt.resize(1); + qt.x[0] = 0; + qt.w[0] = 1; + } + + /*********************Spatial quadrature**********************/ + + if(lens.ssf_npoints>1) + { + Q1 qs_t; + + Quadrature quadrature; + quadrature.get(8, lens.ssf_npoints, qs_t); // 8: int_-infty^infty f(x) Exp[-x^2] dx + std::for_each(qs_t.w.begin(), qs_t.w.end(), [](double &v) { v /= c_Pii2; }); + + qs.reserve(lens.ssf_npoints*lens.ssf_npoints); + for (auto ix = 0; ix < lens.ssf_npoints; ix++) + { + for (auto iy = 0; iy < lens.ssf_npoints; iy++) + { + qs.x.push_back(qs_t.x[ix]); + qs.y.push_back(qs_t.x[iy]); + qs.w.push_back(qs_t.w[ix]*qs_t.w[iy]); + } + } + } + else + { + qs.resize(1); + qs.x[0] = 0; + qs.y[0] = 0; + qs.w[0] = 1; + } } /***************************************************************************/ @@ -1462,34 +1589,34 @@ namespace mt inline int getIndex(int ixmin, int ixmax, double *x, int typ, double x0) { - int ixmid; - switch(typ) + int ixmid; + switch (typ) { - case 0: - { - do{ - ixmid = (ixmin + ixmax)>>1; // divide by 2 - if(x0 <= x[ixmid]) - ixmax = ixmid; - else - ixmin = ixmid; - }while ((ixmax-ixmin)>1); - } - break; - case 1: - { - do{ - ixmid = (ixmin + ixmax)>>1; // divide by 2 - if(x0 < x[ixmid]) - ixmax = ixmid; - else - ixmin = ixmid; - }while ((ixmax-ixmin)>1); - } - break; + case 0: + { + do { + ixmid = (ixmin + ixmax) >> 1; // divide by 2 + if (x0 <= x[ixmid]) + ixmax = ixmid; + else + ixmin = ixmid; + } while ((ixmax - ixmin) > 1); + } + break; + case 1: + { + do { + ixmid = (ixmin + ixmax) >> 1; // divide by 2 + if (x0 < x[ixmid]) + ixmax = ixmid; + else + ixmin = ixmid; + } while ((ixmax - ixmin) > 1); + } + break; } - if(x0 == x[ixmax]) + if (x0 == x[ixmax]) return ixmax; else return ixmin; @@ -1498,18 +1625,18 @@ namespace mt template void get_bn(const T &R, const int &nR, const T &dR, const T &R_max, const bool &pbc, int &iR0, int &iRn) { - int iR_0 = static_cast(floor((R-R_max)/dR)); - int iR_e = static_cast(ceil((R+R_max)/dR)); + int iR_0 = static_cast(floor((R - R_max) / dR)); + int iR_e = static_cast(ceil((R + R_max) / dR)); - if(!pbc) + if (!pbc) { - auto set_Bound = [](const int &i, const int &n)->int{ return (i<0)?0:((i>=n)?n-1:i); }; + auto set_Bound = [](const int &i, const int &n)->int { return (i < 0) ? 0 : ((i >= n) ? n - 1 : i); }; iR_0 = set_Bound(iR_0, nR); iR_e = set_Bound(iR_e, nR); } iR0 = iR_0; - iRn = (iR_0 == iR_e)?0:iR_e-iR_0+1; + iRn = (iR_0 == iR_e) ? 0 : iR_e - iR_0 + 1; } template @@ -1521,11 +1648,11 @@ namespace mt n++; // add bias term TVector M(m*n); - for(auto in = 0; in < n; in++) + for (auto in = 0; in < n; in++) { - for(auto im = 0; im void rdf_3d(Atom_Data> &atoms, Value_type r_max, int nr, TVector &r, TVector &rdf) - { + { using T = Value_type; - const T dr = r_max/nr; - for(auto ir=0; ir(floor(sqrt(d2)/dr)); + auto ir = static_cast(floor(sqrt(d2) / dr)); rdf[ir] += 1; } } } rdf[0] = 0; - for(auto ir=1; ir - TVector func_gauss_1d(TGrid &grid_1d, Value_type sigma, bool shift, + TVector func_gauss_1d(TGrid &grid_1d, Value_type sigma, bool shift, Border_1d> bd, bool nb = true) - { + { using T = Value_type; Gauss_1d gauss(bd, sigma, nb); TVector f(grid_1d.nx); - for(auto ix = 0; ix < grid_1d.nx; ix++) + for (auto ix = 0; ix < grid_1d.nx; ix++) { - auto Rx2 = (shift)?grid_1d.R2_shift(ix, gauss.x_c):grid_1d.R2(ix, gauss.x_c); + auto Rx2 = (shift) ? grid_1d.R2_shift(ix, gauss.x_c) : grid_1d.R2(ix, gauss.x_c); f[ix] = gauss.eval_norm(Rx2); } return f; } - + // get two dimensional Gaussian Filter template - TVector func_gauss_2d_bc(Stream &stream, TGrid &grid_2d, Value_type sigma, bool shift, + TVector func_gauss_2d_bc(Stream &stream, TGrid &grid_2d, Value_type sigma, bool shift, Border_1d> bd, bool nb = true) - { + { using T = Value_type; Gauss_1d gauss(bd, sigma, nb); TVector fy; fy.reserve(grid_2d.ny); - for(auto iy = 0; iy < grid_2d.ny; iy++) + for (auto iy = 0; iy < grid_2d.ny; iy++) { - auto Ry2 = (shift)?grid_2d.Ry2_shift(iy, gauss.x_c):grid_2d.Ry2(iy, gauss.x_c); + auto Ry2 = (shift) ? grid_2d.Ry2_shift(iy, gauss.x_c) : grid_2d.Ry2(iy, gauss.x_c); fy.push_back(gauss.eval_norm(Ry2)); } @@ -1613,9 +1740,9 @@ namespace mt auto thr_gaussian = [&](const Range_2d &range) { - for(auto ix = range.ixy_0; ix < range.ixy_e; ix++) + for (auto ix = range.ixy_0; ix < range.ixy_e; ix++) { - for(auto iy = 0; iy < grid_2d.ny; iy++) + for (auto iy = 0; iy < grid_2d.ny; iy++) { f[grid_2d.ind_col(ix, iy)] = fy[iy]; } @@ -1631,9 +1758,9 @@ namespace mt // get two dimensional Gaussian Filter template - TVector func_gauss_2d(Stream &stream, TGrid &grid_2d, Value_type sigma, bool shift, + TVector func_gauss_2d(Stream &stream, TGrid &grid_2d, Value_type sigma, bool shift, Border_2d> bd, bool nb = true) - { + { using T = Value_type; Gauss_2d gauss(bd, sigma, nb); @@ -1641,11 +1768,11 @@ namespace mt auto thr_gaussian = [&](const Range_2d &range) { - for(auto ix = range.ix_0; ix < range.ix_e; ix++) + for (auto ix = range.ix_0; ix < range.ix_e; ix++) { - for(auto iy = range.iy_0; iy < range.iy_e; iy++) + for (auto iy = range.iy_0; iy < range.iy_e; iy++) { - T R2 = (shift)?grid_2d.R2_shift(ix, iy, gauss.x_c, gauss.y_c):grid_2d.R2(ix, iy, gauss.x_c, gauss.y_c); + T R2 = (shift) ? grid_2d.R2_shift(ix, iy, gauss.x_c, gauss.y_c) : grid_2d.R2(ix, iy, gauss.x_c, gauss.y_c); f[grid_2d.ind_col(ix, iy)] = gauss.eval_norm(R2); } } @@ -1661,17 +1788,17 @@ namespace mt /********************************************************************/ // get one dimensional Hanning Filter template - TVector func_hanning_1d(TGrid &grid_1d, Value_type k, bool shift, + TVector func_hanning_1d(TGrid &grid_1d, Value_type k, bool shift, Border_1d> bd, bool nb = true) - { + { using T = Value_type; Hanning_1d hann(bd, k, nb); TVector f(grid_1d.nx); - for(auto ix = 0; ix < grid_1d.nx; ix++) + for (auto ix = 0; ix < grid_1d.nx; ix++) { - T Rx = (shift)?grid_1d.Rx_shift(ix, hann.x_c):grid_1d.Rx(ix, hann.x_c); + T Rx = (shift) ? grid_1d.Rx_shift(ix, hann.x_c) : grid_1d.Rx(ix, hann.x_c); f[ix] = hann.eval_norm(Rx); } @@ -1680,18 +1807,18 @@ namespace mt // get two dimensional Hanning by row template - TVector func_hanning_2d_bc(Stream &stream, TGrid &grid_2d, Value_type k, bool shift, + TVector func_hanning_2d_bc(Stream &stream, TGrid &grid_2d, Value_type k, bool shift, Border_1d> bd, bool nb = true) - { + { using T = Value_type; Hanning_1d hann(bd, k, nb); TVector fy; fy.reserve(grid_2d.ny); - for(auto iy = 0; iy < grid_2d.ny; iy++) + for (auto iy = 0; iy < grid_2d.ny; iy++) { - T Ry = (shift)?grid_2d.Ry_shift(iy, hann.x_c):grid_2d.Ry(iy, hann.x_c); + T Ry = (shift) ? grid_2d.Ry_shift(iy, hann.x_c) : grid_2d.Ry(iy, hann.x_c); fy.push_back(hann.eval_norm(Ry)); } @@ -1699,9 +1826,9 @@ namespace mt auto thr_hanning = [&](const Range_2d &range) { - for(auto ix = range.ixy_0; ix < range.ixy_e; ix++) + for (auto ix = range.ixy_0; ix < range.ixy_e; ix++) { - for(auto iy = 0; iy < grid_2d.ny; iy++) + for (auto iy = 0; iy < grid_2d.ny; iy++) { f[grid_2d.ind_col(ix, iy)] = fy[iy]; } @@ -1717,9 +1844,9 @@ namespace mt // get two dimensional Hanning Filter template - TVector func_hanning_2d(Stream &stream, TGrid &grid_2d, Value_type k, bool shift, + TVector func_hanning_2d(Stream &stream, TGrid &grid_2d, Value_type k, bool shift, Border_2d> bd, bool nb = true) - { + { using T = Value_type; Hanning_2d hann(bd, k, nb); @@ -1727,11 +1854,11 @@ namespace mt auto thr_hanning = [&](const Range_2d &range) { - for(auto ix = range.ix_0; ix < range.ix_e; ix++) + for (auto ix = range.ix_0; ix < range.ix_e; ix++) { - for(auto iy = range.iy_0; iy < range.iy_e; iy++) + for (auto iy = range.iy_0; iy < range.iy_e; iy++) { - T R = (shift)?grid_2d.R_shift(ix, iy, hann.x_c, hann.y_c):grid_2d.R(ix, iy, hann.x_c, hann.y_c); + T R = (shift) ? grid_2d.R_shift(ix, iy, hann.x_c, hann.y_c) : grid_2d.R(ix, iy, hann.x_c, hann.y_c); f[grid_2d.ind_col(ix, iy)] = hann.eval_norm(R); } } @@ -1747,7 +1874,7 @@ namespace mt /********************************************************************/ // get one dimensional Butterworth Filter template - TVector func_butterworth_1d(TGrid &grid_1d, Value_type radius, + TVector func_butterworth_1d(TGrid &grid_1d, Value_type radius, int n, bool shift, Border_1d> bd, bool nb = true) { using T = Value_type; @@ -1755,9 +1882,9 @@ namespace mt Butterworth_1d butwth(bd, radius, n, nb); TVector f(grid_1d.nx); - for(auto ix = 0; ix < grid_1d.nx; ix++) + for (auto ix = 0; ix < grid_1d.nx; ix++) { - auto Rx2 = (shift)?grid_1d.R2_shift(ix, butwth.x_c):grid_1d.R2(ix, butwth.x_c); + auto Rx2 = (shift) ? grid_1d.R2_shift(ix, butwth.x_c) : grid_1d.R2(ix, butwth.x_c); f[ix] = butwth.eval_norm(Rx2); } @@ -1766,7 +1893,7 @@ namespace mt // get two dimensional Butterworth Filter template - TVector func_butterworth_2d_bc(Stream &stream, TGrid &grid_2d, Value_type radius, + TVector func_butterworth_2d_bc(Stream &stream, TGrid &grid_2d, Value_type radius, int n, bool shift, Border_1d> bd, bool nb = true) { using T = Value_type; @@ -1776,9 +1903,9 @@ namespace mt fy.reserve(grid_2d.ny); - for(auto iy = 0; iy < grid_2d.ny; iy++) + for (auto iy = 0; iy < grid_2d.ny; iy++) { - auto Ry2 = (shift)?grid_2d.Ry2_shift(iy, butwth.x_c):grid_2d.Ry2(iy, butwth.x_c); + auto Ry2 = (shift) ? grid_2d.Ry2_shift(iy, butwth.x_c) : grid_2d.Ry2(iy, butwth.x_c); fy.push_back(butwth.eval_norm(Ry2)); } @@ -1786,9 +1913,9 @@ namespace mt auto thr_butterworth = [&](const Range_2d &range) { - for(auto ix = range.ixy_0; ix < range.ixy_e; ix++) + for (auto ix = range.ixy_0; ix < range.ixy_e; ix++) { - for(auto iy = 0; iy < grid_2d.ny; iy++) + for (auto iy = 0; iy < grid_2d.ny; iy++) { f[grid_2d.ind_col(ix, iy)] = fy[iy]; } @@ -1804,7 +1931,7 @@ namespace mt // get two dimensional Butterworth Filter template - TVector func_butterworth_2d(Stream &stream, TGrid &grid_2d, Value_type radius, + TVector func_butterworth_2d(Stream &stream, TGrid &grid_2d, Value_type radius, int n, bool shift, Border_2d> bd, bool nb = true) { using T = Value_type; @@ -1815,11 +1942,11 @@ namespace mt auto thr_butterworth = [&](const Range_2d &range) { - for(auto ix = range.ix_0; ix < range.ix_e; ix++) + for (auto ix = range.ix_0; ix < range.ix_e; ix++) { - for(auto iy = range.iy_0; iy < range.iy_e; iy++) + for (auto iy = range.iy_0; iy < range.iy_e; iy++) { - T R2 = (shift)?grid_2d.R2_shift(ix, iy, butwth.x_c, butwth.y_c):grid_2d.R2(ix, iy, butwth.x_c, butwth.y_c); + T R2 = (shift) ? grid_2d.R2_shift(ix, iy, butwth.x_c, butwth.y_c) : grid_2d.R2(ix, iy, butwth.x_c, butwth.y_c); f[grid_2d.ind_col(ix, iy)] = butwth.eval_norm(R2); } } @@ -1836,42 +1963,42 @@ namespace mt // get two dimensional radial distribution for regular grid_2d inline void rad_dist_2d(int nR, double *R, double *fR, int nRl, double *Rl, double *rl, double *frl, double *cfrl, bool reg, int typ) - { - double Rlmin = Rl[0], Rlmax = Rl[nRl-1], dRl = Rl[1]-Rl[0]; - - for(auto i = 0; i < nRl-1; i++) + { + double Rlmin = Rl[0], Rlmax = Rl[nRl - 1], dRl = Rl[1] - Rl[0]; + + for (auto i = 0; i < nRl - 1; i++) { - rl[i] = 0.5*(Rl[i]+Rl[i+1]); + rl[i] = 0.5*(Rl[i] + Rl[i + 1]); frl[i] = 0.0; cfrl[i] = 0.0; } int j; - for(auto i = 0; i < nR; i++) + for (auto i = 0; i < nR; i++) { - if((Rlmin <= R[i])&&(R[i] - void rad_dist_2d(TGrid &grid_2d, TVector &Im, Value_type x_i, - Value_type y_i, Value_type radius_i, TVector &rl, TVector &frl) + void rad_dist_2d(TGrid &grid_2d, TVector &Im, Value_type x_i, + Value_type y_i, Value_type radius_i, TVector &rl, TVector &frl) { using T = Value_type; T dR = grid_2d.dRx; - int nrl = static_cast(floor(radius_i/dR+0.5)); + int nrl = static_cast(floor(radius_i / dR + 0.5)); T R_max = dR*nrl; int ix_0, ixe; @@ -1887,28 +2014,28 @@ namespace mt frl.resize(nrl); TVector cfrl(nrl); - for(auto ir = 0; ir < rl.size(); ir++) + for (auto ir = 0; ir < rl.size(); ir++) { rl[ir] = grid_2d.Rx(ir); frl[ir] = 0.0; cfrl[ir] = 0.0; } - for(auto ix = ix_0; ix < ixe; ix++) + for (auto ix = ix_0; ix < ixe; ix++) { - for(auto iy = iy_0; iy < iye; iy++) + for (auto iy = iy_0; iy < iye; iy++) { T R = grid_2d.R(ix, iy, x_i, y_i); - if(R < R_max) + if (R < R_max) { - auto ir = static_cast(floor(R/dR)); + auto ir = static_cast(floor(R / dR)); frl[ir] += Im[grid_2d.ind_col(ix, iy)]; cfrl[ir] += 1.0; } } } - for(auto ir = 0; ir < rl.size(); ir++) + for (auto ir = 0; ir < rl.size(); ir++) { frl[ir] /= ::fmax(1.0, cfrl[ir]); } @@ -1916,13 +2043,13 @@ namespace mt // cumulative radial distribution template - void cum_rad_dist_2d(TGrid &grid_2d, TVector &Im, Value_type x_i, - Value_type y_i, Value_type radius_i, TVector &rl, TVector &frl) - { + void cum_rad_dist_2d(TGrid &grid_2d, TVector &Im, Value_type x_i, + Value_type y_i, Value_type radius_i, TVector &rl, TVector &frl) + { rad_dist_2d(grid_2d, Im, x_i, y_i, radius_i, rl, frl); - for(auto ir=1; ir - TVector add_poiss_nois(Stream &stream, TVector &M_i, - Value_type scf) - { - using T = Value_type; - - TVector M(M_i.size()); - auto thr_poiss_nois = [&](const Range_2d &range) - { - std::random_device rd; - std::mt19937_64 gen(rd()); - std::poisson_distribution randp; - - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto x0 = scf*M_i[ixy]; - randp.param(std::poisson_distribution::param_type(x0)); - M[ixy] = randp(gen); - } - }; - - stream.set_n_act_stream(M_i.size()); - stream.set_grid(M_i.size(), 1); - stream.exec(thr_poiss_nois); - - return M; - }; - - // add Poisson noise - template - TVector add_poiss_nois_by_SNR(Stream &stream, TVector &Im_i, - Value_type SNR_i, Value_type &scl_o) - { - using T = Value_type; - - auto get_SNR = [](Stream &stream, TVector &Im, T Im_std, T scf)->T - { - T x_mean = 0; - T x_var = 0; - auto thr_SNR = [&](const Range_2d &range) - { - std::mt19937_64 gen; - std::poisson_distribution rand; - - T x_mean_partial = 0; - T x_var_partial = 0; - for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) - { - auto x0 = scf*Im[ixy]; - rand.param(std::poisson_distribution::param_type(x0)); - auto xn = rand(gen)-x0; - x_mean_partial += xn; - x_var_partial += xn*xn; - } - - stream.stream_mutex.lock(); - x_mean += x_mean_partial; - x_var += x_var_partial; - stream.stream_mutex.unlock(); - }; - - stream.set_n_act_stream(Im.size()); - stream.set_grid(1, Im.size()); - stream.exec(thr_SNR); - - x_mean /= Im.size(); - x_var = x_var/Im.size()-x_mean*x_mean; - - return scf*Im_std/sqrt(x_var); - }; - - auto Im_i_std = sqrt(variance(stream, Im_i)); - - T SNR_k = get_SNR(stream, Im_i, Im_i_std, 1); - - T k_0 = 1; - T k_e = 1; - - if(SNR_k= SNR_i); - k_e = 2*k_0; - } - - - // bisection method - int ic = 0; - do - { - scl_o = 0.5*(k_0 + k_e); - auto SNR_k = get_SNR(stream, Im_i, Im_i_std, scl_o); - - if(SNR_k < SNR_i) - { - k_0 = scl_o; - } - else - { - k_e = scl_o; - } - ic++; - } while ((fabs(SNR_i-SNR_k)>0.1) && (ic<10)); - - // add Poisson noise - return add_poiss_nois(stream, Im_i, scl_o); - } - /*******************************************************************/ // add periodic boundary border to the image template @@ -2128,28 +2131,28 @@ namespace mt Prime_Num CP; auto ix_0 = border_x; - auto nx = CP(grid_i.nx+2*border_x, eDST_Greater_Than); + auto nx = CP(grid_i.nx + 2 * border_x, eDST_Greater_Than); auto ixe = ix_0 + grid_i.nx; auto bx_l = border_x; auto bx_r = nx - ixe; auto iy_0 = border_y; - auto ny = CP(grid_i.ny+2*border_y, eDST_Greater_Than); + auto ny = CP(grid_i.ny + 2 * border_y, eDST_Greater_Than); auto iye = iy_0 + grid_i.ny; auto by_t = border_y; auto by_b = ny - iye; grid_o.set_input_data(nx, ny, nx*grid_i.dRx, ny*grid_i.dRy, grid_i.dz, grid_i.bwl, grid_i.pbc_xy); - + image_o.resize(grid_o.nxy()); // copy central image - for(auto ix_o=ix_0; ix_o points = {ix_0, ixe, iy_0, iye}; + vector points = { ix_0, ixe, iy_0, iye }; return points; } @@ -2208,73 +2211,73 @@ namespace mt /*******************************************************************/ // add periodic boundary border to the image template - void set_const_border(TGrid &grid_2d, TVector &image, Value_type xb_0, Value_type xb_e, - Value_type yb_0, Value_type yb_e) + void set_const_border(TGrid &grid_2d, TVector &image, Value_type xb_0, Value_type xb_e, + Value_type yb_0, Value_type yb_e) { using T = Value_type; int ix_0 = grid_2d.ceil_dRx(xb_0); - int ix_e = grid_2d.nx-grid_2d.ceil_dRx(xb_e); + int ix_e = grid_2d.nx - grid_2d.ceil_dRx(xb_e); int iy_0 = grid_2d.ceil_dRy(yb_0); - int iy_e = grid_2d.ny-grid_2d.ceil_dRy(yb_e); + int iy_e = grid_2d.ny - grid_2d.ceil_dRy(yb_e); T val_s = 0; T val_ee = 0; int val_c = 0; - for(auto ix=ix_0; ix - TVector_o extract_region_real_part(Stream &stream, int nx_src, int ny_src, - TVector_i &Im_src, int ix0_src, int ixe_src, int iy0_src, int iye_src) + TVector_o extract_region_real_part(Stream &stream, int nx_src, int ny_src, + TVector_i &Im_src, int ix0_src, int ixe_src, int iy0_src, int iye_src) { auto nx_dst = ixe_src - ix0_src; auto ny_dst = iye_src - iy0_src; @@ -2287,7 +2290,7 @@ namespace mt { for (auto iy = range.iy_0; iy < range.iy_e; iy++) { - Im_dst[ix*ny_dst+iy] = Im_src[(ix0_src+ix)*ny_src+(iy0_src+iy)].real(); + Im_dst[ix*ny_dst + iy] = Im_src[(ix0_src + ix)*ny_src + (iy0_src + iy)].real(); } } }; @@ -2322,8 +2325,8 @@ namespace mt // extract region ix_0<=x - TVector_o extract_region_abs(Stream &stream, int nx_src, int ny_src, - TVector_i &Im_src, int ix0_src, int ixe_src, int iy0_src, int iye_src) + TVector_o extract_region_abs(Stream &stream, int nx_src, int ny_src, + TVector_i &Im_src, int ix0_src, int ixe_src, int iy0_src, int iye_src) { auto nx_dst = ixe_src - ix0_src; auto ny_dst = iye_src - iy0_src; @@ -2336,7 +2339,7 @@ namespace mt { for (auto iy = range.iy_0; iy < range.iy_e; iy++) { - Im_dst[ix*ny_dst+iy] = fabs(Im_src[(ix0_src+ix)*ny_src+(iy0_src+iy)]); + Im_dst[ix*ny_dst + iy] = fabs(Im_src[(ix0_src + ix)*ny_src + (iy0_src + iy)]); } } }; @@ -2377,56 +2380,56 @@ namespace mt using T = Value_type; T dR = grid_2d.dRx; - int nrl = static_cast(floor(radius_i/dR+0.5)); + int nrl = static_cast(floor(radius_i / dR + 0.5)); T R_max = dR*nrl; - auto ix_i = static_cast(floor(p_i.x/dR)); - int ix_0 = max(ix_i-nrl, 0); - int ixe = min(ix_i+nrl+1, grid_2d.nx); + auto ix_i = static_cast(floor(p_i.x / dR)); + int ix_0 = max(ix_i - nrl, 0); + int ixe = min(ix_i + nrl + 1, grid_2d.nx); - auto iy_i = static_cast(floor(p_i.y/dR)); - int iy_0 = max(iy_i-nrl, 0); - int iye = min(iy_i+nrl+1, grid_2d.ny); + auto iy_i = static_cast(floor(p_i.y / dR)); + int iy_0 = max(iy_i - nrl, 0); + int iye = min(iy_i + nrl + 1, grid_2d.ny); T R2_max = pow(R_max, 2); r2d p(0, 0); - T alpha = 0.5/pow(R_max, 2); + T alpha = 0.5 / pow(R_max, 2); T wt = 0; - for(auto ix = ix_0; ix < ixe; ix++) + for (auto ix = ix_0; ix < ixe; ix++) { - for(auto iy = iy_0; iy < iye; iy++) + for (auto iy = iy_0; iy < iye; iy++) { auto R2 = grid_2d.R2(ix, iy, p_i.x, p_i.y); - if(R2 < R2_max) + if (R2 < R2_max) { int ixy = grid_2d.ind_col(ix, iy); - auto imv = ((env)?exp(-alpha*R2):1)*Im[ixy]; - p += imv*r2d(grid_2d.Rx(ix), grid_2d.Ry(iy)); + auto imv = ((env) ? exp(-alpha*R2) : 1)*Im[ixy]; + p += imv*r2d(grid_2d.Rx(ix), grid_2d.Ry(iy)); wt += imv; } } } - p /= wt; + p /= wt; - if(module(p-p_i)>=radius_i) + if (module(p - p_i) >= radius_i) { p = p_i; } return p; } - + // fit gaussian 1d - template - TVector fit_gauss_1d(TGrid &grid_1d, TVector &Im_i, Value_type x_i, - Value_type sigma_i, Value_type radius_i) + template + TVector fit_gauss_1d(TGrid &grid_1d, TVector &Im_i, Value_type x_i, + Value_type sigma_i, Value_type radius_i) { using T = Value_type; - auto select_cir_reg = [](TGrid &grid_1d, TVector &Im, T x0, - T radius, TVector &Rx, TVector &Ix, T &Rx_sf, T &Rx_sc, T &Ix_sc) + auto select_cir_reg = [](TGrid &grid_1d, TVector &Im, T x0, + T radius, TVector &Rx, TVector &Ix, T &Rx_sf, T &Rx_sc, T &Ix_sc) { T R_max = radius; T R2_max = pow(R_max, 2); @@ -2455,8 +2458,8 @@ namespace mt int m = Ix.size(); for (auto ix = 0; ix < m; ix++) { - Rx[ix] = (Rx[ix]-Rx_sf)/Rx_sc; - Ix[ix] = Ix[ix]/Ix_sc; + Rx[ix] = (Rx[ix] - Rx_sf) / Rx_sc; + Ix[ix] = Ix[ix] / Ix_sc; } Rx.shrink_to_fit(); @@ -2468,7 +2471,7 @@ namespace mt select_cir_reg(grid_1d, Im_i, x_i, radius_i, Rx, Ix, Rx_sf, Rx_sc, Ix_sc); - T sigma = sigma_i/Rx_sc; + T sigma = sigma_i / Rx_sc; int m = Ix.size(); int n = 3; @@ -2480,51 +2483,51 @@ namespace mt { T x0 = coef[0]; T A = coef[1]; - T alpha = 0.5/pow(coef[2], 2); + T alpha = 0.5 / pow(coef[2], 2); T chi2 = 0; T chi2_ee = 0; const int m = Ix.size(); for (auto im = 0; im < m; im++) { - T x = Rx[im]-x0; - T v = Ix[im]-A*exp(-alpha*x*x); + T x = Rx[im] - x0; + T v = Ix[im] - A*exp(-alpha*x*x); host_device_detail::kh_sum(chi2, v*v, chi2_ee); } return chi2; }; - auto get_dIx_J = [](TVector &Rx, TVector &Ix, TVector &coef, - TVector &dIx, TVector &J) + auto get_dIx_J = [](TVector &Rx, TVector &Ix, TVector &coef, + TVector &dIx, TVector &J) { T x0 = coef[0]; T A = coef[1]; - T alpha = 0.5/pow(coef[2], 2); + T alpha = 0.5 / pow(coef[2], 2); - T c_x0 = 1.0/pow(coef[2], 2); + T c_x0 = 1.0 / pow(coef[2], 2); T c_A = 1; - T c_sx = 1.0/pow(coef[2], 3); + T c_sx = 1.0 / pow(coef[2], 3); const int m = Ix.size(); for (auto im = 0; im < m; im++) { - T x = Rx[im]-x0; + T x = Rx[im] - x0; T v = exp(-alpha*x*x); T f = A*v; - J[0*m+im] = c_x0*x*f; - J[1*m+im] = c_A*v; - J[2*m+im] = c_sx*x*x*f; + J[0 * m + im] = c_x0*x*f; + J[1 * m + im] = c_A*v; + J[2 * m + im] = c_sx*x*x*f; dIx[im] = Ix[im] - f; } }; - T dx_max = ::fmax(grid_1d.dRx/Rx_sc, 0.25*::fmin(sigma, radius_i/Rx_sc)); + T dx_max = ::fmax(grid_1d.dRx / Rx_sc, 0.25*::fmin(sigma, radius_i / Rx_sc)); - vector c_coef_0 = {0, 1, sigma}; - vector c_coef_min = {-dx_max, 0.5, sigma/3}; - vector c_coef_max = {dx_max, 1.25, 3*sigma}; + vector c_coef_0 = { 0, 1, sigma }; + vector c_coef_min = { -dx_max, 0.5, sigma / 3 }; + vector c_coef_max = { dx_max, 1.25, 3 * sigma }; TVector coef_0 = c_coef_0; TVector coef_min = c_coef_min; @@ -2539,7 +2542,7 @@ namespace mt lapack::FLSF flsf; const int niter = 100; - for (auto iter = 0; iter0) + if (rho > 0) { coef = coef_t; - for(auto ic=0; ic1e-6)?(::fmax(lambda/lambda_f, 1e-7)):lambda; + lambda = (rho > 1e-6) ? (::fmax(lambda / lambda_f, 1e-7)) : lambda; } else { @@ -2585,17 +2588,17 @@ namespace mt } } - coef[0] = coef[0]*Rx_sc + Rx_sf; - coef[1] = coef[1]*Ix_sc; - coef[2] = coef[2]*Rx_sc; + coef[0] = coef[0] * Rx_sc + Rx_sf; + coef[1] = coef[1] * Ix_sc; + coef[2] = coef[2] * Rx_sc; return coef; } // fit gaussian 2d - template - TVector fit_ellipt_gauss_2d(TGrid &grid_2d, TVector &Im_i, r2d> p_i, - Value_type sigma_i, Value_type radius_i) + template + TVector fit_ellipt_gauss_2d(TGrid &grid_2d, TVector &Im_i, r2d> p_i, + Value_type sigma_i, Value_type radius_i) { using T = Value_type; using TRegion = Region; @@ -2604,19 +2607,19 @@ namespace mt { T cos_1t = cos(theta); T sin_1t = sin(theta); - T cos_2t = cos(2*theta); - T sin_2t = sin(2*theta); + T cos_2t = cos(2 * theta); + T sin_2t = sin(2 * theta); T sx2 = pow(sx, 2); T sy2 = pow(sy, 2); - a = 0.5*(cos_1t*cos_1t/sx2 + sin_1t*sin_1t/sy2); - b = 0.5*(sin_1t*sin_1t/sx2 + cos_1t*cos_1t/sy2); - c = 0.5*(-sin_2t/sx2 + sin_2t/sy2); + a = 0.5*(cos_1t*cos_1t / sx2 + sin_1t*sin_1t / sy2); + b = 0.5*(sin_1t*sin_1t / sx2 + cos_1t*cos_1t / sy2); + c = 0.5*(-sin_2t / sx2 + sin_2t / sy2); }; - auto select_cir_reg = [](TGrid &grid_2d, TVector &Im, r2d p, - T radius, TRegion ®ion) + auto select_cir_reg = [](TGrid &grid_2d, TVector &Im, r2d p, + T radius, TRegion ®ion) { T R_max = radius; T R2_max = pow(R_max, 2); @@ -2651,20 +2654,20 @@ namespace mt } } - I_m = I_m/I_c; + I_m = I_m / I_c; region.R_max = R_max; region.Rx_sf = p.x; region.Ry_sf = p.y; region.Rxy_sc = R_max; - region.Ixy_sc = (I_m+max_element(region.Ixy))/2; + region.Ixy_sc = (I_m + max_element(region.Ixy)) / 2; int m = region.Ixy.size(); for (auto ixy = 0; ixy < m; ixy++) { - region.Rx[ixy] = (region.Rx[ixy]-region.Rx_sf)/region.Rxy_sc; - region.Ry[ixy] = (region.Ry[ixy]-region.Ry_sf)/region.Rxy_sc; - region.Ixy[ixy] = region.Ixy[ixy]/region.Ixy_sc; + region.Rx[ixy] = (region.Rx[ixy] - region.Rx_sf) / region.Rxy_sc; + region.Ry[ixy] = (region.Ry[ixy] - region.Ry_sf) / region.Rxy_sc; + region.Ixy[ixy] = region.Ixy[ixy] / region.Ixy_sc; } region.Rx.shrink_to_fit(); @@ -2672,8 +2675,8 @@ namespace mt region.Ixy.shrink_to_fit(); }; - auto select_ellip_reg = [&](TGrid &grid_2d, TVector &Im, TVector &coef, - T f0, TRegion ®ion) + auto select_ellip_reg = [&](TGrid &grid_2d, TVector &Im, TVector &coef, + T f0, TRegion ®ion) { T x_c = coef[0]; T y_c = coef[1]; @@ -2682,10 +2685,10 @@ namespace mt ellipse_var(coef[3], coef[4], coef[5], a, b, c); T d = log(f0); - T dd = c*c-4*a*b; + T dd = c*c - 4 * a*b; - T radius_y = sqrt(fabs(4*a*d/dd)); - T radius_x = sqrt(fabs(4*b*d/dd)); + T radius_y = sqrt(fabs(4 * a*d / dd)); + T radius_x = sqrt(fabs(4 * b*d / dd)); T x_0 = x_c - radius_x; T x_e = x_c + radius_x; @@ -2693,25 +2696,25 @@ namespace mt T y_e = y_c + radius_y; int ix_0 = grid_2d.ceil_dRx(x_0); - int ix_e = grid_2d.floor_dRx(x_e)+1; + int ix_e = grid_2d.floor_dRx(x_e) + 1; int iy_0 = grid_2d.ceil_dRy(y_0); - int iy_e = grid_2d.floor_dRy(y_e)+1; + int iy_e = grid_2d.floor_dRy(y_e) + 1; region.clear(); - region.reserve((ix_e-ix_0)*(iy_e-iy_0)); + region.reserve((ix_e - ix_0)*(iy_e - iy_0)); // select circular region for (auto ix = ix_0; ix < ix_e; ix++) - { - T dx = grid_2d.Rx(ix)-x_c; - T ddy = sqrt(fabs(dd*dx*dx-4*b*d)); + { + T dx = grid_2d.Rx(ix) - x_c; + T ddy = sqrt(fabs(dd*dx*dx - 4 * b*d)); - T y_0 = (-c*dx-ddy)/(2*b)+y_c; - T y_e = (-c*dx+ddy)/(2*b)+y_c; + T y_0 = (-c*dx - ddy) / (2 * b) + y_c; + T y_e = (-c*dx + ddy) / (2 * b) + y_c; int iy_0 = grid_2d.lb_index_y(y_0); - int iy_e = grid_2d.ub_index_y(y_e)+1; + int iy_e = grid_2d.ub_index_y(y_e) + 1; for (auto iy = iy_0; iy < iy_e; iy++) { @@ -2730,9 +2733,9 @@ namespace mt int m = region.Ixy.size(); for (auto ixy = 0; ixy < m; ixy++) { - region.Rx[ixy] = (region.Rx[ixy]-region.Rx_sf)/region.Rxy_sc; - region.Ry[ixy] = (region.Ry[ixy]-region.Ry_sf)/region.Rxy_sc; - region.Ixy[ixy] = region.Ixy[ixy]/region.Ixy_sc; + region.Rx[ixy] = (region.Rx[ixy] - region.Rx_sf) / region.Rxy_sc; + region.Ry[ixy] = (region.Ry[ixy] - region.Ry_sf) / region.Rxy_sc; + region.Ixy[ixy] = region.Ixy[ixy] / region.Ixy_sc; } region.shrink_to_fit(); @@ -2742,7 +2745,7 @@ namespace mt select_cir_reg(grid_2d, Im_i, p_i, radius_i, region); - T sigma = sigma_i/region.Rxy_sc; + T sigma = sigma_i / region.Rxy_sc; auto get_chi2 = [&](TVector &Rx, TVector &Ry, TVector &Ixy, TVector &coef)->T { @@ -2762,16 +2765,16 @@ namespace mt const int m = Ixy.size(); for (auto im = 0; im < m; im++) { - T x = Rx[im]-x_0; - T y = Ry[im]-y_0; - T v = Ixy[im]-A*exp(-a*x*x-b*y*y-c*x*y); + T x = Rx[im] - x_0; + T y = Ry[im] - y_0; + T v = Ixy[im] - A*exp(-a*x*x - b*y*y - c*x*y); host_device_detail::kh_sum(chi2, v*v, chi2_ee); } return chi2; }; - auto get_dIxy_J = [](TVector &Rx, TVector &Ry, TVector &Ixy, TVector &coef, - TVector &dIxy, TVector &J) + auto get_dIxy_J = [](TVector &Rx, TVector &Ry, TVector &Ixy, TVector &coef, + TVector &dIxy, TVector &J) { T x_0 = coef[0]; T y_0 = coef[1]; @@ -2782,8 +2785,8 @@ namespace mt T cos_1t = cos(theta); T sin_1t = sin(theta); - T cos_2t = cos(2*theta); - T sin_2t = sin(2*theta); + T cos_2t = cos(2 * theta); + T sin_2t = sin(2 * theta); T sx2 = pow(coef[3], 2); T sy2 = pow(coef[4], 2); @@ -2791,46 +2794,46 @@ namespace mt T sx3 = pow(coef[3], 3); T sy3 = pow(coef[4], 3); - T a = 0.5*(cos_1t*cos_1t/sx2 + sin_1t*sin_1t/sy2); - T b = 0.5*(sin_1t*sin_1t/sx2 + cos_1t*cos_1t/sy2); - T c = 0.5*(-sin_2t/sx2 + sin_2t/sy2); + T a = 0.5*(cos_1t*cos_1t / sx2 + sin_1t*sin_1t / sy2); + T b = 0.5*(sin_1t*sin_1t / sx2 + cos_1t*cos_1t / sy2); + T c = 0.5*(-sin_2t / sx2 + sin_2t / sy2); const int m = Ixy.size(); for (auto im = 0; im < m; im++) { - T x = Rx[im]-x_0; - T y = Ry[im]-y_0; + T x = Rx[im] - x_0; + T y = Ry[im] - y_0; - T v = exp(-a*x*x-b*y*y-c*x*y); + T v = exp(-a*x*x - b*y*y - c*x*y); T f = A*v; - J[0*m+im] = (2*a*x+c*y)*f; - J[1*m+im] = (2*b*y+c*x)*f; - J[2*m+im] = v; - J[3*m+im] = (pow(cos_1t*x, 2)+pow(sin_1t*y, 2)-sin_2t*x*y)*f/sx3; - J[4*m+im] = (pow(sin_1t*x, 2)+pow(cos_1t*y, 2)+sin_2t*x*y)*f/sy3; - J[5*m+im] = (sin_2t*x*x-sin_2t*y*y+2*cos_2t*x*y)*f*(0.5/sx2-0.5/sy2); + J[0 * m + im] = (2 * a*x + c*y)*f; + J[1 * m + im] = (2 * b*y + c*x)*f; + J[2 * m + im] = v; + J[3 * m + im] = (pow(cos_1t*x, 2) + pow(sin_1t*y, 2) - sin_2t*x*y)*f / sx3; + J[4 * m + im] = (pow(sin_1t*x, 2) + pow(cos_1t*y, 2) + sin_2t*x*y)*f / sy3; + J[5 * m + im] = (sin_2t*x*x - sin_2t*y*y + 2 * cos_2t*x*y)*f*(0.5 / sx2 - 0.5 / sy2); dIxy[im] = Ixy[im] - f; } }; - T dRx = grid_2d.dRx/region.Rxy_sc; - T dRy = grid_2d.dRy/region.Rxy_sc; + T dRx = grid_2d.dRx / region.Rxy_sc; + T dRy = grid_2d.dRy / region.Rxy_sc; // 0.8 = exp(-0.5*f^2) T dx = ::fmax(0.668*sigma, 1.5*dRx); T dy = ::fmax(0.668*sigma, 1.5*dRy); - T sigma_x_min = ::fmax(sigma/4, 0.5*dRx); - T sigma_y_min = ::fmax(sigma/4, 0.5*dRy); + T sigma_x_min = ::fmax(sigma / 4, 0.5*dRx); + T sigma_y_min = ::fmax(sigma / 4, 0.5*dRy); - T sigma_x_max = ::fmin(20*sigma, grid_2d.lxh()/region.Rxy_sc); - T sigma_y_max = ::fmin(20*sigma, grid_2d.lyh()/region.Rxy_sc); + T sigma_x_max = ::fmin(20 * sigma, grid_2d.lxh() / region.Rxy_sc); + T sigma_y_max = ::fmin(20 * sigma, grid_2d.lyh() / region.Rxy_sc); - vector c_coef_0 = {0, 0, 1, sigma, sigma, 0}; - vector c_coef_min = {-dx, -dy, 0.5, sigma_x_min, sigma_y_min, -T(c_Pi)}; - vector c_coef_max = {dx, dy, 1.5, sigma_x_max, sigma_y_max, T(c_Pi)}; + vector c_coef_0 = { 0, 0, 1, sigma, sigma, 0 }; + vector c_coef_min = { -dx, -dy, 0.5, sigma_x_min, sigma_y_min, -T(c_Pi) }; + vector c_coef_max = { dx, dy, 1.5, sigma_x_max, sigma_y_max, T(c_Pi) }; TVector coef_0 = c_coef_0; TVector coef_min = c_coef_min; @@ -2840,7 +2843,7 @@ namespace mt lapack::FLSF flsf; int nit = 4; - for(auto it=0; it0) + if (rho > 0) { coef = coef_t; - for(auto ic=0; ic1e-6)?(::fmax(lambda/lambda_f, 1e-7)):lambda; + lambda = (rho > 1e-6) ? (::fmax(lambda / lambda_f, 1e-7)) : lambda; } else { @@ -2901,13 +2904,13 @@ namespace mt } } - coef[0] = coef[0]*region.Rxy_sc + region.Rx_sf; - coef[1] = coef[1]*region.Rxy_sc + region.Ry_sf; - coef[2] = coef[2]*region.Ixy_sc; - coef[3] = coef[3]*region.Rxy_sc; - coef[4] = coef[4]*region.Rxy_sc; + coef[0] = coef[0] * region.Rxy_sc + region.Rx_sf; + coef[1] = coef[1] * region.Rxy_sc + region.Ry_sf; + coef[2] = coef[2] * region.Ixy_sc; + coef[3] = coef[3] * region.Rxy_sc; + coef[4] = coef[4] * region.Rxy_sc; - if(it(floor(sqrt(R2_d)/dR)); + auto ir = static_cast(floor(sqrt(R2_d) / dR)); frl[ir] += Im_i[grid_i.ind_col(ix, iy)]; cfrl[ir] += 1.0; } } } - for(auto ir=0; irfrl[ir+1]) + if (frl[ir] > frl[ir + 1]) { irm = ir; break; @@ -3010,8 +3013,8 @@ namespace mt // select circular region template - Value_type mean_cir_reg(TGrid &grid_i, TVector &Im_i, r2d> p_i, - Value_type radius_i, Value_type bg_i) + Value_type mean_cir_reg(TGrid &grid_i, TVector &Im_i, r2d> p_i, + Value_type radius_i, Value_type bg_i) { using T = Value_type; @@ -3029,7 +3032,7 @@ namespace mt T R2_d = grid_i.R2(ix, iy, p_i.x, p_i.y); if (R2_d < R2_max) { - I_mean += Im_i[grid_i.ind_col(ix, iy)]-bg_i; + I_mean += Im_i[grid_i.ind_col(ix, iy)] - bg_i; Ic++; } } @@ -3044,12 +3047,12 @@ namespace mt { TVector v; - if(!(grid_2d.ckb_bound(p1) && grid_2d.ckb_bound(p2))) + if (!(grid_2d.ckb_bound(p1) && grid_2d.ckb_bound(p2))) { return v; } - if(module(p1-p2) p12 = p2-p1; + r2d p12 = p2 - p1; T mp12 = p12.module(); - nr = (nr<=0)?static_cast(ceil(mp12/grid_2d.dR_min())):nr; + nr = (nr <= 0) ? static_cast(ceil(mp12 / grid_2d.dR_min())) : nr; nr = max(nr, 2); - T dr = mp12/(nr-1); + T dr = mp12 / (nr - 1); r2d u = dr*normalized(p12); v.reserve(nr); - for(auto ir=0; ir p = p1 + T(ir)*u; v.push_back(interp_2d(p, grid_2d, Im)); } return v; } - + template - void interp_profile(Stream &stream, TGrid &grid_2d, TVector &Im, Value_type bg, r2d> p1, r2d> p2, - TVector &x, TVector &y) + void interp_profile(Stream &stream, TGrid &grid_2d, TVector &Im, Value_type bg, r2d> p1, r2d> p2, + TVector &x, TVector &y) { x.clear(); y.clear(); - if(!(grid_2d.ckb_bound(p1) && grid_2d.ckb_bound(p2))) + if (!(grid_2d.ckb_bound(p1) && grid_2d.ckb_bound(p2))) { return; } - if(module(p1-p2) p12 = p2-p1; + r2d p12 = p2 - p1; T mp12 = p12.module(); int nr = grid_2d.ceil_dR_min(mp12); - T dr = mp12/(nr-1); + T dr = mp12 / (nr - 1); r2d u = dr*normalized(p12); x.reserve(nr); y.reserve(nr); - for(auto ir=0; ir p = p1 + T(ir)*u; T v = interp_2d(p, grid_2d, Im); - y.push_back(v-bg); + y.push_back(v - bg); } } // find one maximum in all areas above the thr - template + template TVector fd_peaks_vector_typ_1(TVector &x, TVector &y, Value_type y_thr) { using T = Value_type; @@ -3171,28 +3174,28 @@ namespace mt T x_max = 0; T y_max = y_thr; - bool bb = y[0]>y_thr; + bool bb = y[0] > y_thr; int ipeak = 0; - for(auto ix=0; ixy_thr) + if (y[ix] > y_thr) { - if(y_max < y[ix]) + if (y_max < y[ix]) { y_max = y[ix]; x_max = x[ix]; } bb = true; } - else if(bb) + else if (bb) { x_peak[ipeak++] = x_max; - y_max = y_thr; + y_max = y_thr; bb = false; } } - if(bb) + if (bb) { x_peak[ipeak++] = x_max; } @@ -3204,18 +3207,18 @@ namespace mt } // find all maximum in all areas above the thr - template + template TVector fd_peaks_vector_typ_2(TVector &x, TVector &y, Value_type y_thr) { using T = Value_type; TVector x_peak; x_peak.reserve(y.size()); - for(auto ix=1; ixy_thr) + if (y[ix] > y_thr) { - if((y[ix-1] enable_if_host_vector> - fit_max_pos_1d(TGrid &grid_1d, TVector &Im, Value_type p_i, - Value_type sigma_i, Value_type radius_i) + fit_max_pos_1d(TGrid &grid_1d, TVector &Im, Value_type p_i, + Value_type sigma_i, Value_type radius_i) { using T = Value_type; @@ -3239,45 +3242,45 @@ namespace mt int ix_c = grid_1d.floor_dRx(p_i); int ix_0 = range.ix_0; - for(auto ix=ix_c-1; ix>=range.ix_0; ix--) + for (auto ix = ix_c - 1; ix >= range.ix_0; ix--) { - if(Im[ix-1]>Im[ix]) + if (Im[ix - 1] > Im[ix]) { - ix_0 = ix; + ix_0 = ix; break; } } int ix_e = range.ix_e; - for(auto ix=ix_c+1; ix<=range.ix_e; ix++) + for (auto ix = ix_c + 1; ix <= range.ix_e; ix++) { - if(Im[ix] enable_if_host_vector>> - fit_max_pos_2d(TGrid &grid_2d, TVector &Im, r2d> p_i, - Value_type sigma_i, Value_type radius_i) + fit_max_pos_2d(TGrid &grid_2d, TVector &Im, r2d> p_i, + Value_type sigma_i, Value_type radius_i) { using T = Value_type; @@ -3304,9 +3307,9 @@ namespace mt { using T = Value_type; - vector> pts_c = {r2d(0, 0), r2d(grid_2d.nx-1, 0), r2d(grid_2d.nx-1, grid_2d.ny-1), r2d(0, grid_2d.ny-1)}; + vector> pts_c = { r2d(0, 0), r2d(grid_2d.nx - 1, 0), r2d(grid_2d.nx - 1, grid_2d.ny - 1), r2d(0, grid_2d.ny - 1) }; - auto n_pp = static_cast(ceil(module(r2d(grid_2d.nx, grid_2d.ny))+2)); + auto n_pp = static_cast(ceil(module(r2d(grid_2d.nx, grid_2d.ny)) + 2)); TVector y_pt(n_pp); TVector c_pt(n_pp); @@ -3316,26 +3319,26 @@ namespace mt // get projected points auto krn_proj_point = [&](const T &cos_d, const T &sin_d, const r2d &p)->r2d { - return r2d(cos_d*p.x+sin_d*p.y, -sin_d*p.x+cos_d*p.y); + return r2d(cos_d*p.x + sin_d*p.y, -sin_d*p.x + cos_d*p.y); }; // get reference corner point auto p_0 = krn_proj_point(cos_d, sin_d, pts_c[0]); - for(auto ixy = 1; ixy < pts_c.size(); ixy++) + for (auto ixy = 1; ixy < pts_c.size(); ixy++) { auto p_r = krn_proj_point(cos_d, sin_d, pts_c[ixy]); - if(p_0.y > p_r.y) + if (p_0.y > p_r.y) { p_0 = p_r; } } - for(auto ix = 0; ix < grid_2d.nx; ix++) + for (auto ix = 0; ix < grid_2d.nx; ix++) { - for(auto iy = 0; iy < grid_2d.ny; iy++) + for (auto iy = 0; iy < grid_2d.ny; iy++) { auto ixy = grid_2d.ind_col(ix, iy); - auto p_r = krn_proj_point(cos_d, sin_d, r2d(ix, iy))-p_0; + auto p_r = krn_proj_point(cos_d, sin_d, r2d(ix, iy)) - p_0; auto j = static_cast(floor(p_r.y)); y_pt[j] += M_i[ixy]; c_pt[j] += 1; @@ -3344,11 +3347,11 @@ namespace mt TVector V_o; V_o.reserve(n_pp); - for(auto j = 0; j < n_pp; j++) + for (auto j = 0; j < n_pp; j++) { - if(c_pt[j]>np_min) + if (c_pt[j] > np_min) { - V_o.push_back(y_pt[j]/c_pt[j]); + V_o.push_back(y_pt[j] / c_pt[j]); } } V_o.shrink_to_fit(); @@ -3358,20 +3361,20 @@ namespace mt // get projective standard deviation template - void PSD(Stream &stream, TGrid &grid_2d, TVector &M_i, Value_type np_min, - Value_type del_0, Value_type del_e, Value_type d_del, TVector &x_o, TVector &y_o) + void PSD(Stream &stream, TGrid &grid_2d, TVector &M_i, Value_type np_min, + Value_type del_0, Value_type del_e, Value_type d_del, TVector &x_o, TVector &y_o) { // get number of angles - auto n_delta = static_cast(floor((del_e-del_0)/d_del + 0.5)); + auto n_delta = static_cast(floor((del_e - del_0) / d_del + 0.5)); x_o.resize(n_delta); y_o.resize(n_delta); auto thr_psd = [&](const Range_2d &range) { - for(auto idel=range.ixy_0; idel - TVector PSD_fd_peaks(Stream &stream, TGrid &grid_2d, TVector &M_i, Value_type np_min, - TVector x_i, TVector y_i) + TVector PSD_fd_peaks(Stream &stream, TGrid &grid_2d, TVector &M_i, Value_type np_min, + TVector x_i, TVector y_i) { using T = Value_type; - T d_del = fabs(x_i[1]-x_i[0]); - int nr = max(1, static_cast(ceil(3.0/d_del))); + T d_del = fabs(x_i[1] - x_i[0]); + int nr = max(1, static_cast(ceil(3.0 / d_del))); auto y_f = ftr_median_1d(stream, y_i, nr); T y_mean = 0; T y_max = y_i[0] - y_f[0]; - for(auto ix=0; ix - int get_dmaxIndex_Point2Line(r2d> p1, r2d> p2, - int ix1, int ix2, TVector &x, TVector &y) + int get_dmaxIndex_Point2Line(r2d> p1, r2d> p2, + int ix1, int ix2, TVector &x, TVector &y) { using T = Value_type; - T c1 = p2.y-p1.y; - T c2 = -(p2.x-p1.x); - T c3 = p2.x*p1.y-p2.y*p1.x; + T c1 = p2.y - p1.y; + T c2 = -(p2.x - p1.x); + T c3 = p2.x*p1.y - p2.y*p1.x; T d = sqrt(c1*c1*+c2*c2); - c1 /= d; - c2 /= d; + c1 /= d; + c2 /= d; c3 /= d; - int ix_max = 0; + int ix_max = 0; T dmax = 0; - for(auto ir = ix1; ir < ix2; ir++) + for (auto ir = ix1; ir < ix2; ir++) { - T x0 = x[ir]; + T x0 = x[ir]; T y0 = y[ir]; - T d = fabs(c1*x0+c2*y0+c3); - if(d>dmax) + T d = fabs(c1*x0 + c2*y0 + c3); + if (d > dmax) { dmax = d; ix_max = ir; @@ -3464,36 +3467,36 @@ namespace mt } inline - double getLengthCurve(int ix1, int ix2, double *x, double *y) + double getLengthCurve(int ix1, int ix2, double *x, double *y) { double x1, y1, x2, y2; double d, dx, dy; d = 0; - for(auto i = ix1; i < ix2-1; i++) + for (auto i = ix1; i < ix2 - 1; i++) { x1 = x[i]; y1 = y[i]; - x2 = x[i+1]; y2 = y[i+1]; - dx = x2-x1; dy = y2-y1; + x2 = x[i + 1]; y2 = y[i + 1]; + dx = x2 - x1; dy = y2 - y1; d = d + sqrt(dx*dx + dy*dy); } return d; } inline - double getLengthCurve(int ix1, int ix2, double *x, double *y, double lmax, int &il) + double getLengthCurve(int ix1, int ix2, double *x, double *y, double lmax, int &il) { double x1, y1, x2, y2; double l, dx, dy; - if(ix10)&&(l>=lmax)) + if ((lmax > 0) && (l >= lmax)) { il = i; break; @@ -3503,13 +3506,13 @@ namespace mt else { l = 0; il = ix2; - for(int i = ix1; i>ix2; i--) + for (int i = ix1; i > ix2; i--) { - x1 = x[i-1]; y1 = y[i-1]; + x1 = x[i - 1]; y1 = y[i - 1]; x2 = x[i]; y2 = y[i]; - dx = x2-x1; dy = y2-y1; + dx = x2 - x1; dy = y2 - y1; l = l + sqrt(dx*dx + dy*dy); - if((lmax>0)&&(l>=lmax)) + if ((lmax > 0) && (l >= lmax)) { il = i; break; @@ -3524,7 +3527,7 @@ namespace mt Value_type info_limit_2d(TGrid &grid_2d, TVector &fM_i) { using T = Value_type; - + TVector r, fr; // cumulative radial integration @@ -3532,14 +3535,14 @@ namespace mt // shift and normalize T r0 = r[0], fIr0 = fr[0]; - for(auto ir = 0; ir(5, fr.size()/100); + int nkr = max(5, fr.size() / 100); fr = smooth(fr, nkr); r2d p1(r.front(), fr.front()); @@ -3566,7 +3569,7 @@ namespace mt { using T = Value_type; - dv = ::max(dv, 0.1); + dv = ::fmax(dv, T(0.1)); TVector vr(vr_first, vr_last); @@ -3579,7 +3582,7 @@ namespace mt // remove elements of vs outside the range auto remove = [vr_min, vr_max](T a)->bool { - return ((avr_max)); + return ((a < vr_min) || (a > vr_max)); }; vs.erase(std::remove_if(vs.begin(), vs.end(), remove), vs.end()); @@ -3588,13 +3591,13 @@ namespace mt TVector A_d; A_d.reserve(m_size); - for(auto i = 0; i(val)); auto imin = static_cast(it - vr.begin()); - if(vr_c[imin]) + if (vr_c[imin]) { vr_c[imin] = false; A_d.push_back(*it); @@ -3604,185 +3607,185 @@ namespace mt vs.shrink_to_fit(); } - /************************ read matlab binary file ***********************/ - template - enable_if_real - read_mat_matrix(std::ifstream &bin_file, int nxy, TVector &matrix) - { - using T_o = Value_type; - - vector vect_r(nxy); - bin_file.read(reinterpret_cast(vect_r.data()), nxy*sizeof(T_i)); - - for(auto ik=0; ik - enable_if_complex - read_mat_matrix(std::ifstream &bin_file, int nxy, TVector &matrix) - { - using T = Value_type_r; - using T_o = Value_type_r; - - vector vect_r(nxy); - bin_file.read(reinterpret_cast(vect_r.data()), nxy*sizeof(T)); - vector vect_i(nxy); - bin_file.read(reinterpret_cast(vect_i.data()), nxy*sizeof(T)); - - auto matrix_ptr = reinterpret_cast*>(matrix.data()); - - for(auto ik=0; ik - void read_mat_binary_matrix(const char *filename, Grid_2d> &grid_2d, TVector &matrix) - { - int nx, ny; - double dx, dy; - int type; - - std::ifstream bin_file(filename, std::ofstream::binary); - bin_file.read(reinterpret_cast(&nx), sizeof(int)); - bin_file.read(reinterpret_cast(&ny), sizeof(int)); - bin_file.read(reinterpret_cast(&dx), sizeof(double)); - bin_file.read(reinterpret_cast(&dy), sizeof(double)); - bin_file.read(reinterpret_cast(&type), sizeof(int)); - - grid_2d.set_input_data(nx, ny, nx*dx, ny*dy); - - auto nxy = nx*ny; - matrix.resize(nxy); - - switch (type) - { - case 1: - { - read_mat_matrix(bin_file, nxy, matrix); - } - break; - case 2: - { - read_mat_matrix(bin_file, nxy, matrix); - } - break; - case 3: - { - read_mat_matrix>(bin_file, nxy, matrix); - } - break; - case 4: - { - read_mat_matrix>(bin_file, nxy, matrix); - } - break; - } - bin_file.close(); - } - /************************ write matlab binary file ***********************/ - template - enable_if_real_host_vector - write_mat_matrix(std::ofstream &bin_file, TVector &matrix) - { - //using T = Value_type; - - //bin_file.write(reinterpret_cast(matrix.data()), matrix.size()*sizeof(T)); - } - - template - enable_if_complex_host_vector - write_mat_matrix(std::ofstream &bin_file, TVector &matrix) - { - //using T = Value_type_r; - - //vector vect_r(nxy); - //vector vect_i(nxy); - //for (auto ik = 0; ik(vect_r.data()), matrix.size()*sizeof(T)); - //bin_file.write(reinterpret_cast(vect_i.data()), matrix.size()*sizeof(T)); - } - - template - void write_mat_binary_matrix(const char *filename, Grid_2d> &grid_2d, TVector &matrix) - { - //int type = matrix_type; - - //std::ofstream bin_file(filename, std::ofstream::binary); - //bin_file.write(reinterpret_cast(&(grid_2d.nx)), sizeof(int)); - //bin_file.write(reinterpret_cast(&(grid_2d.ny)), sizeof(int)); - //bin_file.write(reinterpret_cast(&(grid_2d.dRx)), sizeof(double)); - //bin_file.write(reinterpret_cast(&(grid_2d.dRy)), sizeof(double)); - //bin_file.write(reinterpret_cast(&type), sizeof(int)); - - //switch (type) - //{ - //case 1: - //{ - // write_mat_matrix(bin_file, matrix); - //} - //break; - //case 2: - //{ - // write_mat_matrix(bin_file, matrix); - //} - //break; - //case 3: - //{ - // write_mat_matrix>(bin_file, matrix); - //} - //break; - //case 4: - //{ - // write_mat_matrix>(bin_file, matrix); - //} - //break; - //} - //bin_file.close(); - } - - /************************ extract real vector form complex vector**********************/ + /************************ read matlab binary file ***********************/ + template + enable_if_real + read_mat_matrix(std::ifstream &bin_file, int nxy, TVector &matrix) + { + using T_o = Value_type; + + vector vect_r(nxy); + bin_file.read(reinterpret_cast(vect_r.data()), nxy * sizeof(T_i)); + + for (auto ik = 0; ik < nxy; ik++) + { + matrix[ik] = T_o(vect_r[ik]); + } + } + + template + enable_if_complex + read_mat_matrix(std::ifstream &bin_file, int nxy, TVector &matrix) + { + using T = Value_type_r; + using T_o = Value_type_r; + + vector vect_r(nxy); + bin_file.read(reinterpret_cast(vect_r.data()), nxy * sizeof(T)); + vector vect_i(nxy); + bin_file.read(reinterpret_cast(vect_i.data()), nxy * sizeof(T)); + + auto matrix_ptr = reinterpret_cast*>(matrix.data()); + + for (auto ik = 0; ik < nxy; ik++) + { + matrix_ptr[ik].real(vect_r[ik]); + matrix_ptr[ik].imag(vect_i[ik]); + } + } + + template + void read_mat_binary_matrix(const char *filename, Grid_2d> &grid_2d, TVector &matrix) + { + int nx, ny; + double dx, dy; + int type; + + std::ifstream bin_file(filename, std::ofstream::binary); + bin_file.read(reinterpret_cast(&nx), sizeof(int)); + bin_file.read(reinterpret_cast(&ny), sizeof(int)); + bin_file.read(reinterpret_cast(&dx), sizeof(double)); + bin_file.read(reinterpret_cast(&dy), sizeof(double)); + bin_file.read(reinterpret_cast(&type), sizeof(int)); + + grid_2d.set_input_data(nx, ny, nx*dx, ny*dy); + + auto nxy = nx*ny; + matrix.resize(nxy); + + switch (type) + { + case 1: + { + read_mat_matrix(bin_file, nxy, matrix); + } + break; + case 2: + { + read_mat_matrix(bin_file, nxy, matrix); + } + break; + case 3: + { + read_mat_matrix>(bin_file, nxy, matrix); + } + break; + case 4: + { + read_mat_matrix>(bin_file, nxy, matrix); + } + break; + } + bin_file.close(); + } + /************************ write matlab binary file ***********************/ + template + enable_if_real_host_vector + write_mat_matrix(std::ofstream &bin_file, TVector &matrix) + { + //using T = Value_type; + + //bin_file.write(reinterpret_cast(matrix.data()), matrix.size()*sizeof(T)); + } + + template + enable_if_complex_host_vector + write_mat_matrix(std::ofstream &bin_file, TVector &matrix) + { + //using T = Value_type_r; + + //vector vect_r(nxy); + //vector vect_i(nxy); + //for (auto ik = 0; ik(vect_r.data()), matrix.size()*sizeof(T)); + //bin_file.write(reinterpret_cast(vect_i.data()), matrix.size()*sizeof(T)); + } + + template + void write_mat_binary_matrix(const char *filename, Grid_2d> &grid_2d, TVector &matrix) + { + //int type = matrix_type; + + //std::ofstream bin_file(filename, std::ofstream::binary); + //bin_file.write(reinterpret_cast(&(grid_2d.nx)), sizeof(int)); + //bin_file.write(reinterpret_cast(&(grid_2d.ny)), sizeof(int)); + //bin_file.write(reinterpret_cast(&(grid_2d.dRx)), sizeof(double)); + //bin_file.write(reinterpret_cast(&(grid_2d.dRy)), sizeof(double)); + //bin_file.write(reinterpret_cast(&type), sizeof(int)); + + //switch (type) + //{ + //case 1: + //{ + // write_mat_matrix(bin_file, matrix); + //} + //break; + //case 2: + //{ + // write_mat_matrix(bin_file, matrix); + //} + //break; + //case 3: + //{ + // write_mat_matrix>(bin_file, matrix); + //} + //break; + //case 4: + //{ + // write_mat_matrix>(bin_file, matrix); + //} + //break; + //} + //bin_file.close(); + } + + /************************ extract real vector form complex vector**********************/ template void from_complex_to_real(eShow_CData show_data, TVector_c &cdata, TVector_r &data) { - switch(show_data) + switch (show_data) { - case eSCD_CReal: - { - for(auto ixy=0; ixycond_lens.c_10 ; + auto f_0 = input_multislice->cond_lens.c_10; auto f_s = f_0 - (input_multislice->cond_lens.zero_defocus_plane-z_init); input_multislice->cond_lens.set_defocus(f_s); @@ -128,8 +128,6 @@ namespace mt } mt::copy_to_host(output_multislice.stream, psi, output_multislice.psi_0[0]); - output_multislice.shift(); - output_multislice.clear_temporal_data(); } private: diff --git a/src/input_multislice.cuh b/src/input_multislice.cuh index c220aefb..5fb12512 100644 --- a/src/input_multislice.cuh +++ b/src/input_multislice.cuh @@ -7,7 +7,7 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * MULTEM is distributed in the hope that it will be useful, + * MULTEM 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. @@ -35,350 +35,350 @@ namespace mt int number_of_gpu_available(); template - DEVICE_CALLABLE FORCE_INLINE - T get_Vr_factor(const T &E_0, const T &theta); + DEVICE_CALLABLE FORCE_INLINE + T get_Vr_factor(const T &E_0, const T &theta); /**************************************************************************************/ inline - bool is_multislice(const eElec_Spec_Int_Model &int_model) + bool is_multislice(const eElec_Spec_Int_Model &int_model) { return int_model == mt::eESIM_Multislice; } inline - bool is_phase_object(const eElec_Spec_Int_Model &int_model) + bool is_phase_object(const eElec_Spec_Int_Model &int_model) { return int_model == mt::eESIM_Phase_Object; } inline - bool is_weak_phase_object(const eElec_Spec_Int_Model &int_model) + bool is_weak_phase_object(const eElec_Spec_Int_Model &int_model) { return int_model == mt::eESIM_Weak_Phase_Object; } /**************************************************************************************/ inline - bool is_still_atom(const ePhonon_Model &pn_model) + bool is_still_atom(const ePhonon_Model &pn_model) { return pn_model == ePM_Still_Atom; } inline - bool is_absorptive_model(const ePhonon_Model &pn_model) + bool is_absorptive_model(const ePhonon_Model &pn_model) { return pn_model == ePM_Absorptive_Model; } inline - bool is_frozen_phonon(const ePhonon_Model &pn_model) + bool is_frozen_phonon(const ePhonon_Model &pn_model) { return pn_model == ePM_Frozen_Phonon; } inline - bool is_frozen_phonon_single_conf(const ePhonon_Model &pn_model, const bool &pn_single_conf) + bool is_frozen_phonon_single_conf(const ePhonon_Model &pn_model, const bool &pn_single_conf) { return is_frozen_phonon(pn_model) && pn_single_conf; } /**************************************************************************************/ inline - bool is_whole_spec(const eThick_Type &thick_type) + bool is_whole_spec(const eThick_Type &thick_type) { return thick_type == eTT_Whole_Spec; } inline - bool is_through_slices(const eThick_Type &thick_type) + bool is_through_slices(const eThick_Type &thick_type) { return thick_type == eTT_Through_Slices; } inline - bool is_through_thick(const eThick_Type &thick_type) + bool is_through_thick(const eThick_Type &thick_type) { return thick_type == eTT_Through_Thick; } /**************************************************************************************/ inline - bool is_slicing_by_planes(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic) + bool is_slicing_by_planes(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic) { return mt::is_multislice(int_model) && (pot_slic == mt::ePS_Planes); } inline - bool is_slicing_by_dz(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic) + bool is_slicing_by_dz(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic) { return mt::is_multislice(int_model) && (pot_slic == mt::ePS_dz_Proj); } inline - bool is_subslicing(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic) + bool is_subslicing(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic) { return mt::is_multislice(int_model) && (pot_slic == mt::ePS_dz_Sub); } inline - bool is_subslicing_whole_spec(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic, const eThick_Type &thick_type) + bool is_subslicing_whole_spec(const eElec_Spec_Int_Model &int_model, const ePotential_Slicing &pot_slic, const eThick_Type &thick_type) { return mt::is_subslicing(int_model, pot_slic) && is_whole_spec(thick_type); } /**************************************************************************************/ inline - bool is_plane_wave(eIncident_Wave_Type iw_type) + bool is_plane_wave(eIncident_Wave_Type iw_type) { return iw_type == eIWT_Plane_Wave; } inline - bool is_convergent_wave(eIncident_Wave_Type iw_type) + bool is_convergent_wave(eIncident_Wave_Type iw_type) { return iw_type == eIWT_Convergent_Wave; } inline - bool is_user_define_wave(eIncident_Wave_Type iw_type) + bool is_user_define_wave(eIncident_Wave_Type iw_type) { return iw_type == eIWT_User_Define_Wave; } /**************************************************************************************/ inline - bool is_STEM(const eTEM_Sim_Type &sim_type) + bool is_STEM(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_STEM; } inline - bool is_ISTEM(const eTEM_Sim_Type &sim_type) + bool is_ISTEM(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_ISTEM; } inline - bool is_CBED(const eTEM_Sim_Type &sim_type) + bool is_CBED(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_CBED; } inline - bool is_CBEI(const eTEM_Sim_Type &sim_type) + bool is_CBEI(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_CBEI; } inline - bool is_ED(const eTEM_Sim_Type &sim_type) + bool is_ED(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_ED; } inline - bool is_HRTEM(const eTEM_Sim_Type &sim_type) + bool is_HRTEM(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_HRTEM; } inline - bool is_PED(const eTEM_Sim_Type &sim_type) + bool is_PED(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_PED; } inline - bool is_HCTEM(const eTEM_Sim_Type &sim_type) + bool is_HCTEM(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_HCTEM; } inline - bool is_EWFS(const eTEM_Sim_Type &sim_type) + bool is_EWFS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_EWFS; } inline - bool is_EWRS(const eTEM_Sim_Type &sim_type) + bool is_EWRS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_EWRS; } inline - bool is_EWFS_SC(const eTEM_Sim_Type &sim_type, const ePhonon_Model &pn_model, const bool &pn_single_conf) + bool is_EWFS_SC(const eTEM_Sim_Type &sim_type, const ePhonon_Model &pn_model, const bool &pn_single_conf) { return is_EWFS(sim_type) && (!is_frozen_phonon(pn_model) || is_frozen_phonon_single_conf(pn_model, pn_single_conf)); } inline - bool is_EWRS_SC(const eTEM_Sim_Type &sim_type, const ePhonon_Model &pn_model, const bool &pn_single_conf) + bool is_EWRS_SC(const eTEM_Sim_Type &sim_type, const ePhonon_Model &pn_model, const bool &pn_single_conf) { return is_EWRS(sim_type) && (!is_frozen_phonon(pn_model) || is_frozen_phonon_single_conf(pn_model, pn_single_conf)); } inline - bool is_EELS(const eTEM_Sim_Type &sim_type) + bool is_EELS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_EELS; } inline - bool is_EFTEM(const eTEM_Sim_Type &sim_type) + bool is_EFTEM(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_EFTEM; } inline - bool is_IWFS(const eTEM_Sim_Type &sim_type) + bool is_IWFS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_IWFS; } inline - bool is_IWRS(const eTEM_Sim_Type &sim_type) + bool is_IWRS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_IWRS; } inline - bool is_PPFS(const eTEM_Sim_Type &sim_type) + bool is_PPFS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_PPFS; } inline - bool is_PPRS(const eTEM_Sim_Type &sim_type) + bool is_PPRS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_PPRS; } inline - bool is_TFFS(const eTEM_Sim_Type &sim_type) + bool is_TFFS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_TFFS; } inline - bool is_TFRS(const eTEM_Sim_Type &sim_type) + bool is_TFRS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_TFRS; } inline - bool is_PropFS(const eTEM_Sim_Type &sim_type) + bool is_PropFS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_PropFS; } inline - bool is_PropRS(const eTEM_Sim_Type &sim_type) + bool is_PropRS(const eTEM_Sim_Type &sim_type) { return sim_type == mt::eTEMST_PropRS; } inline - bool is_STEM_ISTEM(const eTEM_Sim_Type &sim_type) + bool is_STEM_ISTEM(const eTEM_Sim_Type &sim_type) { return is_STEM(sim_type) || is_ISTEM(sim_type); } inline - bool is_CBED_CBEI(const eTEM_Sim_Type &sim_type) + bool is_CBED_CBEI(const eTEM_Sim_Type &sim_type) { return is_CBED(sim_type) || is_CBEI(sim_type); } inline - bool is_ED_HRTEM(const eTEM_Sim_Type &sim_type) + bool is_ED_HRTEM(const eTEM_Sim_Type &sim_type) { return is_ED(sim_type) || is_HRTEM(sim_type); } inline - bool is_PED_HCTEM(const eTEM_Sim_Type &sim_type) + bool is_PED_HCTEM(const eTEM_Sim_Type &sim_type) { return is_PED(sim_type) || is_HCTEM(sim_type); } inline - bool is_EWFS_EWRS(const eTEM_Sim_Type &sim_type) + bool is_EWFS_EWRS(const eTEM_Sim_Type &sim_type) { return is_EWFS(sim_type) || is_EWRS(sim_type); } inline - bool is_EWFS_EWRS_SC(const eTEM_Sim_Type &sim_type, const ePhonon_Model &pn_model, const bool &pn_single_conf) + bool is_EWFS_EWRS_SC(const eTEM_Sim_Type &sim_type, const ePhonon_Model &pn_model, const bool &pn_single_conf) { return is_EWFS_SC(sim_type, pn_model, pn_single_conf) || is_EWRS_SC(sim_type, pn_model, pn_single_conf); } inline - bool is_EWFS_convergent_wave(const eTEM_Sim_Type &sim_type, const eIncident_Wave_Type &iw_type) + bool is_EWFS_convergent_wave(const eTEM_Sim_Type &sim_type, const eIncident_Wave_Type &iw_type) { return is_EWFS(sim_type) && is_convergent_wave(iw_type); } inline - bool is_EWRS_convergent_wave(const eTEM_Sim_Type &sim_type, const eIncident_Wave_Type &iw_type) + bool is_EWRS_convergent_wave(const eTEM_Sim_Type &sim_type, const eIncident_Wave_Type &iw_type) { return is_EWRS(sim_type) && is_convergent_wave(iw_type); } inline - bool is_EW_convergent_wave(const eTEM_Sim_Type &sim_type, const eIncident_Wave_Type &iw_type) + bool is_EW_convergent_wave(const eTEM_Sim_Type &sim_type, const eIncident_Wave_Type &iw_type) { return is_EWFS_EWRS(sim_type) && is_convergent_wave(iw_type); } inline - bool is_EELS_EFTEM(const eTEM_Sim_Type &sim_type) + bool is_EELS_EFTEM(const eTEM_Sim_Type &sim_type) { return is_EELS(sim_type) || is_EFTEM(sim_type); } inline - bool is_IWFS_IWRS(const eTEM_Sim_Type &sim_type) + bool is_IWFS_IWRS(const eTEM_Sim_Type &sim_type) { return is_IWFS(sim_type) || is_IWRS(sim_type); } inline - bool is_PPFS_PPRS(const eTEM_Sim_Type &sim_type) + bool is_PPFS_PPRS(const eTEM_Sim_Type &sim_type) { return is_PPFS(sim_type) || is_PPRS(sim_type); } inline - bool is_TFFS_TFRS(const eTEM_Sim_Type &sim_type) + bool is_TFFS_TFRS(const eTEM_Sim_Type &sim_type) { return is_TFFS(sim_type) || is_TFRS(sim_type); } inline - bool is_PropFS_PropRS(const eTEM_Sim_Type &sim_type) + bool is_PropFS_PropRS(const eTEM_Sim_Type &sim_type) { return is_PropFS(sim_type) || is_PropRS(sim_type); } inline - bool is_grid_FS(const eTEM_Sim_Type &sim_type) + bool is_grid_FS(const eTEM_Sim_Type &sim_type) { auto bb = is_CBED(sim_type) || is_ED(sim_type) || is_PED(sim_type) || is_EWFS(sim_type); - bb = bb || is_IWFS(sim_type) || is_PPFS(sim_type) || is_TFFS(sim_type); + bb = bb || is_IWFS(sim_type) || is_PPFS(sim_type) || is_TFFS(sim_type); return bb; } inline - bool is_grid_RS(const eTEM_Sim_Type &sim_type) + bool is_grid_RS(const eTEM_Sim_Type &sim_type) { return !is_grid_FS(sim_type); } inline - bool is_simulation_type_FS(const eTEM_Sim_Type &sim_type) + bool is_simulation_type_FS(const eTEM_Sim_Type &sim_type) { auto bb = is_STEM(sim_type) || is_CBED(sim_type) || is_ED(sim_type); bb = bb || is_PED(sim_type) || is_EWFS(sim_type) || is_EELS(sim_type); @@ -387,50 +387,62 @@ namespace mt } inline - bool is_simulation_type_RS(const eTEM_Sim_Type &sim_type) + bool is_simulation_type_RS(const eTEM_Sim_Type &sim_type) { return !is_simulation_type_FS(sim_type); } inline - bool is_specimen_required(const eTEM_Sim_Type &sim_type) + bool is_specimen_required(const eTEM_Sim_Type &sim_type) { return !(is_IWFS_IWRS(sim_type) || is_PropFS_PropRS(sim_type)); } inline - bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM(const eTEM_Sim_Type &sim_type) + bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM(const eTEM_Sim_Type &sim_type) + { + return is_ISTEM(sim_type) || is_CBEI(sim_type) || is_HRTEM(sim_type) || is_HCTEM(sim_type) || is_EFTEM(sim_type); + } + + inline + bool is_CBED_ED_EWFS_PED(const eTEM_Sim_Type &sim_type) { - return is_ISTEM(sim_type) || is_CBEI(sim_type) || is_HRTEM(sim_type) || is_HCTEM(sim_type) || is_EFTEM(sim_type); + return is_CBED(sim_type) || is_ED(sim_type) || is_EWFS(sim_type) || is_PED(sim_type); } inline - bool is_CBED_ED_EWFS_PED(const eTEM_Sim_Type &sim_type) + bool is_obj_lens_temp_spat(const eTEM_Sim_Type &sim_type) { - return is_CBED(sim_type) || is_ED(sim_type) || is_EWFS(sim_type) || is_PED(sim_type); + return is_ISTEM(sim_type) || is_CBEI(sim_type) || is_HRTEM(sim_type) || is_HCTEM(sim_type) || is_EFTEM(sim_type); } inline - eSpace get_simulation_space(const eTEM_Sim_Type &sim_type) + bool is_cond_lens_temp_spat(const eTEM_Sim_Type &sim_type) { - return (is_simulation_type_FS(sim_type) || is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM(sim_type))?mt::eS_Reciprocal:mt::eS_Real; + return is_STEM_ISTEM(sim_type) || is_CBED_CBEI(sim_type) || is_EELS(sim_type); } inline - bool is_scanning(const eTEM_Sim_Type &sim_type) + eSpace get_simulation_space(const eTEM_Sim_Type &sim_type) + { + return (is_simulation_type_FS(sim_type) || is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM(sim_type)) ? mt::eS_Reciprocal : mt::eS_Real; + } + + inline + bool is_scanning(const eTEM_Sim_Type &sim_type) { return is_STEM_ISTEM(sim_type) || is_EELS(sim_type); } /**************************************************************************************/ inline - eIncident_Wave_Type validate_incident_wave_type(const eTEM_Sim_Type &sim_type, eIncident_Wave_Type iw_type) + eIncident_Wave_Type validate_incident_wave_type(const eTEM_Sim_Type &sim_type, eIncident_Wave_Type iw_type) { - if(iw_type == eIWT_Auto) + if (iw_type == eIWT_Auto) { auto bb = is_scanning(sim_type) || is_CBED_CBEI(sim_type); bb = bb || ((is_EWFS_EWRS(sim_type) || is_IWFS_IWRS(sim_type)) && is_convergent_wave(iw_type)); - iw_type = (bb)?mt::eIWT_Convergent_Wave:mt::eIWT_Plane_Wave; + iw_type = (bb) ? mt::eIWT_Convergent_Wave : mt::eIWT_Plane_Wave; } return iw_type; @@ -443,842 +455,914 @@ namespace mt template class Input_Multislice { - public: - using value_type = T; - - eElec_Spec_Int_Model interaction_model; // eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 - ePotential_Type potential_type; // potential type: 1: Doyle(0-4), 2: Peng(0-4), 3: peng(0-12), 4: Kirkland(0-12), 5:Weickenmeier(0-12) adn 6: Lobato(0-12) - - ePhonon_Model pn_model; // 1: Still atom model, 2: Absorptive potential model, 3: Frozen phonon - bool pn_coh_contrib; // true, false - bool pn_single_conf; // single configuration: true, false - FP_Dim pn_dim; // Phonon dimensions - int fp_dist; // 1: Gaussian (Phonon distribution) - int pn_seed; // Random seed(frozen phonon) - int pn_nconf; // true: single phonon configuration, false: number of frozen phonon configurations - int fp_iconf_0; // initial configuration - - Atom_Data atoms; // atoms - bool is_crystal; - - T spec_rot_theta; // angle - r3d spec_rot_u0; // unitary vector - eRot_Point_Type spec_rot_center_type; // 1: geometric center, 2: User define - r3d spec_rot_center_p; // rotation point - - eThick_Type thick_type; // eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 - host_vector thick; // Array of thickes - - ePotential_Slicing potential_slicing; // ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - - Grid_2d grid_2d; // grid information - - eTEM_Sim_Type simulation_type; // 11: Scanning, 12: ISTEM, 21: cbed, 22: cbei, 31: ED, 32: hrtem, 41: ped, 42: hci, ... 51: EW Fourier, 52: EW real - - eIncident_Wave_Type iw_type; // 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto - host_vector> iw_psi; // user define incident wave - host_vector iw_x; // x position - host_vector iw_y; // y position - - T E_0; // Acceleration volatage in KeV - T lambda; // lambda - T theta; // incident tilt (in spherical coordinates) (rad) - T phi; // incident tilt (in spherical coordinates) (rad) + public: + using value_type = T; - eIllumination_Model illumination_model; // 1: Partial coherente mode, 2: transmission cross coefficient - eTemporal_Spatial_Incoh temporal_spatial_incoh; // 1: Spatial and temporal, 2: Temporal, 3: Spatial + System_Configuration system_conf; // System information - Lens cond_lens; // Condenser lens - Lens obj_lens; // Objective lens - - Scanning scanning; // Scanning + eElec_Spec_Int_Model interaction_model; // eESIM_Multislice = 1, eESIM_Phase_Object = 2, eESIM_Weak_Phase_Object = 3 + ePotential_Type potential_type; // potential type: 1: Doyle(0-4), 2: Peng(0-4), 3: peng(0-12), 4: Kirkland(0-12), 5:Weickenmeier(0-12) adn 6: Lobato(0-12) - Detector detector; // STEM Detectors - - EELS eels_fr; // EELS - - eOperation_Mode operation_mode; // eOM_Normal = 1, eOM_Advanced = 2 - bool slice_storage; // true, false - bool reverse_multislice; // true, false - int mul_sign; // multislice sign - - T Vrl; // Atomic potential cut-off - int nR; // Number of grid_bt points - - int nrot; // Total number of rotations - - eLens_Var_Type cdl_var_type; // eLVT_off = 0, eLVT_m = 1, eLVT_f = 2, eLVT_Cs3 = 3, eLVT_Cs5 = 4, eLVT_mfa2 = 5, eLVT_afa2 = 6, eLVT_mfa3 = 7, eLVT_afa3 = 8, eLVT_inner_aper_ang = 9, eLVT_outer_aper_ang = 10 - host_vector cdl_var; // Array of thickes - - host_vector iscan; - host_vector beam_x; // temporal variables for - host_vector beam_y; - - int islice; - bool dp_Shift; // Shift diffraction pattern - - Input_Multislice():simulation_type(eTEMST_EWRS), pn_model(ePM_Still_Atom), interaction_model(eESIM_Multislice), - potential_slicing(ePS_Planes), potential_type(ePT_Lobato_0_12), fp_dist(1), pn_seed(300183), - pn_single_conf(false), pn_nconf(1), fp_iconf_0(1), spec_rot_theta(0), spec_rot_u0(0, 0, 1), - spec_rot_center_type(eRPT_geometric_center), spec_rot_center_p(1, 0, 0), illumination_model(eIM_Partial_Coherent), - temporal_spatial_incoh(eTSI_Temporal_Spatial), thick_type(eTT_Whole_Spec), - operation_mode(eOM_Normal), pn_coh_contrib(false), slice_storage(false), reverse_multislice(false), - mul_sign(1), E_0(300), lambda(0), theta(0), phi(0), nrot(1), Vrl(c_Vrl), nR(c_nR), iw_type(eIWT_Plane_Wave), - is_crystal(false), islice(0), dp_Shift(false){}; - - template - void assign(TInput_Multislice &input_multislice) - { - interaction_model = input_multislice.interaction_model; - potential_type = input_multislice.potential_type; - - operation_mode = input_multislice.operation_mode; - slice_storage = input_multislice.slice_storage; - reverse_multislice = input_multislice.reverse_multislice; - mul_sign = input_multislice.mul_sign; - Vrl = input_multislice.Vrl; - nR = input_multislice.nR; - - pn_model = input_multislice.pn_model; - pn_coh_contrib = input_multislice.pn_coh_contrib; - pn_dim = input_multislice.pn_dim; - fp_dist = input_multislice.fp_dist; - pn_seed = input_multislice.pn_seed; - pn_single_conf = input_multislice.pn_single_conf; - pn_nconf = input_multislice.pn_nconf; - - atoms = input_multislice.atoms; - is_crystal = input_multislice.is_crystal; - - spec_rot_theta = input_multislice.spec_rot_theta; - spec_rot_u0 = input_multislice.spec_rot_u0; - spec_rot_center_type = input_multislice.spec_rot_center_type; - spec_rot_center_p = input_multislice.spec_rot_center_p; - - thick_type = input_multislice.thick_type; - thick = input_multislice.thick; + ePhonon_Model pn_model; // 1: Still atom model, 2: Absorptive potential model, 3: Frozen phonon + bool pn_coh_contrib; // true, false + bool pn_single_conf; // single configuration: true, false + FP_Dim pn_dim; // Phonon dimensions + int fp_dist; // 1: Gaussian (Phonon distribution) + int pn_seed; // Random seed(frozen phonon) + int pn_nconf; // true: single phonon configuration, false: number of frozen phonon configurations + int fp_iconf_0; // initial configuration - potential_slicing = input_multislice.potential_slicing; + Atom_Data atoms; // atoms + bool is_crystal; - grid_2d = input_multislice.grid_2d; + T spec_rot_theta; // angle + r3d spec_rot_u0; // unitary vector + eRot_Point_Type spec_rot_center_type; // 1: geometric center, 2: User define + r3d spec_rot_center_p; // rotation point - simulation_type = input_multislice.simulation_type; + eThick_Type thick_type; // eTT_Whole_Spec = 1, eTT_Through_Thick = 2, eTT_Through_Slices = 3 + host_vector thick; // Array of thickes - iw_type = input_multislice.iw_type; - iw_psi = input_multislice.iw_psi; - iw_x = input_multislice.iw_x; - iw_y = input_multislice.iw_y; + ePotential_Slicing potential_slicing; // ePS_Planes = 1, ePS_dz_Proj = 2, ePS_dz_Sub = 3, ePS_Auto = 4 - E_0 = input_multislice.E_0; - theta = input_multislice.theta; - phi = input_multislice.phi; - nrot = input_multislice.nrot; - - illumination_model = input_multislice.illumination_model; - temporal_spatial_incoh = input_multislice.temporal_spatial_incoh; - - cond_lens = input_multislice.cond_lens; - obj_lens = input_multislice.obj_lens; + Grid_2d grid_2d; // grid information - scanning = input_multislice.scanning; - detector = input_multislice.detector; - - eels_fr = input_multislice.eels_fr; + Range_2d output_area; // Output region information - cdl_var_type = input_multislice.cdl_var_type; - cdl_var = input_multislice.cdl_var; + eTEM_Sim_Type simulation_type; // 11: Scanning, 12: ISTEM, 21: cbed, 22: cbei, 31: ED, 32: hrtem, 41: ped, 42: hci, ... 51: EW Fourier, 52: EW real - iscan = input_multislice.iscan; - beam_x = input_multislice.beam_x; - beam_y = input_multislice.beam_y; - - islice = input_multislice.islice; - dp_Shift = input_multislice.dp_Shift; - } - - template - Input_Multislice& operator=(TInput_Multislice &input_multislice) - { - assign(input_multislice); - return *this; - } + eIncident_Wave_Type iw_type; // 1: Plane_Wave, 2: Convergent_wave, 3:User_Define, 4: auto + host_vector> iw_psi; // user define incident wave + host_vector iw_x; // x position + host_vector iw_y; // y position - void validate_parameters() - { - pn_seed = max(1, pn_seed); + T E_0; // Acceleration volatage in KeV + T lambda; // lambda + T theta; // incident tilt (in spherical coordinates) (rad) + T phi; // incident tilt (in spherical coordinates) (rad) - pn_nconf = (!is_frozen_phonon())?1:max(1, pn_nconf); + eIllumination_Model illumination_model; // 1: Partial coherente mode, 2: transmission cross coefficient + eTemporal_Spatial_Incoh temporal_spatial_incoh; // 1: Spatial and temporal, 2: Temporal, 3: Spatial - fp_iconf_0 = (!is_frozen_phonon())?1:(pn_single_conf)?pn_nconf:1; + Lens cond_lens; // Condenser lens + Lens obj_lens; // Objective lens - islice = max(0, islice); + Scanning scanning; // Scanning - if(isZero(Vrl)) - { - Vrl = c_Vrl; - } + Detector detector; // STEM Detectors - if(isZero(nR)) - { - nR = c_nR; - } + EELS eels_fr; // EELS - dp_Shift = (is_PED())?true:false; + eOperation_Mode operation_mode; // eOM_Normal = 1, eOM_Advanced = 2 + bool slice_storage; // true, false + bool reverse_multislice; // true, false + int mul_sign; // multislice sign - if(!is_scanning()) - { - scanning.set_default(); - } - scanning.set_grid(); + T Vrl; // Atomic potential cut-off + int nR; // Number of grid_bt points - lambda = get_lambda(E_0); + int nrot; // Total number of rotations - // multislice sign - mul_sign = (reverse_multislice)?-1:1; + eLens_Var_Type cdl_var_type; // eLVT_off = 0, eLVT_m = 1, eLVT_f = 2, eLVT_Cs3 = 3, eLVT_Cs5 = 4, eLVT_mfa2 = 5, eLVT_afa2 = 6, eLVT_mfa3 = 7, eLVT_afa3 = 8, eLVT_inner_aper_ang = 9, eLVT_outer_aper_ang = 10 + host_vector cdl_var; // Array of thickes - theta = set_incident_angle(theta); - nrot = max(1, nrot); - if(!is_PED_HCTEM()) - { - nrot = 1; - } + host_vector iscan; + host_vector beam_x; // temporal variables for + host_vector beam_y; - // set beam position - set_beam_position(iw_x, iw_y); + int islice; + bool dp_Shift; // Shift diffraction pattern - if(is_EELS_EFTEM()) - { - pn_coh_contrib = false; - interaction_model = mt::eESIM_Multislice; - illumination_model = eIM_Coherent; - } + Input_Multislice() :simulation_type(eTEMST_EWRS), pn_model(ePM_Still_Atom), interaction_model(eESIM_Multislice), + potential_slicing(ePS_Planes), potential_type(ePT_Lobato_0_12), fp_dist(1), pn_seed(300183), + pn_single_conf(false), pn_nconf(1), fp_iconf_0(1), spec_rot_theta(0), spec_rot_u0(0, 0, 1), + spec_rot_center_type(eRPT_geometric_center), spec_rot_center_p(1, 0, 0), illumination_model(eIM_Partial_Coherent), + temporal_spatial_incoh(eTSI_Temporal_Spatial), thick_type(eTT_Whole_Spec), + operation_mode(eOM_Normal), pn_coh_contrib(false), slice_storage(false), reverse_multislice(false), + mul_sign(1), E_0(300), lambda(0), theta(0), phi(0), nrot(1), Vrl(c_Vrl), nR(c_nR), iw_type(eIWT_Plane_Wave), + is_crystal(false), islice(0), dp_Shift(false) {}; - if(is_EWFS_EWRS()) - { - pn_coh_contrib = true; - illumination_model = eIM_Coherent; - } + template + void assign(TInput_Multislice &input_multislice) + { + interaction_model = input_multislice.interaction_model; + potential_type = input_multislice.potential_type; - // It will be changed when you include spatial incoherences (beta) - if(is_CBED_CBEI() && !is_illu_mod_full_integration()) - { - illumination_model = eIM_Coherent; - } + operation_mode = input_multislice.operation_mode; + slice_storage = input_multislice.slice_storage; + reverse_multislice = input_multislice.reverse_multislice; + mul_sign = input_multislice.mul_sign; + Vrl = input_multislice.Vrl; + nR = input_multislice.nR; - if (is_incoh_temporal_spatial() && isZero(cond_lens.beta)) - { - temporal_spatial_incoh = eTSI_Temporal; - } + pn_model = input_multislice.pn_model; + pn_coh_contrib = input_multislice.pn_coh_contrib; + pn_dim = input_multislice.pn_dim; + fp_dist = input_multislice.fp_dist; + pn_seed = input_multislice.pn_seed; + pn_single_conf = input_multislice.pn_single_conf; + pn_nconf = input_multislice.pn_nconf; - slice_storage = is_slice_storage(); + atoms = input_multislice.atoms; + is_crystal = input_multislice.is_crystal; - if(!is_multislice()) - { - islice = 0; - potential_slicing = ePS_Planes; - if(is_through_slices()) - { - thick_type = eTT_Through_Thick; - } - slice_storage = slice_storage || !is_whole_spec(); - } + spec_rot_theta = input_multislice.spec_rot_theta; + spec_rot_u0 = input_multislice.spec_rot_u0; + spec_rot_center_type = input_multislice.spec_rot_center_type; + spec_rot_center_p = input_multislice.spec_rot_center_p; - if(is_subslicing() && is_through_thick()) - { - thick_type = eTT_Whole_Spec; - } + thick_type = input_multislice.thick_type; + thick = input_multislice.thick; - if(!is_subslicing()) - { - pn_dim.z = false; - } + potential_slicing = input_multislice.potential_slicing; - if(is_spec_rot_active()) - { - thick_type = eTT_Whole_Spec; - spec_rot_u0.normalized(); - // get geometric center - if(spec_rot_center_type == eRPT_geometric_center) - { - spec_rot_center_p = r3d(atoms.x_mean, atoms.y_mean, atoms.z_mean); - } - // rotate atoms - rotate_atoms(atoms, spec_rot_theta, spec_rot_u0, spec_rot_center_p); - // get statistic - atoms.get_statistic(); - // reset theta - spec_rot_theta = 0; - } + grid_2d = input_multislice.grid_2d; - // match slicing with the require thickness - Slicing slicing; - slicing.match_thickness(potential_slicing, atoms, thick_type, thick); + simulation_type = input_multislice.simulation_type; - // remove atoms outside the thickness range - T ee_z = 0.1; - T z_e = thick.back()+ee_z; + iw_type = input_multislice.iw_type; + iw_psi = input_multislice.iw_psi; + iw_x = input_multislice.iw_x; + iw_y = input_multislice.iw_y; - if(atoms.z_max>z_e) - { - T z_0 = atoms.z_min-ee_z; - remove_atoms_outside_z_range(atoms, z_0, z_e); - // get statistic - atoms.get_statistic(); - } + E_0 = input_multislice.E_0; + theta = input_multislice.theta; + phi = input_multislice.phi; + nrot = input_multislice.nrot; - // set condenser lens parameters - cond_lens.set_input_data(E_0, grid_2d); - if(atoms.empty()) - { - cond_lens.zero_defocus_plane = 0; - } - else - { - cond_lens.zero_defocus_plane = cond_lens.get_zero_defocus_plane(atoms.z_min, atoms.z_max); - } + illumination_model = input_multislice.illumination_model; + temporal_spatial_incoh = input_multislice.temporal_spatial_incoh; - cond_lens.zero_defocus_type = eZDT_User_Define; + cond_lens = input_multislice.cond_lens; + obj_lens = input_multislice.obj_lens; - // set objetive lens parameters - obj_lens.set_input_data(E_0, grid_2d); - } + scanning = input_multislice.scanning; + detector = input_multislice.detector; - /**************************************************************************************/ - void set_reverse_multislice(bool rm) - { - reverse_multislice = rm; - mul_sign = (reverse_multislice)?-1:1; - } + eels_fr = input_multislice.eels_fr; - /**************************************************************************************/ - inline - int number_conf() - { - return (pn_nconf-fp_iconf_0+1); - } + cdl_var_type = input_multislice.cdl_var_type; + cdl_var = input_multislice.cdl_var; - int number_of_beams() - { - return (is_plane_wave())?0:iw_x.size(); - } + iscan = input_multislice.iscan; + beam_x = input_multislice.beam_x; + beam_y = input_multislice.beam_y; - bool is_multi_beam() - { - return number_of_beams()>0; - } + islice = input_multislice.islice; + dp_Shift = input_multislice.dp_Shift; + } - template - void set_beam_position(TVector &x, TVector &y) - { - beam_x.assign(x.begin(), x.end()); - beam_y.assign(y.begin(), y.end()); - } + template + Input_Multislice& operator=(TInput_Multislice &input_multislice) + { + assign(input_multislice); + return *this; + } - void set_iscan_beam_position() - { - beam_x.resize(iscan.size()); - beam_y.resize(iscan.size()); - for(auto is=0; is(nconf*nrot); + scanning.set_default(); } + scanning.set_grid(); + + lambda = get_lambda(E_0); - void set_phi(const int &irot) + // multislice sign + mul_sign = (reverse_multislice) ? -1 : 1; + + theta = set_incident_angle(theta); + nrot = max(1, nrot); + if (!is_PED_HCTEM()) { - phi = (irot == 0)?0.0:(c_2Pi*static_cast(irot))/static_cast(nrot); + nrot = 1; } - inline - T get_propagator_factor(const T &z) const - { - return (-mul_sign*c_Pi*lambda*z); - } + // set beam position + set_beam_position(iw_x, iw_y); - T Vr_factor() const + if (is_EELS_EFTEM()) { - return (mul_sign*get_Vr_factor(E_0, theta)); + pn_coh_contrib = false; + interaction_model = mt::eESIM_Multislice; + illumination_model = eIM_Coherent; } - T gx_0() const + if (is_EWFS_EWRS()) { - return sin(theta)*cos(phi)/lambda; + pn_coh_contrib = true; + illumination_model = eIM_Coherent; } - T gy_0() const + // It will be changed when you include spatial incoherences (beta) + if (is_CBED_CBEI() && !is_illu_mod_full_integration()) { - return sin(theta)*sin(phi)/lambda; + illumination_model = eIM_Coherent; } - void set_eels_fr_atom(const int &iatoms, const Atom_Data &atoms) + slice_storage = is_slice_storage(); + + if (!is_multislice()) { - eels_fr.x = grid_2d.exp_factor_Rx(atoms.x[iatoms]); - eels_fr.y = grid_2d.exp_factor_Ry(atoms.y[iatoms]); - eels_fr.occ = atoms.occ[iatoms]; + islice = 0; + potential_slicing = ePS_Planes; + if (is_through_slices()) + { + thick_type = eTT_Through_Thick; + } + slice_storage = slice_storage || !is_whole_spec(); } - /**************************************************************************************/ - bool is_multislice() const + if (is_subslicing() && is_through_thick()) { - return mt::is_multislice(interaction_model); + thick_type = eTT_Whole_Spec; } - bool is_phase_object() const + if (!is_subslicing()) { - return mt::is_phase_object(interaction_model); + pn_dim.z = false; } - bool is_weak_phase_object() const + if (is_spec_rot_active()) { - return mt::is_weak_phase_object(interaction_model); + thick_type = eTT_Whole_Spec; + spec_rot_u0.normalized(); + // get geometric center + if (spec_rot_center_type == eRPT_geometric_center) + { + spec_rot_center_p = r3d(atoms.x_mean, atoms.y_mean, atoms.z_mean); + } + // rotate atoms + rotate_atoms(atoms, spec_rot_theta, spec_rot_u0, spec_rot_center_p); + // get statistic + atoms.get_statistic(); + // reset theta + spec_rot_theta = 0; } - /**************************************************************************************/ + // match slicing with the require thickness + Slicing slicing; + slicing.match_thickness(potential_slicing, atoms, thick_type, thick); - bool is_still_atom() const - { - return mt::is_still_atom(pn_model); - } + // remove atoms outside the thickness range + T ee_z = 0.1; + T z_e = thick.back() + ee_z; - bool is_absorptive_model() const + if (atoms.z_max > z_e) { - return mt::is_absorptive_model(pn_model); + T z_0 = atoms.z_min - ee_z; + remove_atoms_outside_z_range(atoms, z_0, z_e); + // get statistic + atoms.get_statistic(); } - bool is_frozen_phonon() const - { - return mt::is_frozen_phonon(pn_model); - } + /************* verify lenses parameters **************/ - bool is_frozen_phonon_single_conf() const + if (isZero(cond_lens.ssf_sigma)) { - return mt::is_frozen_phonon_single_conf(pn_model, pn_single_conf); + temporal_spatial_incoh = eTSI_Temporal; } - /**************************************************************************************/ - bool is_whole_spec() const + if (!is_illu_mod_full_integration()) { - return mt::is_whole_spec(thick_type); - } + cond_lens.ssf_npoints = 1; + cond_lens.dsf_npoints = 1; - bool is_through_slices() const - { - return mt::is_through_slices(thick_type); + obj_lens.ssf_npoints = 1; + obj_lens.dsf_npoints = 1; } - bool is_through_thick() const + if (is_incoh_temporal()) { - return mt::is_through_thick(thick_type); + cond_lens.ssf_npoints = 1; + obj_lens.ssf_npoints = 1; } - - /**************************************************************************************/ - bool is_slicing_by_planes() const + else if (is_incoh_spatial()) { - return mt::is_slicing_by_planes(interaction_model, potential_slicing); + cond_lens.dsf_npoints = 1; + obj_lens.dsf_npoints = 1; } - bool is_slicing_by_dz() const + // set condenser lens parameters + cond_lens.set_input_data(E_0, grid_2d); + if (atoms.empty()) { - return mt::is_slicing_by_dz(interaction_model, potential_slicing); + cond_lens.zero_defocus_plane = 0; } - - bool is_subslicing() const + else { - return mt::is_subslicing(interaction_model, potential_slicing); + cond_lens.zero_defocus_plane = cond_lens.get_zero_defocus_plane(atoms.z_min, atoms.z_max); } - bool is_subslicing_whole_spec() const - { - return mt::is_subslicing_whole_spec(interaction_model, potential_slicing, thick_type); - } + cond_lens.zero_defocus_type = eZDT_User_Define; - /**************************************************************************************/ - bool is_plane_wave() const - { - return mt::is_plane_wave(iw_type); - } + // set objetive lens parameters + obj_lens.set_input_data(E_0, grid_2d); - bool is_convergent_wave() const - { - return mt::is_convergent_wave(iw_type); - } + // validate output area + validate_output_area(); + } - bool is_user_define_wave() const - { - return mt::is_user_define_wave(iw_type); - } + /**************************************************************************************/ + void set_reverse_multislice(bool rm) + { + reverse_multislice = rm; + mul_sign = (reverse_multislice) ? -1 : 1; + } - /**********************************************************/ - bool is_STEM() const - { - return mt::is_STEM(simulation_type); - } + /**************************************************************************************/ + inline + int number_conf() + { + return (pn_nconf - fp_iconf_0 + 1); + } - bool is_ISTEM() const - { - return mt::is_ISTEM(simulation_type); - } + int number_of_beams() + { + return (is_plane_wave())?0:iw_x.size(); + } - bool is_CBED() const - { - return mt::is_CBED(simulation_type); - } + bool is_multi_beam() + { + return number_of_beams() > 0; + } - bool is_CBEI() const - { - return mt::is_CBEI(simulation_type); - } + template + void set_beam_position(TVector &x, TVector &y) + { + beam_x.assign(x.begin(), x.end()); + beam_y.assign(y.begin(), y.end()); + } - bool is_ED() const + void validate_output_area() + { + if((is_STEM() || is_EELS())) { - return mt::is_ED(simulation_type); - } + output_area.ix_0 = 0; + output_area.ix_e = grid_2d.nx; - bool is_HRTEM() const - { - return mt::is_HRTEM(simulation_type); + output_area.iy_0 = 0; + output_area.iy_e = grid_2d.ny; } - - bool is_PED() const + else { - return mt::is_PED(simulation_type); - } + if(output_area.ix_0==output_area.ix_e) + { + output_area.ix_0 = 0; + output_area.ix_e = grid_2d.nx; + } - bool is_HCTEM() const - { - return mt::is_HCTEM(simulation_type); - } + if(output_area.iy_0==output_area.iy_e) + { + output_area.iy_0 = 0; + output_area.iy_e = grid_2d.ny; + } - bool is_EWFS() const - { - return mt::is_EWFS(simulation_type); + output_area.set_ascending_index(); + output_area.clip_ix(0, grid_2d.nx); + output_area.clip_iy(0, grid_2d.ny); } - bool is_EWRS() const - { - return mt::is_EWRS(simulation_type); - } + output_area.ixy_0 = 0; + output_area.ixy_e = output_area.nxy(); + } - bool is_EWFS_SC() const + void set_iscan_beam_position() + { + beam_x.resize(iscan.size()); + beam_y.resize(iscan.size()); + for (auto is = 0; is < iscan.size(); is++) { - return mt::is_EWFS_SC(simulation_type, pn_model, pn_single_conf); + auto idx = iscan[is]; + beam_x[is] = scanning.x[idx]; + beam_y[is] = scanning.y[idx]; } + } - bool is_EWRS_SC() const - { - return mt::is_EWRS_SC(simulation_type, pn_model, pn_single_conf); - } + /**************************************************************************************/ + bool is_spec_rot_active() const + { + return mt::nonZero(spec_rot_theta); + } - bool is_EELS() const - { - return mt::is_EELS(simulation_type); - } + /**************************************************************************************/ + T Rx_exp_factor() + { + return grid_2d.exp_factor_Rx(beam_x); + } - bool is_EFTEM() const - { - return mt::is_EFTEM(simulation_type); - } + T Ry_exp_factor() + { + return grid_2d.exp_factor_Ry(beam_y); + } - bool is_IWFS() const - { - return mt::is_IWFS(simulation_type); - } + T set_incident_angle(const T &theta) const + { + T n = round(sin(theta) / (lambda*grid_2d.dg_min())); + return (isZero(theta)) ? 0 : asin(n*lambda*grid_2d.dg_min()); + } - bool is_IWRS() const - { - return mt::is_IWRS(simulation_type); - } + T get_phonon_rot_weight() const + { + int nconf = (!is_frozen_phonon() || pn_single_conf) ? 1 : pn_nconf; + return 1.0 / static_cast(nconf*nrot); + } - bool is_PPFS() const - { - return mt::is_PPFS(simulation_type); - } + void set_phi(const int &irot) + { + phi = (irot == 0) ? 0.0 : (c_2Pi*static_cast(irot)) / static_cast(nrot); + } - bool is_PPRS() const - { - return mt::is_PPRS(simulation_type); - } + inline + T get_propagator_factor(const T &z) const + { + return (-mul_sign*c_Pi*lambda*z); + } - bool is_TFFS() const - { - return mt::is_TFFS(simulation_type); - } + T Vr_factor() const + { + return (mul_sign*get_Vr_factor(E_0, theta)); + } - bool is_TFRS() const - { - return mt::is_TFRS(simulation_type); - } + T gx_0() const + { + return sin(theta)*cos(phi) / lambda; + } - bool is_PropFS() const - { - return mt::is_PropFS(simulation_type); - } + T gy_0() const + { + return sin(theta)*sin(phi) / lambda; + } - bool is_PropRS() const - { - return mt::is_PropRS(simulation_type); - } + void set_eels_fr_atom(const int &iatoms, const Atom_Data &atoms) + { + eels_fr.x = grid_2d.exp_factor_Rx(atoms.x[iatoms]); + eels_fr.y = grid_2d.exp_factor_Ry(atoms.y[iatoms]); + eels_fr.occ = atoms.occ[iatoms]; + } - bool is_STEM_ISTEM() const - { - return mt::is_STEM_ISTEM(simulation_type); - } + /**************************************************************************************/ + bool is_multislice() const + { + return mt::is_multislice(interaction_model); + } - bool is_CBED_CBEI() const - { - return mt::is_CBED_CBEI(simulation_type); - } + bool is_phase_object() const + { + return mt::is_phase_object(interaction_model); + } - bool is_ED_HRTEM() const - { - return mt::is_ED_HRTEM(simulation_type); - } + bool is_weak_phase_object() const + { + return mt::is_weak_phase_object(interaction_model); + } - bool is_PED_HCTEM() const - { - return mt::is_PED_HCTEM(simulation_type); - } + /**************************************************************************************/ - bool is_EWFS_EWRS() const - { - return mt::is_EWFS_EWRS(simulation_type); - } + bool is_still_atom() const + { + return mt::is_still_atom(pn_model); + } - bool is_EWFS_EWRS_SC() const - { - return mt::is_EWFS_EWRS_SC(simulation_type, pn_model, pn_single_conf); - } + bool is_absorptive_model() const + { + return mt::is_absorptive_model(pn_model); + } - bool is_EELS_EFTEM() const - { - return mt::is_EELS_EFTEM(simulation_type); - } + bool is_frozen_phonon() const + { + return mt::is_frozen_phonon(pn_model); + } - bool is_IWFS_IWRS() const - { - return mt::is_IWFS_IWRS(simulation_type); - } + bool is_frozen_phonon_single_conf() const + { + return mt::is_frozen_phonon_single_conf(pn_model, pn_single_conf); + } - bool is_PPFS_PPRS() const - { - return mt::is_PPFS_PPRS(simulation_type); - } + /**************************************************************************************/ + bool is_whole_spec() const + { + return mt::is_whole_spec(thick_type); + } - bool is_TFFS_TFRS() const - { - return mt::is_TFFS_TFRS(simulation_type); - } + bool is_through_slices() const + { + return mt::is_through_slices(thick_type); + } - bool is_PropFS_PropRS() const - { - return mt::is_PropFS_PropRS(simulation_type); - } + bool is_through_thick() const + { + return mt::is_through_thick(thick_type); + } - bool is_grid_FS() const - { - return mt::is_grid_FS(simulation_type); - } + /**************************************************************************************/ + bool is_slicing_by_planes() const + { + return mt::is_slicing_by_planes(interaction_model, potential_slicing); + } - bool is_grid_RS() const - { - return mt::is_grid_RS(simulation_type); - } + bool is_slicing_by_dz() const + { + return mt::is_slicing_by_dz(interaction_model, potential_slicing); + } - bool is_simulation_type_FS() const - { - return mt::is_simulation_type_FS(simulation_type); - } + bool is_subslicing() const + { + return mt::is_subslicing(interaction_model, potential_slicing); + } - bool is_simulation_type_RS() const - { - return mt::is_simulation_type_RS(simulation_type); - } + bool is_subslicing_whole_spec() const + { + return mt::is_subslicing_whole_spec(interaction_model, potential_slicing, thick_type); + } - bool is_specimen_required() const - { - return mt::is_specimen_required(simulation_type); - } - - bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM() const - { - return mt::is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM(simulation_type); - } + /**************************************************************************************/ + bool is_plane_wave() const + { + return mt::is_plane_wave(iw_type); + } - bool is_CBED_ED_EWFS_PED() const - { - return mt::is_CBED_ED_EWFS_PED(simulation_type); - } + bool is_convergent_wave() const + { + return mt::is_convergent_wave(iw_type); + } - eSpace get_simulation_space() const - { - return mt::get_simulation_space(simulation_type); - } + bool is_user_define_wave() const + { + return mt::is_user_define_wave(iw_type); + } - bool is_scanning() const - { - return mt::is_scanning(simulation_type); - } + /**********************************************************/ + bool is_STEM() const + { + return mt::is_STEM(simulation_type); + } - /**************************************************************************************/ - void set_incident_wave_type(eIncident_Wave_Type iw_type_i) - { - iw_type = mt::validate_incident_wave_type(simulation_type, iw_type_i); - } + bool is_ISTEM() const + { + return mt::is_ISTEM(simulation_type); + } - /**************************************************************************************/ - bool is_illu_mod_coherent() const - { - return illumination_model == eIM_Coherent; - } + bool is_CBED() const + { + return mt::is_CBED(simulation_type); + } - bool is_illu_mod_partial_coherent() const - { - return illumination_model == eIM_Partial_Coherent; - } + bool is_CBEI() const + { + return mt::is_CBEI(simulation_type); + } - bool is_illu_mod_trans_cross_coef() const - { - return illumination_model == eIM_Trans_Cross_Coef; - } + bool is_ED() const + { + return mt::is_ED(simulation_type); + } - bool is_illu_mod_full_integration() const - { - return illumination_model == eIM_Full_Integration; - } + bool is_HRTEM() const + { + return mt::is_HRTEM(simulation_type); + } - /**************************************************************************************/ - bool is_incoh_temporal_spatial() const - { - return temporal_spatial_incoh == eTSI_Temporal_Spatial; - } + bool is_PED() const + { + return mt::is_PED(simulation_type); + } - bool is_incoh_temporal() const - { - return temporal_spatial_incoh == eTSI_Temporal; - } + bool is_HCTEM() const + { + return mt::is_HCTEM(simulation_type); + } - bool is_incoh_spatial() const - { - return temporal_spatial_incoh == eTSI_Spatial; - } + bool is_EWFS() const + { + return mt::is_EWFS(simulation_type); + } - /**************************************************************************************/ - bool is_detector_circular() const - { - return detector.is_detector_circular(); - } + bool is_EWRS() const + { + return mt::is_EWRS(simulation_type); + } - bool is_detector_radial() const - { - return detector.is_detector_radial(); - } + bool is_EWFS_SC() const + { + return mt::is_EWFS_SC(simulation_type, pn_model, pn_single_conf); + } - bool is_detector_matrix() const - { - return detector.is_detector_matrix(); - } + bool is_EWRS_SC() const + { + return mt::is_EWRS_SC(simulation_type, pn_model, pn_single_conf); + } - /**************************************************************************************/ - bool is_slice_storage() const - { - bool slice_storage = is_PED_HCTEM() || is_EELS_EFTEM(); - slice_storage = slice_storage || is_ISTEM() || (is_STEM() && !pn_coh_contrib); - slice_storage = slice_storage || (is_CBED_CBEI() && is_illu_mod_full_integration()); + bool is_EELS() const + { + return mt::is_EELS(simulation_type); + } - return slice_storage; - } + bool is_EFTEM() const + { + return mt::is_EFTEM(simulation_type); + } - bool is_operation_mode_normal() const - { - return operation_mode == eOM_Normal; - } + bool is_IWFS() const + { + return mt::is_IWFS(simulation_type); + } - bool is_operation_mode_advanced() const - { - return operation_mode == eOM_Advanced; - } + bool is_IWRS() const + { + return mt::is_IWRS(simulation_type); + } - /**************************************************************************************/ - bool is_lvt_off() const - { - return cdl_var == eLVT_off; - } + bool is_PPFS() const + { + return mt::is_PPFS(simulation_type); + } - bool is_lvt_m() const - { - return cdl_var == eLVT_m; - } + bool is_PPRS() const + { + return mt::is_PPRS(simulation_type); + } - bool is_lvt_Cs3() const - { - return cdl_var == eLVT_Cs3; - } + bool is_TFFS() const + { + return mt::is_TFFS(simulation_type); + } - bool is_lvt_Cs5() const - { - return cdl_var == eLVT_Cs5; - } + bool is_TFRS() const + { + return mt::is_TFRS(simulation_type); + } - bool is_lvt_mfa2() const - { - return cdl_var == eLVT_mfa2; - } + bool is_PropFS() const + { + return mt::is_PropFS(simulation_type); + } - bool is_lvt_afa2() const - { - return cdl_var == eLVT_afa2; - } + bool is_PropRS() const + { + return mt::is_PropRS(simulation_type); + } - bool is_lvt_mfa3() const - { - return cdl_var == eLVT_mfa3; - } + bool is_STEM_ISTEM() const + { + return mt::is_STEM_ISTEM(simulation_type); + } - bool is_lvt_afa3 () const - { - return cdl_var == eLVT_afa3; - } + bool is_CBED_CBEI() const + { + return mt::is_CBED_CBEI(simulation_type); + } - bool is_lvt_inner_aper_ang() const - { - return cdl_var == eLVT_inner_aper_ang; - } + bool is_ED_HRTEM() const + { + return mt::is_ED_HRTEM(simulation_type); + } - bool is_lvt_outer_aper_ang () const - { - return cdl_var == eLVT_outer_aper_ang; - } + bool is_PED_HCTEM() const + { + return mt::is_PED_HCTEM(simulation_type); + } + + bool is_EWFS_EWRS() const + { + return mt::is_EWFS_EWRS(simulation_type); + } + + bool is_EWFS_EWRS_SC() const + { + return mt::is_EWFS_EWRS_SC(simulation_type, pn_model, pn_single_conf); + } + + bool is_EELS_EFTEM() const + { + return mt::is_EELS_EFTEM(simulation_type); + } + + bool is_IWFS_IWRS() const + { + return mt::is_IWFS_IWRS(simulation_type); + } + + bool is_PPFS_PPRS() const + { + return mt::is_PPFS_PPRS(simulation_type); + } + + bool is_TFFS_TFRS() const + { + return mt::is_TFFS_TFRS(simulation_type); + } + + bool is_PropFS_PropRS() const + { + return mt::is_PropFS_PropRS(simulation_type); + } + + bool is_grid_FS() const + { + return mt::is_grid_FS(simulation_type); + } + + bool is_grid_RS() const + { + return mt::is_grid_RS(simulation_type); + } + + bool is_simulation_type_FS() const + { + return mt::is_simulation_type_FS(simulation_type); + } + + bool is_simulation_type_RS() const + { + return mt::is_simulation_type_RS(simulation_type); + } + + bool is_specimen_required() const + { + return mt::is_specimen_required(simulation_type); + } + + bool is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM() const + { + return mt::is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM(simulation_type); + } + + bool is_CBED_ED_EWFS_PED() const + { + return mt::is_CBED_ED_EWFS_PED(simulation_type); + } + + bool is_obj_lens_temp_spat() const + { + return mt::is_obj_lens_temp_spat(simulation_type); + } + + bool is_cond_lens_temp_spat() const + { + return mt::is_cond_lens_temp_spat(simulation_type); + } + + eSpace get_simulation_space() const + { + return mt::get_simulation_space(simulation_type); + } + + bool is_scanning() const + { + return mt::is_scanning(simulation_type); + } + + /**************************************************************************************/ + void set_incident_wave_type(eIncident_Wave_Type iw_type_i) + { + iw_type = mt::validate_incident_wave_type(simulation_type, iw_type_i); + } + + /**************************************************************************************/ + bool is_illu_mod_coherent() const + { + return illumination_model == eIM_Coherent; + } + + bool is_illu_mod_partial_coherent() const + { + return illumination_model == eIM_Partial_Coherent; + } + + bool is_illu_mod_trans_cross_coef() const + { + return illumination_model == eIM_Trans_Cross_Coef; + } + + bool is_illu_mod_full_integration() const + { + return illumination_model == eIM_Full_Integration; + } + + /**************************************************************************************/ + bool is_incoh_temporal_spatial() const + { + return temporal_spatial_incoh == eTSI_Temporal_Spatial; + } + + bool is_incoh_temporal() const + { + return temporal_spatial_incoh == eTSI_Temporal; + } + + bool is_incoh_spatial() const + { + return temporal_spatial_incoh == eTSI_Spatial; + } + + /**************************************************************************************/ + bool is_detector_circular() const + { + return detector.is_detector_circular(); + } + + bool is_detector_radial() const + { + return detector.is_detector_radial(); + } + + bool is_detector_matrix() const + { + return detector.is_detector_matrix(); + } + + /**************************************************************************************/ + bool is_slice_storage() const + { + bool slice_storage = is_PED_HCTEM() || is_EELS_EFTEM(); + slice_storage = slice_storage || is_ISTEM() || (is_STEM() && !pn_coh_contrib); + slice_storage = slice_storage || (is_CBED_CBEI() && is_illu_mod_full_integration()); + + return slice_storage; + } + + bool is_operation_mode_normal() const + { + return operation_mode == eOM_Normal; + } + + bool is_operation_mode_advanced() const + { + return operation_mode == eOM_Advanced; + } + + /**************************************************************************************/ + bool is_lvt_off() const + { + return cdl_var == eLVT_off; + } + + bool is_lvt_m() const + { + return cdl_var == eLVT_m; + } + + bool is_lvt_Cs3() const + { + return cdl_var == eLVT_Cs3; + } + + bool is_lvt_Cs5() const + { + return cdl_var == eLVT_Cs5; + } + + bool is_lvt_mfa2() const + { + return cdl_var == eLVT_mfa2; + } + + bool is_lvt_afa2() const + { + return cdl_var == eLVT_afa2; + } + + bool is_lvt_mfa3() const + { + return cdl_var == eLVT_mfa3; + } + + bool is_lvt_afa3() const + { + return cdl_var == eLVT_afa3; + } + + bool is_lvt_inner_aper_ang() const + { + return cdl_var == eLVT_inner_aper_ang; + } + + bool is_lvt_outer_aper_ang() const + { + return cdl_var == eLVT_outer_aper_ang; + } }; diff --git a/src/lin_alg_def.cuh b/src/lin_alg_def.cuh index 2b5e2a7b..11282b4f 100644 --- a/src/lin_alg_def.cuh +++ b/src/lin_alg_def.cuh @@ -20,257 +20,16 @@ #define LIN_ALG_DEF_H #include +#include #include "math.cuh" namespace mt { - template - struct r3d; - - // template - // class Vector; + /************************************************************************/ + /********************************2d vector*******************************/ + /************************************************************************/ - template - struct Rand_r3d - { - public: - void set_seed(int seed_new) - { - gen_u.seed(seed_new); - rand_u.reset(); - rand_temp.reset(); - } - - r3d operator()() - { - return r3d(rand_u(gen_u), rand_u(gen_u), rand_u(gen_u)); - } - - T temp() - { - rand_temp(gen_u); - } - - private: - std::mt19937_64 gen_u; - std::uniform_real_distribution rand_u; - std::uniform_real_distribution rand_temp; - }; - - // /*******************************mxn matrix*********************************/ - // template - // struct Mmxn - // { - // using value_type = T; - - // int m; - // int n; - - // Vector data; - - - // DEVICE_CALLABLE - // inline Mmxn(const int &m_i = 1, const int &n_i = 1) - // { - // m = m_i; - // n = n_i; - - // data.resize(m*n); - // } - - // DEVICE_CALLABLE - // inline Mmxn& operator+=(const Mmxn r) - // { - // - // for(auto i=0; i& operator-=(const Mmxn r) - // { - // for(auto i=0; i& operator*=(const T r) - // { - // if(this->n!=r.m) - // { - // return; - // } - - // for(auto ir=0; ir& operator/=(const T r) - // { - // for(auto i=0; i - // DEVICE_CALLABLE - // inline Mmxn operator+(const Mmxn &lhs, const Mmxn &rhs) - // { - // return Mmxn(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn operator+(const Mmxn &lhs, const X &rhs) - // { - // return Mmxn(lhs.x+rhs, lhs.y+rhs, lhs.z+rhs); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn operator+(const X &lhs, const Mmxn &rhs) - // { - // return Mmxn(lhs+rhs.x, lhs+rhs.y, lhs+rhs.z); - // } - - - // template - // DEVICE_CALLABLE - // inline Mmxn operator-(const Mmxn &lhs, const Mmxn &rhs) - // { - // return Mmxn(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn operator-(const Mmxn &lhs, const X &rhs) - // { - // return Mmxn(lhs.x-rhs, lhs.y-rhs, lhs.z-rhs); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn operator-(const X &lhs, const Mmxn &rhs) - // { - // return Mmxn(lhs-rhs.x, lhs-rhs.y, lhs-rhs.z); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn operator*(const Mmxn &lhs, const Mmxn &rhs) - // { - // return Mmxn(lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn operator*(const Mmxn &lhs, const X &rhs) - // { - // return Mmxn(lhs.x*rhs, lhs.y*rhs, lhs.z*rhs); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn operator*(const X &lhs, const Mmxn &rhs) - // { - // return Mmxn(lhs*rhs.x, lhs*rhs.y, lhs*rhs.z); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn operator/(const Mmxn &lhs, const X &rhs) - // { - // return Mmxn(lhs.x/rhs, lhs.y/rhs, lhs.z/rhs); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn fmin(const Mmxn lhs, const Mmxn rhs) - // { - // return Mmxn(::fmin(lhs.x, rhs.x), ::fmin(lhs.y, rhs.y), ::fmin(lhs.z, rhs.z)); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn fmax(const Mmxn lhs, const Mmxn rhs) - // { - // return Mmxn(::fmax(lhs.x, rhs.x), ::fmax(lhs.y, rhs.y), ::fmax(lhs.z, rhs.z)); - // } - - // template - // DEVICE_CALLABLE - // inline X norm(const Mmxn& r) - // { - // return r.x*r.x + r.y*r.y + r.z*r.z; - // } - - // template - // DEVICE_CALLABLE - // inline X module(const Mmxn& r) - // { - // return sqrt(norm(r)); - // } - - // template - // DEVICE_CALLABLE - // inline Mmxn normalized(const Mmxn& r) - // { - // return r/r.module(); - // } - - - // // template - // // DEVICE_CALLABLE - // // inline Mmxn matrix_prod(const TVector &Rm) - // // { - // // Mmxn r_o; - // // r_o.x = Rm[0]*x + Rm[3]*y + Rm[6]*z; - // // r_o.y = Rm[1]*x + Rm[4]*y + Rm[7]*z; - // // r_o.z = Rm[2]*x + Rm[5]*y + Rm[8]*z; - // // return r_o; - // // } - - // template - // DEVICE_CALLABLE - // inline X dot(const Mmxn &lhs, const Mmxn &rhs) - // { - // return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; - // } - - // template - // DEVICE_CALLABLE - // inline X angle(const Mmxn &lhs, const Mmxn &rhs) - // { - // return acos(dot(lhs, rhs)/(lhs.module()*rhs.module())); - // } - - /******************************2d vector*********************************/ template struct r2d { @@ -481,17 +240,6 @@ namespace mt return r/module(r); } - // template - // DEVICE_CALLABLE - // inline r2d matrix_prod(const TVector &Rm) - // { - // r2d r_o; - // r_o.x = Rm[0]*x + Rm[3]*y + Rm[6]*z; - // r_o.y = Rm[1]*x + Rm[4]*y + Rm[7]*z; - // r_o.z = Rm[2]*x + Rm[5]*y + Rm[8]*z; - // return r_o; - // } - template DEVICE_CALLABLE inline X dot(const r2d &lhs, const r2d &rhs) @@ -506,7 +254,10 @@ namespace mt return acos(dot(lhs, rhs)/(lhs.module()*rhs.module())); } - /******************************3d vector*********************************/ + /************************************************************************/ + /********************************3d vector*******************************/ + /************************************************************************/ + template struct r3d { @@ -584,8 +335,8 @@ namespace mt DEVICE_CALLABLE inline void normalized() { - auto rm = module(); - *this /= (isZero(rm))?1.0:rm; + auto rm = module(); + *this /= module(); } template @@ -682,14 +433,14 @@ namespace mt template DEVICE_CALLABLE - inline r3d fmin(const r3d lhs, const r3d rhs) + inline r3d fmin(const r3d &lhs, const r3d &rhs) { return r3d(::fmin(lhs.x, rhs.x), ::fmin(lhs.y, rhs.y), ::fmin(lhs.z, rhs.z)); } template DEVICE_CALLABLE - inline r3d fmax(const r3d lhs, const r3d rhs) + inline r3d fmax(const r3d &lhs, const r3d &rhs) { return r3d(::fmax(lhs.x, rhs.x), ::fmax(lhs.y, rhs.y), ::fmax(lhs.z, rhs.z)); } @@ -715,18 +466,6 @@ namespace mt return r/r.module(); } - - // template - // DEVICE_CALLABLE - // inline r3d matrix_prod(const TVector &Rm) - // { - // r3d r_o; - // r_o.x = Rm[0]*x + Rm[3]*y + Rm[6]*z; - // r_o.y = Rm[1]*x + Rm[4]*y + Rm[7]*z; - // r_o.z = Rm[2]*x + Rm[5]*y + Rm[8]*z; - // return r_o; - // } - template DEVICE_CALLABLE inline X dot(const r3d &lhs, const r3d &rhs) @@ -740,5 +479,400 @@ namespace mt { return acos(dot(lhs, rhs)/(lhs.module()*rhs.module())); } + + /************************************************************************/ + /********************************3x3 matrix******************************/ + /************************************************************************/ + + template + struct M3x3 + { + using value_type = T; + + const int m; + const int n; + const int m_size; + + std::vector data; + + DEVICE_CALLABLE + inline M3x3(): m(3), n(3), m_size(m*n) + { + data.resize(m_size); + } + + template + DEVICE_CALLABLE + inline M3x3(const TVector &v): m(3), n(3), m_size(m*n) + { + data.resize(m_size); + + if (v.size()>=m_size) + { + std::copy(v.begin(), v.begin()+m_size, data.begin()); + } + } + + int size() const + { + return m_size; + } + + DEVICE_CALLABLE FORCE_INLINE + T& operator[](const int idx){ return data[idx]; } + + DEVICE_CALLABLE FORCE_INLINE + const T& operator[](const int idx) const { return data[idx]; } + + DEVICE_CALLABLE FORCE_INLINE + T& operator()(const int ir, const int ic){ return data[ir-1+m*(ic-1)]; } + + DEVICE_CALLABLE FORCE_INLINE + const T& operator()(const int ir, const int ic) const { return data[ir-1+m*(ic-1)]; } + + DEVICE_CALLABLE + inline M3x3& operator+=(const T &r) + { + for(auto ik=0; ik& operator+=(const M3x3 &r) + { + for(auto ik=0; ik& operator-=(const T &r) + { + for(auto ik=0; ik& operator-=(const M3x3 &r) + { + for(auto ik=0; ik& operator*=(const T &r) + { + for(auto ik=0; ik& operator*=(const M3x3 &r) + { + T a11 = data[0]*r.data[0] + data[3]*r.data[1] + data[6]*r.data[2]; + T a21 = data[0]*r.data[3] + data[3]*r.data[4] + data[6]*r.data[5]; + T a31 = data[0]*r.data[6] + data[3]*r.data[7] + data[6]*r.data[8]; + + T a12 = data[1]*r.data[0] + data[4]*r.data[1] + data[7]*r.data[2]; + T a22 = data[1]*r.data[3] + data[4]*r.data[4] + data[7]*r.data[5]; + T a32 = data[1]*r.data[6] + data[4]*r.data[7] + data[7]*r.data[8]; + + T a13 = data[2]*r.data[0] + data[5]*r.data[1] + data[8]*r.data[2]; + T a23 = data[2]*r.data[3] + data[5]*r.data[4] + data[8]*r.data[5]; + T a33 = data[2]*r.data[6] + data[5]*r.data[7] + data[8]*r.data[8]; + + data[0] = a11; + data[1] = a21; + data[2] = a31; + + data[3] = a12; + data[4] = a22; + data[5] = a32; + + data[6] = a13; + data[7] = a23; + data[8] = a33; + + return *this; + } + + DEVICE_CALLABLE + inline M3x3& operator/=(const T r) + { + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 operator+(const M3x3 &lhs, const X &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 operator+(const X &lhs, const M3x3 &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 operator+(const M3x3 &lhs, const M3x3 &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 operator-(const M3x3 &lhs, const X &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 operator-(const X &lhs, const M3x3 &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 operator-(const M3x3 &lhs, const M3x3 &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 operator*(const M3x3 &lhs, const X &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 operator*(const X &lhs, const M3x3 &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline r3d operator*(const M3x3 &lhs, const r3d &rhs) + { + r3d V; + + V.x = lhs[0]*rhs.x + lhs[3]*rhs.y + lhs[6]*rhs.z; + V.y = lhs[1]*rhs.x + lhs[4]*rhs.y + lhs[7]*rhs.z; + V.z = lhs[2]*rhs.x + lhs[5]*rhs.y + lhs[8]*rhs.z; + + return V; + } + + template + DEVICE_CALLABLE + inline r3d operator*(const r3d &lhs, const M3x3 &rhs) + { + r3d V; + + V.x = lhs[0]*rhs.x + lhs[1]*rhs.y + lhs[2]*rhs.z; + V.y = lhs[3]*rhs.x + lhs[4]*rhs.y + lhs[5]*rhs.z; + V.z = lhs[6]*rhs.x + lhs[7]*rhs.y + lhs[8]*rhs.z; + + return V; + } + + template + DEVICE_CALLABLE + inline M3x3 operator*(const M3x3 &lhs, const M3x3 &rhs) + { + M3x3 M; + + M[0] = lhs[0]*rhs[0] + lhs[3]*rhs[1] + lhs[6]*rhs[2]; + M[1] = lhs[0]*rhs[3] + lhs[3]*rhs[4] + lhs[6]*rhs[5]; + M[2] = lhs[0]*rhs[6] + lhs[3]*rhs[7] + lhs[6]*rhs[8]; + + M[3] = lhs[1]*rhs[0] + lhs[4]*rhs[1] + lhs[7]*rhs[2]; + M[4] = lhs[1]*rhs[3] + lhs[4]*rhs[4] + lhs[7]*rhs[5]; + M[5] = lhs[1]*rhs[6] + lhs[4]*rhs[7] + lhs[7]*rhs[8]; + + M[6] = lhs[2]*rhs[0] + lhs[5]*rhs[1] + lhs[8]*rhs[2]; + M[7] = lhs[2]*rhs[3] + lhs[5]*rhs[4] + lhs[8]*rhs[5]; + M[8] = lhs[2]*rhs[6] + lhs[5]*rhs[7] + lhs[8]*rhs[8]; + + return M; + } + + template + DEVICE_CALLABLE + inline M3x3 operator/(const M3x3 &lhs, const X &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 operator/(const X &lhs, const M3x3 &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 fmin(const M3x3 &lhs, const M3x3 &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline M3x3 fmax(const M3x3 &lhs, const M3x3 &rhs) + { + M3x3 M; + + for(auto ik=0; ik + DEVICE_CALLABLE + inline X det(const M3x3& M) + { + X d = M(1,1)*M(2,2)*M(3,3)+M(1,2)*M(2,3)*M(3,1)+M(1,3)*M(2,1)*M(3,2); + d -= M(1,3)*M(2,2)*M(3,1)+M(1,2)*M(2,1)*M(3,3)+M(1,1)*M(2,3)*M(3,2); + + return d; + } + + template + DEVICE_CALLABLE + inline M3x3 inv(const M3x3& M) + { + M3x3 Mo; + + Mo(1,1) = M(2,2)*M(3,3)-M(2,3)*M(3,2); + Mo(2,1) = M(2,3)*M(3,1)-M(2,1)*M(3,3); + Mo(3,1) = M(2,1)*M(3,2)-M(2,2)*M(3,1); + + Mo(1,2) = M(1,3)*M(3,2)-M(1,2)*M(3,3); + Mo(2,2) = M(1,1)*M(3,3)-M(1,3)*M(3,1); + Mo(3,2) = M(1,2)*M(3,1)-M(1,1)*M(3,2); + + Mo(1,3) = M(1,2)*M(2,3)-M(1,3)*M(2,2); + Mo(3,3) = M(1,1)*M(2,2)-M(1,2)*M(2,1); + Mo(2,3) = M(1,3)*M(2,1)-M(1,1)*M(2,3); + + Mo /= det(M); + + return Mo; + } } // namespace mt #endif \ No newline at end of file diff --git a/src/math.cuh b/src/math.cuh index 2d6e3232..b222e2a6 100644 --- a/src/math.cuh +++ b/src/math.cuh @@ -38,7 +38,59 @@ // #pragma message("nonCuda MATH_H") //#endif -#ifndef __CUDACC__ +#ifdef __CUDACC__ + #include + #include + #include + using thrust::complex; + using thrust::norm; + using thrust::polar; + using thrust::arg; + using thrust::abs; + + template + DEVICE_CALLABLE FORCE_INLINE + T bessel_j0(const T &x) + { + return j0(x); + } + + template + DEVICE_CALLABLE FORCE_INLINE + T bessel_j1(const T &x) + { + return j1(x); + } + + template + DEVICE_CALLABLE FORCE_INLINE + T bessel_jn(const int &n, const T &x) + { + return jn(n, x); + } + + template + DEVICE_CALLABLE FORCE_INLINE + T bessel_y0(const T &x) + { + return y0(x); + } + + template + DEVICE_CALLABLE FORCE_INLINE + T bessel_y1(const T &x) + { + return y1(x); + } + + template + DEVICE_CALLABLE FORCE_INLINE + T bessel_yn(const int &n, const T &x) + { + return yn(n, x); + } + +#else #include #include using std::complex; @@ -374,76 +426,30 @@ } return by; } - -#else - #include - #include - #include - using thrust::complex; - using thrust::norm; - using thrust::polar; - using thrust::arg; - using thrust::abs; - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_j0(const T &x) - { - return j0(x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_j1(const T &x) - { - return j1(x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_jn(const int &n, const T &x) - { - return jn(n, x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_y0(const T &x) - { - return y0(x); - } - - template - DEVICE_CALLABLE FORCE_INLINE - T bessel_y1(const T &x) - { - return y1(x); - } +#endif + using std::min; + using std::max; template DEVICE_CALLABLE FORCE_INLINE - T bessel_yn(const int &n, const T &x) + T square(T x) { - return yn(n, x); + return x*x; } -#endif - using std::min; - using std::max; - - //#ifndef __APPLE__ - DEVICE_CALLABLE FORCE_INLINE - double norm(const double &x) - { - return x*x; - } - - DEVICE_CALLABLE FORCE_INLINE - float norm(const float &x) - { - return x*x; - } - // #endif + //#ifndef __APPLE__ + DEVICE_CALLABLE FORCE_INLINE + double norm(const double &x) + { + return x*x; + } + + DEVICE_CALLABLE FORCE_INLINE + float norm(const float &x) + { + return x*x; + } + // #endif template DEVICE_CALLABLE FORCE_INLINE diff --git a/src/matlab_mex.cuh b/src/matlab_mex.cuh index d120fefe..b854ca59 100644 --- a/src/matlab_mex.cuh +++ b/src/matlab_mex.cuh @@ -268,18 +268,21 @@ namespace mt { system_conf.device = mx_get_scalar_field(mx_input, "device"); system_conf.precision = mx_get_scalar_field(mx_input, "precision"); - system_conf.cpu_ncores = mx_get_scalar_field(mx_input, "cpu_ncores"); + system_conf.cpu_ncores = 1; + //system_conf.cpu_ncores = mx_get_scalar_field(mx_input, "cpu_ncores"); system_conf.cpu_nthread = mx_get_scalar_field(mx_input, "cpu_nthread"); - system_conf.gpu_device = mx_get_scalar_field(mx_input, "gpu_device"); - system_conf.gpu_nstream = mx_get_scalar_field(mx_input, "gpu_nstream"); + system_conf.gpu_device = mx_get_scalar_field(mx_input, "gpu_device"); + system_conf.gpu_nstream = 0; + //system_conf.gpu_nstream = mx_get_scalar_field(mx_input, "gpu_nstream"); system_conf.active = true; } else { system_conf.cpu_nthread = 4; system_conf.active = false; - }; + } system_conf.validate_parameters(); + system_conf.set_device(); return system_conf; } diff --git a/src/matlab_types.cuh b/src/matlab_types.cuh index 8aba3a91..4f58bf49 100644 --- a/src/matlab_types.cuh +++ b/src/matlab_types.cuh @@ -77,7 +77,7 @@ namespace mt template std::ostream& operator<<(std::ostream& out, const complex_s& z){ - return out << "("<< z.real() << ", " << z.imag() << ")"; + return out << "("<< z.real() << ", " << z.imag() <<")"; } /*********************pointer to double matrix*****************/ @@ -523,10 +523,10 @@ namespace mt template enable_if_host_vector_and_rmatrix - add_square_scale_to_host(Stream &stream, Value_type w_i, + add_scale_square_to_host(Stream &stream, Value_type w_i, TVector_i &M_i, TVector_o &M_o, Vector, e_host> *M_i_h = nullptr) { - auto thr_add_square_scale_to_host = [&](const Range_2d &range) + auto thr_add_scale_square_to_host = [&](const Range_2d &range) { for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) { @@ -537,7 +537,7 @@ namespace mt stream.set_n_act_stream(M_o.size()); stream.set_grid(1, M_o.size()); - stream.exec(thr_add_square_scale_to_host); + stream.exec(thr_add_scale_square_to_host); } template diff --git a/src/memory_info.cuh b/src/memory_info.cuh index 0482274c..5179165e 100644 --- a/src/memory_info.cuh +++ b/src/memory_info.cuh @@ -138,7 +138,6 @@ namespace mt device_properties.resize(device_count); for (auto idev = 0; idev < device_count; idev++) { - cudaSetDevice(idev); cudaDeviceProp cuda_device_prop; cudaGetDeviceProperties(&cuda_device_prop, idev); @@ -148,8 +147,11 @@ namespace mt memory_info(device_properties[idev].total_memory_size, device_properties[idev].free_memory_size); } - auto compare_fn = [](const Device_Properties &a, const Device_Properties &b)->bool{ return a.compute_capability > b.compute_capability; }; - std::sort(device_properties.begin(), device_properties.end(), compare_fn); + //auto compare_fn = [](const Device_Properties &a, const Device_Properties &b)->bool + //{ + // return a.compute_capability > b.compute_capability; + //}; + //std::sort(device_properties.begin(), device_properties.end(), compare_fn); } inline diff --git a/src/microscope_effects.cuh b/src/microscope_effects.cuh index 0f2fbcfb..c4b823db 100644 --- a/src/microscope_effects.cuh +++ b/src/microscope_effects.cuh @@ -51,7 +51,7 @@ namespace mt } // Load quadratures - temporal_spatial_quadratures(input_multislice->obj_lens, qt, qs); + obj_lens_temporal_spatial_quadratures(input_multislice->obj_lens, qt, qs); } void operator()(Vector &fpsi, Vector &m2psi_tot) @@ -92,8 +92,6 @@ namespace mt Vector m2psi_tot(input_multislice->grid_2d.nxy()); this->operator()(psi, m2psi_tot); mt::copy_to_host(output_multislice.stream, m2psi_tot, output_multislice.m2psi_tot[0]); - output_multislice.shift(); - output_multislice.clear_temporal_data(); } private: @@ -106,19 +104,19 @@ namespace mt void PCTF_LI_WPO_TEM(const eTemporal_Spatial_Incoh &temporal_spatial_incoh, Vector &fpsi, Vector &m2psi_tot) { - T_r sf = input_multislice->obj_lens.sf; - T_r beta = input_multislice->obj_lens.beta; + T_r dsf_sigma = input_multislice->obj_lens.dsf_sigma; + T_r ssf_sigma = input_multislice->obj_lens.ssf_sigma; switch(temporal_spatial_incoh) { case eTSI_Temporal: // Temporal { - input_multislice->obj_lens.beta = 0; + input_multislice->obj_lens.set_ssf_sigma(0); } break; case eTSI_Spatial: // Spatial { - input_multislice->obj_lens.sf = 0; + input_multislice->obj_lens.set_dsf_sigma(0); } break; } @@ -127,8 +125,8 @@ namespace mt fft_2d->inverse(psi); mt::square(*stream, psi, m2psi_tot); - input_multislice->obj_lens.sf = sf; - input_multislice->obj_lens.beta = beta; + input_multislice->obj_lens.set_dsf_sigma(dsf_sigma); + input_multislice->obj_lens.set_ssf_sigma(ssf_sigma); } void num_int_TEM(const eTemporal_Spatial_Incoh &temporal_spatial_incoh, Vector &fpsi, Vector &m2psi_tot) @@ -144,12 +142,12 @@ namespace mt { for(auto j = 0; jobj_lens.sf*qt.x[j]+c_10_0; + auto c_10 = input_multislice->obj_lens.dsf_iehwgd*qt.x[j]+c_10_0; input_multislice->obj_lens.set_defocus(c_10); mt::apply_CTF(*stream, input_multislice->grid_2d, input_multislice->obj_lens, qs.x[i], qs.y[i], fpsi, psi); fft_2d->inverse(psi); - mt::add_square_scale(*stream, qs.w[i]*qt.w[j], psi, m2psi_tot); + mt::add_scale_square(*stream, qs.w[i]*qt.w[j], psi, m2psi_tot); } } } @@ -158,12 +156,12 @@ namespace mt { for(auto j = 0; jobj_lens.sf*qt.x[j]+c_10_0; + auto c_10 = input_multislice->obj_lens.dsf_iehwgd*qt.x[j]+c_10_0; input_multislice->obj_lens.set_defocus(c_10); mt::apply_CTF(*stream, input_multislice->grid_2d, input_multislice->obj_lens, 0.0, 0.0, fpsi, psi); fft_2d->inverse(psi); - mt::add_square_scale(*stream, qt.w[j], psi, m2psi_tot); + mt::add_scale_square(*stream, qt.w[j], psi, m2psi_tot); } } break; @@ -173,7 +171,7 @@ namespace mt { mt::apply_CTF(*stream, input_multislice->grid_2d, input_multislice->obj_lens, qs.x[i], qs.y[i], fpsi, psi); fft_2d->inverse(psi); - mt::add_square_scale(*stream, qs.w[i], psi, m2psi_tot); + mt::add_scale_square(*stream, qs.w[i], psi, m2psi_tot); } } } diff --git a/src/multislice.cuh b/src/multislice.cuh index ee7f8574..532236a6 100644 --- a/src/multislice.cuh +++ b/src/multislice.cuh @@ -20,6 +20,7 @@ #define MULTISLICE_H #include +#include "math.cuh" #include "types.cuh" #include "traits.cuh" #include "input_multislice.cuh" @@ -29,6 +30,7 @@ #include "host_device_functions.cuh" #include "energy_loss.cuh" #include "wave_function.cuh" +#include "timing.cuh" namespace mt { @@ -101,7 +103,7 @@ namespace mt ext_iter = 0; /*****************************************************************/ - T_r w = input_multislice->get_weight(); + T_r w = input_multislice->get_phonon_rot_weight(); output_multislice.init(); @@ -151,57 +153,65 @@ namespace mt wave_function.set_m2psi_coh(output_multislice); } - - output_multislice.shift(); - output_multislice.clear_temporal_data(); } template void CBED_CBEI(TOutput_multislice &output_multislice) { - Q1 qt; - Q2 qs; - - // Load quadratures - temporal_spatial_quadratures(input_multislice->cond_lens, qt, qs); - - /*****************************************************************/ - - T_r w = input_multislice->get_weight(); - T_r f_0 = input_multislice->cond_lens.c_10 ; - // T_r theta_0 = input_multislice->theta; - // T_r phi_0 = input_multislice->phi; - output_multislice.init(); if(input_multislice->is_illu_mod_full_integration()) { - ext_niter = qt.size()*input_multislice->number_conf(); + Q1 qt; + Q2 qs; + + // Load quadratures + cond_lens_temporal_spatial_quadratures(input_multislice->cond_lens, qt, qs); + + /*****************************************************************/ + double w_pr_0 = input_multislice->get_phonon_rot_weight(); + double c_10_0 = input_multislice->cond_lens.c_10; + double dsf_iehwgd = input_multislice->cond_lens.dsf_iehwgd; + double ssf_iehwgd = input_multislice->cond_lens.ssf_iehwgd; + const int nbeams = input_multislice->number_of_beams(); + Vector beam_x(nbeams); + Vector beam_y(nbeams); + + ext_niter = qs.size()*qt.size()*input_multislice->number_conf(); ext_iter = 0; for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) { wave_function.move_atoms(iconf); - for(auto j = 0; jcond_lens.sf*qt.x[j]+f_0; - input_multislice->cond_lens.set_defocus(f); - wave_function.set_incident_wave(wave_function.psi_z); - wave_function.psi(w*qt.w[j], wave_function.psi_z, output_multislice); + for(auto ibeam = 0; ibeamiw_x[ibeam]; + beam_y[ibeam] = ssf_iehwgd*qs.y[ispat] + input_multislice->iw_y[ibeam]; + } - ext_iter++; - if(ext_stop_sim) break; + // temporal incoherence + for(auto itemp = 0; itempcond_lens.set_defocus(c_10); + wave_function.set_incident_wave(wave_function.psi_z, beam_x, beam_y); + wave_function.psi(w_pr_0*qs.w[ispat]*qt.w[itemp], wave_function.psi_z, output_multislice); + + ext_iter++; + if(ext_stop_sim) break; + } } if(ext_stop_sim) break; } wave_function.set_m2psi_coh(output_multislice); - output_multislice.shift(); - output_multislice.clear_temporal_data(); - - input_multislice->obj_lens.set_defocus(f_0); + input_multislice->obj_lens.set_defocus(c_10_0); + input_multislice->set_beam_position(input_multislice->iw_x, input_multislice->iw_y); } else { @@ -222,7 +232,7 @@ namespace mt ext_iter = 0; /*****************************************************************/ - T_r w = input_multislice->get_weight(); + T_r w = input_multislice->get_phonon_rot_weight(); output_multislice.init(); @@ -242,9 +252,6 @@ namespace mt } wave_function.set_m2psi_coh(output_multislice); - - output_multislice.shift(); - output_multislice.clear_temporal_data(); } template @@ -254,14 +261,16 @@ namespace mt ext_iter = 0; /*****************************************************************/ - T_r w = input_multislice->get_weight(); + T_r w = input_multislice->get_phonon_rot_weight(); output_multislice.init(); for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) { - wave_function.move_atoms(iconf); + wave_function.move_atoms(iconf); + wave_function.set_incident_wave(wave_function.psi_z); + wave_function.psi(w, wave_function.psi_z, output_multislice); ext_iter++; @@ -269,9 +278,6 @@ namespace mt } wave_function.set_m2psi_coh(output_multislice); - - output_multislice.shift(); - output_multislice.clear_temporal_data(); } template @@ -286,7 +292,7 @@ namespace mt } /*****************************************************************/ - T_r w = input_multislice->get_weight(); + T_r w = input_multislice->get_phonon_rot_weight(); auto psi = [&](T_r w, Vector &psi_z, TOutput_multislice &output_multislice) { @@ -325,6 +331,10 @@ namespace mt output_multislice.init(); + input_multislice->iscan.resize(1); + input_multislice->beam_x.resize(1); + input_multislice->beam_y.resize(1); + if(input_multislice->is_EELS()) { for(auto iconf = input_multislice->fp_iconf_0; iconf <= input_multislice->pn_nconf; iconf++) @@ -354,9 +364,6 @@ namespace mt if(ext_stop_sim) break; } } - - output_multislice.shift(); - output_multislice.clear_temporal_data(); } Input_Multislice *input_multislice; @@ -378,7 +385,6 @@ namespace mt template int Multislice::ext_iter = 0; - } // namespace mt #endif diff --git a/src/output_multislice.hpp b/src/output_multislice.hpp index 856a74b0..19b84d82 100644 --- a/src/output_multislice.hpp +++ b/src/output_multislice.hpp @@ -7,7 +7,7 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * MULTEM is distributed in the hope that it will be useful, + * MULTEM 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. @@ -19,6 +19,7 @@ #ifndef OUTPUT_MULTISLICE_H #define OUTPUT_MULTISLICE_H +#include #include #include "math.cuh" @@ -34,812 +35,1324 @@ namespace mt { inline - bool is_ot_image_tot_coh(const eTEM_Output_Type &output_type) + bool is_ot_image_tot_coh(const eTEM_Output_Type &output_type) { - return output_type==mt::eTEMOT_image_tot_coh; + return output_type == mt::eTEMOT_image_tot_coh; } inline - bool is_ot_image_tot(const eTEM_Output_Type &output_type) + bool is_ot_image_tot(const eTEM_Output_Type &output_type) { - return output_type==mt::eTEMOT_image_tot; + return output_type == mt::eTEMOT_image_tot; } inline - bool is_ot_m2psi_tot_coh(const eTEM_Output_Type &output_type) + bool is_ot_m2psi_tot_coh(const eTEM_Output_Type &output_type) { - return output_type==mt::eTEMOT_m2psi_tot_coh; + return output_type == mt::eTEMOT_m2psi_tot_coh; } inline - bool is_ot_m2psi_tot(const eTEM_Output_Type &output_type) + bool is_ot_m2psi_tot(const eTEM_Output_Type &output_type) { - return output_type==mt::eTEMOT_m2psi_tot; + return output_type == mt::eTEMOT_m2psi_tot; } inline - bool is_ot_m2psi_tot_psi_coh(const eTEM_Output_Type &output_type) + bool is_ot_m2psi_tot_psi_coh(const eTEM_Output_Type &output_type) { - return output_type==mt::eTEMOT_m2psi_tot_psi_coh; + return output_type == mt::eTEMOT_m2psi_tot_psi_coh; } inline - bool is_ot_psi_coh(const eTEM_Output_Type &output_type) + bool is_ot_psi_coh(const eTEM_Output_Type &output_type) { - return output_type==mt::eTEMOT_psi_coh; + return output_type == mt::eTEMOT_psi_coh; } inline - bool is_ot_psi_0(const eTEM_Output_Type &output_type) + bool is_ot_psi_0(const eTEM_Output_Type &output_type) { - return output_type==mt::eTEMOT_psi_0; + return output_type == mt::eTEMOT_psi_0; } inline - bool is_ot_V(const eTEM_Output_Type &output_type) + bool is_ot_V(const eTEM_Output_Type &output_type) { - return output_type==mt::eTEMOT_V; + return output_type == mt::eTEMOT_V; } inline - bool is_ot_trans(const eTEM_Output_Type &output_type) + bool is_ot_trans(const eTEM_Output_Type &output_type) { - return output_type==mt::eTEMOT_trans; + return output_type == mt::eTEMOT_trans; } /**************************************************************************************/ template - class Output_Multislice: public Input_Multislice + class Output_Multislice : public Input_Multislice { - public: - using T_r = T; - using T_c = complex; - - using TVector_r = host_vector; - using TVector_c = host_vector>; - - Output_Multislice(): Input_Multislice(), output_type(eTEMOT_m2psi_tot), ndetector(0), nx(0), ny(0), dx(0), dy(0), dr(0){} - - template - void assign(TOutput_Multislice &output_multislice) - { - assign_input_multislice(output_multislice); - - output_type = output_multislice.output_type; - ndetector = output_multislice.ndetector; - nx = output_multislice.nx; - ny = output_multislice.ny; - dx = output_multislice.dx; - dy = output_multislice.dy; - dr = output_multislice.dr; - - x = output_multislice.x; - y = output_multislice.y; - r = output_multislice.r; - - image_tot.resize(output_multislice.image_tot.size()); - for(auto ithk = 0; ithk < output_multislice.image_tot.size(); ithk++) - { - image_tot[ithk].image.resize(output_multislice.image_tot[ithk].image.size()); - for(auto idet = 0; idet < output_multislice.image_tot[ithk].image.size(); idet++) - { - image_tot[ithk].image[idet] = output_multislice.image_tot[ithk].image[idet]; - } - } - - image_coh.resize(output_multislice.image_coh.size()); - for(auto ithk = 0; ithk < output_multislice.image_coh.size(); ithk++) + public: + using T_r = T; + using T_c = complex; + + using TVector_hr = host_vector; + using TVector_hc = host_vector>; + + using TVector_dr = device_vector; + using TVector_dc = device_vector>; + + Output_Multislice() : Input_Multislice(), output_type(eTEMOT_m2psi_tot), + ndetector(0), nx(0), ny(0), dx(0), dy(0), dr(0), n_thk(0), n_thk_d(0) {} + + template + void assign(TOutput_Multislice &output_multislice) + { + assign_input_multislice(output_multislice); + + output_type = output_multislice.output_type; + ndetector = output_multislice.ndetector; + nx = output_multislice.nx; + ny = output_multislice.ny; + dx = output_multislice.dx; + dy = output_multislice.dy; + dr = output_multislice.dr; + + x = output_multislice.x; + y = output_multislice.y; + r = output_multislice.r; + + image_tot.resize(output_multislice.image_tot.size()); + for (auto ithk = 0; ithk < output_multislice.image_tot.size(); ithk++) + { + image_tot[ithk].image.resize(output_multislice.image_tot[ithk].image.size()); + for (auto idet = 0; idet < output_multislice.image_tot[ithk].image.size(); idet++) { - image_coh[ithk].image.resize(output_multislice.image_coh[ithk].image.size()); - for(auto idet = 0; idet < output_multislice.image_coh[ithk].image.size(); idet++) - { - image_coh[ithk].image[idet] = output_multislice.image_coh[ithk].image[idet]; - } + image_tot[ithk].image[idet] = output_multislice.image_tot[ithk].image[idet]; } + } - m2psi_tot.resize(output_multislice.m2psi_tot.size()); - for(auto ithk = 0; ithk < output_multislice.m2psi_tot.size(); ithk++) + image_coh.resize(output_multislice.image_coh.size()); + for (auto ithk = 0; ithk < output_multislice.image_coh.size(); ithk++) + { + image_coh[ithk].image.resize(output_multislice.image_coh[ithk].image.size()); + for (auto idet = 0; idet < output_multislice.image_coh[ithk].image.size(); idet++) { - m2psi_tot[ithk] = output_multislice.m2psi_tot[ithk]; + image_coh[ithk].image[idet] = output_multislice.image_coh[ithk].image[idet]; } + } - m2psi_coh.resize(output_multislice.m2psi_coh.size()); - for(auto ithk = 0; ithk < output_multislice.m2psi_coh.size(); ithk++) - { - m2psi_coh[ithk] = output_multislice.m2psi_coh[ithk]; - } + m2psi_tot.resize(output_multislice.m2psi_tot.size()); + for (auto ithk = 0; ithk < output_multislice.m2psi_tot.size(); ithk++) + { + m2psi_tot[ithk] = output_multislice.m2psi_tot[ithk]; + } - psi_coh.resize(output_multislice.psi_coh.size()); - for(auto ithk = 0; ithk < output_multislice.psi_coh.size(); ithk++) - { - psi_coh[ithk] = output_multislice.psi_coh[ithk]; - } + m2psi_coh.resize(output_multislice.m2psi_coh.size()); + for (auto ithk = 0; ithk < output_multislice.m2psi_coh.size(); ithk++) + { + m2psi_coh[ithk] = output_multislice.m2psi_coh[ithk]; + } - V.resize(output_multislice.V.size()); - for(auto ithk = 0; ithk < output_multislice.V.size(); ithk++) - { - V[ithk] = output_multislice.V[ithk]; - } + psi_coh.resize(output_multislice.psi_coh.size()); + for (auto ithk = 0; ithk < output_multislice.psi_coh.size(); ithk++) + { + psi_coh[ithk] = output_multislice.psi_coh[ithk]; + } - trans.resize(output_multislice.trans.size()); - for(auto ithk = 0; ithk < output_multislice.trans.size(); ithk++) - { - trans[ithk] = output_multislice.trans[ithk]; - } + V.resize(output_multislice.V.size()); + for (auto ithk = 0; ithk < output_multislice.V.size(); ithk++) + { + V[ithk] = output_multislice.V[ithk]; + } - psi_0.resize(output_multislice.psi_0.size()); - for(auto ithk = 0; ithk < output_multislice.psi_0.size(); ithk++) - { - psi_0[ithk] = output_multislice.psi_0[ithk]; - } + trans.resize(output_multislice.trans.size()); + for (auto ithk = 0; ithk < output_multislice.trans.size(); ithk++) + { + trans[ithk] = output_multislice.trans[ithk]; } - template - Output_Multislice& operator=(TOutput_Multislice &output_multislice) + psi_0.resize(output_multislice.psi_0.size()); + for (auto ithk = 0; ithk < output_multislice.psi_0.size(); ithk++) { - assign(output_multislice); - return *this; + psi_0[ithk] = output_multislice.psi_0[ithk]; } + } - void clear() - { - output_type = eTEMOT_m2psi_tot; - ndetector = 0; - nx = 0; - ny = 0; - dx = 0; - dy = 0; - dr = 0; + template + Output_Multislice& operator=(TOutput_Multislice &output_multislice) + { + assign(output_multislice); + return *this; + } - x.clear(); - x.shrink_to_fit(); + void clear() + { + output_type = eTEMOT_m2psi_tot; + ndetector = 0; + nx = 0; + ny = 0; + dx = 0; + dy = 0; + dr = 0; - y.clear(); - y.shrink_to_fit(); + n_thk = 0; + n_thk_d = 0; - r.clear(); - r.shrink_to_fit(); + x.clear(); + x.shrink_to_fit(); - image_tot.clear(); - image_tot.shrink_to_fit(); + y.clear(); + y.shrink_to_fit(); - image_coh.clear(); - image_coh.shrink_to_fit(); + r.clear(); + r.shrink_to_fit(); - m2psi_tot.clear(); - m2psi_tot.shrink_to_fit(); + image_tot.clear(); + image_tot.shrink_to_fit(); - m2psi_coh.clear(); - m2psi_coh.shrink_to_fit(); + image_coh.clear(); + image_coh.shrink_to_fit(); - psi_coh.clear(); - psi_coh.shrink_to_fit(); + m2psi_tot.clear(); + m2psi_tot.shrink_to_fit(); - V.clear(); - V.shrink_to_fit(); + m2psi_coh.clear(); + m2psi_coh.shrink_to_fit(); - trans.clear(); - trans.shrink_to_fit(); + psi_coh.clear(); + psi_coh.shrink_to_fit(); - psi_0.clear(); - psi_0.shrink_to_fit(); - } + /*******************************************/ + psi_zh.clear(); + psi_zh.shrink_to_fit(); - template - void set_input_data(TInput_Multislice *input_multislice) - { - clear(); + m2psi_zh.clear(); + m2psi_zh.shrink_to_fit(); - stream.resize(1); + thk_gpu.clear(); + thk_gpu.shrink_to_fit(); - assign_input_multislice(*input_multislice); + m2psi_tot_d.clear(); + m2psi_tot_d.shrink_to_fit(); - ndetector = (this->is_EELS())?1:this->detector.size(); - - set_output_grid(); + m2psi_coh_d.clear(); + m2psi_coh_d.shrink_to_fit(); - set_output_type(); + psi_coh_d.clear(); + psi_coh_d.shrink_to_fit(); - switch(output_type) + /*******************************************/ + V.clear(); + V.shrink_to_fit(); + + trans.clear(); + trans.shrink_to_fit(); + + psi_0.clear(); + psi_0.shrink_to_fit(); + } + + void clean_temporal() + { + psi_zh.clear(); + //psi_zh.shrink_to_fit(); + + m2psi_zh.clear(); + //m2psi_zh.shrink_to_fit(); + + switch (output_type) + { + case eTEMOT_image_tot_coh: { - case eTEMOT_image_tot_coh: + for (auto ithk = 0; ithk < n_thk; ithk++) { - image_tot.resize(this->thick.size()); - image_coh.resize(this->thick.size()); - psi_coh.resize(this->thick.size()); + psi_coh[ithk].clear(); + //psi_coh[ithk].shrink_to_fit(); + + thk_gpu[ithk] = false; - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + if(ithkgrid_2d.nxy()); - mt::fill(stream, psi_coh[ithk], T_c(0)); - } - } - break; - case eTEMOT_image_tot: + } + break; + case eTEMOT_m2psi_tot_coh: + { + for (auto ithk = 0; ithk < n_thk; ithk++) { - image_tot.resize(this->thick.size()); + psi_coh[ithk].clear(); + //psi_coh[ithk].shrink_to_fit(); - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + thk_gpu[ithk] = false; + + if(ithkthick.size()); - m2psi_coh.resize(this->thick.size()); - psi_coh.resize(this->thick.size()); + psi_coh.clear(); + //psi_coh.shrink_to_fit(); - for(auto ithk = 0; ithk < this->thick.size(); ithk++) - { - m2psi_tot[ithk].resize(nxy()); - m2psi_coh[ithk].resize(nxy()); - psi_coh[ithk].resize(nxy()); + thk_gpu.clear(); + //thk_gpu.shrink_to_fit(); - mt::fill(stream, m2psi_tot[ithk], T_r(0)); - mt::fill(stream, m2psi_coh[ithk], T_r(0)); - mt::fill(stream, psi_coh[ithk], T_c(0)); - } - } - break; - case eTEMOT_m2psi_tot: - { - m2psi_tot.resize(this->thick.size()); + m2psi_tot_d.clear(); + //m2psi_tot_d.shrink_to_fit(); - for(auto ithk = 0; ithk < this->thick.size(); ithk++) - { - m2psi_tot[ithk].resize(nxy()); + m2psi_coh_d.clear(); + //m2psi_coh_d.shrink_to_fit(); - mt::fill(stream, m2psi_tot[ithk], T_r(0)); - } - } - break; - case eTEMOT_m2psi_tot_psi_coh: + psi_coh_d.clear(); + //psi_coh_d.shrink_to_fit(); + } + break; + case eTEMOT_m2psi_tot: + { + for (auto ithk = 0; ithk < n_thk; ithk++) { - m2psi_tot.resize(this->thick.size()); - psi_coh.resize(this->thick.size()); + thk_gpu[ithk] = false; - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + if(ithkthick.size()); - for(auto ithk = 0; ithk < this->thick.size(); ithk++) - { - psi_coh[ithk].resize(nxy()); + thk_gpu.clear(); + //thk_gpu.shrink_to_fit(); - mt::fill(stream, psi_coh[ithk], T_c(0)); - } - } - break; - case eTEMOT_psi_0: + m2psi_tot_d.clear(); + //m2psi_tot_d.shrink_to_fit(); + } + break; + case eTEMOT_m2psi_tot_psi_coh: + { + for (auto ithk = 0; ithk < n_thk; ithk++) { - psi_0.resize(this->thick.size()); - - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + thk_gpu[ithk] = false; + if(ithkthick.size()); - for(auto ithk = 0; ithk < this->thick.size(); ithk++) - { - V[ithk].resize(nxy()); + thk_gpu.clear(); + //thk_gpu.shrink_to_fit(); - mt::fill(stream, V[ithk], T_r(0)); - } - } - break; - case eTEMOT_trans: - { - trans.resize(this->thick.size()); + m2psi_tot_d.clear(); + //m2psi_tot_d.shrink_to_fit(); - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + psi_coh_d.clear(); + //psi_coh_d.shrink_to_fit(); + } + break; + case eTEMOT_psi_coh: + { + for (auto ithk = 0; ithk < n_thk; ithk++) + { + thk_gpu[ithk] = false; + if(ithk + void set_input_data(TInput_Multislice *input_multislice) + { + clear(); - void init() - { - switch(output_type) + stream.resize(1); + + assign_input_multislice(*input_multislice); + + // set required number of thickness + n_thk = this->thick.size(); + n_thk_d = 0; + + thk_gpu.resize(n_thk); + std::fill(thk_gpu.begin(), thk_gpu.end(), false); + + // check selected device + auto bb_is_device = this->system_conf.is_device(); + + // get available gpu free memory + double free_memory_mb = get_free_memory() - 10; + int nxy_r = this->output_area.nxy(); + int nxy_g = this->grid_2d.nxy(); + + if(bb_is_device) + { + psi_zh.resize(nxy_g); + m2psi_zh.resize(nxy_g); + } + + ndetector = (this->is_EELS()) ? 1 : this->detector.size(); + + set_output_grid(); + + set_output_type(); + + switch (output_type) + { + case eTEMOT_image_tot_coh: { - case eTEMOT_image_tot_coh: + image_tot.resize(n_thk); + image_coh.resize(n_thk); + psi_coh.resize(n_thk); + + n_thk_d = (bb_is_device)?cal_n_thk_a(free_memory_mb, nxy_g):0; + n_thk_d = min(n_thk_d, n_thk); + + psi_coh_d.resize(n_thk_d); + + for (auto ithk = 0; ithk < n_thk; ithk++) { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + image_tot[ithk].image.resize(ndetector); + image_coh[ithk].image.resize(ndetector); + + for (auto idet = 0; idet < ndetector; idet++) { - for(auto idet = 0; idet < image_tot[ithk].image.size(); idet++) - { - mt::fill(stream, image_tot[ithk].image[idet], T_r(0)); - mt::fill(stream, image_coh[ithk].image[idet], T_r(0)); - } - mt::fill(stream, psi_coh[ithk], 0); + image_tot[ithk].image[idet].resize(nxy()); + image_coh[ithk].image[idet].resize(nxy()); } - } - break; - case eTEMOT_image_tot: - { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + + psi_coh[ithk].resize(nxy_g); + + if(ithkthick.size(); ithk++) + image_tot[ithk].image.resize(ndetector); + + for (auto idet = 0; idet < ndetector; idet++) { - mt::fill(stream, m2psi_tot[ithk], T_r(0)); - mt::fill(stream, m2psi_coh[ithk], T_r(0)); - mt::fill(stream, psi_coh[ithk], T_c(0)); + image_tot[ithk].image[idet].resize(nxy()); } } - break; - case eTEMOT_m2psi_tot: + } + break; + case eTEMOT_m2psi_tot_coh: + { + m2psi_tot.resize(n_thk); + m2psi_coh.resize(n_thk); + psi_coh.resize(n_thk); + + n_thk_d = (bb_is_device)?cal_n_thk_a(free_memory_mb, nxy_r+nxy_g):0; + n_thk_d = min(n_thk_d, n_thk); + + m2psi_tot_d.resize(n_thk_d); + m2psi_coh_d.resize(n_thk_d); + psi_coh_d.resize(n_thk_d); + + for (auto ithk = 0; ithk < n_thk; ithk++) { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + m2psi_tot[ithk].resize(nxy_r); + m2psi_coh[ithk].resize(nxy_r); + psi_coh[ithk].resize(nxy_g); + + if(ithk(free_memory_mb, nxy_r):0; + n_thk_d = min(n_thk_d, n_thk); + + m2psi_tot_d.resize(n_thk_d); + + for (auto ithk = 0; ithk < n_thk; ithk++) { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + m2psi_tot[ithk].resize(nxy_r); + + if(ithk(free_memory_mb, nxy_r+2*nxy_g):0; + n_thk_d = min(n_thk_d, n_thk); + + m2psi_tot_d.resize(n_thk_d); + psi_coh_d.resize(n_thk_d); + + for (auto ithk = 0; ithk < n_thk; ithk++) { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + m2psi_tot[ithk].resize(nxy_r); + psi_coh[ithk].resize(nxy_g); + + if(ithk(free_memory_mb, nxy_g):0; + n_thk_d = min(n_thk_d, n_thk); + + psi_coh_d.resize(n_thk_d); + + for (auto ithk = 0; ithk < n_thk; ithk++) { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + psi_coh[ithk].resize(nxy_g); + + if(ithkthick.size(); ithk++) - { - mt::fill(stream, V[ithk], T_r(0)); - } + psi_0[ithk].resize(nxy_r); } - break; - case eTEMOT_trans: + } + break; + case eTEMOT_V: + { + V.resize(n_thk); + + for (auto ithk = 0; ithk < n_thk; ithk++) { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) - { - mt::fill(stream, trans[ithk], T_c(0)); - } + V[ithk].resize(nxy_r); } - break; } - } - - void init_psi_coh() - { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + break; + case eTEMOT_trans: { - mt::fill(stream, psi_coh[ithk], 0); + trans.resize(n_thk); + + for (auto ithk = 0; ithk < n_thk; ithk++) + { + trans[ithk].resize(nxy_r); + } } + break; } + } - void shift() - { - switch(output_type) + void init() + { + switch (output_type) + { + case eTEMOT_image_tot_coh: + { + for (auto ithk = 0; ithk < this->thick.size(); ithk++) { - case eTEMOT_m2psi_tot_coh: + for (auto idet = 0; idet < image_tot[ithk].image.size(); idet++) { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) - { - mt::fft2_shift(stream, this->grid_2d, m2psi_tot[ithk]); - mt::fft2_shift(stream, this->grid_2d, m2psi_coh[ithk]); - } + mt::fill(stream, image_tot[ithk].image[idet], T_r(0)); + mt::fill(stream, image_coh[ithk].image[idet], T_r(0)); } - break; - case eTEMOT_m2psi_tot: - { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) - { - mt::fft2_shift(stream, this->grid_2d, m2psi_tot[ithk]); - } - } - break; - case eTEMOT_m2psi_tot_psi_coh: + mt::fill(stream, psi_coh[ithk], T_c(0)); + + if(ithkthick.size(); ithk++) - { - mt::fft2_shift(stream, this->grid_2d, m2psi_tot[ithk]); - mt::fft2_shift(stream, this->grid_2d, psi_coh[ithk]); - } + thrust::fill(psi_coh_d[ithk].begin(), psi_coh_d[ithk].end(), T_c(0)); } - break; - case eTEMOT_psi_coh: + } + } + break; + case eTEMOT_image_tot: + { + for (auto ithk = 0; ithk < this->thick.size(); ithk++) + { + for (auto idet = 0; idet < image_tot[ithk].image.size(); idet++) { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) - { - mt::fft2_shift(stream, this->grid_2d, psi_coh[ithk]); - } + mt::fill(stream, image_tot[ithk].image[idet], T_r(0)); } - break; - case eTEMOT_psi_0: + } + } + break; + case eTEMOT_m2psi_tot_coh: + { + for (auto ithk = 0; ithk < this->thick.size(); ithk++) + { + mt::fill(stream, m2psi_tot[ithk], T_r(0)); + mt::fill(stream, m2psi_coh[ithk], T_r(0)); + mt::fill(stream, psi_coh[ithk], T_c(0)); + + if(ithkthick.size(); ithk++) - { - mt::fft2_shift(stream, this->grid_2d, psi_0[ithk]); - } + thrust::fill(m2psi_tot_d[ithk].begin(), m2psi_tot_d[ithk].end(), T_r(0)); + thrust::fill(m2psi_coh_d[ithk].begin(), m2psi_coh_d[ithk].end(), T_r(0)); + thrust::fill(psi_coh_d[ithk].begin(), psi_coh_d[ithk].end(), T_c(0)); } - break; - case eTEMOT_V: + } + + } + break; + case eTEMOT_m2psi_tot: + { + for (auto ithk = 0; ithk < this->thick.size(); ithk++) + { + mt::fill(stream, m2psi_tot[ithk], T_r(0)); + + if(ithkthick.size(); ithk++) - { - mt::fft2_shift(stream, this->grid_2d, V[ithk]); - } + thrust::fill(m2psi_tot_d[ithk].begin(), m2psi_tot_d[ithk].end(), T_r(0)); } - break; - case eTEMOT_trans: + } + } + break; + case eTEMOT_m2psi_tot_psi_coh: + { + for (auto ithk = 0; ithk < this->thick.size(); ithk++) + { + mt::fill(stream, m2psi_tot[ithk], T_r(0)); + mt::fill(stream, psi_coh[ithk], T_c(0)); + + if(ithkthick.size(); ithk++) - { - mt::fft2_shift(stream, this->grid_2d, trans[ithk]); - } + thrust::fill(m2psi_tot_d[ithk].begin(), m2psi_tot_d[ithk].end(), T_r(0)); + thrust::fill(psi_coh_d[ithk].begin(), psi_coh_d[ithk].end(), T_c(0)); } - break; } } - - void clear_temporal_data() + break; + case eTEMOT_psi_coh: { - if(is_ot_image_tot_coh()||is_ot_m2psi_tot_coh()) + for (auto ithk = 0; ithk < this->thick.size(); ithk++) { - for(auto ithk = 0; ithk < this->thick.size(); ithk++) + mt::fill(stream, psi_coh[ithk], T_c(0)); + + if(ithkthick.size(); ithk++) + { + mt::fill(stream, psi_0[ithk], T_c(0)); + } + } + break; + case eTEMOT_V: + { + for (auto ithk = 0; ithk < this->thick.size(); ithk++) + { + mt::fill(stream, V[ithk], T_r(0)); + } + } + break; + case eTEMOT_trans: { - return mt::is_ot_image_tot_coh(output_type); + for (auto ithk = 0; ithk < this->thick.size(); ithk++) + { + mt::fill(stream, trans[ithk], T_c(0)); + } + } + break; } + } - inline - bool is_ot_image_tot() const + void init_psi_coh() + { + for (auto ithk = 0; ithk < this->thick.size(); ithk++) { - return mt::is_ot_image_tot(output_type); + if(ithk + void add_scale_psi_coh(int ithk, T_c w, TVector &phi) + { + if(thk_gpu[ithk]) { - return mt::is_ot_m2psi_tot_coh(output_type); + thrust::transform(thrust::device, phi.begin(), phi.end(), psi_coh_d[ithk].begin(), psi_coh_d[ithk].begin(), functor::add_scale(w)); } + else + { + mt::add_scale_to_host(stream, w, phi, psi_coh[ithk], &psi_zh); + } + } - inline - bool is_ot_m2psi_tot() const + template + void add_scale_shift_psi_coh(int ithk, T_c w, TVector &phi) + { + if(thk_gpu[ithk]) + { + mt::add_scale_shift_2d(this->grid_2d, w, phi, psi_coh_d[ithk], &psi_zh); + } + else { - return mt::is_ot_m2psi_tot(output_type); + mt::add_scale_shift_2d(this->grid_2d, w, phi, psi_coh[ithk], &psi_zh); } + } - inline - bool is_ot_m2psi_tot_psi_coh() const + template + void add_scale_crop_shift_psi_coh(int ithk, T_c w, TVector &phi) + { + if(thk_gpu[ithk]) + { + mt::add_scale_crop_shift_2d(this->grid_2d, w, phi, this->output_area, psi_coh_d[ithk], &psi_zh); + } + else { - return mt::is_ot_m2psi_tot_psi_coh(output_type); + mt::add_scale_crop_shift_2d(this->grid_2d, w, phi, this->output_area, psi_coh[ithk], &psi_zh); } + } - inline - bool is_ot_psi_coh() const + template + void add_scale_crop_shift_m2psi_coh_from_psi(int ithk, T_r w, TVector &phi) + { + if(thk_gpu[ithk]) { - return mt::is_ot_psi_coh(output_type); + mt::add_scale_square_crop_shift_2d(this->grid_2d, w, phi, this->output_area, m2psi_coh_d[ithk], &psi_zh); } + else + { + mt::add_scale_square_crop_shift_2d(this->grid_2d, w, phi, this->output_area, m2psi_coh[ithk], &psi_zh); + } + } - inline - bool is_ot_psi_0() const + template + void add_scale_crop_shift_m2psi_coh_from_m2psi(int ithk, T_r w, TVector &m2phi) + { + if(thk_gpu[ithk]) + { + mt::add_scale_crop_shift_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_coh_d[ithk], &m2psi_zh); + } + else { - return mt::is_ot_psi_0(output_type); + mt::add_scale_crop_shift_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_coh[ithk], &m2psi_zh); } + } - inline - bool is_ot_V() const + template + void add_scale_crop_shift_m2psi_tot_from_psi(int ithk, T_r w, TVector phi) + { + if(thk_gpu[ithk]) + { + mt::add_scale_square_crop_shift_2d(this->grid_2d, w, phi, this->output_area, m2psi_tot_d[ithk], &psi_zh); + } + else { - return mt::is_ot_V(output_type); + mt::add_scale_square_crop_shift_2d(this->grid_2d, w, phi, this->output_area, m2psi_tot[ithk], &psi_zh); } + } - inline - bool is_ot_trans() const + template + void add_scale_crop_shift_m2psi_tot_from_m2psi(int ithk, T_r w, TVector &m2phi) + { + if(thk_gpu[ithk]) { - return mt::is_ot_trans(output_type); + mt::add_scale_crop_shift_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_tot_d[ithk], &m2psi_zh); } + else + { + mt::add_scale_crop_shift_2d(this->grid_2d, w, m2phi, this->output_area, m2psi_tot[ithk], &m2psi_zh); + } + } - host_vector extract_data(ePhonon_Model_Output fp_ctr, eShow_CData show_data, int ithk, int idet=0) + /***************************************************************************/ + template + void set_psi_coh(int ithk, TVector &phi) + { + if(thk_gpu[ithk]) + { + thrust::copy(phi.begin(), phi.end(), psi_coh_d[ithk].begin()); + } + else { - host_vector data(nxy()); + thrust::copy(phi.begin(), phi.end(), psi_coh[ithk].begin()); + } + } - switch(output_type) - { - case eTEMOT_image_tot_coh: - { - data = (fp_ctr==eFMO_Total)?image_tot[ithk].image[idet]:image_coh[ithk].image[idet]; - } - break; - case eTEMOT_image_tot: - { - data = image_tot[ithk].image[idet]; - } - break; - case eTEMOT_m2psi_tot_coh: - { - data = (fp_ctr==eFMO_Total)?m2psi_tot[ithk]:m2psi_coh[ithk]; - } - break; - case eTEMOT_m2psi_tot: - { - data = m2psi_tot[ithk]; - } - break; - case eTEMOT_m2psi_tot_psi_coh: - { - if(fp_ctr==eFMO_Total) - { - data = m2psi_tot[ithk]; - } - else - { - from_complex_to_real(show_data, psi_coh[ithk], data); - } - } - break; - case eTEMOT_psi_coh: - { - from_complex_to_real(show_data, psi_coh[ithk], data); - } - break; - case eTEMOT_psi_0: - { - from_complex_to_real(show_data, psi_0[ithk], data); - } - break; - case eTEMOT_V: - { - data = V[ithk]; - } - break; - case eTEMOT_trans: - { - from_complex_to_real(show_data, trans[ithk], data); - } - break; - } + template + void set_shift_psi_coh(int ithk, TVector &phi) + { + if(thk_gpu[ithk]) + { + mt::assign_shift_2d(this->grid_2d, phi, psi_coh_d[ithk], &psi_zh); + } + else + { + mt::assign_shift_2d(this->grid_2d, phi, psi_coh[ithk], &psi_zh); + } + } - return data; + template + void set_crop_shift_psi_coh(int ithk, TVector &phi) + { + if(thk_gpu[ithk]) + { + mt::assign_crop_shift_2d(this->grid_2d, phi, this->output_area, psi_coh_d[ithk], &psi_zh); } + else + { + mt::assign_crop_shift_2d(this->grid_2d, phi, this->output_area, psi_coh[ithk], &psi_zh); + } + } - eTEM_Output_Type output_type; + template + void set_crop_shift_m2psi_coh(int ithk, TVector &m2phi) + { + if(thk_gpu[ithk]) + { + mt::assign_crop_shift_2d(this->grid_2d, m2phi, this->output_area, m2psi_coh_d[ithk], &m2psi_zh); + } + else + { + mt::assign_crop_shift_2d(this->grid_2d, m2phi, this->output_area, m2psi_coh[ithk], &m2psi_zh); + } + } - int ndetector; - int nx; - int ny; - T_r dx; - T_r dy; - T_r dr; + template + void set_crop_shift_m2psi_tot(int ithk, TVector &m2phi) + { + if(thk_gpu[ithk]) + { + mt::assign_crop_shift_2d(this->grid_2d, m2phi, this->output_area, m2psi_tot_d[ithk], &m2psi_zh); + } + else + { + mt::assign_crop_shift_2d(this->grid_2d, m2phi, this->output_area, m2psi_tot[ithk], &m2psi_zh); + } + } - host_vector x; - host_vector y; - host_vector r; + /***************************************************************************/ + template + void from_psi_coh_2_phi(int ithk, TVector &phi) + { + if(thk_gpu[ithk]) + { + thrust::copy(psi_coh_d[ithk].begin(), psi_coh_d[ithk].end(), phi.begin()); + } + else + { + thrust::copy(psi_coh[ithk].begin(), psi_coh[ithk].end(), phi.begin()); + } + } - host_vector> image_tot; - host_vector> image_coh; - host_vector m2psi_tot; - host_vector m2psi_coh; - host_vector psi_coh; - host_vector V; - host_vector trans; - host_vector psi_0; + template + void from_m2psi_coh_2_m2phi(int ithk, TVector &m2phi) + { + if(thk_gpu[ithk]) + { + thrust::copy(m2psi_coh_d[ithk].begin(), m2psi_coh_d[ithk].end(), m2phi.begin()); + } + else + { + thrust::copy(m2psi_coh[ithk].begin(), m2psi_coh[ithk].end(), m2phi.begin()); + } + } + + template + void from_m2psi_tot_2_m2phi(int ithk, TVector &m2phi) + { + if(thk_gpu[ithk]) + { + thrust::copy(m2psi_tot_d[ithk].begin(), m2psi_tot_d[ithk].end(), m2phi.begin()); + } + else + { + thrust::copy(m2psi_tot[ithk].begin(), m2psi_tot[ithk].end(), m2phi.begin()); + } + } - Stream stream; - private: + void gather() + { + const int n_thk = this->thick.size(); - void set_output_grid() + switch (output_type) { - if(this->is_STEM() || this->is_EELS()) + case eTEMOT_m2psi_tot_coh: + { + for (auto ithk = 0; ithk < n_thk; ithk++) { - nx = this->scanning.nx; - ny = this->scanning.ny; - dx = this->scanning.dRx; - dy = this->scanning.dRy; - - x = this->scanning.x; - y = this->scanning.y; - r = this->scanning.r; + if(ithkgrid_2d.nx; - ny = this->grid_2d.ny; - const bool is_RS = this->is_grid_RS(); - dx = (is_RS)?this->grid_2d.dRx:this->grid_2d.dgx; - dy = (is_RS)?this->grid_2d.dRy:this->grid_2d.dgy; - - x.resize(nx); - y.resize(ny); - - for(auto ix = 0; ixgrid_2d.Rx(ix):this->grid_2d.gx(ix); + thrust::copy(m2psi_tot_d[ithk].begin(), m2psi_tot_d[ithk].end(), m2psi_tot[ithk].begin()); } - - for(auto iy = 0; iygrid_2d.Ry(iy):this->grid_2d.gy(iy); + thrust::copy(m2psi_tot_d[ithk].begin(), m2psi_tot_d[ithk].end(), m2psi_tot[ithk].begin()); + thrust::copy(psi_coh_d[ithk].begin(), psi_coh_d[ithk].end(), psi_coh[ithk].begin()); } } } - - // 1:(image_tot, image_coh); 2:(image_tot); 3:(m2psi_tot, m2psi_coh); 4:(m2psi_tot); - // 5:(m2psi_tot, psi_coh); 6:(psi_coh); 7:(psi_0); 8:(V); 9:(trans) - void set_output_type() + break; + case eTEMOT_psi_coh: { - if(this->is_STEM() || this->is_EELS()) + for (auto ithk = 0; ithk < n_thk; ithk++) { - output_type = (this->pn_coh_contrib)?eTEMOT_image_tot_coh:eTEMOT_image_tot; + if(ithkis_ISTEM() || this->is_CBED_CBEI() ||this->is_PED_HCTEM() || - this->is_ED_HRTEM() || this->is_EFTEM()) + } + break; + case eTEMOT_psi_0: + { + for (auto ithk = 0; ithk < n_thk; ithk++) { - output_type = (this->pn_coh_contrib)?eTEMOT_m2psi_tot_coh:eTEMOT_m2psi_tot; + mt::fft2_shift(stream, this->grid_2d, psi_0[ithk]); } - else if(this->is_EWFS_EWRS()) + } + break; + case eTEMOT_V: + { + for (auto ithk = 0; ithk < n_thk; ithk++) { - output_type = (this->is_EWFS_EWRS_SC())?eTEMOT_psi_coh:eTEMOT_m2psi_tot_psi_coh; + mt::fft2_shift(stream, this->grid_2d, V[ithk]); } - else if(this->is_PropFS_PropRS()) + } + break; + case eTEMOT_trans: + { + for (auto ithk = 0; ithk < n_thk; ithk++) { - output_type = eTEMOT_psi_coh; + mt::fft2_shift(stream, this->grid_2d, trans[ithk]); } - else if(this->is_IWFS_IWRS()) + } + break; + } + } + + int nxy() const { return nx*ny; } + + /**************************************************************************************/ + inline + bool is_ot_image_tot_coh() const + { + return mt::is_ot_image_tot_coh(output_type); + } + + inline + bool is_ot_image_tot() const + { + return mt::is_ot_image_tot(output_type); + } + + inline + bool is_ot_m2psi_tot_coh() const + { + return mt::is_ot_m2psi_tot_coh(output_type); + } + + inline + bool is_ot_m2psi_tot() const + { + return mt::is_ot_m2psi_tot(output_type); + } + + inline + bool is_ot_m2psi_tot_psi_coh() const + { + return mt::is_ot_m2psi_tot_psi_coh(output_type); + } + + inline + bool is_ot_psi_coh() const + { + return mt::is_ot_psi_coh(output_type); + } + + inline + bool is_ot_psi_0() const + { + return mt::is_ot_psi_0(output_type); + } + + inline + bool is_ot_V() const + { + return mt::is_ot_V(output_type); + } + + inline + bool is_ot_trans() const + { + return mt::is_ot_trans(output_type); + } + + host_vector extract_data(ePhonon_Model_Output fp_ctr, eShow_CData show_data, int ithk, int idet = 0) + { + host_vector data(nxy()); + + switch (output_type) + { + case eTEMOT_image_tot_coh: + { + data = (fp_ctr == eFMO_Total) ? image_tot[ithk].image[idet] : image_coh[ithk].image[idet]; + } + break; + case eTEMOT_image_tot: + { + data = image_tot[ithk].image[idet]; + } + break; + case eTEMOT_m2psi_tot_coh: + { + data = (fp_ctr == eFMO_Total) ? m2psi_tot[ithk] : m2psi_coh[ithk]; + } + break; + case eTEMOT_m2psi_tot: + { + data = m2psi_tot[ithk]; + } + break; + case eTEMOT_m2psi_tot_psi_coh: + { + if (fp_ctr == eFMO_Total) { - output_type = eTEMOT_psi_0; + data = m2psi_tot[ithk]; } - else if(this->is_PPFS_PPRS()) + else { - output_type = eTEMOT_V; + from_complex_to_real(show_data, psi_coh[ithk], data); } - else if(this->is_TFFS_TFRS()) + } + break; + case eTEMOT_psi_coh: + { + from_complex_to_real(show_data, psi_coh[ithk], data); + } + break; + case eTEMOT_psi_0: + { + from_complex_to_real(show_data, psi_0[ithk], data); + } + break; + case eTEMOT_V: + { + data = V[ithk]; + } + break; + case eTEMOT_trans: + { + from_complex_to_real(show_data, trans[ithk], data); + } + break; + } + + return data; + } + + eTEM_Output_Type output_type; + + int ndetector; + int nx; + int ny; + T_r dx; + T_r dy; + T_r dr; + + host_vector x; + host_vector y; + host_vector r; + + host_vector> image_tot; + host_vector> image_coh; + + host_vector m2psi_tot; + host_vector m2psi_coh; + host_vector psi_coh; + host_vector V; + host_vector trans; + host_vector psi_0; + + std::vector thk_gpu; + host_vector m2psi_tot_d; + host_vector m2psi_coh_d; + host_vector psi_coh_d; + + Stream stream; + private: + Vector psi_zh; + Vector m2psi_zh; + + int n_thk; + int n_thk_d; + + template + int cal_n_thk_a(double memory, int nxy) + { + return static_cast(floor(memory/mt::sizeMb(nxy))); + } + + void set_output_grid() + { + if (this->is_STEM() || this->is_EELS()) + { + nx = this->scanning.nx; + ny = this->scanning.ny; + + dx = this->scanning.dRx; + dy = this->scanning.dRy; + + x = this->scanning.x; + y = this->scanning.y; + r = this->scanning.r; + } + else + { + nx = this->output_area.nx(); + ny = this->output_area.ny(); + + const bool is_RS = this->is_grid_RS(); + dx = (is_RS)?this->grid_2d.dRx:this->grid_2d.dgx; + dy = (is_RS)?this->grid_2d.dRy:this->grid_2d.dgy; + + x.resize(nx); + y.resize(ny); + + for (auto ix = this->output_area.ix_0; ix < this->output_area.ix_e; ix++) + { + int ix_s = ix-this->output_area.ix_0; + x[ix_s] = (is_RS)?this->grid_2d.Rx(ix):this->grid_2d.gx(ix); + } + + for (auto iy = this->output_area.iy_0; iy < this->output_area.iy_e; iy++) { - output_type = eTEMOT_trans; + int iy_s = iy-this->output_area.iy_0; + y[iy_s] = (is_RS)?this->grid_2d.Ry(iy):this->grid_2d.gy(iy); } } + } + + // 1:(image_tot, image_coh); 2:(image_tot); 3:(m2psi_tot, m2psi_coh); 4:(m2psi_tot); + // 5:(m2psi_tot, psi_coh); 6:(psi_coh); 7:(psi_0); 8:(V); 9:(trans) + void set_output_type() + { + if (this->is_STEM() || this->is_EELS()) + { + output_type = (this->pn_coh_contrib) ? eTEMOT_image_tot_coh : eTEMOT_image_tot; + } + else if (this->is_ISTEM() || this->is_CBED_CBEI() || this->is_PED_HCTEM() || + this->is_ED_HRTEM() || this->is_EFTEM()) + { + output_type = (this->pn_coh_contrib) ? eTEMOT_m2psi_tot_coh : eTEMOT_m2psi_tot; + } + else if (this->is_EWFS_EWRS()) + { + output_type = (this->is_EWFS_EWRS_SC()) ? eTEMOT_psi_coh : eTEMOT_m2psi_tot_psi_coh; + } + else if (this->is_PropFS_PropRS()) + { + output_type = eTEMOT_psi_coh; + } + else if (this->is_IWFS_IWRS()) + { + output_type = eTEMOT_psi_0; + } + else if (this->is_PPFS_PPRS()) + { + output_type = eTEMOT_V; + } + else if (this->is_TFFS_TFRS()) + { + output_type = eTEMOT_trans; + } + } - template - void assign_input_multislice(TInput_Multislice &input_multislice) - { - this->interaction_model = input_multislice.interaction_model; - this->potential_type = input_multislice.potential_type; + template + void assign_input_multislice(TInput_Multislice &input_multislice) + { + this->system_conf = input_multislice.system_conf; - this->operation_mode = input_multislice.operation_mode; - this->slice_storage = input_multislice.slice_storage; - this->reverse_multislice = input_multislice.reverse_multislice; - this->mul_sign = input_multislice.mul_sign; - this->Vrl = input_multislice.Vrl; - this->nR = input_multislice.nR; + this->interaction_model = input_multislice.interaction_model; + this->potential_type = input_multislice.potential_type; - this->pn_model = input_multislice.pn_model; - this->pn_coh_contrib = input_multislice.pn_coh_contrib; - this->pn_dim = input_multislice.pn_dim; - this->fp_dist = input_multislice.fp_dist; - this->pn_seed = input_multislice.pn_seed; - this->pn_single_conf = input_multislice.pn_single_conf; - this->pn_nconf = input_multislice.pn_nconf; + this->operation_mode = input_multislice.operation_mode; + this->slice_storage = input_multislice.slice_storage; + this->reverse_multislice = input_multislice.reverse_multislice; + this->mul_sign = input_multislice.mul_sign; + this->Vrl = input_multislice.Vrl; + this->nR = input_multislice.nR; - this->atoms = input_multislice.atoms; - this->is_crystal = input_multislice.is_crystal; + this->pn_model = input_multislice.pn_model; + this->pn_coh_contrib = input_multislice.pn_coh_contrib; + this->pn_dim = input_multislice.pn_dim; + this->fp_dist = input_multislice.fp_dist; + this->pn_seed = input_multislice.pn_seed; + this->pn_single_conf = input_multislice.pn_single_conf; + this->pn_nconf = input_multislice.pn_nconf; - this->spec_rot_theta = input_multislice.spec_rot_theta; - this->spec_rot_u0 = input_multislice.spec_rot_u0; - this->spec_rot_center_type = input_multislice.spec_rot_center_type; - this->spec_rot_center_p = input_multislice.spec_rot_center_p; + this->atoms = input_multislice.atoms; + this->is_crystal = input_multislice.is_crystal; - this->thick_type = input_multislice.thick_type; - this->thick = input_multislice.thick; + this->spec_rot_theta = input_multislice.spec_rot_theta; + this->spec_rot_u0 = input_multislice.spec_rot_u0; + this->spec_rot_center_type = input_multislice.spec_rot_center_type; + this->spec_rot_center_p = input_multislice.spec_rot_center_p; - this->potential_slicing = input_multislice.potential_slicing; + this->thick_type = input_multislice.thick_type; + this->thick = input_multislice.thick; - this->grid_2d = input_multislice.grid_2d; + this->potential_slicing = input_multislice.potential_slicing; - this->simulation_type = input_multislice.simulation_type; + this->grid_2d = input_multislice.grid_2d; + this->output_area = input_multislice.output_area; - this->iw_type = input_multislice.iw_type; - this->iw_psi = input_multislice.iw_psi; - this->iw_x = input_multislice.iw_x; - this->iw_y = input_multislice.iw_y; + this->simulation_type = input_multislice.simulation_type; - this->E_0 = input_multislice.E_0; - this->theta = input_multislice.theta; - this->phi = input_multislice.phi; - this->nrot = input_multislice.nrot; + this->iw_type = input_multislice.iw_type; + this->iw_psi = input_multislice.iw_psi; + this->iw_x = input_multislice.iw_x; + this->iw_y = input_multislice.iw_y; - this->illumination_model = input_multislice.illumination_model; - this->temporal_spatial_incoh = input_multislice.temporal_spatial_incoh; + this->E_0 = input_multislice.E_0; + this->theta = input_multislice.theta; + this->phi = input_multislice.phi; + this->nrot = input_multislice.nrot; - this->cond_lens = input_multislice.cond_lens; - this->obj_lens = input_multislice.obj_lens; + this->illumination_model = input_multislice.illumination_model; + this->temporal_spatial_incoh = input_multislice.temporal_spatial_incoh; - this->scanning = input_multislice.scanning; - this->detector = input_multislice.detector; + this->cond_lens = input_multislice.cond_lens; + this->obj_lens = input_multislice.obj_lens; - this->eels_fr = input_multislice.eels_fr; + this->scanning = input_multislice.scanning; + this->detector = input_multislice.detector; - this->cdl_var_type = input_multislice.cdl_var_type; - this->cdl_var = input_multislice.cdl_var; + this->eels_fr = input_multislice.eels_fr; - this->iscan = input_multislice.iscan; - this->beam_x = input_multislice.beam_x; - this->beam_y = input_multislice.beam_y; + this->cdl_var_type = input_multislice.cdl_var_type; + this->cdl_var = input_multislice.cdl_var; - this->islice = input_multislice.islice; - this->dp_Shift = input_multislice.dp_Shift; - } + this->iscan = input_multislice.iscan; + this->beam_x = input_multislice.beam_x; + this->beam_y = input_multislice.beam_y; + + this->islice = input_multislice.islice; + this->dp_Shift = input_multislice.dp_Shift; + } }; } // namespace mt -#endif +#endif \ No newline at end of file diff --git a/src/projected_potential.cuh b/src/projected_potential.cuh index d4916583..397b1b01 100644 --- a/src/projected_potential.cuh +++ b/src/projected_potential.cuh @@ -40,7 +40,7 @@ namespace mt static const eDevice device = dev; - Projected_Potential(): stream(nullptr), n_atoms_p(512){} + Projected_Potential(): stream(nullptr), n_atoms_s(512){} void set_input_data(Input_Multislice *input_multislice_i, Stream *stream_i) { @@ -56,11 +56,11 @@ namespace mt atom_type[iatom_type].assign(Spec::atom_type[iatom_type]); } - n_atoms_p = (device==e_host)?(stream->size()):512; + n_atoms_s = (device==e_host)?(stream->size()):512; int nv = max(this->input_multislice->grid_2d.nx_dRx(this->atoms.l_x_int), this->input_multislice->grid_2d.ny_dRy(this->atoms.l_y_int)); - stream_data.resize(n_atoms_p); + stream_data.resize(n_atoms_s); for(auto i = 0; iinput_multislice->grid_2d.nxy()); } @@ -143,7 +143,7 @@ namespace mt int iatoms = iatom_0; while (iatoms <= iatom_e) { - int n_atoms = min(n_atoms_p, iatom_e-iatoms+1); + int n_atoms = min(n_atoms_s, iatom_e-iatoms+1); set_atom_Vp(z_0, z_e, iatoms, n_atoms, atom_Vp); //get_cubic_poly_coef_Vz(*stream, atom_Vp_h); @@ -186,14 +186,12 @@ namespace mt { this->operator()(islice, islice, V_0); mt::copy_to_host(output_multislice.stream, V_0, output_multislice.V[0]); - output_multislice.shift(); - output_multislice.clear_temporal_data(); } Vector V_0; Stream *stream; private: - int n_atoms_p; + int n_atoms_s; struct Stream_Data { @@ -225,9 +223,9 @@ namespace mt Vector, e_host> c3; // third coefficient }; - void set_atom_Vp(const T &z_0, const T &z_e, int iatoms, int n_atoms_p, Vector, dev> &atom_Vp) + void set_atom_Vp(const T &z_0, const T &z_e, int iatoms, int n_atoms, Vector, dev> &atom_Vp) { - for(auto istream = 0; istream < n_atoms_p; istream++) + for(auto istream = 0; istream < n_atoms; istream++) { auto iZ = this->atoms.Z[iatoms]-1; auto charge = this->atoms.charge[iatoms]; @@ -245,6 +243,7 @@ namespace mt atom_Vp_h[istream].set_iy0_iyn(this->input_multislice->grid_2d, coef.R_max); atom_Vp_h[istream].R2_tap = coef.R2_tap(); atom_Vp_h[istream].tap_cf = coef.tap_cf; + if(device==e_host) { atom_Vp_h[istream].iv = raw_pointer_cast(stream_data.iv[istream].data()); @@ -272,7 +271,7 @@ namespace mt } iatoms++; } - thrust::copy(atom_Vp_h.begin(), atom_Vp_h.end(), atom_Vp.begin()); + thrust::copy(atom_Vp_h.begin(), atom_Vp_h.begin()+n_atoms, atom_Vp.begin()); } void get_cubic_poly_coef_Vz(Stream &stream, Vector, e_host> &atom_Vp) diff --git a/src/propagator.cuh b/src/propagator.cuh index 706a9294..de53a41f 100644 --- a/src/propagator.cuh +++ b/src/propagator.cuh @@ -76,11 +76,12 @@ namespace mt else { fft_2d->forward(psi_i, psi_o); + mt::propagate(*stream, input_multislice->grid_2d, input_multislice->get_propagator_factor(z), gxu, gyu, psi_o, psi_o); if(space_out == eS_Real) { - fft_2d->inverse(psi_o); + fft_2d->inverse(psi_o, psi_o); } } } @@ -99,8 +100,6 @@ namespace mt mt::fft2_shift(*stream, input_multislice->grid_2d, psi); this->operator()(space_out, gxu, gyu, z, psi); mt::copy_to_host(output_multislice.stream, psi, output_multislice.psi_coh[0]); - output_multislice.shift(); - output_multislice.clear_temporal_data(); } private: diff --git a/src/quadrature.hpp b/src/quadrature.hpp index 116b562f..cee1e264 100644 --- a/src/quadrature.hpp +++ b/src/quadrature.hpp @@ -35,6 +35,14 @@ namespace mt { using value_type = Value_type; + if (nQuad <= 1) + { + Q.resize(1); + Q.x[0] = 0; + Q.w[0] = 1; + return; + } + value_type xmin, xmax, rmax = 225; cQ.resize(nQuad); diff --git a/src/random.cuh b/src/random.cuh index fc99b536..05c60b22 100644 --- a/src/random.cuh +++ b/src/random.cuh @@ -400,6 +400,182 @@ namespace mt std::normal_distribution randn_z; }; + /***************************************************************/ + + // add Gaussian noise + template + void add_gauss_nois(Stream &stream, TVector &M_i, + Value_type sigma, TVector &M_o) + { + using T = Value_type; + + auto thr_gauss_nois = [&](const Range_2d &range) + { + std::random_device rd; + std::mt19937_64 gen(rd()); + std::normal_distribution randn; + + for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) + { + M_o[ixy] = M_i[ixy] + sigma*randn(gen); + } + }; + + stream.set_n_act_stream(M_i.size()); + stream.set_grid(M_i.size(), 1); + stream.exec(thr_gauss_nois); + }; + + // add Gaussian noise + template + TVector add_gauss_nois(Stream &stream, TVector &M_i, + Value_type sigma) + { + using T = Value_type; + + TVector M(M_i.size()); + auto thr_gauss_nois = [&](const Range_2d &range) + { + std::random_device rd; + std::mt19937_64 gen(rd()); + std::normal_distribution randn; + + for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) + { + M[ixy] = M_i[ixy] + sigma*randn(gen); + } + }; + + stream.set_n_act_stream(M_i.size()); + stream.set_grid(M_i.size(), 1); + stream.exec(thr_gauss_nois); + + return M; + }; + /***************************************************************/ + // add Poisson noise + template + TVector add_poiss_nois(Stream &stream, TVector &M_i, + Value_type scf) + { + using T = Value_type; + + TVector M(M_i.size()); + auto thr_poiss_nois = [&](const Range_2d &range) + { + std::random_device rd; + std::mt19937_64 gen(rd()); + std::poisson_distribution randp; + + for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) + { + auto x0 = scf*M_i[ixy]; + randp.param(std::poisson_distribution::param_type(x0)); + M[ixy] = randp(gen); + } + }; + + stream.set_n_act_stream(M_i.size()); + stream.set_grid(M_i.size(), 1); + stream.exec(thr_poiss_nois); + + return M; + }; + + // add Poisson noise + template + TVector add_poiss_nois_by_SNR(Stream &stream, TVector &Im_i, + Value_type SNR_i, Value_type &scl_o) + { + using T = Value_type; + + auto get_SNR = [](Stream &stream, TVector &Im, T Im_std, T scf)->T + { + T x_mean = 0; + T x_var = 0; + auto thr_SNR = [&](const Range_2d &range) + { + std::mt19937_64 gen; + std::poisson_distribution rand; + + T x_mean_partial = 0; + T x_var_partial = 0; + for(auto ixy = range.ixy_0; ixy < range.ixy_e; ixy++) + { + auto x0 = scf*Im[ixy]; + rand.param(std::poisson_distribution::param_type(x0)); + auto xn = rand(gen)-x0; + x_mean_partial += xn; + x_var_partial += xn*xn; + } + + stream.stream_mutex.lock(); + x_mean += x_mean_partial; + x_var += x_var_partial; + stream.stream_mutex.unlock(); + }; + + stream.set_n_act_stream(Im.size()); + stream.set_grid(1, Im.size()); + stream.exec(thr_SNR); + + x_mean /= Im.size(); + x_var = x_var/Im.size()-x_mean*x_mean; + + return scf*Im_std/sqrt(x_var); + }; + + auto Im_i_std = sqrt(variance(stream, Im_i)); + + T SNR_k = get_SNR(stream, Im_i, Im_i_std, 1); + + T k_0 = 1; + T k_e = 1; + + if(SNR_k= SNR_i); + k_e = 2*k_0; + } + + + // bisection method + int ic = 0; + do + { + scl_o = 0.5*(k_0 + k_e); + auto SNR_k = get_SNR(stream, Im_i, Im_i_std, scl_o); + + if(SNR_k < SNR_i) + { + k_0 = scl_o; + } + else + { + k_e = scl_o; + } + ic++; + } while ((fabs(SNR_i-SNR_k)>0.1) && (ic<10)); + + // add Poisson noise + return add_poiss_nois(stream, Im_i, scl_o); + } + } // namespace mt #endif \ No newline at end of file diff --git a/src/slicing.hpp b/src/slicing.hpp index 567a33f6..283654a0 100644 --- a/src/slicing.hpp +++ b/src/slicing.hpp @@ -167,8 +167,8 @@ namespace mt } std::vector zt2(z_plane.begin(), z_plane.end()); - auto bb_ali = !atoms.amorp_lay_info.empty(); - if(bb_ali && (fabs(atoms.z_min-z_plane.front())>z_eps)) + auto bb_ali = !atoms.amorp_lay_info.empty(); + if(bb_ali && (fabs(atoms.z_min-z_plane.front())>z_eps)) { T dz_b = get_spacing(1, z_plane); auto amorp = atoms.amorp_lay_info.front(); @@ -176,7 +176,7 @@ namespace mt z_plane.insert(z_plane.begin(), z_plane_top.begin(), z_plane_top.end()); } - if(bb_ali && (fabs(z_plane.back()-atoms.z_max)>z_eps)) + if(bb_ali && (fabs(z_plane.back()-atoms.z_max)>z_eps)) { T dz_b = get_spacing(z_plane.size()-1, z_plane); auto amorp = atoms.amorp_lay_info.back(); diff --git a/src/timing.cuh b/src/timing.cuh new file mode 100644 index 00000000..e2f4665a --- /dev/null +++ b/src/timing.cuh @@ -0,0 +1,121 @@ +/* + * This file is part of MULTEM. + * Copyright 2017 Ivan Lobato + * + * MULTEM 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 3 of the License, or + * (at your option) any later version. + * + * MULTEM 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 MULTEM. If not, see . + */ + +#ifndef TIMING_H +#define TIMING_H + +#include "types.cuh" +#include + +#ifdef __CUDACC__ + #include + #include +#endif + +namespace mt +{ + template + struct Timing; + + template<> + struct Timing + { + public: + + Timing() + { + cudaEventCreate(&start); + cudaEventCreate(&stop); + } + + ~Timing() + { + free(); + } + + void tic() + { + cudaEventRecord(start); + } + + void toc() + { + cudaEventRecord(stop); + } + + float elapsed_ms() + { + //cudaDeviceSynchronize(); + cudaEventSynchronize(stop); + + float milliseconds = 0; + cudaEventElapsedTime(&milliseconds, start, stop); + + return milliseconds; + } + + float elapsed_s() + { + return elapsed_ms()/1000; + } + + private: + cudaEvent_t start; + cudaEvent_t stop; + + void free() + { + cudaEventDestroy(start); + cudaEventDestroy(stop); + } + }; + + + template<> + struct Timing + { + public: + void tic() + { + start = std::chrono::high_resolution_clock::now(); + } + + void toc() + { + stop = std::chrono::high_resolution_clock::now(); + } + + float elapsed_ms() + { + float milliseconds = std::chrono::duration_cast(stop-start).count()*1e-3; + + return milliseconds; + } + + float elapsed_s() + { + return elapsed_ms()/1000; + } + + private: + std::chrono::high_resolution_clock::time_point start; + std::chrono::high_resolution_clock::time_point stop; + }; +} // namespace mt + +#endif \ No newline at end of file diff --git a/src/tomography.cuh b/src/tomography.cuh index 4f0063ce..44688d77 100644 --- a/src/tomography.cuh +++ b/src/tomography.cuh @@ -368,7 +368,7 @@ namespace mt Stream stream; Box_Occ box; - Rand_r3d rand; + Rand_3d rand; int rand_trial; T chi2_0; diff --git a/src/traits.cuh b/src/traits.cuh index 8c723326..5347bcac 100644 --- a/src/traits.cuh +++ b/src/traits.cuh @@ -241,7 +241,7 @@ namespace mt using enable_if_double = typename std::enable_if::value, U>::type; template - using enable_if_real = typename std::enable_if::value, U>::type; + using enable_if_real = typename std::enable_if::value, U>::type; template using enable_if_cfloat = typename std::enable_if::value, U>::type; @@ -311,20 +311,20 @@ namespace mt /*********************************type***********************************/ - template - enable_if_float, int> + template + enable_if_float, int> matrix_type(TVector &vector){ return 1; } - template - enable_if_double, int> + template + enable_if_double, int> matrix_type(TVector &vector){ return 2; } - template - enable_if_cfloat, int> + template + enable_if_cfloat, int> matrix_type(TVector &vector){ return 3; } - template - enable_if_cdouble, int> + template + enable_if_cdouble, int> matrix_type(TVector &vector){ return 4; } } // namespace mt diff --git a/src/transmission_function.cuh b/src/transmission_function.cuh index 5b104f02..e8780e39 100644 --- a/src/transmission_function.cuh +++ b/src/transmission_function.cuh @@ -29,7 +29,6 @@ #include "output_multislice.hpp" #include "projected_potential.cuh" - namespace mt { template @@ -98,6 +97,7 @@ namespace mt else { Projected_Potential::operator()(islice, this->V_0); + //this->operator()(islice, this->V_0); trans(this->input_multislice->Vr_factor(), this->V_0, trans_0); } } @@ -105,6 +105,7 @@ namespace mt void trans(const int &islice_0, const int &islice_e, Vector &trans_0) { Projected_Potential::operator()(islice_0, islice_e, this->V_0); + //this->operator()(islice_0, islice_e, this->V_0); trans(this->input_multislice->Vr_factor(), this->V_0, trans_0); } @@ -113,8 +114,6 @@ namespace mt { trans(islice, trans_0); mt::copy_to_host(output_multislice.stream, trans_0, output_multislice.trans[0]); - output_multislice.shift(); - output_multislice.clear_temporal_data(); } void move_atoms(const int &fp_iconf) diff --git a/src/types.cuh b/src/types.cuh index 637f3569..2c42c9f0 100644 --- a/src/types.cuh +++ b/src/types.cuh @@ -96,11 +96,13 @@ namespace mt const double c_5i2 = 2.236067977499789696409; // 5^(1/2) const double c_7i2 = 2.645751311064590590502; // 7^(1/2) - const double c_fwhm2sigma = 0.42466090014400953; // fwhm to sigma + const double c_hwhm_2_sigma = 0.84932180028801907; // hwhm to sigma 1/(sqrt(2*log(2))) + const double c_fwhm_2_sigma = 0.42466090014400953; // fwhm to sigma 1/(2*sqrt(2*log(2))) + const double c_iehwgd_2_sigma = 0.70710678118654746; // iehwgd to sigma 1/sqrt(2) const double c_mrad_2_rad = 1.0e-03; // mrad-->rad const double c_deg_2_rad = 0.01745329251994329576924; // degrees-->rad - const double c_mm_2_Angs = 1.0e+07; // mm-->Angstrom + const double c_mm_2_Angs = 1.0e+07; // mm-->Angstrom const double c_eV_2_keV = 1e-03; // ev-->keV const int c_cSynCPU = 5; @@ -114,9 +116,6 @@ namespace mt const int c_thrnxy = 256; const double c_Vrl = 0.015; - #define IsFS(i, nh) ((i < nh)?i:i-2*nh) - #define IsRS(i, nh) ((i < nh)?i+nh:i-nh) - const int cSizeofI = sizeof(int); const int cSizeofRD = sizeof(double); const int cSizeofRF = sizeof(float); @@ -505,20 +504,35 @@ namespace mt return m_size; } - template - rVector(rVector &vector) + rVector(const rVector &vector) { m_size = vector.m_size; V = vector.V; } - template - rVector(TVector &vector) + rVector(Vector &vector) { m_size = vector.size(); V = raw_pointer_cast(vector.data()); } + rVector(Vector &vector) + { + m_size = vector.size(); + V = raw_pointer_cast(vector.data()); + } + + //rVector(host_vector &vector) + //{ + // m_size = vector.size(); + // V = raw_pointer_cast(vector.data()); + //} + + //rVector(device_vector &vector) + //{ + // m_size = vector.size(); + // V = raw_pointer_cast(vector.data()); + //} DEVICE_CALLABLE FORCE_INLINE T& operator[](const int i){ return V[i]; } @@ -650,9 +664,39 @@ namespace mt int ixy_e; // final index Range_1d(): ix_0(0), ix_e(0), ixy_0(0), ixy_e(0){} + Range_1d(int ix_0i, int ix_ei): ix_0(ix_0i), ix_e(ix_ei) + { + ixy_0 = 0; + ixy_e = nx(); + } + template Range_1d(const TGrid &grid_1d){ set_grid(grid_1d); } + void clear() + { + ix_0 = 0; + ix_e = 0; + ixy_0 = 0; + ixy_e = 0; + } + + int nx() const { return (ix_e-ix_0);} + + void clip_ix(int ix_0i, int ix_ei) + { + ix_0 = min(ix_ei, max(ix_0i, ix_0)); + ix_e = min(ix_ei, max(ix_0i, ix_e)); + } + + void set_ascending_index() + { + if(ix_0>ix_e) + { + std::swap(ix_0, ix_e); + } + } + template void set_grid(const TGrid &grid_1d) { @@ -674,9 +718,26 @@ namespace mt Range_2d(): ix_0(0), ix_e(0), iy_0(0), iy_e(0), ixy_0(0), ixy_e(0){} + Range_2d(int ix_0i, int ix_ei, int iy_0i, int iy_ei): ix_0(ix_0i), ix_e(ix_ei), + iy_0(iy_0i), iy_e(iy_ei) + { + ixy_0 = 0; + ixy_e = nxy(); + } + template Range_2d(const TGrid &grid_2d){ set_grid(grid_2d); } + void clear() + { + ix_0 = 0; + ix_e = 0; + iy_0 = 0; + iy_e = 0; + ixy_0 = 0; + ixy_e = 0; + } + template void set_grid(const TGrid &grid_2d) { @@ -687,6 +748,67 @@ namespace mt ixy_0 = 0; ixy_e = grid_2d.nxy(); } + + DEVICE_CALLABLE FORCE_INLINE + int nx() const { return (ix_e-ix_0);} + + DEVICE_CALLABLE FORCE_INLINE + int ny() const { return (iy_e-iy_0);} + + DEVICE_CALLABLE FORCE_INLINE + int nxy() const { return (nx()*ny());} + + DEVICE_CALLABLE FORCE_INLINE + void clip_ix(int ix_0i, int ix_ei) + { + ix_0 = min(ix_ei, max(ix_0i, ix_0)); + ix_e = min(ix_ei, max(ix_0i, ix_e)); + } + + DEVICE_CALLABLE FORCE_INLINE + void clip_iy(int iy_0i, int iy_ei) + { + iy_0 = min(iy_ei, max(iy_0i, iy_0)); + iy_e = min(iy_ei, max(iy_0i, iy_e)); + } + + DEVICE_CALLABLE FORCE_INLINE + void set_ascending_index() + { + if(ix_0>ix_e) + { + std::swap(ix_0, ix_e); + } + + if(iy_0>iy_e) + { + std::swap(iy_0, iy_e); + } + } + + DEVICE_CALLABLE FORCE_INLINE + bool chk_ix_bound(const int &ix) const + { + return (ix_0<=ix)&&(ix(floor((v_id-v_min)/dv)); - auto v_imin = v_min + (ih-1)*dv; - auto v_imax = v_imin + dv; - - if(v_id= 0; ik--) - { - v_imin = v_min + (ik-1)*dv; - v_imax = v_imin + dv; - if((v_imin<=v_id)&&(v_idv_imax) - { - for (auto ik = ih; ik < nbins; ik++) - { - v_imin = v_min + ik*dv; - v_imax = v_imin + dv; - if((v_imin<=v_id)&&(v_id= 0; ik--) + { + v_imin = v_min + (ik-1)*dv; + v_imax = v_imin + dv; + if((v_imin<=v_id)&&(v_idv_imax) + { + for (auto ik = ih; ik < nbins; ik++) + { + v_imin = v_min + ik*dv; + v_imax = v_imin + dv; + if((v_imin<=v_id)&&(v_id image; }; - /**************************** Spatial Incoherence ***************************/ - template - struct Spatial_Incoherence - { - using value_type = T; - - T beta; // Divergence semi-angle (rad) - int nbeta; // Number of integration steps for the divergence semi-angle - - T lambda; // wavelength(Angstrom) - - T sggs; // standard deviation - int ngxs; // Number of source sampling points x - int ngys; // Number of source sampling points y - T dgxs; // source sampling m_size; - T dgys; // source sampling m_size; - T g2_maxs; // q maximum square; - - Spatial_Incoherence(): beta(0), nbeta(0), lambda(0), - sggs(0), ngxs(0), ngys(0), dgxs(0), dgys(0), g2_maxs(0) {} - - void set_input_data(T E_0, Grid_2d &grid_2d) - { - lambda = get_lambda(E_0); - - T g0s = sin(beta)/lambda; - sggs = g0s/c_2i2; - T gmaxs = 3.5*sggs; - g2_maxs = gmaxs*gmaxs; - T dgs = gmaxs/static_cast(nbeta); - - int n; - n = (dgs(floor(grid_2d.dgx/dgs)+1):1; - ngxs = static_cast(floor(n*gmaxs/grid_2d.dgx)) + 1; - dgxs = gmaxs/ngxs; - - n = (dgs(floor(grid_2d.dgy/dgs)+1):1; - ngys = static_cast(floor(n*gmaxs/grid_2d.dgy)) + 1; - dgys = gmaxs/ngys; - } - - template - void assign(TSpatial_Incoherence &spt_incoh) - { - beta = spt_incoh.beta; - nbeta = spt_incoh.nbeta; - - lambda = spt_incoh.lambda; - - sggs = spt_incoh.sggs; - ngxs = spt_incoh.ngxs; - ngys = spt_incoh.ngys; - dgxs = spt_incoh.dgxs; - dgys = spt_incoh.dgys; - g2_maxs = spt_incoh.g2_maxs; - } - - template - Spatial_Incoherence& operator=(TSpatial_Incoherence &spt_incoh) - { - assign(spt_incoh); - return *this; - } - - inline - T gxs(const int &ix) const { return static_cast(ix)*dgxs; } - - inline - T gys(const int &iy) const { return static_cast(iy)*dgys; } - - inline - T g2s(const int &ix, const int &iy) const - { - T gxi = gxs(ix); - T gyi = gys(iy); - return gxi*gxi + gyi*gyi; - } - }; - /****************************lens***************************/ template struct Lens @@ -2816,11 +2860,14 @@ namespace mt T inner_aper_ang; // Inner aperture (rad); T outer_aper_ang; // Outer aperture (rad); - T sf; // Defocus Spread (Å) - int nsf; // Number of integration steps for the defocus Spread + T dsf_sigma; // Standard deviation of the defocus spread function(Å) + int dsf_npoints; // Number of integration points of the efocus spread function + T dsf_iehwgd; // e^-1 half-width value of the Gaussian distribution - T beta; // Divergence semi-angle (rad) - int nbeta; // Number of integration steps for the divergence semi-angle + T ssf_sigma; // Standard deviation of the source spread function: For parallel ilumination(Å^-1); otherwise (Å) + int ssf_npoints; // Number of integration points of the source spread function + T ssf_iehwgd; // e^-1 half-width value of the Gaussian distribution + T ssf_beta; // divergence semi-angle (rad) eZero_Defocus_Type zero_defocus_type; // Defocus type: eZDT_First = 1, eZDT_Middle = 2, eZDT_Last = 3, eZDT_User_Define = 4 T zero_defocus_plane; // plane @@ -2850,8 +2897,6 @@ namespace mt T g2_min; // inner_aper_ang/lambda T g2_max; // outer_aper_ang/lambda - - T sggs; // standard deviation int ngxs; // Number of source sampling points x int ngys; // Number of source sampling points y T dgxs; // source sampling m_size; @@ -2862,9 +2907,9 @@ namespace mt c_30(0), c_32(0), phi_32(0), c_34(0), phi_34(0), c_41(0), phi_41(0), c_43(0), phi_43(0), c_45(0), phi_45(0), c_50(0), c_52(0), phi_52(0), c_54(0), phi_54(0), c_56(0), phi_56(0), - inner_aper_ang(0), outer_aper_ang(0), sf(0), nsf(0), beta(0), - nbeta(0), zero_defocus_plane(0), gamma(0), lambda(0), lambda2(0), - g2_min(0), g2_max(0), sggs(0), ngxs(0), ngys(0), dgxs(0), dgys(0), g2_maxs(0), + inner_aper_ang(0), outer_aper_ang(0), dsf_sigma(0), dsf_npoints(0), dsf_iehwgd(0), + ssf_sigma(0), ssf_npoints(0), ssf_iehwgd(0), ssf_beta(0), zero_defocus_plane(0), gamma(0), lambda(0), + lambda2(0), g2_min(0), g2_max(0), ngxs(0), ngys(0), dgxs(0), dgys(0), g2_maxs(0), c_c_10(0), c_c_12(0), c_c_21(0), c_c_23(0), c_c_30(0), c_c_32(0), c_c_34(0), c_c_41(0), c_c_43(0), c_c_45(0), c_c_50(0), c_c_52(0), c_c_54(0), c_c_56(0) {} @@ -2897,11 +2942,12 @@ namespace mt g2_min = (isZero(inner_aper_ang)||(inner_aper_ang<0))?0:pow(sin(inner_aper_ang)/lambda, 2); g2_max = (isZero(outer_aper_ang)||(outer_aper_ang<0))?grid_2d.g2_max(): pow(sin(outer_aper_ang)/lambda, 2); - T g0s = sin(beta)/lambda; - sggs = g0s/c_2i2; - T gmaxs = 3.5*sggs; + set_dsf_sigma(dsf_sigma); + set_ssf_sigma(ssf_sigma); + + T gmaxs = 3.5*ssf_sigma; g2_maxs = gmaxs*gmaxs; - T dgs = gmaxs/static_cast(nbeta); + T dgs = gmaxs/static_cast(ssf_npoints); int n; n = (dgs(floor(grid_2d.dgx/dgs)+1):1; @@ -2913,6 +2959,19 @@ namespace mt dgys = gmaxs/ngys; } + void set_dsf_sigma(T dsf_sigma_i) + { + dsf_sigma = dsf_sigma_i; + dsf_iehwgd = c_2i2*dsf_sigma; + } + + void set_ssf_sigma(T ssf_sigma_i) + { + ssf_sigma = ssf_sigma_i; + ssf_iehwgd = c_2i2*ssf_sigma; + ssf_beta = asin(ssf_iehwgd*lambda); + } + void set_defocus(T f_i) { c_10 = f_i; @@ -3004,11 +3063,14 @@ namespace mt inner_aper_ang = lens.inner_aper_ang; outer_aper_ang = lens.outer_aper_ang; - sf = lens.sf; - nsf = lens.nsf; + dsf_sigma = lens.dsf_sigma; + dsf_npoints = lens.dsf_npoints; + dsf_iehwgd = lens.dsf_iehwgd; - beta = lens.beta; - nbeta = lens.nbeta; + ssf_sigma = lens.ssf_sigma; + ssf_npoints = lens.ssf_npoints; + ssf_iehwgd = lens.ssf_iehwgd; + ssf_beta = lens.ssf_beta; gamma = lens.gamma; lambda = lens.lambda; @@ -3036,7 +3098,6 @@ namespace mt g2_min = lens.g2_min; g2_max = lens.g2_max; - sggs = lens.sggs; ngxs = lens.ngxs; ngys = lens.ngys; dgxs = lens.dgxs; @@ -4356,7 +4417,21 @@ namespace mt { device = e_host; } - set_device(); + if(is_device()) + { + #ifdef __CUDACC__ + if(!is_gpu_available()) + { + device = mt::e_host; + n_gpu = 0; + } + else + { + n_gpu = number_of_gpu_available(); + gpu_device = min(max(0, gpu_device), n_gpu-1); + } + #endif + } cpu_nthread = max(1, cpu_nthread); gpu_nstream = max(1, gpu_nstream); @@ -4368,16 +4443,7 @@ namespace mt if(is_device()) { #ifdef __CUDACC__ - if(!is_gpu_available()) - { - device = mt::e_host; - } - else - { - auto ngpu = number_of_gpu_available(); - gpu_device = min(max(0, gpu_device), ngpu-1); - cudaSetDevice(gpu_device); - } + cudaSetDevice(gpu_device); #endif } else @@ -4387,6 +4453,19 @@ namespace mt } } + int get_device() + { + int idx_dev = -1; + if(is_device()) + { + #ifdef __CUDACC__ + cudaGetDevice(&idx_dev); + #endif + } + + return idx_dev; + } + bool is_host() const { return device == mt::e_host; @@ -4426,6 +4505,9 @@ namespace mt { return is_double() && is_device(); } + + private: + int n_gpu; }; /************************regions*************************/ @@ -4757,7 +4839,7 @@ namespace mt DEVICE_CALLABLE FORCE_INLINE T operator()(const T &Rx) const { - return pow(cos(cx*Rx), 2); + return ::square(cos(cx*Rx)); } }; @@ -4824,7 +4906,7 @@ namespace mt DEVICE_CALLABLE FORCE_INLINE T operator()(const T &R) const { - return pow(cos(cxy*R), 2); + return ::square(cos(cxy*R)); } }; @@ -4860,7 +4942,7 @@ namespace mt { n = n_i; radius = radius_i; - R02 = pow(radius, 2); + R02 = ::square(radius); Rx2_l = 1e+6*radius; x_c = x_c_i; k = 0; diff --git a/src/wave_function.cuh b/src/wave_function.cuh index 2f76fac8..7a27ac20 100644 --- a/src/wave_function.cuh +++ b/src/wave_function.cuh @@ -19,6 +19,7 @@ #ifndef WAVE_FUNCTION_H #define WAVE_FUNCTION_H +#include "math.cuh" #include "types.cuh" #include "fft.cuh" #include "input_multislice.cuh" @@ -49,12 +50,6 @@ namespace mt psi_z.resize(input_multislice_i->grid_2d.nxy()); m2psi_z.resize(input_multislice_i->grid_2d.nxy()); - if(this->device == e_device) - { - psi_zh.resize(input_multislice_i->grid_2d.nxy()); - m2psi_zh.resize(input_multislice_i->grid_2d.nxy()); - } - if(input_multislice_i->is_STEM()) { detector.assign(input_multislice_i->detector); @@ -155,33 +150,35 @@ namespace mt if(this->input_multislice->pn_coh_contrib) { - mt::add_scale_to_host(output_multislice.stream, w_i, *psi_z_o, output_multislice.psi_coh[ithk], &psi_zh); + output_multislice.add_scale_psi_coh(ithk, w_i, *psi_z_o); } } else if(this->input_multislice->is_EWFS_EWRS_SC()) { - mt::copy_to_host(output_multislice.stream, *psi_z_o, output_multislice.psi_coh[ithk], &psi_zh); + output_multislice.set_crop_shift_psi_coh(ithk, *psi_z_o); + } + else if(this->input_multislice->is_EWFS_EWRS()) + { + output_multislice.add_scale_crop_shift_m2psi_tot_from_psi(ithk, w_i, *psi_z_o); + output_multislice.add_scale_crop_shift_psi_coh(ithk, w_i, *psi_z_o); } else if(this->input_multislice->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM()) { microscope_effects(*psi_z_o, m2psi_z); - mt::add_scale_to_host(output_multislice.stream, w_i, m2psi_z, output_multislice.m2psi_tot[ithk], &m2psi_zh); + output_multislice.add_scale_crop_shift_m2psi_tot_from_m2psi(ithk, w_i, m2psi_z); if(this->input_multislice->pn_coh_contrib) { - mt::add_scale_to_host(output_multislice.stream, w_i, *psi_z_o, output_multislice.psi_coh[ithk], &psi_zh); + output_multislice.add_scale_psi_coh(ithk, w_i, *psi_z_o); } } else { + output_multislice.add_scale_crop_shift_m2psi_tot_from_psi(ithk, w_i, *psi_z_o); + if(this->input_multislice->pn_coh_contrib) { - mt::add_scale_m2psi_psi_to_host(output_multislice.stream, w_i, *psi_z_o, output_multislice.m2psi_tot[ithk], output_multislice.psi_coh[ithk], &psi_zh); - } - else - { - mt::square(*(this->stream), *psi_z_o, m2psi_z); - mt::add_scale_to_host(output_multislice.stream, w_i, m2psi_z, output_multislice.m2psi_tot[ithk], &m2psi_zh); + output_multislice.add_scale_psi_coh(ithk, w_i, *psi_z_o); } } } @@ -195,11 +192,13 @@ namespace mt return; } + int n_thk = this->input_multislice->thick.size(); + if(this->input_multislice->is_STEM()) { - for(auto ithk = 0; ithk < this->slicing.thick.size(); ithk++) + for(auto ithk = 0; ithk < n_thk; ithk++) { - mt::assign(output_multislice.psi_coh[ithk], psi_z, &psi_zh); + output_multislice.from_psi_coh_2_phi(ithk, psi_z); for(auto iDet = 0; iDetinput_multislice->iscan[0]; @@ -209,18 +208,19 @@ namespace mt } else if(this->input_multislice->is_ISTEM_CBEI_HRTEM_HCTEM_EFTEM()) { - for(auto ithk = 0; ithk < this->slicing.thick.size(); ithk++) + for(auto ithk = 0; ithk < n_thk; ithk++) { - mt::assign(output_multislice.psi_coh[ithk], psi_z, &psi_zh); + output_multislice.from_psi_coh_2_phi(ithk, psi_z); microscope_effects(psi_z, m2psi_z); - mt::copy_to_host(output_multislice.stream, m2psi_z, output_multislice.m2psi_coh[ithk], &m2psi_zh); + output_multislice.set_crop_shift_m2psi_coh(ithk, m2psi_z); } } else { - for(auto ithk = 0; ithk < this->slicing.thick.size(); ithk++) + for(auto ithk = 0; ithk < n_thk; ithk++) { - mt::square(output_multislice.stream, output_multislice.psi_coh[ithk], output_multislice.m2psi_coh[ithk]); + output_multislice.from_psi_coh_2_phi(ithk, psi_z); + output_multislice.add_scale_crop_shift_m2psi_coh_from_psi(ithk, 1.0, psi_z); } } } @@ -229,6 +229,7 @@ namespace mt void psi_slice(const T_r &gxu, const T_r &gyu, const int &islice, TVector_c &psi_z) { this->transmit(islice, psi_z); + if(this->input_multislice->is_multislice()) { propagator(eS_Real, gxu, gyu, this->dz(islice), psi_z); @@ -244,6 +245,7 @@ namespace mt for(auto islice = 0; isliceslicing.slice.size(); islice++) { psi_slice(gx_0, gy_0, islice, psi_z); + set_m2psi_tot_psi_coh(psi_z, gx_0, gy_0, islice, w_i, output_multislice); } } @@ -289,33 +291,38 @@ namespace mt { mt::hard_aperture(*(this->stream), this->input_multislice->grid_2d, this->input_multislice->eels_fr.g_collection, 1.0, psi_z); microscope_effects(psi_z, m2psi_z); - mt::add_scale_to_host(output_multislice.stream, w_i, m2psi_z, output_multislice.m2psi_tot[ithk], &m2psi_zh); + output_multislice.add_scale_crop_shift_m2psi_tot_from_m2psi(ithk, w_i, m2psi_z); } } } - void set_incident_wave(TVector_c &psi) + void set_incident_wave(TVector_c &psi, Vector &beam_x, Vector &beam_y) { T_r gxu = 0; T_r gyu = 0; - auto &beam_x = this->input_multislice->beam_x; - auto &beam_y = this->input_multislice->beam_y; auto z_init = this->slicing.z_m(0); incident_wave(psi, gxu, gyu, beam_x, beam_y, z_init); } + void set_incident_wave(TVector_c &psi) + { + auto &beam_x = this->input_multislice->beam_x; + auto &beam_y = this->input_multislice->beam_y; + + set_incident_wave(psi, beam_x, beam_y); + } + Propagator propagator; TVector_c psi_z; TVector_r m2psi_z; - Vector psi_zh; - Vector m2psi_zh; - Detector detector; Microscope_Effects microscope_effects; Incident_Wave incident_wave; + + //mt::Timing time; }; } // namespace mt