From 5cf74da1bb5d9327a11552a5a7300b1f479c5e32 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Sat, 3 Aug 2019 09:01:04 -0400 Subject: [PATCH 01/40] Add a text editor to egs_view Initial commit with very basic groundwork for a text editor in egs_view. Adds some syntax highlighting, and begins building a structure in geometries to return input keys. Includes debug statements and nonsense behaviour. --- HEN_HOUSE/egs++/Makefile | 10 +- HEN_HOUSE/egs++/egs_application.cpp | 2 + HEN_HOUSE/egs++/egs_application.h | 4 + HEN_HOUSE/egs++/egs_base_geometry.cpp | 2 + HEN_HOUSE/egs++/egs_base_geometry.h | 10 + HEN_HOUSE/egs++/egs_input_struct.cpp | 136 +++++++++ HEN_HOUSE/egs++/egs_input_struct.h | 116 ++++++++ HEN_HOUSE/egs++/geometry/egs_box/Makefile | 2 +- HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp | 50 +++- HEN_HOUSE/egs++/geometry/egs_box/egs_box.h | 18 ++ HEN_HOUSE/egs++/view/egs_editor.cpp | 277 +++++++++++++++++++ HEN_HOUSE/egs++/view/egs_editor.h | 62 +++++ HEN_HOUSE/egs++/view/egs_highlighter.cpp | 125 +++++++++ HEN_HOUSE/egs++/view/egs_highlighter.h | 77 ++++++ HEN_HOUSE/egs++/view/view.pro | 16 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 197 ++++++++++++- HEN_HOUSE/egs++/view/viewcontrol.h | 10 + HEN_HOUSE/egs++/view/viewcontrol.ui | 160 +++++++++-- 18 files changed, 1238 insertions(+), 36 deletions(-) create mode 100644 HEN_HOUSE/egs++/egs_input_struct.cpp create mode 100644 HEN_HOUSE/egs++/egs_input_struct.h create mode 100644 HEN_HOUSE/egs++/view/egs_editor.cpp create mode 100644 HEN_HOUSE/egs++/view/egs_editor.h create mode 100644 HEN_HOUSE/egs++/view/egs_highlighter.cpp create mode 100644 HEN_HOUSE/egs++/view/egs_highlighter.h diff --git a/HEN_HOUSE/egs++/Makefile b/HEN_HOUSE/egs++/Makefile index adfaee04b..d283ed24b 100644 --- a/HEN_HOUSE/egs++/Makefile +++ b/HEN_HOUSE/egs++/Makefile @@ -49,7 +49,7 @@ egspp_files = egs_input egs_base_geometry egs_library egs_transformations \ egs_base_source egs_functions egs_application egs_run_control \ egs_scoring egs_interpolator egs_atomic_relaxations \ egs_ausgab_object egs_particle_track egs_fortran_geometry \ - egs_ensdf + egs_ensdf egs_input_struct egspp_objects = $(addprefix $(DSO1), $(addsuffix .$(obje), $(egspp_files))) config1h = $(IEGS1)$(DSEP)egs_config1.h egs_libconfig.h egs_functions.h @@ -80,7 +80,7 @@ lib_objects = $(addprefix $(DSO1), $(addsuffix .$(obje), $(all_libs))) #****************************************************************************** -all: $(EGS_BINDIR)egspp$(EXE) $(ABS_DSO)$(libpre)egspp$(libext) glibs slibs shapes aobjects gtest +all: $(EGS_BINDIR)egspp$(EXE) $(ABS_DSO)$(libpre)egspp$(libext) $(ABS_DSO)$(libpre)egs_input_struct$(libext) glibs slibs shapes aobjects gtest $(EGS_BINDIR)egspp$(EXE): $(dso) $(DSO1)egspp.$(obje) $(ABS_DSO)$(libpre)egspp$(libext) $(CXX) $(INC1) $(DEF1) $(opt) $(EOUT)$@ $(DSO1)egspp.$(obje) $(lib_link1) $(link2_prefix)egspp$(link2_suffix) @@ -92,6 +92,9 @@ $(DSO1)egspp.$(obje): egspp.cpp egs_application.h egs_base_geometry.h egs_vector egs_math.h egs_library.h $(config1h) $(CXX) $(INC1) $(DEF1) $(opt) -c $(COUT)$@ $(notdir $(basename $@)).cpp +$(ABS_DSO)$(libpre)egs_input_struct$(libext): $(dso) $(DSO1)egs_input_struct.$(obje) + $(CXX) $(INC1) $(DEFS) $(opt) $(shared) $(DSO1)egs_input_struct.$(obje) $(extra) + $(DSO1)egs_interpolator.$(obje): egs_interpolator.cpp egs_interpolator.h \ $(config1h) @@ -138,6 +141,9 @@ $(DSO1)egs_base_source.$(obje): egs_base_source.cpp egs_base_source.h \ $(DSO1)egs_ensdf.$(obje): egs_ensdf.cpp egs_ensdf.h \ $(config1h) egs_functions.h egs_math.h egs_alias_table.h egs_atomic_relaxations.h +$(DSO1)egs_input_struct.$(obje): egs_input_struct.cpp egs_input_struct.h \ + $(config1h) + $(DSO1)egs_geometry_tester.$(obje): egs_geometry_tester.cpp \ egs_geometry_tester.h egs_input.h egs_vector.h egs_base_geometry.h \ egs_shapes.h egs_rndm.h egs_transformations.h egs_timer.h egs_math.h \ diff --git a/HEN_HOUSE/egs++/egs_application.cpp b/HEN_HOUSE/egs++/egs_application.cpp index 764c070e6..5ed337f77 100644 --- a/HEN_HOUSE/egs++/egs_application.cpp +++ b/HEN_HOUSE/egs++/egs_application.cpp @@ -101,6 +101,8 @@ static EGS_LOCAL EGS_Application *active_egs_application = 0; int EGS_Application::n_apps = 0; +unique_ptr EGS_Application::inputStructure = unique_ptr(); + EGS_EXPORT EGS_Application *EGS_Application::activeApplication() { return active_egs_application; } diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index 59fc1d45e..03e4f59e0 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -44,7 +44,9 @@ #include "egs_base_source.h" #include "egs_simple_container.h" #include "egs_interpolator.h" +#include "egs_input_struct.h" +#include #include #include using namespace std; @@ -1197,6 +1199,8 @@ class EGS_EXPORT EGS_Application { //************************************************************ virtual void setLatch(int latch) {}; + static unique_ptr inputStructure; + }; #define APP_MAIN(app_name) \ diff --git a/HEN_HOUSE/egs++/egs_base_geometry.cpp b/HEN_HOUSE/egs++/egs_base_geometry.cpp index e622679d1..44b95283b 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.cpp +++ b/HEN_HOUSE/egs++/egs_base_geometry.cpp @@ -1170,3 +1170,5 @@ int EGS_BaseGeometry::setLabels(const string &inp) { return 1; } + + diff --git a/HEN_HOUSE/egs++/egs_base_geometry.h b/HEN_HOUSE/egs++/egs_base_geometry.h index 33bbfe66f..1fa46cf2f 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -44,10 +44,12 @@ #define EGS_BASE_GEOMETRY_ #include "egs_vector.h" +#include "egs_input_struct.h" #include #include #include +#include using std::string; using std::vector; @@ -72,6 +74,14 @@ class label { vector regions; }; +static shared_ptr blockInput = make_shared("geometry"); +static void setBaseGeometryInputs() { + blockInput->addSingleInput("name", true, "The user-declared unique name of this geometry."); + shared_ptr mediaBlock = blockInput->addBlockInput("media input"); + mediaBlock->addSingleInput("media", true, "A list of media that are used in this geometry."); + mediaBlock->addSingleInput("set medium", false, "TODO"); +} + /*! \brief Base geometry class. Every geometry class must be derived from EGS_BaseGeometry. diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp new file mode 100644 index 000000000..b1cbc25f4 --- /dev/null +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -0,0 +1,136 @@ +/* +############################################################################### +# +# EGSnrc egs++ input struct +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc 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 Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Reid Townson, 2019 +# +# Contributors: +# +############################################################################### +*/ + + +/*! \file egs_input_struct.cpp + * \brief The input struct cpp file + * \RT + * + */ + +#include "egs_functions.h" +#include "egs_input_struct.h" + +EGS_InputStruct::EGS_InputStruct() {} + +EGS_InputStruct::~EGS_InputStruct() {} + +EGS_BlockInput::EGS_BlockInput() {} + +EGS_BlockInput::EGS_BlockInput(string blockTit, bool isReq, shared_ptr par) { + blockTitle = blockTit; + isRequired = isReq; + parent = par; +} + +EGS_BlockInput::~EGS_BlockInput() {} + +void EGS_BlockInput::setTitle(string blockTit) { + blockTitle = blockTit; +} + +string EGS_BlockInput::getTitle() { + return blockTitle; +} + +void EGS_BlockInput::addSingleInput(string attr, bool isReq, const string desc, const vector vals) { + singleInputs.push_back(EGS_SingleInput(attr, isReq, desc, vals)); +} + +shared_ptr EGS_BlockInput::addBlockInput(string blockTit, bool isReq) { + egsInformation("addBlockInput\n"); + blockInputs.push_back(make_shared(blockTit, isReq, shared_from_this())); + egsInformation("addBlockInput2\n"); + + return blockInputs.back(); +} + +vector EGS_BlockInput::getSingleInputs() { + return singleInputs; +} + +vector> EGS_BlockInput::getBlockInputs() { + return blockInputs; +} + +EGS_SingleInput EGS_BlockInput::getSingleInput(string attr) { + for(auto& inp : singleInputs) { + // TODO: this assumes unique attr + if(inp.getAttribute() == attr) { + return inp; + } + } + + return EGS_SingleInput(); +} + +void EGS_BlockInput::setParent(shared_ptr par) { + parent = par; +} + +shared_ptr EGS_BlockInput::getParent() { + return parent; +} + +EGS_SingleInput::EGS_SingleInput() {} + +EGS_SingleInput::EGS_SingleInput(string attr, bool isReq, const string desc, const vector vals) { + attribute = attr; + isRequired = isReq; + description = desc; + values = vals; +} + +EGS_SingleInput::~EGS_SingleInput() {} + +void EGS_SingleInput::addRequirement(string attr, string val) { + +} + +vector EGS_SingleInput::getDependents() { + +} + +string EGS_SingleInput::getAttribute() { + return attribute; +} + +bool EGS_SingleInput::getRequired() { + return isRequired; +} + +const vector EGS_SingleInput::getValues() { + return values; +} + + + + + diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h new file mode 100644 index 000000000..54b0d0fa5 --- /dev/null +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -0,0 +1,116 @@ +/* +############################################################################### +# +# EGSnrc egs++ input struct headers +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc 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 Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Reid Townson, 2019 +# +# Contributors: +# +# An application has one global scope input struct object. Input blocks are +# then added to contain geometries or sources. Input blocks may contain single +# inputs. +# +############################################################################### +*/ + + +/*! \file egs_input_struct.h + * \brief The input struct header file + * \RT + * + */ + +#ifndef EGS_INPUT_STRUCT_ +#define EGS_INPUT_STRUCT_ + +#include +#include +#include "egs_libconfig.h" +#include + +using namespace std; + +class EGS_EXPORT EGS_SingleInput { + +public: + EGS_SingleInput(); + EGS_SingleInput(string attr, bool isReq, const string desc, const vector vals); + string getAttribute(); + bool getRequired(); + ~EGS_SingleInput(); + const vector getValues(); + +protected: + + void addRequirement(string attr, string value=""); + vector getDependents(); + +private: + + vector dependents; + vector requirements; + string attribute; + bool isRequired; + string description; + vector values; +}; + +class EGS_EXPORT EGS_BlockInput + : public std::enable_shared_from_this { +public: + EGS_BlockInput(); + EGS_BlockInput(string blockTit, bool isReq = false, shared_ptr par = nullptr); + ~EGS_BlockInput(); + + void setTitle(string blockTit); + string getTitle(); + void addSingleInput(string attr, bool isReq, const string desc, const vector vals = vector()); + shared_ptr addBlockInput(string blockTit, bool isReq = false); + vector getSingleInputs(); + vector> getBlockInputs(); + EGS_SingleInput getSingleInput(string attr); + void setParent(shared_ptr par); + shared_ptr getParent(); + + +private: + + vector singleInputs; + vector> blockInputs; + shared_ptr parent; + string blockTitle; + bool isRequired; + const string desc; +}; + +class EGS_EXPORT EGS_InputStruct { +public: + EGS_InputStruct(); + ~EGS_InputStruct(); + + void addBlockInput(EGS_InputStruct *parent, string blockTit, bool isReq); +}; + + +#endif + + diff --git a/HEN_HOUSE/egs++/geometry/egs_box/Makefile b/HEN_HOUSE/egs++/geometry/egs_box/Makefile index 58b7cd67a..4b34b541e 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/Makefile +++ b/HEN_HOUSE/egs++/geometry/egs_box/Makefile @@ -36,7 +36,7 @@ DEFS = $(DEF1) -DBUILD_BOX_DLL library = egs_box lib_files = egs_box -my_deps = egs_transformations.h +my_deps = egs_transformations.h egs_input_struct.h extra_dep = $(addprefix $(DSOLIBS), $(my_deps)) include $(SPEC_DIR)egspp_libs.spec diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp index a84c41f21..0721c242e 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -37,6 +37,7 @@ #include "egs_box.h" #include "egs_input.h" +#include "egs_base_geometry.h" void EGS_Box::printInfo() const { EGS_BaseGeometry::printInfo(); @@ -44,7 +45,8 @@ void EGS_Box::printInfo() const { egsInformation("=======================================================\n"); } -string EGS_Box::type("EGS_Box"); +static string EGS_BOX_LOCAL typeStr("EGS_Box"); +string EGS_Box::type(typeStr); static char EGS_BOX_LOCAL ebox_message1[] = "createGeometry(box): %s\n"; static char EGS_BOX_LOCAL ebox_message2[] = "null input?"; @@ -53,19 +55,56 @@ static char EGS_BOX_LOCAL ebox_message4[] = "expecting 1 or 3 float inputs for 'box size'"; static char EGS_BOX_LOCAL ebox_key1[] = "box size"; +static bool inputSet = false; + +struct EGS_BOX_LOCAL BoxInputs { + vector boxSize; +}; +BoxInputs inp; + +// TODO was going to add this function in addition to the blockinput stuff +EGS_BOX_LOCAL int loadInputs(EGS_Input *input) { + int err = input->getInput(ebox_key1,inp.boxSize); + if(err && blockInput->getSingleInput(ebox_key1).getRequired()) { + egsWarning(ebox_message1,ebox_message3); + return 0; + } + + return 1; +} + extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(); + + blockInput->addSingleInput("library", true, "The type of geometry.", vector(1, typeStr)); + blockInput->addSingleInput("box size", true, "1 or 3 numbers defining the box size"); + } + + EGS_BOX_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return blockInput; + } + EGS_BOX_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { egsWarning(ebox_message1,ebox_message2); return 0; } - vector s; - int err = input->getInput(ebox_key1,s); - if (err) { - egsWarning(ebox_message1,ebox_message3); + + if(!loadInputs(input)) { + egsWarning("Failed to load the inputs for %s.\n", typeStr.c_str()); return 0; } + + vector s; + s = inp.boxSize; + EGS_AffineTransform *t = EGS_AffineTransform::getTransformation(input); EGS_Box *result; if (s.size() == 1) { @@ -90,5 +129,4 @@ extern "C" { result->setLabels(input); return result; } - } diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h index b63a33bcb..4aaf55622 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h @@ -109,6 +109,13 @@ class EGS_BOX_EXPORT EGS_Box : public EGS_BaseGeometry { public: +// EGS_Box() : EGS_BaseGeometry("empty") { +// inputBlock.addBlockInput("geometry", true); +// inputBlock.addSingleInput("library", true, {"egs_box"}); +// inputBlock.addSingleInput("name", true); +// }; + //static EGS_BlockInput getInputs(); + EGS_Box(EGS_Float a, const EGS_AffineTransform *t = 0, const string &Name = "") : EGS_BaseGeometry(Name), ax(a), ay(a), az(a), T(0) { @@ -134,6 +141,17 @@ class EGS_BOX_EXPORT EGS_Box : public EGS_BaseGeometry { } }; + // Build the input structure that this class will adhere to + // Any new input parameters should be included here +// EGS_BlockInput getInputBlock() { +// //inputBlock = new EGS_BlockInput("geometry"); +// /*inputBlock->addBlockInput("geometry", true); +// inputBlock->addSingleInput("library", true, {"egs_box"}); +// inputBlock->addSingleInput("name", true);*/ +// +// return inputBlock; +// }; + bool isInside(const EGS_Vector &x) { EGS_Vector xp = T ? x*(*T) : x; if (2*xp.x + ax < 0 || 2*xp.x - ax > 0) { diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp new file mode 100644 index 000000000..c4baa74b4 --- /dev/null +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -0,0 +1,277 @@ + +#include + +#include "egs_editor.h" + +EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) +{ + this->setFrameShape(QFrame::NoFrame); + + installEventFilter(this); + viewport()->installEventFilter(this); + + lineNumberArea = new LineNumberArea(this); + + connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); + connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); + connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); + connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(autoComplete())); + + updateLineNumberAreaWidth(0); + highlightCurrentLine(); +} + + + +int EGS_Editor::lineNumberAreaWidth() +{ + int digits = 1; + int max = qMax(1, blockCount()); + while (max >= 10) { + max /= 10; + ++digits; + } + + int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits; + + return space; +} + + + +void EGS_Editor::updateLineNumberAreaWidth(int /* newBlockCount */) +{ + setViewportMargins(lineNumberAreaWidth()+5, 0, 0, 0); +} + + + +void EGS_Editor::updateLineNumberArea(const QRect &rect, int dy) +{ + if (dy) + lineNumberArea->scroll(0, dy); + else + lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + + if (rect.contains(viewport()->rect())) + updateLineNumberAreaWidth(0); +} + + + +void EGS_Editor::resizeEvent(QResizeEvent *e) +{ + QPlainTextEdit::resizeEvent(e); + + QRect cr = contentsRect(); + lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); +} + + + +void EGS_Editor::highlightCurrentLine() +{ + QList extraSelections; + + if (!isReadOnly()) { + QTextEdit::ExtraSelection selection; + + QColor lineColor = QColor(Qt::lightGray).lighter(120); + + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + extraSelections.append(selection); + } + + setExtraSelections(extraSelections); +} + + + +void EGS_Editor::autoComplete() +{ + QTextCursor cursor = textCursor(); + int clickedPosition = cursor.position(); + + // Get the text of the current line + cursor.movePosition(QTextCursor::StartOfBlock); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + QString selectedText = cursor.selectedText(); + + if(selectedText.simplified() == "library =") { + //insertPlainText(selectedText); + + // Init popup + QListView *popup = new QListView; + popup->setEditTriggers(QAbstractItemView::NoEditTriggers); + popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + popup->setSelectionBehavior(QAbstractItemView::SelectRows); + popup->setSelectionMode(QAbstractItemView::SingleSelection); + //popup->setModelColumn(d->column); + + popup->setParent(nullptr); + // This option seems to take control of mouse + key inputs + // essentially locking up the computer, beware! + //popup->setWindowFlag(Qt::Popup); + popup->setWindowFlag(Qt::ToolTip); + popup->setFocusPolicy(Qt::NoFocus); + + popup->installEventFilter(this); + + QObject::connect(popup, SIGNAL(clicked(QModelIndex)), + this, SLOT(insertCompletion(QModelIndex))); + QObject::connect(this, SIGNAL(cursorPositionChanged()), + popup, SLOT(hide())); +// +// QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), +// this, SLOT(_q_completionSelected(QItemSelection))); + + // Init model + QStringListModel *model; + model = new QStringListModel(this); + + // Make data + QStringList List; + List << "egs_box" << "egs_cd_geometry" << "egs_cones"; + model->setStringList(List); + + popup->setModel(model); + + // Create a selection popup + QRect rect; //tmp rect + int maxVisibleItems = 6; + const QRect screen = this->frameRect(); + Qt::LayoutDirection dir = this->layoutDirection(); + QPoint pos; + int rh, w; + int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = popup->horizontalScrollBar(); + if (hsb && hsb->isVisible()) + h += popup->horizontalScrollBar()->sizeHint().height(); + + if (rect.isValid()) { + rh = rect.height(); + w = rect.width(); + pos = this->mapToGlobal(dir == Qt::RightToLeft ? rect.bottomRight() : rect.bottomLeft()); + } else { + rh = this->height(); + pos = this->mapToGlobal(QPoint(0, this->height() - 2)); + w = this->width(); + } + + // Constrain the box size to the window + if (w > screen.width()) + w = screen.width(); + if ((pos.x() + w) > (screen.x() + screen.width())) + pos.setX(screen.x() + screen.width() - w); + if (pos.x() < screen.x()) + pos.setX(screen.x()); + + int top = pos.y() - rh - screen.top() + 2; + int bottom = screen.bottom() - pos.y(); + h = qMax(h, popup->minimumHeight()); + if (h > bottom) { + h = qMin(qMax(top, bottom), h); + + if (top > bottom) + pos.setY(pos.y() - h - rh + 2); + } + + popup->setGeometry(pos.x(), pos.y(), w, h); + + // Show the popup + if (!popup->isVisible()) + popup->show(); + } +} + +void EGS_Editor::insertCompletion(QModelIndex index) { + insertPlainText("test"); + //insertPlainText(index); +} + + + +void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) +{ + QPainter painter(lineNumberArea); + //painter.fillRect(event->rect(), QColor(Qt::lightGray).lighter(110)); + + + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + int top = static_cast(blockBoundingGeometry(block).translated(contentOffset()).top()); + int bottom = top + static_cast(blockBoundingRect(block).height()); + + while (block.isValid() && top <= event->rect().bottom()) { + if (block.isVisible() && bottom >= event->rect().top()) { + QString number = QString::number(blockNumber + 1); + painter.setPen(Qt::black); + painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), + Qt::AlignRight, number); + } + + block = block.next(); + top = bottom; + bottom = top + static_cast(blockBoundingRect(block).height()); + ++blockNumber; + } +} + +bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { + + if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *mouseEvent = static_cast(event); + + // track `Ctrl + Click` in the text edit + if ((obj == this->viewport()) && + (mouseEvent->button() == Qt::LeftButton) && + (QGuiApplication::keyboardModifiers() == Qt::ControlModifier)) { + // open the link (if any) at the current position + //openLinkAtCursorPosition(); + return true; + } + } + + return QPlainTextEdit::eventFilter(obj, event); +} + +//bool EGS_Editor::openLinkAtCursorPosition() { +// QTextCursor cursor = this->textCursor(); +// int clickedPosition = cursor.position(); + +// // select the text in the clicked block and find out on +// // which position we clicked +// cursor.movePosition(QTextCursor::StartOfBlock); +// int positionFromStart = clickedPosition - cursor.position(); +// cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + +// QString selectedText = cursor.selectedText(); + +// // find out which url in the selected text was clicked +// QString urlString = getMarkdownUrlAtPosition(selectedText, +// positionFromStart); +// QUrl url = QUrl(urlString); +// bool isRelativeFileUrl = urlString.startsWith("file://.."); + +// qDebug() << __func__ << " - 'emit urlClicked( urlString )': " +// << urlString; + +// emit urlClicked(urlString); + +// if ((url.isValid() && isValidUrl(urlString)) || isRelativeFileUrl) { +// // ignore some schemata +// if (!(_ignoredClickUrlSchemata.contains(url.scheme()) || +// isRelativeFileUrl)) { +// // open the url +// openUrl(urlString); +// } + +// return true; +// } + +// return false; +//} + diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h new file mode 100644 index 000000000..951a426b5 --- /dev/null +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -0,0 +1,62 @@ +#ifndef EGS_EDITOR_H +#define EGS_EDITOR_H + +#include +#include +#include +#include + +class QPaintEvent; +class QResizeEvent; +class QSize; +class QWidget; + +class LineNumberArea; + +class EGS_Editor : public QPlainTextEdit +{ + Q_OBJECT + +public: + EGS_Editor(QWidget *parent = 0); + + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberAreaWidth(); + +protected: + void resizeEvent(QResizeEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event); + +private slots: + void updateLineNumberAreaWidth(int newBlockCount); + void highlightCurrentLine(); + void autoComplete(); + void insertCompletion(QModelIndex index); + void updateLineNumberArea(const QRect &, int); + +private: + QWidget *lineNumberArea; +}; + + +class LineNumberArea : public QWidget +{ +public: + LineNumberArea(EGS_Editor *editor) : QWidget(editor) { + egsEditor = editor; + } + + QSize sizeHint() const override { + return QSize(egsEditor->lineNumberAreaWidth(), 0); + } + +protected: + void paintEvent(QPaintEvent *event) override { + egsEditor->lineNumberAreaPaintEvent(event); + } + +private: + EGS_Editor *egsEditor; +}; + +#endif // EGS_EDITOR_H diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.cpp b/HEN_HOUSE/egs++/view/egs_highlighter.cpp new file mode 100644 index 000000000..9b7cbf394 --- /dev/null +++ b/HEN_HOUSE/egs++/view/egs_highlighter.cpp @@ -0,0 +1,125 @@ +/* +############################################################################### +# +# EGSnrc egs++ input highlighter +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc 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 Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Reid Townson, 2019 +# +# Contributors: +# +############################################################################### +*/ + +#include "egs_highlighter.h" + +EGS_Highlighter::EGS_Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) { + + HighlightingRule rule; + + keywordFormat.setForeground(Qt::darkRed); + keywordFormat.setFontWeight(QFont::Bold); + + QStringList keywordPatterns; + keywordPatterns << ":(start|stop).*\\S:"; + + foreach (const QString &pattern, keywordPatterns) { + rule.pattern = QRegularExpression(pattern); + rule.format = keywordFormat; + highlightingRules.append(rule); + } + + attributeFormat.setForeground(Qt::darkBlue); + rule.pattern = QRegularExpression(".*="); + rule.format = attributeFormat; + highlightingRules.append(rule); + + numberFormat.setForeground(Qt::darkGreen); + rule.pattern = QRegularExpression("[+-]?(\\d*\\.)?\\d"); + rule.format = numberFormat; + highlightingRules.append(rule); + + definitionFormat.setForeground(Qt::darkMagenta); + definitionFormat.setFontWeight(QFont::Bold); + rule.pattern = QRegularExpression(":(start|stop).*(definition|MC transport parameter|run control|scoring options):"); + rule.format = definitionFormat; + highlightingRules.append(rule); + + nameFormat.setForeground(Qt::darkBlue); + nameFormat.setFontWeight(QFont::Bold); + rule.pattern = QRegularExpression("name.*=.*"); + rule.format = nameFormat; + highlightingRules.append(rule); + + quotationFormat.setForeground(Qt::darkRed); + rule.pattern = QRegularExpression("\".*\""); + rule.format = quotationFormat; + highlightingRules.append(rule); + + squotationFormat.setForeground(Qt::red); + rule.pattern = QRegularExpression("\'.*\'"); + rule.format = squotationFormat; + highlightingRules.append(rule); + + // Comment highlighting must come last + singleLineCommentFormat.setForeground(Qt::gray); + rule.pattern = QRegularExpression("#[^\n]*"); + rule.format = singleLineCommentFormat; + highlightingRules.append(rule); + + // For multi-line comments + //multiLineCommentFormat.setForeground(Qt::red); + + //commentStartExpression = QRegularExpression("/\\*"); + //commentEndExpression = QRegularExpression("\\*/"); +} + +void EGS_Highlighter::highlightBlock(const QString &text) +{ + foreach (const HighlightingRule &rule, highlightingRules) { + QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); + while (matchIterator.hasNext()) { + QRegularExpressionMatch match = matchIterator.next(); + setFormat(match.capturedStart(), match.capturedLength(), rule.format); + } + } + setCurrentBlockState(0); + + /* + //For multi-line comments + int startIndex = 0; + if (previousBlockState() != 1) + startIndex = text.indexOf(commentStartExpression); + + while (startIndex >= 0) { + QRegularExpressionMatch match = commentEndExpression.match(text, startIndex); + int endIndex = match.capturedStart(); + int commentLength = 0; + if (endIndex == -1) { + setCurrentBlockState(1); + commentLength = text.length() - startIndex; + } else { + commentLength = endIndex - startIndex + + match.capturedLength(); + } + setFormat(startIndex, commentLength, multiLineCommentFormat); + startIndex = text.indexOf(commentStartExpression, startIndex + commentLength); + }*/ +} diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.h b/HEN_HOUSE/egs++/view/egs_highlighter.h new file mode 100644 index 000000000..aba79d181 --- /dev/null +++ b/HEN_HOUSE/egs++/view/egs_highlighter.h @@ -0,0 +1,77 @@ +/* +############################################################################### +# +# EGSnrc egs++ input highlighter +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc 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 Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Reid Townson, 2019 +# +# Contributors: +# +############################################################################### +*/ + +#ifndef EGS_HIGHLIGHTER_H +#define EGS_HIGHLIGHTER_H + +#include +#include +#include + +class QTextDocument; + +class EGS_Highlighter : public QSyntaxHighlighter +{ + Q_OBJECT +public: + explicit EGS_Highlighter(QTextDocument *parent = nullptr); + +protected: + void highlightBlock(const QString &text) override; + +private: + struct HighlightingRule + { + QRegularExpression pattern; + QTextCharFormat format; + }; + QVector highlightingRules; + + QRegularExpression commentStartExpression, + commentEndExpression; + + QTextCharFormat keywordFormat, + attributeFormat, + numberFormat, + definitionFormat, + nameFormat, + singleLineCommentFormat, + quotationFormat, + squotationFormat, + functionFormat; + //QTextCharFormat multiLineCommentFormat; + +signals: + +public slots: + +}; + +#endif // EGS_HIGHLIGHTER_H diff --git a/HEN_HOUSE/egs++/view/view.pro b/HEN_HOUSE/egs++/view/view.pro index 4dbc8ab15..8eb7fa42d 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -41,11 +41,15 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets HEADERS += egs_visualizer.h image_window.h egs_light.h \ clippingplanes.h viewcontrol.h geometryview.ui.h \ saveimage.h egs_user_color.h egs_track_view.h \ - renderworker.h + renderworker.h \ + egs_highlighter.h \ + egs_editor.h SOURCES += main.cpp egs_visualizer.cpp egs_track_view.cpp \ saveimage.cpp clippingplanes.cpp viewcontrol.cpp \ - renderworker.cpp image_window.cpp + renderworker.cpp image_window.cpp \ + egs_highlighter.cpp \ + egs_editor.cpp FORMS = saveimage.ui clippingplanes.ui viewcontrol.ui @@ -54,7 +58,7 @@ win32 { DEFINES += WIN32 DEFINES += VDEBUG RC_FILE = egs_view.rc - LIBS += ../dso/$$my_machine/egspp.lib + LIBS += ../dso/$$my_machine/egspp.lib ../dso/$$my_machine/egs_input_struct.lib DESTDIR = ../dso/$$my_machine TARGET = egs_view } @@ -62,7 +66,7 @@ win32 { unix { CONFIG += qt warn_on release $$my_build macx { - LIBS += -L../dso/$$my_machine -legspp + LIBS += -L../dso/$$my_machine -legspp -legs_input_struct TARGET = ../../bin/$$my_machine/egs_view } !macx { @@ -70,13 +74,13 @@ unix { !contains( CONFIG, static ){ message( "Dynamic build..." ) TARGET = egs_view - LIBS += -L../dso/$$my_machine -Wl,-rpath,$$hhouse/egs++/dso/$$my_machine -legspp + LIBS += -L../dso/$$my_machine -Wl,-rpath,$$hhouse/egs++/dso/$$my_machine -legspp -legs_input_struct } contains( CONFIG, static ){ message( "Static build ..." ) DESTDIR = ../../pieces/linux #LIBS += -L../dso/$$my_machine -Wl,-rpath,$$hhouse/egs++/dso/$$my_machine -legspp # Fixes path to library - LIBS += -L$$hhouse/egs++/dso/$$my_machine -legspp # Relies on LD_LIBRARY_PATH + LIBS += -L$$hhouse/egs++/dso/$$my_machine -legspp -legs_input_struct # Relies on LD_LIBRARY_PATH UNAME = $$system(getconf LONG_BIT) contains( UNAME, 64 ){ message( "-> 64 bit ($$SNAME)" ) diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 5d3bd48ab..d50243965 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -44,6 +44,8 @@ #include "egs_input.h" #include "egs_ausgab_object.h" #include "ausgab_objects/egs_dose_scoring/egs_dose_scoring.h" +#include "egs_library.h" +#include "egs_input_struct.h" #include #include @@ -68,6 +70,25 @@ using namespace std; #define M_PI 3.14159265358979323846 #endif +typedef EGS_Application *(*createAppFunction)(int argc, char **argv); +typedef EGS_BaseGeometry *(*createGeomFunction)(); +typedef EGS_BaseSource *(*isSourceFunction)(); +typedef shared_ptr (*getInputsFunction)(); + +#ifdef WIN32 + #ifdef CYGWIN + const char fs = '/'; + #else + const char fs = '\\'; + #endif + string lib_prefix = ""; + string lib_suffix = ".dll"; +#else + const char fs = '/'; + string lib_prefix = "lib"; + string lib_suffix = ".so"; +#endif + static unsigned char standard_red[] = { 255, 0, 0, 0, 255, 255, 128, 0, 0, 0, 128, 128, 191, 80, 0, 0, 0, 0, 85, 255, 192, 128 @@ -175,6 +196,137 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Add the clipping planes widget to the designated layout clipLayout->addWidget(cplanes); + // Initialize the editor and syntax highlighter + egsinpEdit = new EGS_Editor(); + editorLayout->addWidget(egsinpEdit); + highlighter = new EGS_Highlighter(egsinpEdit->document()); + + // Load an egs++ application to parse the input file + string app_name; + int appc = 5; + char* appv[] = { "egspp", "-a", "tutor7pp", "-i", "tracks1.egsinp", "-p", "tutor_data"}; + + // Appv: %s -a application [-p pegs_file] [-i input_file] [-o output_file] [-b] [-P number_of_parallel_jobs] [-j job_index] + if (!EGS_Application::getArgument(appc,appv,"-a","--application",app_name)) { + egsFatal("test fail\n\n"); + } + + string lib_dir; + EGS_Application::checkEnvironmentVar(appc,appv,"-e","--egs-home","EGS_HOME",lib_dir); + lib_dir += "bin"; + lib_dir += fs; + lib_dir += CONFIG_NAME; + lib_dir += fs; + + EGS_Library egs_lib(app_name.c_str(),lib_dir.c_str()); + if (!egs_lib.load()) egsFatal("\n%s: Failed to load the %s application library from %s\n\n", + appv[0],app_name.c_str(),lib_dir.c_str()); + + createAppFunction createApp = (createAppFunction) egs_lib.resolve("createApplication"); + if (!createApp) egsFatal("\n%s: Failed to resolve the address of the 'createApplication' function" + " in the application library %s\n\n",appv[0],egs_lib.libraryFile()); + + EGS_Application *app = createApp(appc,appv); + if (!app) { + egsFatal("\n%s: Failed to construct the application %s\n\n",appv[0],app_name.c_str()); + } + egsInformation("Testapp %f\n",app->getRM()); + + // Get a list of all the libraries in the dso directory + string dso_dir; + EGS_Application::checkEnvironmentVar(appc,appv,"-H","--hen-house","HEN_HOUSE",dso_dir); + dso_dir += "egs++"; + dso_dir += fs; + dso_dir += "dso"; + dso_dir += fs; + dso_dir += CONFIG_NAME; + dso_dir += fs; + + QDir directory(dso_dir.c_str()); + QStringList libraries = directory.entryList(QStringList() << (lib_prefix+"*"+lib_suffix).c_str(), QDir::Files); + QStringList geomLibs, sourceLibs; + + // For each library, try to load it and determine if it is geometry or source + for(const auto& lib : libraries) { + // Remove the extension + QString libName = lib.left(lib.lastIndexOf(".")); + // Remove the prefix (EGS_Library adds it automatically) + libName = libName.right(libName.length() - lib_prefix.length()); + + egsInformation("testlib trying %s\n", libName.toLatin1().data()); + + EGS_Library egs_lib(libName.toLatin1().data(),dso_dir.c_str()); + if (!egs_lib.load()) { + continue; + } + + createGeomFunction createGeom = (createGeomFunction) egs_lib.resolve("createGeometry"); + if (createGeom) { + /*EGS_BaseGeometry *geom = createGeom(); + EGS_BlockInput *inputBlock = geom->getInputBlock(); + + geomLibs.append(libName); + + egsInformation("test1a\n"); + vector singleInputs = inputBlock->getSingleInputs(); + egsInformation("test1\n"); + for(auto& inp : singleInputs) { + const vector vals = inp.getValues(); + egsInformation("test %s\n", inp.getAttribute().c_str()); + for(auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + delete inputBlock; + delete geom;*/ + + getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); + egsInformation(" testgeom %s\n",libName.toLatin1().data()); + if(getInputs) { + + shared_ptr geom = getInputs(); + if(geom) { + // Only add geometries to the list that have a function + // to get the input template + geomLibs.append(libName); + + geomTemplates.push_back(geom); + + vector singleInputs = geom->getSingleInputs(); + for(auto& inp : singleInputs) { + const vector vals = inp.getValues(); + egsInformation(" single %s\n", inp.getAttribute().c_str()); + for(auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + + vector> inputBlocks = geom->getBlockInputs(); + for(auto& block : inputBlocks) { + egsInformation(" block %s\n", block->getTitle().c_str()); + vector singleInputs = block->getSingleInputs(); + for(auto& inp : singleInputs) { + const vector vals = inp.getValues(); + egsInformation(" single %s\n", inp.getAttribute().c_str()); + for(auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + } + } + } + } + + bool isSource = (bool) egs_lib.resolve("createSource"); + if (isSource) { + sourceLibs.append(libName); + } + } + + // Populate the geometry and simulation template lists + comboBox_geomTemplate->addItems(geomLibs); + comboBox_simTemplate->addItems(sourceLibs); + // set the widget to show near the left-upper corner of the screen move(QPoint(25,25)); } @@ -225,7 +377,7 @@ bool GeometryViewControl::loadInput(bool reloading, EGS_BaseGeometry *simGeom) { // check that the file (still) exists QFile file(filename); if (!file.exists()) { - egsWarning("\nFile %s does not exist anymore!\n\n",filename.toUtf8().constData()); + egsWarning("\nInput file %s does not exist!\n\n",filename.toUtf8().constData()); return false; } @@ -411,6 +563,11 @@ bool GeometryViewControl::loadInput(bool reloading, EGS_BaseGeometry *simGeom) { // See if any of the dose checkboxes are checked doseCheckbox_toggled(); + // Load the egsinp file into the editor + if (file.open(QFile::ReadOnly | QFile::Text)) { + egsinpEdit->setPlainText(file.readAll()); + } + return true; } @@ -1074,6 +1231,26 @@ void GeometryViewControl::loadConfig(QString configFilename) { updateView(true); } +void GeometryViewControl::saveEgsinp() { +#ifdef VIEW_DEBUG + egsWarning("In saveEgsinp()\n"); +#endif + + // Prompt the user for a filename and open the file for writing + QString newFilename = QFileDialog::getSaveFileName(this, "Save input file as...", filename); + QFile egsinpFile(newFilename); + if (!egsinpFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + return; + } + QTextStream out(&egsinpFile); + + // Write the text from the editor window + out << egsinpEdit->toPlainText() << flush; + + // Reload the input so that the changes are recognized + reloadInput(); +} + void GeometryViewControl::setFilename(QString str) { filename = str; } @@ -2932,6 +3109,8 @@ void GeometryViewControl::enlargeFont() { controlsText->selectAll(); controlsText->setFontPointSize(controlsFont.pointSize() + 1); controlsText->setTextCursor(cursor); + + egsinpEdit->zoomIn(); } void GeometryViewControl::shrinkFont() { @@ -2946,6 +3125,8 @@ void GeometryViewControl::shrinkFont() { controlsText->selectAll(); controlsText->setFontPointSize(controlsFont.pointSize() - 1); controlsText->setTextCursor(cursor); + + egsinpEdit->zoomOut(); } void GeometryViewControl::setFontSize(int size) { @@ -2962,3 +3143,17 @@ void GeometryViewControl::setFontSize(int size) { controlsText->setTextCursor(cursor); } +void GeometryViewControl::insertGeomTemplate(int ind) { + QString selection = comboBox_geomTemplate->itemText(ind); + + QTextCursor cursor(egsinpEdit->textCursor()); + egsinpEdit->insertPlainText(selection); +} + +void GeometryViewControl::insertSimTemplate(int ind) { + QString selection = comboBox_simTemplate->itemText(ind); + + QTextCursor cursor(egsinpEdit->textCursor()); + egsinpEdit->insertPlainText(selection); +} + diff --git a/HEN_HOUSE/egs++/view/viewcontrol.h b/HEN_HOUSE/egs++/view/viewcontrol.h index 9d594683e..346e03d4e 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -39,6 +39,9 @@ #include #include "egs_user_color.h" #include "egs_vector.h" +#include "egs_highlighter.h" +#include "egs_editor.h" +#include "egs_advanced_application.h" #include @@ -85,6 +88,7 @@ public slots: virtual void loadDose(); virtual void loadConfig(); virtual void saveConfig(); + virtual void saveEgsinp(); virtual void updateSimulationGeometry(int ind); virtual void checkboxAxes(bool toggle); virtual void checkboxAxesLabels(bool toggle); @@ -144,6 +148,8 @@ public slots: virtual void changeTrackMaxE(int t); virtual void changeTrackMaxPo(int t); virtual void updateTracks(vector ntracks); + virtual void insertGeomTemplate(int ind); + virtual void insertSimTemplate(int ind); private: @@ -200,7 +206,11 @@ public slots: energyScaling; vector> scoreArrays; vector geometryNames; + vector> geomTemplates; EGS_BaseGeometry *origSimGeom; + EGS_Editor *egsinpEdit; + EGS_Highlighter *highlighter; + EGS_AdvancedApplication *egsApp; protected slots: diff --git a/HEN_HOUSE/egs++/view/viewcontrol.ui b/HEN_HOUSE/egs++/view/viewcontrol.ui index 04af2e65c..5c206ac72 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui +++ b/HEN_HOUSE/egs++/view/viewcontrol.ui @@ -67,7 +67,7 @@ 0 - + 0 @@ -93,7 +93,7 @@ 0 0 671 - 563 + 567 @@ -118,7 +118,7 @@ - 0 + 4 @@ -157,7 +157,7 @@ - Simulation geometry + View geometry @@ -433,6 +433,14 @@ true + + + 0 + 0 + 297 + 189 + + @@ -1640,15 +1648,15 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Rotate: </span><span style=" font-size:10pt;">hold left MB</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Zoom:</span><span style=" font-size:10pt;"> scroll or hold middle MB</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Pan: </span><span style=" font-size:10pt;">Ctrl + left MB</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Roll:</span><span style=" font-size:10pt;"> Shift + left MB</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Set rotation point:</span><span style=" font-size:10pt;"> double left MB</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Home:</span><span style=" font-size:10pt;"> Home</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Set home:</span><span style=" font-size:10pt;"> Alt + Home</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Look along X (Y or Z): </span><span style=" font-size:10pt;">x (y or z)</span></p></body></html> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; font-weight:600;">Rotate: </span><span style=" font-family:'Cantarell'; font-size:10pt;">hold left MB</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; font-weight:600;">Zoom:</span><span style=" font-family:'Cantarell'; font-size:10pt;"> scroll or hold middle MB</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; font-weight:600;">Pan: </span><span style=" font-family:'Cantarell'; font-size:10pt;">Ctrl + left MB</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; font-weight:600;">Roll:</span><span style=" font-family:'Cantarell'; font-size:10pt;"> Shift + left MB</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; font-weight:600;">Set rotation point:</span><span style=" font-family:'Cantarell'; font-size:10pt;"> double left MB</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; font-weight:600;">Home:</span><span style=" font-family:'Cantarell'; font-size:10pt;"> Home</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; font-weight:600;">Set home:</span><span style=" font-family:'Cantarell'; font-size:10pt;"> Alt + Home</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; font-weight:600;">Look along X (Y or Z): </span><span style=" font-family:'Cantarell'; font-size:10pt;">x (y or z)</span></p></body></html> @@ -1659,6 +1667,61 @@ p, li { white-space: pre-wrap; } + + + + 0 + 0 + + + + Editor + + + + + + + + QLayout::SetMaximumSize + + + + + + 0 + 0 + + + + Insert template: + + + + + + + + Geometry + + + + + + + + + Simulation + + + + + + + + + + @@ -1675,7 +1738,7 @@ p, li { white-space: pre-wrap; } 0 0 675 - 25 + 21 @@ -1687,6 +1750,7 @@ p, li { white-space: pre-wrap; } + @@ -1706,7 +1770,7 @@ p, li { white-space: pre-wrap; } - &Open... + &Open egsinp... Ctrl+O @@ -1722,7 +1786,7 @@ p, li { white-space: pre-wrap; } - Save &image... + Save &image Ctrl+I @@ -1730,10 +1794,10 @@ p, li { white-space: pre-wrap; } - &Save settings... + Save settin&gs - Ctrl+S + Ctrl+G @@ -1770,7 +1834,7 @@ p, li { white-space: pre-wrap; } - Open &dose... + Open 3d&dose... Ctrl+D @@ -1778,12 +1842,20 @@ p, li { white-space: pre-wrap; } - Open trac&ks... + Open ptrac&ks... Ctrl+K + + + &Save egsinp + + + Ctrl+S + + @@ -2176,6 +2248,22 @@ p, li { white-space: pre-wrap; } + + actionSave_egsinp + triggered() + GeometryViewControl + saveEgsinp() + + + -1 + -1 + + + 20 + 20 + + + showPhotonsCheckbox toggled(bool) @@ -2400,6 +2488,38 @@ p, li { white-space: pre-wrap; } + + comboBox_simTemplate + activated(int) + GeometryViewControl + insertSimTemplate(int) + + + 20 + 20 + + + 20 + 20 + + + + + comboBox_geomTemplate + activated(int) + GeometryViewControl + insertGeomTemplate(int) + + + 20 + 20 + + + 20 + 20 + + + ambientLight sliderPressed() From 439a0dca0e5738018a8bbc1434b6127baac93ece Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 13 Dec 2019 11:30:39 -0500 Subject: [PATCH 02/40] Non-working temporary commit --- HEN_HOUSE/egs++/egs_input_struct.cpp | 55 +++++++ HEN_HOUSE/egs++/egs_input_struct.h | 10 +- HEN_HOUSE/egs++/view/egs_editor.cpp | 192 +++++++++++++++-------- HEN_HOUSE/egs++/view/egs_editor.h | 13 +- HEN_HOUSE/egs++/view/egs_highlighter.cpp | 3 +- HEN_HOUSE/egs++/view/egs_highlighter.h | 6 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 29 ++-- HEN_HOUSE/egs++/view/viewcontrol.h | 1 + 8 files changed, 220 insertions(+), 89 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index b1cbc25f4..e79f50016 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -42,6 +42,32 @@ EGS_InputStruct::EGS_InputStruct() {} EGS_InputStruct::~EGS_InputStruct() {} +void EGS_InputStruct::addBlockInput(shared_ptr block) { + blockInputs.push_back(block); +} + +void EGS_InputStruct::addBlockInputs(vector> blocks) { + egsInformation("testA EGS_InputStruct::addBlockInputs\n"); + blockInputs.insert(blockInputs.end(), blocks.begin(), blocks.end()); +} + +shared_ptr EGS_InputStruct::getLibraryBlock(string blockTitle, string libraryName) { + // Loop through each input block in the structure to find the library with + // the matching name + egsInformation("testA EGS_InputStruct::getLibraryBlock\n"); + //shared_ptr libraryBlock; + //shared_ptr libraryBlock = make_shared("geometry"); + //auto libraryBlock = make_shared(); +// for(auto& block : blockInputs) { +// libraryBlock = block->getLibraryBlock(blockTitle, libraryName); +// egsInformation("testB EGS_InputStruct::getLibraryBlock\n"); +// if(libraryBlock) { +// break; +// } +// } + return nullptr; +} + EGS_BlockInput::EGS_BlockInput() {} EGS_BlockInput::EGS_BlockInput(string blockTit, bool isReq, shared_ptr par) { @@ -99,6 +125,35 @@ shared_ptr EGS_BlockInput::getParent() { return parent; } +shared_ptr EGS_BlockInput::getLibraryBlock(string blockTitle, string libraryName) { + egsInformation("test EGS_BlockInput::getLibraryBlock\n"); + //shared_ptr libraryBlock(new EGS_BlockInput); + auto libraryBlock = make_shared(); + + +// // First search the singleInputs for the library name +// // only if the block title matches (e.g. it's a geometry, or a source) +// if(this->getTitle() == blockTitle) { +// egsInformation("test2 EGS_BlockInput::getLibraryBlock\n"); +// for(auto& inp : singleInputs) { +// if(inp.getAttribute() == libraryName) { +// egsInformation("test3 EGS_BlockInput::getLibraryBlock\n"); +// return shared_ptr(this); +// } +// } +// } +// +// // If not found, go through input blocks +// for(auto& block : blockInputs) { +// libraryBlock = block->getLibraryBlock(blockTitle, libraryName); +// if(libraryBlock) { +// egsInformation("test4 EGS_BlockInput::getLibraryBlock\n"); +// return libraryBlock; +// } +// } + return libraryBlock; +} + EGS_SingleInput::EGS_SingleInput() {} EGS_SingleInput::EGS_SingleInput(string attr, bool isReq, const string desc, const vector vals) { diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index 54b0d0fa5..6b838c147 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -90,6 +90,7 @@ class EGS_EXPORT EGS_BlockInput EGS_SingleInput getSingleInput(string attr); void setParent(shared_ptr par); shared_ptr getParent(); + shared_ptr getLibraryBlock(string blockTitle, string libraryName); private: @@ -107,7 +108,14 @@ class EGS_EXPORT EGS_InputStruct { EGS_InputStruct(); ~EGS_InputStruct(); - void addBlockInput(EGS_InputStruct *parent, string blockTit, bool isReq); + void addBlockInput(shared_ptr block); + //void addBlockInput(string blockTit, bool isReq); + void addBlockInputs(vector> blocks); + shared_ptr getLibraryBlock(string blockTitle, string libraryName); + +private: + + vector> blockInputs; }; diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index c4baa74b4..74df337e6 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -2,14 +2,17 @@ #include #include "egs_editor.h" +#include "egs_functions.h" -EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) -{ +EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { this->setFrameShape(QFrame::NoFrame); installEventFilter(this); viewport()->installEventFilter(this); + const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); + this->setFont(fixedFont); + lineNumberArea = new LineNumberArea(this); connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); @@ -21,10 +24,19 @@ EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) highlightCurrentLine(); } +EGS_Editor::~EGS_Editor() { + if(lineNumberArea) { + delete lineNumberArea; + } +} +void EGS_Editor::setInputStruct(shared_ptr inp) { + cout << "test EGS_Editor::setInputStruct" << endl; + inputStruct = *inp; + shared_ptr libraryBlock = inputStruct.getLibraryBlock("",""); +} -int EGS_Editor::lineNumberAreaWidth() -{ +int EGS_Editor::lineNumberAreaWidth() { int digits = 1; int max = qMax(1, blockCount()); while (max >= 10) { @@ -39,28 +51,28 @@ int EGS_Editor::lineNumberAreaWidth() -void EGS_Editor::updateLineNumberAreaWidth(int /* newBlockCount */) -{ +void EGS_Editor::updateLineNumberAreaWidth(int /* newBlockCount */) { setViewportMargins(lineNumberAreaWidth()+5, 0, 0, 0); } -void EGS_Editor::updateLineNumberArea(const QRect &rect, int dy) -{ - if (dy) +void EGS_Editor::updateLineNumberArea(const QRect &rect, int dy) { + if (dy) { lineNumberArea->scroll(0, dy); - else + } + else { lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + } - if (rect.contains(viewport()->rect())) + if (rect.contains(viewport()->rect())) { updateLineNumberAreaWidth(0); + } } -void EGS_Editor::resizeEvent(QResizeEvent *e) -{ +void EGS_Editor::resizeEvent(QResizeEvent *e) { QPlainTextEdit::resizeEvent(e); QRect cr = contentsRect(); @@ -69,8 +81,7 @@ void EGS_Editor::resizeEvent(QResizeEvent *e) -void EGS_Editor::highlightCurrentLine() -{ +void EGS_Editor::highlightCurrentLine() { QList extraSelections; if (!isReadOnly()) { @@ -90,18 +101,17 @@ void EGS_Editor::highlightCurrentLine() -void EGS_Editor::autoComplete() -{ - QTextCursor cursor = textCursor(); - int clickedPosition = cursor.position(); +void EGS_Editor::autoComplete() { + // Get the input structure + EGS_BlockInput inp = getBlockInput(); // Get the text of the current line + QTextCursor cursor = textCursor(); cursor.movePosition(QTextCursor::StartOfBlock); cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); QString selectedText = cursor.selectedText(); - if(selectedText.simplified() == "library =") { - //insertPlainText(selectedText); + if (selectedText.simplified() == "library = ") { // Init popup QListView *popup = new QListView; @@ -109,21 +119,19 @@ void EGS_Editor::autoComplete() popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); popup->setSelectionBehavior(QAbstractItemView::SelectRows); popup->setSelectionMode(QAbstractItemView::SingleSelection); - //popup->setModelColumn(d->column); - popup->setParent(nullptr); - // This option seems to take control of mouse + key inputs + popup->setFocusPolicy(Qt::NoFocus); + popup->installEventFilter(this); + + // The Qt::Popup option seems to take control of mouse + key inputs // essentially locking up the computer, beware! //popup->setWindowFlag(Qt::Popup); popup->setWindowFlag(Qt::ToolTip); - popup->setFocusPolicy(Qt::NoFocus); - - popup->installEventFilter(this); QObject::connect(popup, SIGNAL(clicked(QModelIndex)), - this, SLOT(insertCompletion(QModelIndex))); + this, SLOT(insertCompletion(QModelIndex))); QObject::connect(this, SIGNAL(cursorPositionChanged()), - popup, SLOT(hide())); + popup, SLOT(hide())); // // QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), // this, SLOT(_q_completionSelected(QItemSelection))); @@ -133,57 +141,43 @@ void EGS_Editor::autoComplete() model = new QStringListModel(this); // Make data - QStringList List; - List << "egs_box" << "egs_cd_geometry" << "egs_cones"; - model->setStringList(List); + QStringList itemList; + itemList << "egs_box" << "egs_cd_geometry" << "egs_cones" << "eii_iii"; + model->setStringList(itemList); popup->setModel(model); + popup->setFont(this->font()); + + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } + } // Create a selection popup - QRect rect; //tmp rect int maxVisibleItems = 6; const QRect screen = this->frameRect(); - Qt::LayoutDirection dir = this->layoutDirection(); QPoint pos; int rh, w; int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; QScrollBar *hsb = popup->horizontalScrollBar(); - if (hsb && hsb->isVisible()) + if (hsb && hsb->isVisible()) { h += popup->horizontalScrollBar()->sizeHint().height(); - - if (rect.isValid()) { - rh = rect.height(); - w = rect.width(); - pos = this->mapToGlobal(dir == Qt::RightToLeft ? rect.bottomRight() : rect.bottomLeft()); - } else { - rh = this->height(); - pos = this->mapToGlobal(QPoint(0, this->height() - 2)); - w = this->width(); } - // Constrain the box size to the window - if (w > screen.width()) - w = screen.width(); - if ((pos.x() + w) > (screen.x() + screen.width())) - pos.setX(screen.x() + screen.width() - w); - if (pos.x() < screen.x()) - pos.setX(screen.x()); - - int top = pos.y() - rh - screen.top() + 2; - int bottom = screen.bottom() - pos.y(); - h = qMax(h, popup->minimumHeight()); - if (h > bottom) { - h = qMin(qMax(top, bottom), h); - - if (top > bottom) - pos.setY(pos.y() - h - rh + 2); - } + rh = this->height(); + pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + w = 20 + strLength * fm.horizontalAdvance('9'); popup->setGeometry(pos.x(), pos.y(), w, h); // Show the popup - if (!popup->isVisible()) + if (!popup->isVisible()) { popup->show(); + } } } @@ -192,10 +186,76 @@ void EGS_Editor::insertCompletion(QModelIndex index) { //insertPlainText(index); } +// TODO: on clicking a new position in doc +// - get nearest :start, load inputstruct (for geom/src, get library first) +EGS_BlockInput EGS_Editor::getBlockInput() { + cout << "test getBlockInput " << endl; + shared_ptr libraryBlock = inputStruct.getLibraryBlock("",""); + + QString library, blockTitle; + vector stopList; + for(QTextBlock block = textCursor().block(); block.isValid(); block = block.previous()) { + QString line = block.text().simplified(); + + // Get block library for input blocks based on a shared library + // e.g. geometries and sources + int pos = line.lastIndexOf("library ="); + if(pos >= 0) { + pos += 9; + library = line.mid(pos, line.size()-pos).simplified(); + cout << "test1 " << library.toLatin1().data() << endl; + } + + // Get block title + pos = line.lastIndexOf(":start "); + if(pos >= 0) { + pos += 7; + int endPos = line.indexOf(":",pos); + if(endPos > 0) { + blockTitle = line.mid(pos, endPos-pos); + //cout << "test2 " << blockTitle.toLatin1().data() << endl; + if(stopList.size() > 0 && blockTitle == stopList.back()) { + stopList.pop_back(); + blockTitle.clear(); + } else { + break; + } + } + } + // Save a vector of blocks that have already been closed + // This means both a matching :start and :stop are above the cursor + // so we're not inside the block + pos = line.lastIndexOf(":stop "); + if(pos >= 0) { + pos += 6; + int endPos = line.indexOf(":",pos); + if(endPos > 0) { + QString stopTitle = line.mid(pos, endPos-pos); + stopList.push_back(stopTitle); + } + } + } + + // If we got the library tag, we can directly look up this input block structure + shared_ptr inputBlock; + cout << "test4a " << blockTitle.toLatin1().data() << endl; + +// if(library.size() > 0) { +// cout << "test3a " << endl; +// inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); +// cout << "test3b " << endl; +// if(inputBlock) { +// cout << "test3 " << inputBlock->getTitle().c_str() << endl; +// } +// } + cout << "test4b " << endl; + + + return EGS_BlockInput(); +} -void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) -{ +void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) { QPainter painter(lineNumberArea); //painter.fillRect(event->rect(), QColor(Qt::lightGray).lighter(110)); @@ -227,8 +287,8 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { // track `Ctrl + Click` in the text edit if ((obj == this->viewport()) && - (mouseEvent->button() == Qt::LeftButton) && - (QGuiApplication::keyboardModifiers() == Qt::ControlModifier)) { + (mouseEvent->button() == Qt::LeftButton) && + (QGuiApplication::keyboardModifiers() == Qt::ControlModifier)) { // open the link (if any) at the current position //openLinkAtCursorPosition(); return true; diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h index 951a426b5..9e8bdcae6 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.h +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -6,6 +6,8 @@ #include #include +#include "egs_input_struct.h" + class QPaintEvent; class QResizeEvent; class QSize; @@ -13,15 +15,16 @@ class QWidget; class LineNumberArea; -class EGS_Editor : public QPlainTextEdit -{ +class EGS_Editor : public QPlainTextEdit { Q_OBJECT public: EGS_Editor(QWidget *parent = 0); + ~EGS_Editor(); void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth(); + void setInputStruct(shared_ptr inp); protected: void resizeEvent(QResizeEvent *event) override; @@ -35,12 +38,14 @@ private slots: void updateLineNumberArea(const QRect &, int); private: + EGS_BlockInput getBlockInput(); + QWidget *lineNumberArea; + EGS_InputStruct inputStruct; }; -class LineNumberArea : public QWidget -{ +class LineNumberArea : public QWidget { public: LineNumberArea(EGS_Editor *editor) : QWidget(editor) { egsEditor = editor; diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.cpp b/HEN_HOUSE/egs++/view/egs_highlighter.cpp index 9b7cbf394..2724f1cf5 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.cpp +++ b/HEN_HOUSE/egs++/view/egs_highlighter.cpp @@ -91,8 +91,7 @@ EGS_Highlighter::EGS_Highlighter(QTextDocument *parent) : QSyntaxHighlighter(par //commentEndExpression = QRegularExpression("\\*/"); } -void EGS_Highlighter::highlightBlock(const QString &text) -{ +void EGS_Highlighter::highlightBlock(const QString &text) { foreach (const HighlightingRule &rule, highlightingRules) { QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); while (matchIterator.hasNext()) { diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.h b/HEN_HOUSE/egs++/view/egs_highlighter.h index aba79d181..322024166 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.h +++ b/HEN_HOUSE/egs++/view/egs_highlighter.h @@ -37,8 +37,7 @@ class QTextDocument; -class EGS_Highlighter : public QSyntaxHighlighter -{ +class EGS_Highlighter : public QSyntaxHighlighter { Q_OBJECT public: explicit EGS_Highlighter(QTextDocument *parent = nullptr); @@ -47,8 +46,7 @@ class EGS_Highlighter : public QSyntaxHighlighter void highlightBlock(const QString &text) override; private: - struct HighlightingRule - { + struct HighlightingRule { QRegularExpression pattern; QTextCharFormat format; }; diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index d50243965..01f57f7ec 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -204,7 +204,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Load an egs++ application to parse the input file string app_name; int appc = 5; - char* appv[] = { "egspp", "-a", "tutor7pp", "-i", "tracks1.egsinp", "-p", "tutor_data"}; + char *appv[] = { "egspp", "-a", "tutor7pp", "-i", "tracks1.egsinp", "-p", "tutor_data"}; // Appv: %s -a application [-p pegs_file] [-i input_file] [-o output_file] [-b] [-P number_of_parallel_jobs] [-j job_index] if (!EGS_Application::getArgument(appc,appv,"-a","--application",app_name)) { @@ -246,8 +246,10 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) QStringList libraries = directory.entryList(QStringList() << (lib_prefix+"*"+lib_suffix).c_str(), QDir::Files); QStringList geomLibs, sourceLibs; + inputStruct = make_shared(); + // For each library, try to load it and determine if it is geometry or source - for(const auto& lib : libraries) { + for (const auto &lib : libraries) { // Remove the extension QString libName = lib.left(lib.lastIndexOf(".")); // Remove the prefix (EGS_Library adds it automatically) @@ -282,10 +284,10 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); egsInformation(" testgeom %s\n",libName.toLatin1().data()); - if(getInputs) { + if (getInputs) { shared_ptr geom = getInputs(); - if(geom) { + if (geom) { // Only add geometries to the list that have a function // to get the input template geomLibs.append(libName); @@ -293,22 +295,22 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) geomTemplates.push_back(geom); vector singleInputs = geom->getSingleInputs(); - for(auto& inp : singleInputs) { + for (auto &inp : singleInputs) { const vector vals = inp.getValues(); egsInformation(" single %s\n", inp.getAttribute().c_str()); - for(auto&& val : vals) { + for (auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } } vector> inputBlocks = geom->getBlockInputs(); - for(auto& block : inputBlocks) { + for (auto &block : inputBlocks) { egsInformation(" block %s\n", block->getTitle().c_str()); vector singleInputs = block->getSingleInputs(); - for(auto& inp : singleInputs) { + for (auto &inp : singleInputs) { const vector vals = inp.getValues(); egsInformation(" single %s\n", inp.getAttribute().c_str()); - for(auto&& val : vals) { + for (auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } } @@ -323,12 +325,12 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } + inputStruct->addBlockInputs(geomTemplates); + egsinpEdit->setInputStruct(inputStruct); + // Populate the geometry and simulation template lists comboBox_geomTemplate->addItems(geomLibs); comboBox_simTemplate->addItems(sourceLibs); - - // set the widget to show near the left-upper corner of the screen - move(QPoint(25,25)); } GeometryViewControl::~GeometryViewControl() { @@ -347,6 +349,9 @@ GeometryViewControl::~GeometryViewControl() { delete EGS_AusgabObject::getObject(i); } } + if(highlighter) { + delete highlighter; + } } void GeometryViewControl::selectInput() { diff --git a/HEN_HOUSE/egs++/view/viewcontrol.h b/HEN_HOUSE/egs++/view/viewcontrol.h index 346e03d4e..7a80cd03f 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -211,6 +211,7 @@ public slots: EGS_Editor *egsinpEdit; EGS_Highlighter *highlighter; EGS_AdvancedApplication *egsApp; + shared_ptr inputStruct; protected slots: From 1caf68c6f59f5c955f1859bbab09753475446508 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Sat, 3 Aug 2019 09:01:04 -0400 Subject: [PATCH 03/40] Add a text editor to egs_view Initial commit with very basic groundwork for a text editor in egs_view. Adds some syntax highlighting, and begins building a structure in geometries to return input keys. Includes debug statements and nonsense behaviour. --- HEN_HOUSE/egs++/egs_input_struct.cpp | 55 ------- HEN_HOUSE/egs++/egs_input_struct.h | 10 +- HEN_HOUSE/egs++/view/egs_editor.cpp | 192 ++++++++--------------- HEN_HOUSE/egs++/view/egs_editor.h | 13 +- HEN_HOUSE/egs++/view/egs_highlighter.cpp | 3 +- HEN_HOUSE/egs++/view/egs_highlighter.h | 6 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 26 ++- HEN_HOUSE/egs++/view/viewcontrol.h | 1 - 8 files changed, 89 insertions(+), 217 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index e79f50016..b1cbc25f4 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -42,32 +42,6 @@ EGS_InputStruct::EGS_InputStruct() {} EGS_InputStruct::~EGS_InputStruct() {} -void EGS_InputStruct::addBlockInput(shared_ptr block) { - blockInputs.push_back(block); -} - -void EGS_InputStruct::addBlockInputs(vector> blocks) { - egsInformation("testA EGS_InputStruct::addBlockInputs\n"); - blockInputs.insert(blockInputs.end(), blocks.begin(), blocks.end()); -} - -shared_ptr EGS_InputStruct::getLibraryBlock(string blockTitle, string libraryName) { - // Loop through each input block in the structure to find the library with - // the matching name - egsInformation("testA EGS_InputStruct::getLibraryBlock\n"); - //shared_ptr libraryBlock; - //shared_ptr libraryBlock = make_shared("geometry"); - //auto libraryBlock = make_shared(); -// for(auto& block : blockInputs) { -// libraryBlock = block->getLibraryBlock(blockTitle, libraryName); -// egsInformation("testB EGS_InputStruct::getLibraryBlock\n"); -// if(libraryBlock) { -// break; -// } -// } - return nullptr; -} - EGS_BlockInput::EGS_BlockInput() {} EGS_BlockInput::EGS_BlockInput(string blockTit, bool isReq, shared_ptr par) { @@ -125,35 +99,6 @@ shared_ptr EGS_BlockInput::getParent() { return parent; } -shared_ptr EGS_BlockInput::getLibraryBlock(string blockTitle, string libraryName) { - egsInformation("test EGS_BlockInput::getLibraryBlock\n"); - //shared_ptr libraryBlock(new EGS_BlockInput); - auto libraryBlock = make_shared(); - - -// // First search the singleInputs for the library name -// // only if the block title matches (e.g. it's a geometry, or a source) -// if(this->getTitle() == blockTitle) { -// egsInformation("test2 EGS_BlockInput::getLibraryBlock\n"); -// for(auto& inp : singleInputs) { -// if(inp.getAttribute() == libraryName) { -// egsInformation("test3 EGS_BlockInput::getLibraryBlock\n"); -// return shared_ptr(this); -// } -// } -// } -// -// // If not found, go through input blocks -// for(auto& block : blockInputs) { -// libraryBlock = block->getLibraryBlock(blockTitle, libraryName); -// if(libraryBlock) { -// egsInformation("test4 EGS_BlockInput::getLibraryBlock\n"); -// return libraryBlock; -// } -// } - return libraryBlock; -} - EGS_SingleInput::EGS_SingleInput() {} EGS_SingleInput::EGS_SingleInput(string attr, bool isReq, const string desc, const vector vals) { diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index 6b838c147..54b0d0fa5 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -90,7 +90,6 @@ class EGS_EXPORT EGS_BlockInput EGS_SingleInput getSingleInput(string attr); void setParent(shared_ptr par); shared_ptr getParent(); - shared_ptr getLibraryBlock(string blockTitle, string libraryName); private: @@ -108,14 +107,7 @@ class EGS_EXPORT EGS_InputStruct { EGS_InputStruct(); ~EGS_InputStruct(); - void addBlockInput(shared_ptr block); - //void addBlockInput(string blockTit, bool isReq); - void addBlockInputs(vector> blocks); - shared_ptr getLibraryBlock(string blockTitle, string libraryName); - -private: - - vector> blockInputs; + void addBlockInput(EGS_InputStruct *parent, string blockTit, bool isReq); }; diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 74df337e6..c4baa74b4 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -2,17 +2,14 @@ #include #include "egs_editor.h" -#include "egs_functions.h" -EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { +EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) +{ this->setFrameShape(QFrame::NoFrame); installEventFilter(this); viewport()->installEventFilter(this); - const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); - this->setFont(fixedFont); - lineNumberArea = new LineNumberArea(this); connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); @@ -24,19 +21,10 @@ EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { highlightCurrentLine(); } -EGS_Editor::~EGS_Editor() { - if(lineNumberArea) { - delete lineNumberArea; - } -} -void EGS_Editor::setInputStruct(shared_ptr inp) { - cout << "test EGS_Editor::setInputStruct" << endl; - inputStruct = *inp; - shared_ptr libraryBlock = inputStruct.getLibraryBlock("",""); -} -int EGS_Editor::lineNumberAreaWidth() { +int EGS_Editor::lineNumberAreaWidth() +{ int digits = 1; int max = qMax(1, blockCount()); while (max >= 10) { @@ -51,28 +39,28 @@ int EGS_Editor::lineNumberAreaWidth() { -void EGS_Editor::updateLineNumberAreaWidth(int /* newBlockCount */) { +void EGS_Editor::updateLineNumberAreaWidth(int /* newBlockCount */) +{ setViewportMargins(lineNumberAreaWidth()+5, 0, 0, 0); } -void EGS_Editor::updateLineNumberArea(const QRect &rect, int dy) { - if (dy) { +void EGS_Editor::updateLineNumberArea(const QRect &rect, int dy) +{ + if (dy) lineNumberArea->scroll(0, dy); - } - else { + else lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); - } - if (rect.contains(viewport()->rect())) { + if (rect.contains(viewport()->rect())) updateLineNumberAreaWidth(0); - } } -void EGS_Editor::resizeEvent(QResizeEvent *e) { +void EGS_Editor::resizeEvent(QResizeEvent *e) +{ QPlainTextEdit::resizeEvent(e); QRect cr = contentsRect(); @@ -81,7 +69,8 @@ void EGS_Editor::resizeEvent(QResizeEvent *e) { -void EGS_Editor::highlightCurrentLine() { +void EGS_Editor::highlightCurrentLine() +{ QList extraSelections; if (!isReadOnly()) { @@ -101,17 +90,18 @@ void EGS_Editor::highlightCurrentLine() { -void EGS_Editor::autoComplete() { - // Get the input structure - EGS_BlockInput inp = getBlockInput(); +void EGS_Editor::autoComplete() +{ + QTextCursor cursor = textCursor(); + int clickedPosition = cursor.position(); // Get the text of the current line - QTextCursor cursor = textCursor(); cursor.movePosition(QTextCursor::StartOfBlock); cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); QString selectedText = cursor.selectedText(); - if (selectedText.simplified() == "library = ") { + if(selectedText.simplified() == "library =") { + //insertPlainText(selectedText); // Init popup QListView *popup = new QListView; @@ -119,19 +109,21 @@ void EGS_Editor::autoComplete() { popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); popup->setSelectionBehavior(QAbstractItemView::SelectRows); popup->setSelectionMode(QAbstractItemView::SingleSelection); - popup->setParent(nullptr); - popup->setFocusPolicy(Qt::NoFocus); - popup->installEventFilter(this); + //popup->setModelColumn(d->column); - // The Qt::Popup option seems to take control of mouse + key inputs + popup->setParent(nullptr); + // This option seems to take control of mouse + key inputs // essentially locking up the computer, beware! //popup->setWindowFlag(Qt::Popup); popup->setWindowFlag(Qt::ToolTip); + popup->setFocusPolicy(Qt::NoFocus); + + popup->installEventFilter(this); QObject::connect(popup, SIGNAL(clicked(QModelIndex)), - this, SLOT(insertCompletion(QModelIndex))); + this, SLOT(insertCompletion(QModelIndex))); QObject::connect(this, SIGNAL(cursorPositionChanged()), - popup, SLOT(hide())); + popup, SLOT(hide())); // // QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), // this, SLOT(_q_completionSelected(QItemSelection))); @@ -141,43 +133,57 @@ void EGS_Editor::autoComplete() { model = new QStringListModel(this); // Make data - QStringList itemList; - itemList << "egs_box" << "egs_cd_geometry" << "egs_cones" << "eii_iii"; - model->setStringList(itemList); + QStringList List; + List << "egs_box" << "egs_cd_geometry" << "egs_cones"; + model->setStringList(List); popup->setModel(model); - popup->setFont(this->font()); - - // Get max string length - int strLength = 0; - for (auto &item: itemList) { - if (item.size() > strLength) { - strLength = item.size(); - } - } // Create a selection popup + QRect rect; //tmp rect int maxVisibleItems = 6; const QRect screen = this->frameRect(); + Qt::LayoutDirection dir = this->layoutDirection(); QPoint pos; int rh, w; int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; QScrollBar *hsb = popup->horizontalScrollBar(); - if (hsb && hsb->isVisible()) { + if (hsb && hsb->isVisible()) h += popup->horizontalScrollBar()->sizeHint().height(); + + if (rect.isValid()) { + rh = rect.height(); + w = rect.width(); + pos = this->mapToGlobal(dir == Qt::RightToLeft ? rect.bottomRight() : rect.bottomLeft()); + } else { + rh = this->height(); + pos = this->mapToGlobal(QPoint(0, this->height() - 2)); + w = this->width(); } - rh = this->height(); - pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); - QFontMetrics fm(popup->font()); - w = 20 + strLength * fm.horizontalAdvance('9'); + // Constrain the box size to the window + if (w > screen.width()) + w = screen.width(); + if ((pos.x() + w) > (screen.x() + screen.width())) + pos.setX(screen.x() + screen.width() - w); + if (pos.x() < screen.x()) + pos.setX(screen.x()); + + int top = pos.y() - rh - screen.top() + 2; + int bottom = screen.bottom() - pos.y(); + h = qMax(h, popup->minimumHeight()); + if (h > bottom) { + h = qMin(qMax(top, bottom), h); + + if (top > bottom) + pos.setY(pos.y() - h - rh + 2); + } popup->setGeometry(pos.x(), pos.y(), w, h); // Show the popup - if (!popup->isVisible()) { + if (!popup->isVisible()) popup->show(); - } } } @@ -186,76 +192,10 @@ void EGS_Editor::insertCompletion(QModelIndex index) { //insertPlainText(index); } -// TODO: on clicking a new position in doc -// - get nearest :start, load inputstruct (for geom/src, get library first) -EGS_BlockInput EGS_Editor::getBlockInput() { - cout << "test getBlockInput " << endl; - shared_ptr libraryBlock = inputStruct.getLibraryBlock("",""); - - QString library, blockTitle; - vector stopList; - for(QTextBlock block = textCursor().block(); block.isValid(); block = block.previous()) { - QString line = block.text().simplified(); - - // Get block library for input blocks based on a shared library - // e.g. geometries and sources - int pos = line.lastIndexOf("library ="); - if(pos >= 0) { - pos += 9; - library = line.mid(pos, line.size()-pos).simplified(); - cout << "test1 " << library.toLatin1().data() << endl; - } - - // Get block title - pos = line.lastIndexOf(":start "); - if(pos >= 0) { - pos += 7; - int endPos = line.indexOf(":",pos); - if(endPos > 0) { - blockTitle = line.mid(pos, endPos-pos); - //cout << "test2 " << blockTitle.toLatin1().data() << endl; - if(stopList.size() > 0 && blockTitle == stopList.back()) { - stopList.pop_back(); - blockTitle.clear(); - } else { - break; - } - } - } - // Save a vector of blocks that have already been closed - // This means both a matching :start and :stop are above the cursor - // so we're not inside the block - pos = line.lastIndexOf(":stop "); - if(pos >= 0) { - pos += 6; - int endPos = line.indexOf(":",pos); - if(endPos > 0) { - QString stopTitle = line.mid(pos, endPos-pos); - stopList.push_back(stopTitle); - } - } - } - - // If we got the library tag, we can directly look up this input block structure - shared_ptr inputBlock; - cout << "test4a " << blockTitle.toLatin1().data() << endl; - -// if(library.size() > 0) { -// cout << "test3a " << endl; -// inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); -// cout << "test3b " << endl; -// if(inputBlock) { -// cout << "test3 " << inputBlock->getTitle().c_str() << endl; -// } -// } - cout << "test4b " << endl; - - - return EGS_BlockInput(); -} -void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) { +void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) +{ QPainter painter(lineNumberArea); //painter.fillRect(event->rect(), QColor(Qt::lightGray).lighter(110)); @@ -287,8 +227,8 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { // track `Ctrl + Click` in the text edit if ((obj == this->viewport()) && - (mouseEvent->button() == Qt::LeftButton) && - (QGuiApplication::keyboardModifiers() == Qt::ControlModifier)) { + (mouseEvent->button() == Qt::LeftButton) && + (QGuiApplication::keyboardModifiers() == Qt::ControlModifier)) { // open the link (if any) at the current position //openLinkAtCursorPosition(); return true; diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h index 9e8bdcae6..951a426b5 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.h +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -6,8 +6,6 @@ #include #include -#include "egs_input_struct.h" - class QPaintEvent; class QResizeEvent; class QSize; @@ -15,16 +13,15 @@ class QWidget; class LineNumberArea; -class EGS_Editor : public QPlainTextEdit { +class EGS_Editor : public QPlainTextEdit +{ Q_OBJECT public: EGS_Editor(QWidget *parent = 0); - ~EGS_Editor(); void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth(); - void setInputStruct(shared_ptr inp); protected: void resizeEvent(QResizeEvent *event) override; @@ -38,14 +35,12 @@ private slots: void updateLineNumberArea(const QRect &, int); private: - EGS_BlockInput getBlockInput(); - QWidget *lineNumberArea; - EGS_InputStruct inputStruct; }; -class LineNumberArea : public QWidget { +class LineNumberArea : public QWidget +{ public: LineNumberArea(EGS_Editor *editor) : QWidget(editor) { egsEditor = editor; diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.cpp b/HEN_HOUSE/egs++/view/egs_highlighter.cpp index 2724f1cf5..9b7cbf394 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.cpp +++ b/HEN_HOUSE/egs++/view/egs_highlighter.cpp @@ -91,7 +91,8 @@ EGS_Highlighter::EGS_Highlighter(QTextDocument *parent) : QSyntaxHighlighter(par //commentEndExpression = QRegularExpression("\\*/"); } -void EGS_Highlighter::highlightBlock(const QString &text) { +void EGS_Highlighter::highlightBlock(const QString &text) +{ foreach (const HighlightingRule &rule, highlightingRules) { QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); while (matchIterator.hasNext()) { diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.h b/HEN_HOUSE/egs++/view/egs_highlighter.h index 322024166..aba79d181 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.h +++ b/HEN_HOUSE/egs++/view/egs_highlighter.h @@ -37,7 +37,8 @@ class QTextDocument; -class EGS_Highlighter : public QSyntaxHighlighter { +class EGS_Highlighter : public QSyntaxHighlighter +{ Q_OBJECT public: explicit EGS_Highlighter(QTextDocument *parent = nullptr); @@ -46,7 +47,8 @@ class EGS_Highlighter : public QSyntaxHighlighter { void highlightBlock(const QString &text) override; private: - struct HighlightingRule { + struct HighlightingRule + { QRegularExpression pattern; QTextCharFormat format; }; diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 01f57f7ec..a3cf61435 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -204,7 +204,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Load an egs++ application to parse the input file string app_name; int appc = 5; - char *appv[] = { "egspp", "-a", "tutor7pp", "-i", "tracks1.egsinp", "-p", "tutor_data"}; + char* appv[] = { "egspp", "-a", "tutor7pp", "-i", "tracks1.egsinp", "-p", "tutor_data"}; // Appv: %s -a application [-p pegs_file] [-i input_file] [-o output_file] [-b] [-P number_of_parallel_jobs] [-j job_index] if (!EGS_Application::getArgument(appc,appv,"-a","--application",app_name)) { @@ -246,10 +246,8 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) QStringList libraries = directory.entryList(QStringList() << (lib_prefix+"*"+lib_suffix).c_str(), QDir::Files); QStringList geomLibs, sourceLibs; - inputStruct = make_shared(); - // For each library, try to load it and determine if it is geometry or source - for (const auto &lib : libraries) { + for(const auto& lib : libraries) { // Remove the extension QString libName = lib.left(lib.lastIndexOf(".")); // Remove the prefix (EGS_Library adds it automatically) @@ -284,10 +282,10 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); egsInformation(" testgeom %s\n",libName.toLatin1().data()); - if (getInputs) { + if(getInputs) { shared_ptr geom = getInputs(); - if (geom) { + if(geom) { // Only add geometries to the list that have a function // to get the input template geomLibs.append(libName); @@ -295,22 +293,22 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) geomTemplates.push_back(geom); vector singleInputs = geom->getSingleInputs(); - for (auto &inp : singleInputs) { + for(auto& inp : singleInputs) { const vector vals = inp.getValues(); egsInformation(" single %s\n", inp.getAttribute().c_str()); - for (auto&& val : vals) { + for(auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } } vector> inputBlocks = geom->getBlockInputs(); - for (auto &block : inputBlocks) { + for(auto& block : inputBlocks) { egsInformation(" block %s\n", block->getTitle().c_str()); vector singleInputs = block->getSingleInputs(); - for (auto &inp : singleInputs) { + for(auto& inp : singleInputs) { const vector vals = inp.getValues(); egsInformation(" single %s\n", inp.getAttribute().c_str()); - for (auto&& val : vals) { + for(auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } } @@ -325,12 +323,12 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } - inputStruct->addBlockInputs(geomTemplates); - egsinpEdit->setInputStruct(inputStruct); - // Populate the geometry and simulation template lists comboBox_geomTemplate->addItems(geomLibs); comboBox_simTemplate->addItems(sourceLibs); + + // set the widget to show near the left-upper corner of the screen + move(QPoint(25,25)); } GeometryViewControl::~GeometryViewControl() { diff --git a/HEN_HOUSE/egs++/view/viewcontrol.h b/HEN_HOUSE/egs++/view/viewcontrol.h index 7a80cd03f..346e03d4e 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -211,7 +211,6 @@ public slots: EGS_Editor *egsinpEdit; EGS_Highlighter *highlighter; EGS_AdvancedApplication *egsApp; - shared_ptr inputStruct; protected slots: From 0d03724d9b41015506b3bdbd06d9738a635e8e4c Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 13 Dec 2019 11:30:39 -0500 Subject: [PATCH 04/40] Non-working temporary commit --- HEN_HOUSE/egs++/egs_input_struct.cpp | 50 +++++++ HEN_HOUSE/egs++/egs_input_struct.h | 10 +- HEN_HOUSE/egs++/view/egs_editor.cpp | 169 ++++++++++++++--------- HEN_HOUSE/egs++/view/egs_editor.h | 13 +- HEN_HOUSE/egs++/view/egs_highlighter.cpp | 3 +- HEN_HOUSE/egs++/view/egs_highlighter.h | 6 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 26 ++-- 7 files changed, 188 insertions(+), 89 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index b1cbc25f4..f7c50e36d 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -42,6 +42,30 @@ EGS_InputStruct::EGS_InputStruct() {} EGS_InputStruct::~EGS_InputStruct() {} +void EGS_InputStruct::addBlockInput(shared_ptr block) { + blockInputs.push_back(block); +} + +void EGS_InputStruct::addBlockInputs(vector> blocks) { + egsInformation("testA EGS_InputStruct::addBlockInputs\n"); + blockInputs.insert(blockInputs.end(), blocks.begin(), blocks.end()); +} + +shared_ptr EGS_InputStruct::getLibraryBlock(string blockTitle, string libraryName) { + // Loop through each input block in the structure to find the library with + // the matching name + egsInformation("testA EGS_InputStruct::getLibraryBlock\n"); + shared_ptr libraryBlock; + for(auto& block : blockInputs) { + libraryBlock = block->getLibraryBlock(blockTitle, libraryName); + egsInformation("testB EGS_InputStruct::getLibraryBlock\n"); + if(libraryBlock) { + break; + } + } + return libraryBlock; +} + EGS_BlockInput::EGS_BlockInput() {} EGS_BlockInput::EGS_BlockInput(string blockTit, bool isReq, shared_ptr par) { @@ -99,6 +123,32 @@ shared_ptr EGS_BlockInput::getParent() { return parent; } +shared_ptr EGS_BlockInput::getLibraryBlock(string blockTitle, string libraryName) { + shared_ptr libraryBlock(new EGS_BlockInput); + egsInformation("test EGS_BlockInput::getLibraryBlock\n"); + + // First search the singleInputs for the library name + // only if the block title matches (e.g. it's a geometry, or a source) + if(this->getTitle() == blockTitle) { + egsInformation("test2 EGS_BlockInput::getLibraryBlock\n"); + for(auto& inp : singleInputs) { + if(inp.getAttribute() == libraryName) { + egsInformation("test3 EGS_BlockInput::getLibraryBlock\n"); + return shared_ptr(this); + } + } + } + + // If not found, go through input blocks + for(auto& block : blockInputs) { + libraryBlock = block->getLibraryBlock(blockTitle, libraryName); + if(libraryBlock) { + egsInformation("test4 EGS_BlockInput::getLibraryBlock\n"); + return libraryBlock; + } + } +} + EGS_SingleInput::EGS_SingleInput() {} EGS_SingleInput::EGS_SingleInput(string attr, bool isReq, const string desc, const vector vals) { diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index 54b0d0fa5..6b838c147 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -90,6 +90,7 @@ class EGS_EXPORT EGS_BlockInput EGS_SingleInput getSingleInput(string attr); void setParent(shared_ptr par); shared_ptr getParent(); + shared_ptr getLibraryBlock(string blockTitle, string libraryName); private: @@ -107,7 +108,14 @@ class EGS_EXPORT EGS_InputStruct { EGS_InputStruct(); ~EGS_InputStruct(); - void addBlockInput(EGS_InputStruct *parent, string blockTit, bool isReq); + void addBlockInput(shared_ptr block); + //void addBlockInput(string blockTit, bool isReq); + void addBlockInputs(vector> blocks); + shared_ptr getLibraryBlock(string blockTitle, string libraryName); + +private: + + vector> blockInputs; }; diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index c4baa74b4..3a19eaab3 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -2,14 +2,17 @@ #include #include "egs_editor.h" +#include "egs_functions.h" -EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) -{ +EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { this->setFrameShape(QFrame::NoFrame); installEventFilter(this); viewport()->installEventFilter(this); + const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); + this->setFont(fixedFont); + lineNumberArea = new LineNumberArea(this); connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); @@ -21,10 +24,18 @@ EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) highlightCurrentLine(); } +EGS_Editor::~EGS_Editor() { + if(lineNumberArea) { + delete lineNumberArea; + } +} +void EGS_Editor::setInputStruct(shared_ptr inp) { + cout << "test EGS_Editor::setInputStruct" << endl; + inputStruct = inp; +} -int EGS_Editor::lineNumberAreaWidth() -{ +int EGS_Editor::lineNumberAreaWidth() { int digits = 1; int max = qMax(1, blockCount()); while (max >= 10) { @@ -39,28 +50,28 @@ int EGS_Editor::lineNumberAreaWidth() -void EGS_Editor::updateLineNumberAreaWidth(int /* newBlockCount */) -{ +void EGS_Editor::updateLineNumberAreaWidth(int /* newBlockCount */) { setViewportMargins(lineNumberAreaWidth()+5, 0, 0, 0); } -void EGS_Editor::updateLineNumberArea(const QRect &rect, int dy) -{ - if (dy) +void EGS_Editor::updateLineNumberArea(const QRect &rect, int dy) { + if (dy) { lineNumberArea->scroll(0, dy); - else + } + else { lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + } - if (rect.contains(viewport()->rect())) + if (rect.contains(viewport()->rect())) { updateLineNumberAreaWidth(0); + } } -void EGS_Editor::resizeEvent(QResizeEvent *e) -{ +void EGS_Editor::resizeEvent(QResizeEvent *e) { QPlainTextEdit::resizeEvent(e); QRect cr = contentsRect(); @@ -69,8 +80,7 @@ void EGS_Editor::resizeEvent(QResizeEvent *e) -void EGS_Editor::highlightCurrentLine() -{ +void EGS_Editor::highlightCurrentLine() { QList extraSelections; if (!isReadOnly()) { @@ -90,18 +100,17 @@ void EGS_Editor::highlightCurrentLine() -void EGS_Editor::autoComplete() -{ - QTextCursor cursor = textCursor(); - int clickedPosition = cursor.position(); +void EGS_Editor::autoComplete() { + // Get the input structure + EGS_BlockInput inp = getBlockInput(); // Get the text of the current line + QTextCursor cursor = textCursor(); cursor.movePosition(QTextCursor::StartOfBlock); cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); QString selectedText = cursor.selectedText(); - if(selectedText.simplified() == "library =") { - //insertPlainText(selectedText); + if (selectedText.simplified() == "library = ") { // Init popup QListView *popup = new QListView; @@ -109,21 +118,19 @@ void EGS_Editor::autoComplete() popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); popup->setSelectionBehavior(QAbstractItemView::SelectRows); popup->setSelectionMode(QAbstractItemView::SingleSelection); - //popup->setModelColumn(d->column); - popup->setParent(nullptr); - // This option seems to take control of mouse + key inputs + popup->setFocusPolicy(Qt::NoFocus); + popup->installEventFilter(this); + + // The Qt::Popup option seems to take control of mouse + key inputs // essentially locking up the computer, beware! //popup->setWindowFlag(Qt::Popup); popup->setWindowFlag(Qt::ToolTip); - popup->setFocusPolicy(Qt::NoFocus); - - popup->installEventFilter(this); QObject::connect(popup, SIGNAL(clicked(QModelIndex)), - this, SLOT(insertCompletion(QModelIndex))); + this, SLOT(insertCompletion(QModelIndex))); QObject::connect(this, SIGNAL(cursorPositionChanged()), - popup, SLOT(hide())); + popup, SLOT(hide())); // // QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), // this, SLOT(_q_completionSelected(QItemSelection))); @@ -133,57 +140,43 @@ void EGS_Editor::autoComplete() model = new QStringListModel(this); // Make data - QStringList List; - List << "egs_box" << "egs_cd_geometry" << "egs_cones"; - model->setStringList(List); + QStringList itemList; + itemList << "egs_box" << "egs_cd_geometry" << "egs_cones" << "eii_iii"; + model->setStringList(itemList); popup->setModel(model); + popup->setFont(this->font()); + + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } + } // Create a selection popup - QRect rect; //tmp rect int maxVisibleItems = 6; const QRect screen = this->frameRect(); - Qt::LayoutDirection dir = this->layoutDirection(); QPoint pos; int rh, w; int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; QScrollBar *hsb = popup->horizontalScrollBar(); - if (hsb && hsb->isVisible()) + if (hsb && hsb->isVisible()) { h += popup->horizontalScrollBar()->sizeHint().height(); - - if (rect.isValid()) { - rh = rect.height(); - w = rect.width(); - pos = this->mapToGlobal(dir == Qt::RightToLeft ? rect.bottomRight() : rect.bottomLeft()); - } else { - rh = this->height(); - pos = this->mapToGlobal(QPoint(0, this->height() - 2)); - w = this->width(); } - // Constrain the box size to the window - if (w > screen.width()) - w = screen.width(); - if ((pos.x() + w) > (screen.x() + screen.width())) - pos.setX(screen.x() + screen.width() - w); - if (pos.x() < screen.x()) - pos.setX(screen.x()); - - int top = pos.y() - rh - screen.top() + 2; - int bottom = screen.bottom() - pos.y(); - h = qMax(h, popup->minimumHeight()); - if (h > bottom) { - h = qMin(qMax(top, bottom), h); - - if (top > bottom) - pos.setY(pos.y() - h - rh + 2); - } + rh = this->height(); + pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + w = 20 + strLength * fm.horizontalAdvance('9'); popup->setGeometry(pos.x(), pos.y(), w, h); // Show the popup - if (!popup->isVisible()) + if (!popup->isVisible()) { popup->show(); + } } } @@ -192,10 +185,54 @@ void EGS_Editor::insertCompletion(QModelIndex index) { //insertPlainText(index); } +// TODO: on clicking a new position in doc +// - get nearest :start, load inputstruct (for geom/src, get library first) +EGS_BlockInput EGS_Editor::getBlockInput() { + + QString library, blockTitle; + for(QTextBlock block = textCursor().block(); block.isValid(); block = block.previous()) { + QString line = block.text().simplified(); + + // Get block library for input blocks based on a shared library + // e.g. geometries and sources + int startPos = line.lastIndexOf("library ="); + if(startPos >= 0) { + startPos += 9; + library = line.mid(startPos, line.size()-startPos).simplified(); + cout << "test1 " << library.toLatin1().data() << endl; + } + + // Get block title + startPos = line.lastIndexOf(":start "); + if(startPos >= 0) { + startPos += 7; + int endPos = line.indexOf(":",startPos); + if(endPos > 0) { + blockTitle = line.mid(startPos, endPos-startPos); + cout << "test2 " << blockTitle.toLatin1().data() << endl; + break; + } + } + } + // If we got the library tag, we can directly look up this input block structure + shared_ptr inputBlock; + cout << "test4a " << endl; + shared_ptr libraryBlock = inputStruct->getLibraryBlock("",""); + if(library.size() > 0) { + cout << "test3a " << endl; + inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); + cout << "test3b " << endl; + if(inputBlock) { + cout << "test3 " << inputBlock->getTitle().c_str() << endl; + } + } + + + return EGS_BlockInput(); +} -void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) -{ +void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) { QPainter painter(lineNumberArea); //painter.fillRect(event->rect(), QColor(Qt::lightGray).lighter(110)); @@ -227,8 +264,8 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { // track `Ctrl + Click` in the text edit if ((obj == this->viewport()) && - (mouseEvent->button() == Qt::LeftButton) && - (QGuiApplication::keyboardModifiers() == Qt::ControlModifier)) { + (mouseEvent->button() == Qt::LeftButton) && + (QGuiApplication::keyboardModifiers() == Qt::ControlModifier)) { // open the link (if any) at the current position //openLinkAtCursorPosition(); return true; diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h index 951a426b5..f02e8a6f9 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.h +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -6,6 +6,8 @@ #include #include +#include "egs_input_struct.h" + class QPaintEvent; class QResizeEvent; class QSize; @@ -13,15 +15,16 @@ class QWidget; class LineNumberArea; -class EGS_Editor : public QPlainTextEdit -{ +class EGS_Editor : public QPlainTextEdit { Q_OBJECT public: EGS_Editor(QWidget *parent = 0); + ~EGS_Editor(); void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth(); + void setInputStruct(shared_ptr inp); protected: void resizeEvent(QResizeEvent *event) override; @@ -35,12 +38,14 @@ private slots: void updateLineNumberArea(const QRect &, int); private: + EGS_BlockInput getBlockInput(); + QWidget *lineNumberArea; + shared_ptr inputStruct; }; -class LineNumberArea : public QWidget -{ +class LineNumberArea : public QWidget { public: LineNumberArea(EGS_Editor *editor) : QWidget(editor) { egsEditor = editor; diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.cpp b/HEN_HOUSE/egs++/view/egs_highlighter.cpp index 9b7cbf394..2724f1cf5 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.cpp +++ b/HEN_HOUSE/egs++/view/egs_highlighter.cpp @@ -91,8 +91,7 @@ EGS_Highlighter::EGS_Highlighter(QTextDocument *parent) : QSyntaxHighlighter(par //commentEndExpression = QRegularExpression("\\*/"); } -void EGS_Highlighter::highlightBlock(const QString &text) -{ +void EGS_Highlighter::highlightBlock(const QString &text) { foreach (const HighlightingRule &rule, highlightingRules) { QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); while (matchIterator.hasNext()) { diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.h b/HEN_HOUSE/egs++/view/egs_highlighter.h index aba79d181..322024166 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.h +++ b/HEN_HOUSE/egs++/view/egs_highlighter.h @@ -37,8 +37,7 @@ class QTextDocument; -class EGS_Highlighter : public QSyntaxHighlighter -{ +class EGS_Highlighter : public QSyntaxHighlighter { Q_OBJECT public: explicit EGS_Highlighter(QTextDocument *parent = nullptr); @@ -47,8 +46,7 @@ class EGS_Highlighter : public QSyntaxHighlighter void highlightBlock(const QString &text) override; private: - struct HighlightingRule - { + struct HighlightingRule { QRegularExpression pattern; QTextCharFormat format; }; diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index a3cf61435..fb2618028 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -204,7 +204,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Load an egs++ application to parse the input file string app_name; int appc = 5; - char* appv[] = { "egspp", "-a", "tutor7pp", "-i", "tracks1.egsinp", "-p", "tutor_data"}; + char *appv[] = { "egspp", "-a", "tutor7pp", "-i", "tracks1.egsinp", "-p", "tutor_data"}; // Appv: %s -a application [-p pegs_file] [-i input_file] [-o output_file] [-b] [-P number_of_parallel_jobs] [-j job_index] if (!EGS_Application::getArgument(appc,appv,"-a","--application",app_name)) { @@ -246,8 +246,10 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) QStringList libraries = directory.entryList(QStringList() << (lib_prefix+"*"+lib_suffix).c_str(), QDir::Files); QStringList geomLibs, sourceLibs; + shared_ptr inputStruct(new EGS_InputStruct); + // For each library, try to load it and determine if it is geometry or source - for(const auto& lib : libraries) { + for (const auto &lib : libraries) { // Remove the extension QString libName = lib.left(lib.lastIndexOf(".")); // Remove the prefix (EGS_Library adds it automatically) @@ -282,10 +284,10 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); egsInformation(" testgeom %s\n",libName.toLatin1().data()); - if(getInputs) { + if (getInputs) { shared_ptr geom = getInputs(); - if(geom) { + if (geom) { // Only add geometries to the list that have a function // to get the input template geomLibs.append(libName); @@ -293,22 +295,22 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) geomTemplates.push_back(geom); vector singleInputs = geom->getSingleInputs(); - for(auto& inp : singleInputs) { + for (auto &inp : singleInputs) { const vector vals = inp.getValues(); egsInformation(" single %s\n", inp.getAttribute().c_str()); - for(auto&& val : vals) { + for (auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } } vector> inputBlocks = geom->getBlockInputs(); - for(auto& block : inputBlocks) { + for (auto &block : inputBlocks) { egsInformation(" block %s\n", block->getTitle().c_str()); vector singleInputs = block->getSingleInputs(); - for(auto& inp : singleInputs) { + for (auto &inp : singleInputs) { const vector vals = inp.getValues(); egsInformation(" single %s\n", inp.getAttribute().c_str()); - for(auto&& val : vals) { + for (auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } } @@ -323,12 +325,12 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } + inputStruct->addBlockInputs(geomTemplates); + egsinpEdit->setInputStruct(inputStruct); + // Populate the geometry and simulation template lists comboBox_geomTemplate->addItems(geomLibs); comboBox_simTemplate->addItems(sourceLibs); - - // set the widget to show near the left-upper corner of the screen - move(QPoint(25,25)); } GeometryViewControl::~GeometryViewControl() { From 56429560dd31effbd018d2317839f58dff75b80b Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 4 Feb 2020 12:22:03 -0500 Subject: [PATCH 05/40] Add editor autocomplete and input checking --- HEN_HOUSE/egs++/egs_base_geometry.h | 4 +- HEN_HOUSE/egs++/egs_input_struct.cpp | 74 +++- HEN_HOUSE/egs++/egs_input_struct.h | 10 +- HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp | 36 +- .../egs_cd_geometry/egs_cd_geometry.cpp | 67 +++- HEN_HOUSE/egs++/view/egs_editor.cpp | 379 +++++++++++++----- HEN_HOUSE/egs++/view/egs_editor.h | 8 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 56 ++- HEN_HOUSE/egs++/view/viewcontrol.h | 1 + 9 files changed, 470 insertions(+), 165 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_base_geometry.h b/HEN_HOUSE/egs++/egs_base_geometry.h index 1fa46cf2f..bdbe10d36 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -76,9 +76,9 @@ class label { static shared_ptr blockInput = make_shared("geometry"); static void setBaseGeometryInputs() { - blockInput->addSingleInput("name", true, "The user-declared unique name of this geometry."); + blockInput->addSingleInput("name", true, "The user-declared unique name of this geometry. This is the name you may refer to elsewhere in the input file"); shared_ptr mediaBlock = blockInput->addBlockInput("media input"); - mediaBlock->addSingleInput("media", true, "A list of media that are used in this geometry."); + mediaBlock->addSingleInput("media", true, "A list of media that are used in this geometry"); mediaBlock->addSingleInput("set medium", false, "TODO"); } diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index f7c50e36d..036513605 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -51,14 +51,16 @@ void EGS_InputStruct::addBlockInputs(vector> blocks) blockInputs.insert(blockInputs.end(), blocks.begin(), blocks.end()); } +vector> EGS_InputStruct::getBlockInputs() { + return blockInputs; +} + shared_ptr EGS_InputStruct::getLibraryBlock(string blockTitle, string libraryName) { // Loop through each input block in the structure to find the library with // the matching name - egsInformation("testA EGS_InputStruct::getLibraryBlock\n"); - shared_ptr libraryBlock; + auto libraryBlock = make_shared(); for(auto& block : blockInputs) { libraryBlock = block->getLibraryBlock(blockTitle, libraryName); - egsInformation("testB EGS_InputStruct::getLibraryBlock\n"); if(libraryBlock) { break; } @@ -66,6 +68,22 @@ shared_ptr EGS_InputStruct::getLibraryBlock(string blockTitle, s return libraryBlock; } +vector EGS_InputStruct::getLibraryOptions(string blockTitle) { + // Loop through each input block in the structure to find all the possible + // library options that match the input block type + // E.g. find all the geometry libraries + vector libOptions; + for(auto& block : blockInputs) { + if(block && block->getTitle() == blockTitle) { + string lib = block->getSingleInput("library")->getValues().front(); + if(lib.size() > 0) { + libOptions.push_back(lib); + } + } + } + return libOptions; +} + EGS_BlockInput::EGS_BlockInput() {} EGS_BlockInput::EGS_BlockInput(string blockTit, bool isReq, shared_ptr par) { @@ -85,18 +103,17 @@ string EGS_BlockInput::getTitle() { } void EGS_BlockInput::addSingleInput(string attr, bool isReq, const string desc, const vector vals) { - singleInputs.push_back(EGS_SingleInput(attr, isReq, desc, vals)); + singleInputs.push_back(make_shared(attr, isReq, desc, vals)); } shared_ptr EGS_BlockInput::addBlockInput(string blockTit, bool isReq) { egsInformation("addBlockInput\n"); blockInputs.push_back(make_shared(blockTit, isReq, shared_from_this())); - egsInformation("addBlockInput2\n"); return blockInputs.back(); } -vector EGS_BlockInput::getSingleInputs() { +vector> EGS_BlockInput::getSingleInputs() { return singleInputs; } @@ -104,15 +121,15 @@ vector> EGS_BlockInput::getBlockInputs() { return blockInputs; } -EGS_SingleInput EGS_BlockInput::getSingleInput(string attr) { +shared_ptr EGS_BlockInput::getSingleInput(string attr) { for(auto& inp : singleInputs) { // TODO: this assumes unique attr - if(inp.getAttribute() == attr) { + if(inp && inp->getAttribute() == attr) { return inp; } } - return EGS_SingleInput(); + return nullptr; } void EGS_BlockInput::setParent(shared_ptr par) { @@ -124,29 +141,44 @@ shared_ptr EGS_BlockInput::getParent() { } shared_ptr EGS_BlockInput::getLibraryBlock(string blockTitle, string libraryName) { - shared_ptr libraryBlock(new EGS_BlockInput); - egsInformation("test EGS_BlockInput::getLibraryBlock\n"); // First search the singleInputs for the library name // only if the block title matches (e.g. it's a geometry, or a source) if(this->getTitle() == blockTitle) { - egsInformation("test2 EGS_BlockInput::getLibraryBlock\n"); - for(auto& inp : singleInputs) { - if(inp.getAttribute() == libraryName) { - egsInformation("test3 EGS_BlockInput::getLibraryBlock\n"); - return shared_ptr(this); + for(auto &inp: singleInputs) { + if(!inp) { + continue; + } + if(egsEquivStr(inp->getAttribute(), "library")) { + if(inp->getValues().size() && egsEquivStr(inp->getValues().front(), libraryName)) { + return shared_from_this(); + } else { + break; + } } } } // If not found, go through input blocks - for(auto& block : blockInputs) { - libraryBlock = block->getLibraryBlock(blockTitle, libraryName); + for(auto &block: blockInputs) { + auto libraryBlock = block->getLibraryBlock(blockTitle, libraryName); if(libraryBlock) { - egsInformation("test4 EGS_BlockInput::getLibraryBlock\n"); return libraryBlock; } } + return nullptr; +} + +bool EGS_BlockInput::contains(string inputTag) { + for(auto &inp: singleInputs) { + if(!inp) { + continue; + } + if(egsEquivStr(inp->getAttribute(), inputTag)) { + return true; + } + } + return false; } EGS_SingleInput::EGS_SingleInput() {} @@ -180,6 +212,10 @@ const vector EGS_SingleInput::getValues() { return values; } +string EGS_SingleInput::getDescription() { + return description; +} + diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index 6b838c147..e882d385c 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -58,6 +58,7 @@ class EGS_EXPORT EGS_SingleInput { bool getRequired(); ~EGS_SingleInput(); const vector getValues(); + string getDescription(); protected: @@ -85,17 +86,18 @@ class EGS_EXPORT EGS_BlockInput string getTitle(); void addSingleInput(string attr, bool isReq, const string desc, const vector vals = vector()); shared_ptr addBlockInput(string blockTit, bool isReq = false); - vector getSingleInputs(); + vector> getSingleInputs(); vector> getBlockInputs(); - EGS_SingleInput getSingleInput(string attr); + shared_ptr getSingleInput(string attr); void setParent(shared_ptr par); shared_ptr getParent(); shared_ptr getLibraryBlock(string blockTitle, string libraryName); + bool contains(string inputTag); private: - vector singleInputs; + vector> singleInputs; vector> blockInputs; shared_ptr parent; string blockTitle; @@ -111,7 +113,9 @@ class EGS_EXPORT EGS_InputStruct { void addBlockInput(shared_ptr block); //void addBlockInput(string blockTit, bool isReq); void addBlockInputs(vector> blocks); + vector> getBlockInputs(); shared_ptr getLibraryBlock(string blockTitle, string libraryName); + vector getLibraryOptions(string blockTitle); private: diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp index 0721c242e..425200fa2 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -55,17 +55,17 @@ static char EGS_BOX_LOCAL ebox_message4[] = "expecting 1 or 3 float inputs for 'box size'"; static char EGS_BOX_LOCAL ebox_key1[] = "box size"; -static bool inputSet = false; +static bool EGS_BOX_LOCAL inputSet = false; -struct EGS_BOX_LOCAL BoxInputs { +struct EGS_BOX_LOCAL InputOptions { vector boxSize; }; -BoxInputs inp; +InputOptions inp; -// TODO was going to add this function in addition to the blockinput stuff -EGS_BOX_LOCAL int loadInputs(EGS_Input *input) { +// Process inputs from the egsinp file +EGS_BOX_LOCAL int processInputs(EGS_Input *input) { int err = input->getInput(ebox_key1,inp.boxSize); - if(err && blockInput->getSingleInput(ebox_key1).getRequired()) { + if(err && blockInput->getSingleInput(ebox_key1)->getRequired()) { egsWarning(ebox_message1,ebox_message3); return 0; } @@ -80,8 +80,24 @@ extern "C" { setBaseGeometryInputs(); - blockInput->addSingleInput("library", true, "The type of geometry.", vector(1, typeStr)); - blockInput->addSingleInput("box size", true, "1 or 3 numbers defining the box size"); + // Format: name, isRequired, description, vector string of allowed values + blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso", vector(1, typeStr)); + blockInput->addSingleInput("box size", true, "1 number defining the side-length of a cube, or 3 numbers defining the x, y, and z side-lengths"); + } + + EGS_BOX_EXPORT string getExample() { + string example +{R"( + :start geometry: + library = EGS_Box + name = my_box + box size = 1 2 3 + :start media input: + media = water + :stop media input: + :stop geometry: +)"}; + return example; } EGS_BOX_EXPORT shared_ptr getInputs() { @@ -97,8 +113,8 @@ extern "C" { return 0; } - if(!loadInputs(input)) { - egsWarning("Failed to load the inputs for %s.\n", typeStr.c_str()); + if(!processInputs(input)) { + egsWarning("Failed to process the inputs for %s.\n", typeStr.c_str()); return 0; } diff --git a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp index 4a4660e02..3119b1222 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp @@ -47,7 +47,26 @@ #define S_STREAM std::istringstream #endif -string EGS_CDGeometry::type = "EGS_CDGeometry"; +static string EGS_CDGEOMETRY_LOCAL typeStr("EGS_CDGeometry"); +string EGS_CDGeometry::type(typeStr); + +static bool EGS_CDGEOMETRY_LOCAL inputSet = false; + +struct EGS_CDGEOMETRY_LOCAL InputOptions { + string bg_name; +}; +InputOptions inp; + +// Process inputs from the egsinp file +EGS_CDGEOMETRY_LOCAL int processInputs(EGS_Input *input) { +// int err = input->getInput(ebox_key1,inp.boxSize); +// if(err && blockInput->getSingleInput(ebox_key1)->getRequired()) { +// egsWarning(ebox_message1,ebox_message3); +// return 0; +// } + + return 1; +} void EGS_CDGeometry::setMedia(EGS_Input *,int,const int *) { egsWarning("EGS_CDGeometry::setMedia: don't use this method. Use the\n" @@ -111,6 +130,39 @@ void EGS_CDGeometry::setUpIndexing() { extern "C" { + static void setInputs() { + inputSet = true; + + // Format: name, isRequired, description, vector string of allowed values + blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso", vector(1, typeStr)); + + blockInput->addSingleInput("base geometry", true, "The name of the geometry that defines regions for this 'cutting device'. It is within these regions that other geometries will be placed to create a composite geometry"); + blockInput->addSingleInput("set geometry", true, "The region number in the base geometry, followed by the name of the geometry to place in that region. If this geometry extends beyond the region boundaries, it will be cut to size"); + } + + EGS_CDGEOMETRY_EXPORT string getExample() { + string example +{R"( + :start geometry: + library = EGS_CDGeometry + name = my_cd + base geometry = my_regions + # set geometry = 1 geom means: + # in region 1 of the basegeometry, use geometry named "geom" + set geometry = 0 my_geom1 + set geometry = 1 my_geom2 + :stop geometry: +)"}; + return example; + } + + EGS_CDGEOMETRY_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return blockInput; + } + EGS_CDGEOMETRY_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { egsWarning("createGeometry(CD_Geometry): null input?\n"); @@ -121,16 +173,21 @@ extern "C" { EGS_BaseGeometry::createSingleGeometry(ij); delete ij; } - string bg_name; - int err = input->getInput("base geometry",bg_name); + + if(!processInputs(input)) { + egsWarning("Failed to process the inputs for %s.\n", typeStr.c_str()); + return 0; + } + + int err = input->getInput("base geometry",inp.bg_name); if (err) { egsWarning("createGeometry(CD_Geometry): no 'base geometry' input\n"); return 0; } - EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(bg_name); + EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(inp.bg_name); if (!g) { egsWarning("createGeometry(CD_Geometry): no geometry named %s is" - " defined\n",bg_name.c_str()); + " defined\n",inp.bg_name.c_str()); return 0; } int nreg = g->regions(); diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 3a19eaab3..f755355a2 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -1,37 +1,82 @@ - -#include - #include "egs_editor.h" #include "egs_functions.h" EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { this->setFrameShape(QFrame::NoFrame); + // Capture events installEventFilter(this); viewport()->installEventFilter(this); + // Set the font const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); this->setFont(fixedFont); + // Set the tab width to 4 spaces + const int tabStop = 4; // 4 characters + QFontMetrics metrics(fixedFont); + this->setTabStopWidth(tabStop * metrics.width(' ')); + + // Initialize an area for displaying line numbers lineNumberArea = new LineNumberArea(this); + updateLineNumberAreaWidth(0); + + // Highlight the line currently selected by the cursor + highlightCurrentLine(); + + // The standard font format has no underline + normalFormat.setUnderlineStyle(QTextCharFormat::NoUnderline); + + // The format for invalid inputs + // Adds a little red squiggly line + invalidFormat.setUnderlineColor(QColor("red")); + invalidFormat.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); + + // Initialize the auto completion popup + popup = new QListView; + popup->setEditTriggers(QAbstractItemView::NoEditTriggers); + popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + popup->setSelectionBehavior(QAbstractItemView::SelectRows); + popup->setSelectionMode(QAbstractItemView::SingleSelection); + popup->setParent(nullptr); + popup->setFocusPolicy(Qt::NoFocus); + popup->installEventFilter(this); + + // The Qt::Popup option seems to take control of mouse + key inputs + // essentially locking up the computer, beware! + //popup->setWindowFlag(Qt::Popup); + popup->setWindowFlag(Qt::ToolTip); + + // Init model + model = new QStringListModel(this); connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); + connect(this, SIGNAL(cursorPositionChanged()), popup, SLOT(hide())); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(autoComplete())); + connect(popup, SIGNAL(clicked(QModelIndex)), this, SLOT(insertCompletion(QModelIndex))); + +// +// QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), +// this, SLOT(_q_completionSelected(QItemSelection))); + - updateLineNumberAreaWidth(0); - highlightCurrentLine(); } EGS_Editor::~EGS_Editor() { if(lineNumberArea) { delete lineNumberArea; } + if(popup) { + delete popup; + } + if(model) { + delete model; + } } void EGS_Editor::setInputStruct(shared_ptr inp) { - cout << "test EGS_Editor::setInputStruct" << endl; inputStruct = inp; } @@ -98,108 +143,219 @@ void EGS_Editor::highlightCurrentLine() { setExtraSelections(extraSelections); } - +int EGS_Editor::countStartingWhitespace(const QString &s) { + int i, l = s.size(); + for(i = 0; i < l && s[i] == ' '; ++i); + return i; +} void EGS_Editor::autoComplete() { // Get the input structure - EGS_BlockInput inp = getBlockInput(); + QString blockTitle; + shared_ptr inputBlockTemplate = getBlockInput(blockTitle); // Get the text of the current line QTextCursor cursor = textCursor(); - cursor.movePosition(QTextCursor::StartOfBlock); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - QString selectedText = cursor.selectedText(); - - if (selectedText.simplified() == "library = ") { - - // Init popup - QListView *popup = new QListView; - popup->setEditTriggers(QAbstractItemView::NoEditTriggers); - popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - popup->setSelectionBehavior(QAbstractItemView::SelectRows); - popup->setSelectionMode(QAbstractItemView::SingleSelection); - popup->setParent(nullptr); - popup->setFocusPolicy(Qt::NoFocus); - popup->installEventFilter(this); - - // The Qt::Popup option seems to take control of mouse + key inputs - // essentially locking up the computer, beware! - //popup->setWindowFlag(Qt::Popup); - popup->setWindowFlag(Qt::ToolTip); - - QObject::connect(popup, SIGNAL(clicked(QModelIndex)), - this, SLOT(insertCompletion(QModelIndex))); - QObject::connect(this, SIGNAL(cursorPositionChanged()), - popup, SLOT(hide())); -// -// QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), -// this, SLOT(_q_completionSelected(QItemSelection))); - - // Init model - QStringListModel *model; - model = new QStringListModel(this); + QString selectedText = cursor.block().text().simplified(); - // Make data - QStringList itemList; - itemList << "egs_box" << "egs_cd_geometry" << "egs_cones" << "eii_iii"; - model->setStringList(itemList); - - popup->setModel(model); - popup->setFont(this->font()); + // If the first character is a "#", ignore this line + if(selectedText.startsWith("#")) { + return; + } - // Get max string length - int strLength = 0; - for (auto &item: itemList) { - if (item.size() > strLength) { - strLength = item.size(); + // Check the validity of the inputs + // If this line contains an "=" then it should match a single input + int equalsPos = selectedText.indexOf("="); + if(equalsPos != -1) { + QString inputTag = selectedText.left(equalsPos).simplified(); + QString inputVal = selectedText.right(selectedText.size() - equalsPos - 1).simplified(); + + // If we found a template for this type of input block, + // check that the input tag (LHS) is valid + if(inputBlockTemplate) { + + + QList extraSelections = this->extraSelections(); + QTextEdit::ExtraSelection selection; + selection.cursor = textCursor(); + selection.cursor.joinPreviousEditBlock(); + + // Select the whole line + selection.cursor.movePosition(QTextCursor::StartOfBlock); + selection.cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + + // Reset the format to have no red underline + selection.cursor.setCharFormat(normalFormat); + + // Check that the input block template contains this type of input + //bool inputValid = inputBlockTemplate->contains(inputTag.toStdString()); + shared_ptr inputPtr = inputBlockTemplate->getSingleInput(inputTag.toStdString()); + if(!inputPtr) { + // Select the input tag + selection.cursor.movePosition(QTextCursor::StartOfBlock); + + // If whitespace was trimmed from the start of the line, + // we account for it so only the input tag is underlined + int originalEqualsPos = cursor.block().text().indexOf("="); + int numWhitespace = countStartingWhitespace(cursor.block().text()); + if(numWhitespace > 0) { + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, numWhitespace); + } + + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, originalEqualsPos - numWhitespace); + + // Set the format to have a red underline + selection.cursor.setCharFormat(invalidFormat); + } else { + // If the input is valid, add the description as a tooltip + QTextCharFormat newFormat; + newFormat.setToolTip(QString::fromStdString(inputPtr->getDescription())); + + selection.cursor.setCharFormat(newFormat); } + + selection.cursor.endEditBlock(); + extraSelections.append(selection); + setExtraSelections(extraSelections); } - // Create a selection popup - int maxVisibleItems = 6; - const QRect screen = this->frameRect(); - QPoint pos; - int rh, w; - int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; - QScrollBar *hsb = popup->horizontalScrollBar(); - if (hsb && hsb->isVisible()) { - h += popup->horizontalScrollBar()->sizeHint().height(); + // Return if the input value (RHS) is already filled + // This way we only offer options for blank inputs + if(inputVal != "") { + return; } - rh = this->height(); - pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); - QFontMetrics fm(popup->font()); - w = 20 + strLength * fm.horizontalAdvance('9'); + // Create a pop-up if there is a list of possible input values + if (inputTag == "library") { + + // Get the list of possible libraries for this type of input block + // I.e. if this is a geometry, only offer geometries as options + vector vals = inputStruct->getLibraryOptions(blockTitle.toStdString()); + + // Populate the popup list + QStringList itemList; + for(auto &v: vals) { + itemList << QString(v.c_str()); + } + if(itemList.size() > 0) { + model->setStringList(itemList); + } - popup->setGeometry(pos.x(), pos.y(), w, h); + popup->setModel(model); + popup->setFont(this->font()); + + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } + } + + // Create a selection popup + int maxVisibleItems = 6; + int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = popup->horizontalScrollBar(); + if (hsb && hsb->isVisible()) { + h += popup->horizontalScrollBar()->sizeHint().height(); + } - // Show the popup - if (!popup->isVisible()) { - popup->show(); + QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + int w = 20 + strLength * fm.horizontalAdvance('9'); + + popup->setGeometry(pos.x(), pos.y(), w, h); + + // Show the popup + if (!popup->isVisible()) { + popup->show(); + } + } else { + + // Return if we couldn't find a template for this input block + if(!inputBlockTemplate) { + return; + } + + // Check for this input tag in the template + shared_ptr inp = inputBlockTemplate->getSingleInput(inputTag.toStdString()); + + // Return if we didn't find this input in the template + if(!inp) { + return; + } + + // Get the possible values + auto vals = inp->getValues(); + + // Return if we don't have a list of values to choose from + if(vals.size() == 0) { + return; + } + + // Populate the popup list + QStringList itemList; + for(auto &v: vals) { + itemList << QString(v.c_str()); + } + if(itemList.size() > 0) { + model->setStringList(itemList); + } + + popup->setModel(model); + popup->setFont(this->font()); + + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } + } + + // Create a selection popup + int maxVisibleItems = 6; + int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = popup->horizontalScrollBar(); + if (hsb && hsb->isVisible()) { + h += popup->horizontalScrollBar()->sizeHint().height(); + } + + QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + int w = 20 + strLength * fm.horizontalAdvance('9'); + + popup->setGeometry(pos.x(), pos.y(), w, h); + + // Show the popup + if (!popup->isVisible()) { + popup->show(); + } } } } void EGS_Editor::insertCompletion(QModelIndex index) { - insertPlainText("test"); - //insertPlainText(index); + insertPlainText(model->data(index).toString()); } -// TODO: on clicking a new position in doc -// - get nearest :start, load inputstruct (for geom/src, get library first) -EGS_BlockInput EGS_Editor::getBlockInput() { - - QString library, blockTitle; +shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { + QString library; + vector stopList; + bool withinOtherBlock = false; for(QTextBlock block = textCursor().block(); block.isValid(); block = block.previous()) { QString line = block.text().simplified(); // Get block library for input blocks based on a shared library // e.g. geometries and sources - int startPos = line.lastIndexOf("library ="); - if(startPos >= 0) { - startPos += 9; - library = line.mid(startPos, line.size()-startPos).simplified(); - cout << "test1 " << library.toLatin1().data() << endl; + // Only look for the library tag if we're not in a sub-block + int pos; + if(!withinOtherBlock) { + pos = line.lastIndexOf("library ="); + if(pos >= 0) { + pos += 9; + library = line.mid(pos, line.size()-pos).simplified(); + } } // Get block title @@ -208,28 +364,41 @@ EGS_BlockInput EGS_Editor::getBlockInput() { startPos += 7; int endPos = line.indexOf(":",startPos); if(endPos > 0) { - blockTitle = line.mid(startPos, endPos-startPos); - cout << "test2 " << blockTitle.toLatin1().data() << endl; - break; + blockTitle = line.mid(pos, endPos-pos); + if(stopList.size() > 0 && blockTitle == stopList.back()) { + stopList.pop_back(); + blockTitle.clear(); + withinOtherBlock = false; + } else { + break; + } + } + } + + // Save a vector of blocks that have already been closed + // This means both a matching :start and :stop are above the cursor + // so we're not inside the block + pos = line.lastIndexOf(":stop "); + if(pos >= 0) { + pos += 6; + int endPos = line.indexOf(":",pos); + if(endPos > 0) { + QString stopTitle = line.mid(pos, endPos-pos); + stopList.push_back(stopTitle); + withinOtherBlock = true; } } } // If we got the library tag, we can directly look up this input block structure - shared_ptr inputBlock; - cout << "test4a " << endl; - shared_ptr libraryBlock = inputStruct->getLibraryBlock("",""); if(library.size() > 0) { - cout << "test3a " << endl; - inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); - cout << "test3b " << endl; + shared_ptr inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); if(inputBlock) { - cout << "test3 " << inputBlock->getTitle().c_str() << endl; + return inputBlock; } } - - return EGS_BlockInput(); + return nullptr; } void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) { @@ -270,6 +439,30 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { //openLinkAtCursorPosition(); return true; } + } else if(event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + + // Insert 4 spaces instead of tabs + if (keyEvent->key() == Qt::Key_Tab) { + insertPlainText(" "); + return true; + } else if(keyEvent->key() == Qt::Key_Backtab) { + // Delete 4 spaces from the front of the line + QTextCursor cursor = textCursor(); + QString line = cursor.block().text(); + if(line.startsWith(" ")) { + cursor.movePosition(QTextCursor::StartOfBlock); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 4); + cursor.removeSelectedText(); + } else if(line.startsWith("\t")) { + cursor.movePosition(QTextCursor::StartOfBlock); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1); + cursor.removeSelectedText(); + } + return true; + } + } else if(event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { + popup->hide(); } return QPlainTextEdit::eventFilter(obj, event); diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h index f02e8a6f9..66fe149d3 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.h +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "egs_input_struct.h" @@ -38,10 +39,15 @@ private slots: void updateLineNumberArea(const QRect &, int); private: - EGS_BlockInput getBlockInput(); + shared_ptr getBlockInput(QString &blockTitle); + int countStartingWhitespace(const QString &s); QWidget *lineNumberArea; shared_ptr inputStruct; + QListView *popup; + QStringListModel *model; + QTextCharFormat normalFormat, + invalidFormat; }; diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index fb2618028..004833cab 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -74,6 +74,7 @@ typedef EGS_Application *(*createAppFunction)(int argc, char **argv); typedef EGS_BaseGeometry *(*createGeomFunction)(); typedef EGS_BaseSource *(*isSourceFunction)(); typedef shared_ptr (*getInputsFunction)(); +typedef string (*getExampleFunction)(); #ifdef WIN32 #ifdef CYGWIN @@ -225,12 +226,13 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) createAppFunction createApp = (createAppFunction) egs_lib.resolve("createApplication"); if (!createApp) egsFatal("\n%s: Failed to resolve the address of the 'createApplication' function" " in the application library %s\n\n",appv[0],egs_lib.libraryFile()); - +/*TODO left here crash 'cause tutor7pp isn't compiled <======================= EGS_Application *app = createApp(appc,appv); if (!app) { egsFatal("\n%s: Failed to construct the application %s\n\n",appv[0],app_name.c_str()); } egsInformation("Testapp %f\n",app->getRM()); + */ // Get a list of all the libraries in the dso directory string dso_dir; @@ -264,40 +266,19 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) createGeomFunction createGeom = (createGeomFunction) egs_lib.resolve("createGeometry"); if (createGeom) { - /*EGS_BaseGeometry *geom = createGeom(); - EGS_BlockInput *inputBlock = geom->getInputBlock(); - - geomLibs.append(libName); - - egsInformation("test1a\n"); - vector singleInputs = inputBlock->getSingleInputs(); - egsInformation("test1\n"); - for(auto& inp : singleInputs) { - const vector vals = inp.getValues(); - egsInformation("test %s\n", inp.getAttribute().c_str()); - for(auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } - } - delete inputBlock; - delete geom;*/ + egsInformation(" testgeom %s\n",libName.toLatin1().data()); getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); - egsInformation(" testgeom %s\n",libName.toLatin1().data()); if (getInputs) { shared_ptr geom = getInputs(); if (geom) { - // Only add geometries to the list that have a function - // to get the input template - geomLibs.append(libName); - geomTemplates.push_back(geom); - vector singleInputs = geom->getSingleInputs(); + vector> singleInputs = geom->getSingleInputs(); for (auto &inp : singleInputs) { - const vector vals = inp.getValues(); - egsInformation(" single %s\n", inp.getAttribute().c_str()); + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getAttribute().c_str()); for (auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } @@ -306,10 +287,10 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) vector> inputBlocks = geom->getBlockInputs(); for (auto &block : inputBlocks) { egsInformation(" block %s\n", block->getTitle().c_str()); - vector singleInputs = block->getSingleInputs(); + vector> singleInputs = block->getSingleInputs(); for (auto &inp : singleInputs) { - const vector vals = inp.getValues(); - egsInformation(" single %s\n", inp.getAttribute().c_str()); + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getAttribute().c_str()); for (auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } @@ -317,6 +298,15 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } + + getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); + if (getExample) { + // Only add geometries to the list that have a function + // to get the input example + geomLibs.append(libName); + + geomExamples.push_back(getExample()); + } } bool isSource = (bool) egs_lib.resolve("createSource"); @@ -3149,10 +3139,12 @@ void GeometryViewControl::setFontSize(int size) { } void GeometryViewControl::insertGeomTemplate(int ind) { - QString selection = comboBox_geomTemplate->itemText(ind); + //QString selection = comboBox_geomTemplate->itemText(ind); - QTextCursor cursor(egsinpEdit->textCursor()); - egsinpEdit->insertPlainText(selection); + if(ind > 0) { + QTextCursor cursor(egsinpEdit->textCursor()); + egsinpEdit->insertPlainText(QString::fromStdString(geomExamples[ind-1])); + } } void GeometryViewControl::insertSimTemplate(int ind) { diff --git a/HEN_HOUSE/egs++/view/viewcontrol.h b/HEN_HOUSE/egs++/view/viewcontrol.h index 346e03d4e..68e4057a0 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -206,6 +206,7 @@ public slots: energyScaling; vector> scoreArrays; vector geometryNames; + vector geomExamples; vector> geomTemplates; EGS_BaseGeometry *origSimGeom; EGS_Editor *egsinpEdit; From 19922d9f6ce4403f34fb2a0f6da793f22d919f05 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Sat, 22 Feb 2020 09:27:19 -0500 Subject: [PATCH 06/40] Improve egs_view editor input checking --- HEN_HOUSE/egs++/egs_base_geometry.h | 11 +- HEN_HOUSE/egs++/egs_input_struct.cpp | 106 +++- HEN_HOUSE/egs++/egs_input_struct.h | 32 +- HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp | 1 + .../egs_cd_geometry/egs_cd_geometry.cpp | 32 +- .../egs++/geometry/egs_cones/egs_cones.cpp | 57 +++ HEN_HOUSE/egs++/view/egs_editor.cpp | 452 ++++++++++++++++-- HEN_HOUSE/egs++/view/egs_editor.h | 7 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 4 +- 9 files changed, 601 insertions(+), 101 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_base_geometry.h b/HEN_HOUSE/egs++/egs_base_geometry.h index bdbe10d36..1d1fca46d 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -75,11 +75,14 @@ class label { }; static shared_ptr blockInput = make_shared("geometry"); -static void setBaseGeometryInputs() { +static void setBaseGeometryInputs(bool includeMediaBlock = true) { blockInput->addSingleInput("name", true, "The user-declared unique name of this geometry. This is the name you may refer to elsewhere in the input file"); - shared_ptr mediaBlock = blockInput->addBlockInput("media input"); - mediaBlock->addSingleInput("media", true, "A list of media that are used in this geometry"); - mediaBlock->addSingleInput("set medium", false, "TODO"); + + if(includeMediaBlock) { + shared_ptr mediaBlock = blockInput->addBlockInput("media input"); + mediaBlock->addSingleInput("media", true, "A list of media that are used in this geometry"); + mediaBlock->addSingleInput("set medium", false, "TODO"); + } } /*! \brief Base geometry class. Every geometry class must be derived from diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index 036513605..b8e5ea2b9 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -47,7 +47,6 @@ void EGS_InputStruct::addBlockInput(shared_ptr block) { } void EGS_InputStruct::addBlockInputs(vector> blocks) { - egsInformation("testA EGS_InputStruct::addBlockInputs\n"); blockInputs.insert(blockInputs.end(), blocks.begin(), blocks.end()); } @@ -102,12 +101,12 @@ string EGS_BlockInput::getTitle() { return blockTitle; } -void EGS_BlockInput::addSingleInput(string attr, bool isReq, const string desc, const vector vals) { - singleInputs.push_back(make_shared(attr, isReq, desc, vals)); +shared_ptr EGS_BlockInput::addSingleInput(string inputTag, bool isReq, const string desc, const vector vals) { + singleInputs.push_back(make_shared(inputTag, isReq, desc, vals)); + return singleInputs.back(); } shared_ptr EGS_BlockInput::addBlockInput(string blockTit, bool isReq) { - egsInformation("addBlockInput\n"); blockInputs.push_back(make_shared(blockTit, isReq, shared_from_this())); return blockInputs.back(); @@ -117,14 +116,51 @@ vector> EGS_BlockInput::getSingleInputs() { return singleInputs; } +vector> EGS_BlockInput::getSingleInputs(string title) { + if(egsEquivStr(blockTitle, title)) { + return singleInputs; + } else { + for(auto &block: blockInputs) { + auto inp = block->getSingleInputs(title); + if(inp.size() > 0) { + return inp; + } + } + } + + return {}; +} + vector> EGS_BlockInput::getBlockInputs() { return blockInputs; } -shared_ptr EGS_BlockInput::getSingleInput(string attr) { +shared_ptr EGS_BlockInput::getSingleInput(string inputTag) { for(auto& inp : singleInputs) { - // TODO: this assumes unique attr - if(inp && inp->getAttribute() == attr) { + // TODO: this assumes unique inputTag + if(inp && egsEquivStr(inp->getTag(), inputTag)) { + return inp; + } + } + + return nullptr; +} + +shared_ptr EGS_BlockInput::getSingleInput(string inputTag, string title) { + // First search the top-level input block + if(egsEquivStr(blockTitle, title)) { + for(auto &inp: singleInputs) { + // TODO: this assumes unique inputTag + if(inp && egsEquivStr(inp->getTag(), inputTag)) { + return inp; + } + } + } + + // If not found, go through input lower level blocks + for(auto &block: blockInputs) { + auto inp = block->getSingleInput(inputTag, title); + if(inp) { return inp; } } @@ -132,6 +168,20 @@ shared_ptr EGS_BlockInput::getSingleInput(string attr) { return nullptr; } +shared_ptr EGS_BlockInput::getBlockInput(string title) { + if(egsEquivStr(blockTitle, title)) { + return shared_from_this(); + } else { + for(auto &block: blockInputs) { + if(egsEquivStr(block->getTitle(), title)) { + return block; + } + } + } + + return nullptr; +} + void EGS_BlockInput::setParent(shared_ptr par) { parent = par; } @@ -141,15 +191,15 @@ shared_ptr EGS_BlockInput::getParent() { } shared_ptr EGS_BlockInput::getLibraryBlock(string blockTitle, string libraryName) { - // First search the singleInputs for the library name // only if the block title matches (e.g. it's a geometry, or a source) - if(this->getTitle() == blockTitle) { + // TODO: remove blockTitle from input params?? + //if(this->getTitle() == blockTitle) { for(auto &inp: singleInputs) { if(!inp) { continue; } - if(egsEquivStr(inp->getAttribute(), "library")) { + if(egsEquivStr(inp->getTag(), "library")) { if(inp->getValues().size() && egsEquivStr(inp->getValues().front(), libraryName)) { return shared_from_this(); } else { @@ -157,7 +207,7 @@ shared_ptr EGS_BlockInput::getLibraryBlock(string blockTitle, st } } } - } + //} // If not found, go through input blocks for(auto &block: blockInputs) { @@ -174,17 +224,30 @@ bool EGS_BlockInput::contains(string inputTag) { if(!inp) { continue; } - if(egsEquivStr(inp->getAttribute(), inputTag)) { + if(egsEquivStr(inp->getTag(), inputTag)) { return true; } } return false; } +void EGS_BlockInput::addDependency(shared_ptr inp, string val) { + dependencyInp = inp; + dependencyVal = val; +} + +shared_ptr EGS_BlockInput::getDependencyInp() { + return dependencyInp; +} + +string EGS_BlockInput::getDependencyVal() { + return dependencyVal; +} + EGS_SingleInput::EGS_SingleInput() {} -EGS_SingleInput::EGS_SingleInput(string attr, bool isReq, const string desc, const vector vals) { - attribute = attr; +EGS_SingleInput::EGS_SingleInput(string inputTag, bool isReq, const string desc, const vector vals) { + tag = inputTag; isRequired = isReq; description = desc; values = vals; @@ -192,16 +255,21 @@ EGS_SingleInput::EGS_SingleInput(string attr, bool isReq, const string desc, con EGS_SingleInput::~EGS_SingleInput() {} -void EGS_SingleInput::addRequirement(string attr, string val) { - +void EGS_SingleInput::addDependency(shared_ptr inp, string val) { + dependencyInp.push_back(inp); + dependencyVal.push_back(val); } -vector EGS_SingleInput::getDependents() { +vector> EGS_SingleInput::getDependencyInp() { + return dependencyInp; +} +vector EGS_SingleInput::getDependencyVal() { + return dependencyVal; } -string EGS_SingleInput::getAttribute() { - return attribute; +string EGS_SingleInput::getTag() { + return tag; } bool EGS_SingleInput::getRequired() { diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index e882d385c..7ba723e9c 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -53,26 +53,26 @@ class EGS_EXPORT EGS_SingleInput { public: EGS_SingleInput(); - EGS_SingleInput(string attr, bool isReq, const string desc, const vector vals); - string getAttribute(); - bool getRequired(); + EGS_SingleInput(string inputTag, bool isReq, const string desc, const vector vals); ~EGS_SingleInput(); + + string getTag(); + bool getRequired(); const vector getValues(); string getDescription(); - -protected: - - void addRequirement(string attr, string value=""); - vector getDependents(); + void addDependency(shared_ptr inp, string val=""); + vector> getDependencyInp(); + vector getDependencyVal(); private: - vector dependents; vector requirements; - string attribute; + string tag; bool isRequired; string description; vector values; + vector> dependencyInp; + vector dependencyVal; }; class EGS_EXPORT EGS_BlockInput @@ -84,15 +84,21 @@ class EGS_EXPORT EGS_BlockInput void setTitle(string blockTit); string getTitle(); - void addSingleInput(string attr, bool isReq, const string desc, const vector vals = vector()); + shared_ptr addSingleInput(string inputTag, bool isReq, const string desc, const vector vals = vector()); shared_ptr addBlockInput(string blockTit, bool isReq = false); vector> getSingleInputs(); + vector> getSingleInputs(string title); vector> getBlockInputs(); - shared_ptr getSingleInput(string attr); + shared_ptr getSingleInput(string inputTag); + shared_ptr getSingleInput(string inputTag, string title); + shared_ptr getBlockInput(string title); void setParent(shared_ptr par); shared_ptr getParent(); shared_ptr getLibraryBlock(string blockTitle, string libraryName); bool contains(string inputTag); + void addDependency(shared_ptr inp, string val=""); + shared_ptr getDependencyInp(); + string getDependencyVal(); private: @@ -103,6 +109,8 @@ class EGS_EXPORT EGS_BlockInput string blockTitle; bool isRequired; const string desc; + shared_ptr dependencyInp; + string dependencyVal; }; class EGS_EXPORT EGS_InputStruct { diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp index 425200fa2..82a827020 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -25,6 +25,7 @@ # # Contributors: Frederic Tessier # Marc Chamberland +# Reid Townson # ############################################################################### */ diff --git a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp index 3119b1222..157949974 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Ernesto Mainegra-Hing # Marc Chamberland +# Reid Townson # ############################################################################### */ @@ -52,22 +53,6 @@ string EGS_CDGeometry::type(typeStr); static bool EGS_CDGEOMETRY_LOCAL inputSet = false; -struct EGS_CDGEOMETRY_LOCAL InputOptions { - string bg_name; -}; -InputOptions inp; - -// Process inputs from the egsinp file -EGS_CDGEOMETRY_LOCAL int processInputs(EGS_Input *input) { -// int err = input->getInput(ebox_key1,inp.boxSize); -// if(err && blockInput->getSingleInput(ebox_key1)->getRequired()) { -// egsWarning(ebox_message1,ebox_message3); -// return 0; -// } - - return 1; -} - void EGS_CDGeometry::setMedia(EGS_Input *,int,const int *) { egsWarning("EGS_CDGeometry::setMedia: don't use this method. Use the\n" " setMedia() methods of the geometry objects that make up this geometry\n"); @@ -133,11 +118,14 @@ extern "C" { static void setInputs() { inputSet = true; + setBaseGeometryInputs(false); + // Format: name, isRequired, description, vector string of allowed values blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso", vector(1, typeStr)); blockInput->addSingleInput("base geometry", true, "The name of the geometry that defines regions for this 'cutting device'. It is within these regions that other geometries will be placed to create a composite geometry"); blockInput->addSingleInput("set geometry", true, "The region number in the base geometry, followed by the name of the geometry to place in that region. If this geometry extends beyond the region boundaries, it will be cut to size"); + blockInput->addSingleInput("new indexing style", false, "Set to 1 to use a new region numbering algorithm. Defaults to 0, to use the original indexing style"); } EGS_CDGEOMETRY_EXPORT string getExample() { @@ -174,20 +162,16 @@ extern "C" { delete ij; } - if(!processInputs(input)) { - egsWarning("Failed to process the inputs for %s.\n", typeStr.c_str()); - return 0; - } - - int err = input->getInput("base geometry",inp.bg_name); + string bg_name; + int err = input->getInput("base geometry", bg_name); if (err) { egsWarning("createGeometry(CD_Geometry): no 'base geometry' input\n"); return 0; } - EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(inp.bg_name); + EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(bg_name); if (!g) { egsWarning("createGeometry(CD_Geometry): no geometry named %s is" - " defined\n",inp.bg_name.c_str()); + " defined\n",bg_name.c_str()); return 0; } int nreg = g->regions(); diff --git a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp index 55d1af03d..b9a952d4d 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -27,6 +27,7 @@ # Marc Chamberland # Randle Taylor # Ernesto Mainegra-Hing +# Reid Townson # ############################################################################### */ @@ -52,6 +53,8 @@ string EGS_ParallelCones::type = "EGS_ParallelCones"; string EGS_ConeSet::type = "EGS_ConeSet"; string EGS_ConeStack::type = "EGS_ConeStack"; +static bool EGS_CONES_LOCAL inputSet = false; + void EGS_ConeStack::clear(bool all) { if (nltot > 0) { if (all) { @@ -247,6 +250,60 @@ void EGS_ConeSet::printInfo() const { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + // Format: name, isRequired, description, vector string of allowed values + blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso", {"EGS_Cones"}); + auto typePtr = blockInput->addSingleInput("type", true, "The type of cone", {"EGS_SimpleCone", "EGS_ParallelCones", "EGS_ConeSet", "EGS_ConeStack"}); + + blockInput->addSingleInput("axis", false, "The unit vector defining the axis along the length of the cones. Layers or cones are added sequentially in the vector direction"); + + auto inpPtr = blockInput->addSingleInput("apex", false, "TODO"); + inpPtr->addDependency(typePtr,"EGS_SimpleCone"); + inpPtr->addDependency(typePtr,"EGS_ParallelCones"); + inpPtr->addDependency(typePtr,"EGS_ConeSet"); + + auto blockPtr = blockInput->addBlockInput("layer"); + blockPtr->addDependency(typePtr,"EGS_ConeStack"); + blockPtr->addSingleInput("thickness", true, "TODO"); + blockPtr->addSingleInput("top radii", false, "TODO"); + blockPtr->addSingleInput("bottom radii", true, "TODO"); + blockPtr->addSingleInput("media", true, "TODO"); + + // EGS_ConeSet + //auto anglesPtr = blockInput->addSingleInput("opening angles", false, "TODO")->addDependency(typePtr, "EGS_ConeSet"); +// inpPtr = blockInput->addSingleInput("opening angles in radian", false, "TODO")->addDependency(typePtr, "EGS_ConeSet"); + //inpPtr->addDependency(anglesPtr, "", true); + + } + + EGS_CONES_EXPORT string getExample(string type) { + string example; + example = +{R"( + :start geometry: + library = EGS_CDGeometry + name = my_cd + base geometry = my_regions + # set geometry = 1 geom means: + # in region 1 of the basegeometry, use geometry named "geom" + set geometry = 0 my_geom1 + set geometry = 1 my_geom2 + :stop geometry: +)"}; + return example; + } + + EGS_CONES_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return blockInput; + } + EGS_CONES_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index f755355a2..57b21ca3f 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -24,14 +24,6 @@ EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { // Highlight the line currently selected by the cursor highlightCurrentLine(); - // The standard font format has no underline - normalFormat.setUnderlineStyle(QTextCharFormat::NoUnderline); - - // The format for invalid inputs - // Adds a little red squiggly line - invalidFormat.setUnderlineColor(QColor("red")); - invalidFormat.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); - // Initialize the auto completion popup popup = new QListView; popup->setEditTriggers(QAbstractItemView::NoEditTriggers); @@ -145,15 +137,11 @@ void EGS_Editor::highlightCurrentLine() { int EGS_Editor::countStartingWhitespace(const QString &s) { int i, l = s.size(); - for(i = 0; i < l && s[i] == ' '; ++i); + for(i = 0; i < l && s[i] == ' ' || s[i] == '\t'; ++i); return i; } void EGS_Editor::autoComplete() { - // Get the input structure - QString blockTitle; - shared_ptr inputBlockTemplate = getBlockInput(blockTitle); - // Get the text of the current line QTextCursor cursor = textCursor(); QString selectedText = cursor.block().text().simplified(); @@ -163,6 +151,15 @@ void EGS_Editor::autoComplete() { return; } + // Get the input structure + QString blockTitle; + shared_ptr inputBlockTemplate = getBlockInput(blockTitle); + + // If we aren't inside an input block, ignore this line + if(blockTitle.size() < 1) { + return; + } + // Check the validity of the inputs // If this line contains an "=" then it should match a single input int equalsPos = selectedText.indexOf("="); @@ -174,7 +171,6 @@ void EGS_Editor::autoComplete() { // check that the input tag (LHS) is valid if(inputBlockTemplate) { - QList extraSelections = this->extraSelections(); QTextEdit::ExtraSelection selection; selection.cursor = textCursor(); @@ -185,12 +181,14 @@ void EGS_Editor::autoComplete() { selection.cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); // Reset the format to have no red underline - selection.cursor.setCharFormat(normalFormat); + QTextCharFormat format; + format.setUnderlineStyle(QTextCharFormat::NoUnderline); // Check that the input block template contains this type of input - //bool inputValid = inputBlockTemplate->contains(inputTag.toStdString()); - shared_ptr inputPtr = inputBlockTemplate->getSingleInput(inputTag.toStdString()); + // If the input isn't defined, it will return nullptr + shared_ptr inputPtr = inputBlockTemplate->getSingleInput(inputTag.toStdString(), blockTitle.toStdString()); if(!inputPtr) { + // Red underline the input tag // Select the input tag selection.cursor.movePosition(QTextCursor::StartOfBlock); @@ -205,15 +203,39 @@ void EGS_Editor::autoComplete() { selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, originalEqualsPos - numWhitespace); // Set the format to have a red underline - selection.cursor.setCharFormat(invalidFormat); + format.setUnderlineColor(QColor("red")); + format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); } else { - // If the input is valid, add the description as a tooltip QTextCharFormat newFormat; - newFormat.setToolTip(QString::fromStdString(inputPtr->getDescription())); - selection.cursor.setCharFormat(newFormat); + // Check if this input has any dependencies + // and then confirm that the dependencies are satisfied + if(inputHasDependency(inputPtr) && inputDependencySatisfied(inputPtr) == false) { + // Red underline the input tag + // Select the input tag + selection.cursor.movePosition(QTextCursor::StartOfBlock); + + // If whitespace was trimmed from the start of the line, + // we account for it so only the input tag is underlined + int originalEqualsPos = cursor.block().text().indexOf("="); + int numWhitespace = countStartingWhitespace(cursor.block().text()); + if(numWhitespace > 0) { + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, numWhitespace); + } + + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, originalEqualsPos - numWhitespace); + + // Set the format to have a red underline + format.setUnderlineColor(QColor("red")); + format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); + } + + // If the input is valid, add the description as a tooltip + format.setToolTip(QString::fromStdString(inputPtr->getDescription())); } + selection.cursor.setCharFormat(format); + selection.cursor.endEditBlock(); extraSelections.append(selection); setExtraSelections(extraSelections); @@ -332,29 +354,240 @@ void EGS_Editor::autoComplete() { popup->show(); } } + + // If this is just an empty line, we can offer suggestions of valid inputs + } else if(inputBlockTemplate && selectedText == "") { + + vector> singleInputs = inputBlockTemplate->getSingleInputs(blockTitle.toStdString()); + + // Populate the popup list + QStringList itemList; + + // Add all the single inputs for the top level block + for(auto &inp: singleInputs) { + if(!egsEquivStr(inp->getTag(), "library")) { + itemList << QString((inp->getTag() + " = ").c_str()); + } + } + if(itemList.size() > 0) { + model->setStringList(itemList); + } + + popup->setModel(model); + popup->setFont(this->font()); + + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } + } + + // Create a selection popup + int maxVisibleItems = 6; + int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = popup->horizontalScrollBar(); + if (hsb && hsb->isVisible()) { + h += popup->horizontalScrollBar()->sizeHint().height(); + } + + QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + int w = 20 + strLength * fm.horizontalAdvance('9'); + + popup->setGeometry(pos.x(), pos.y(), w, h); + + // Show the popup + if (!popup->isVisible()) { + popup->show(); + } + + // If this is the start of an input block, check that it belongs here + } else if(selectedText.contains(":start ")) { + + // If we're inside another input block that we have a template for, + // Check to this that this is a valid input block to exist here + if(inputBlockTemplate) { + + // Get the block title + QString blockTitle; + int pos = selectedText.lastIndexOf(":start "); + pos += 7; + int endPos = selectedText.indexOf(":",pos); + if(endPos > 0) { + blockTitle = selectedText.mid(pos, endPos-pos); + } + + QList extraSelections = this->extraSelections(); + QTextEdit::ExtraSelection selection; + selection.cursor = textCursor(); + selection.cursor.joinPreviousEditBlock(); + + // Select the whole line + selection.cursor.movePosition(QTextCursor::StartOfBlock); + selection.cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + + // Reset the format to have no red underline + QTextCharFormat format; + format.setUnderlineStyle(QTextCharFormat::NoUnderline); + + cout << "test " << blockTitle.toLatin1().data() << endl; + auto inputPtr = inputBlockTemplate->getBlockInput(blockTitle.toStdString()); + if(!inputPtr) { + cout << "test2 " << blockTitle.toLatin1().data() << endl; + // Red underline the input tag + // Select the input tag + selection.cursor.movePosition(QTextCursor::StartOfBlock); + + // If whitespace was trimmed from the start of the line, + // we account for it so only the input tag is underlined + int originalEqualsPos = cursor.block().text().lastIndexOf(":"); + int numWhitespace = countStartingWhitespace(cursor.block().text()); + if(numWhitespace > 0) { + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, numWhitespace); + } + + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, originalEqualsPos - numWhitespace); + + // Set the format to have a red underline + format.setUnderlineColor(QColor("red")); + format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); + } + + selection.cursor.setCharFormat(format); + + selection.cursor.endEditBlock(); + extraSelections.append(selection); + setExtraSelections(extraSelections); + } } } void EGS_Editor::insertCompletion(QModelIndex index) { + this->moveCursor(QTextCursor::EndOfBlock); insertPlainText(model->data(index).toString()); } shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { - QString library; - vector stopList; + + blockTitle = getBlockTitle(); + if(blockTitle.size() < 1) { + return nullptr; + } + + QString library = getInputValue("library", textCursor().block()); + + // If we couldn't find a library tag in the current block, + // try searching the containing block (if there is one) + if(library.size() < 1) { + // If we're current on a :start line, start searching on the next line + // so that we're actually starting within the block + QTextBlock blockEnd; + if(textCursor().block().text().contains(":start ")) { + blockEnd = getBlockEnd(textCursor().block().next()); + } else { + blockEnd = getBlockEnd(textCursor().block()); + } + if(!blockEnd.isValid()) { + return nullptr; + } + + // Go to the line after the end of the current input block + blockEnd = blockEnd.next(); + + // Check for the library tag here + library = getInputValue("library", blockEnd); + } + + cout << "test getBlockInput " << blockTitle.toLatin1().data() << " " << library.toLatin1().data() << endl; + + // If we got the library tag, we can directly look up this input block structure + if(library.size() > 0) { + shared_ptr inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); + if(inputBlock) { + return inputBlock; + } + } + + return nullptr; +} + +QString EGS_Editor::getBlockTitle() { + vector innerList; + QString blockTitle; bool withinOtherBlock = false; + + // Starting at the current line, starting iterating in reverse through + // the previous lines for(QTextBlock block = textCursor().block(); block.isValid(); block = block.previous()) { QString line = block.text().simplified(); + // Get block title + int pos = line.lastIndexOf(":start "); + if(pos >= 0) { + pos += 7; + int endPos = line.indexOf(":",pos); + if(endPos > 0) { + blockTitle = line.mid(pos, endPos-pos); + if(innerList.size() > 0 && blockTitle == innerList.back()) { + innerList.pop_back(); + blockTitle.clear(); + withinOtherBlock = false; + } else { + break; + } + } + } + + // Save a vector of blocks that have already been closed + // This means both a matching :start and :stop are above the cursor + // so we're not inside the block + pos = line.lastIndexOf(":stop "); + if(pos >= 0) { + pos += 6; + int endPos = line.indexOf(":",pos); + if(endPos > 0) { + QString stopTitle = line.mid(pos, endPos-pos); + innerList.push_back(stopTitle); + withinOtherBlock = true; + } + } + } + + return blockTitle; +} + +QString EGS_Editor::getInputValue(QString inp, QTextBlock currentBlock) { + QString value; + vector innerList; + bool withinOtherBlock = false; + + // Get the last textblock in this input block + // so that we search all the inputs in the block + QTextBlock blockEnd = getBlockEnd(currentBlock); + if(!blockEnd.isValid()) { + return ""; + } + + // Starting at the last line, start iterating in reverse through + // the previous lines + blockEnd = blockEnd.previous(); + for(QTextBlock block = blockEnd; block.isValid(); block = block.previous()) { + QString line = block.text().simplified(); + // Get block library for input blocks based on a shared library // e.g. geometries and sources // Only look for the library tag if we're not in a sub-block int pos; if(!withinOtherBlock) { - pos = line.lastIndexOf("library ="); + pos = line.lastIndexOf(inp.simplified()); if(pos >= 0) { - pos += 9; - library = line.mid(pos, line.size()-pos).simplified(); + int pos2 = line.lastIndexOf("="); + if(pos2 > pos) { + value = line.right(line.size()-pos2-1).simplified(); + break; + } } } @@ -364,13 +597,14 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { startPos += 7; int endPos = line.indexOf(":",startPos); if(endPos > 0) { - blockTitle = line.mid(pos, endPos-pos); - if(stopList.size() > 0 && blockTitle == stopList.back()) { - stopList.pop_back(); - blockTitle.clear(); + QString blockTitle = line.mid(pos, endPos-pos); + if(innerList.size() > 0 && blockTitle == innerList.back()) { + innerList.pop_back(); withinOtherBlock = false; } else { - break; + // If we got to the start of the block, + // then we failed to find the input + return ""; } } } @@ -384,23 +618,127 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { int endPos = line.indexOf(":",pos); if(endPos > 0) { QString stopTitle = line.mid(pos, endPos-pos); - stopList.push_back(stopTitle); + innerList.push_back(stopTitle); withinOtherBlock = true; } } } - // If we got the library tag, we can directly look up this input block structure - if(library.size() > 0) { - shared_ptr inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); - if(inputBlock) { - return inputBlock; + return value; +} + +QTextBlock EGS_Editor::getBlockEnd(QTextBlock currentBlock) { + vector innerList; + bool withinOtherBlock = false; + + // Starting at the current line, starting iterating in forward through + // the next lines + for(QTextBlock block = currentBlock; block.isValid(); block = block.next()) { + QString line = block.text().simplified(); + + // Save a vector of blocks that are contained within this input block + // This means both a matching :start and :stop are below the cursor + // so we're not inside the block + int pos = line.lastIndexOf(":start "); + if(pos >= 0) { + pos += 7; + int endPos = line.indexOf(":",pos); + if(endPos > 0) { + QString startTitle = line.mid(pos, endPos-pos); + innerList.push_back(startTitle); + withinOtherBlock = true; + } + } + + // Save a vector of blocks that are contained within this input block + // so that we can skip them + pos = line.lastIndexOf(":stop "); + if(pos >= 0) { + pos += 6; + int startPos = line.indexOf(":",pos); + if(startPos > 0) { + QString blockTitle = line.mid(pos, startPos-pos); + if(innerList.size() > 0 && blockTitle == innerList.back()) { + innerList.pop_back(); + blockTitle.clear(); + withinOtherBlock = false; + } else { + return block; + } + } } } - return nullptr; + return QTextBlock(); +} + +bool EGS_Editor::inputHasDependency(shared_ptr inp) { + auto dependencyInp = inp->getDependencyInp(); + if(dependencyInp.size() < 1) { + return false; + } else { + return true; + } +} + +/*bool EGS_Editor::inputHasDependency(shared_ptr inp) { + auto dependencyInp = inp->getDependencyInp(); + if(!dependencyInp) { + return false; + } else { + return true; + } +}*/ + +bool EGS_Editor::inputDependencySatisfied(shared_ptr inp) { + + auto dependencyInp = inp->getDependencyInp(); + if(dependencyInp.size() < 1) { + return false; + } + auto dependencyVal = inp->getDependencyVal(); + + // Loop through the dependencies + bool satisfied = false; + size_t i = 0; + for(auto &depInp: dependencyInp) { + + string depTag = depInp->getTag(); + + // Get the value from the input file + QString val = getInputValue(QString::fromStdString(depTag), textCursor().block()); + + // Do an OR operation + if(egsEquivStr(val.toLatin1().data(), dependencyVal[i])) { + return true; + } + + ++i; + } + + return satisfied; } +/*bool EGS_Editor::inputDependencySatisfied(shared_ptr inp) { + + shared_ptr dependencyInp = inp->getDependencyInp(); + if(!dependencyInp) { + return false; + } + + // Get the input tag that we're looking for + string dependencyTag = dependencyInp->getTag(); + string dependencyVal = inp->getDependencyVal(); + + QString val = getInputValue(QString::fromStdString(dependencyTag), textCursor().block()); + + if(egsEquivStr(val.toLatin1().data(), dependencyVal.c_str())) { + return true; + } else { + return false; + } +}*/ + void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) { QPainter painter(lineNumberArea); //painter.fillRect(event->rect(), QColor(Qt::lightGray).lighter(110)); @@ -460,6 +798,44 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { cursor.removeSelectedText(); } return true; + } else if(keyEvent->key() == Qt::Key_Return) { + QTextCursor cursor = textCursor(); + QString line = cursor.block().text(); + + // Get the current indentation amount + QString indentation; + for(size_t i = 0; i < line.size(); ++i) { + if(line.at(i) == ' ') { + indentation += ' '; + } else if(line.at(i) == '\t') { + indentation += " "; + } else { + break; + } + } + + QString stopLine; + int pos = line.lastIndexOf(":start "); + if(pos > -1) { + stopLine = line.replace(pos, 7, ":stop "); + } + + // If we inserted the ":stop" line, then also insert a line between + // and leave the cursor there + if(stopLine.size() > 0) { + insertPlainText("\n" + indentation + " "); + insertPlainText("\n" + stopLine); + cursor.movePosition(QTextCursor::PreviousBlock); + cursor.movePosition(QTextCursor::EndOfBlock); + setTextCursor(cursor); + + // Normally, we just insert a new line with matching indentation + } else { + insertPlainText("\n" + indentation); + } + + // Skip the usual return event! So we have to handle it here + return true; } } else if(event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { popup->hide(); diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h index 66fe149d3..ff29a3826 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.h +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -40,14 +40,17 @@ private slots: private: shared_ptr getBlockInput(QString &blockTitle); + QString getBlockTitle(); + QString getInputValue(QString inp, QTextBlock currentBlock); + QTextBlock getBlockEnd(QTextBlock currentBlock); + bool inputHasDependency(shared_ptr inp); + bool inputDependencySatisfied(shared_ptr inp); int countStartingWhitespace(const QString &s); QWidget *lineNumberArea; shared_ptr inputStruct; QListView *popup; QStringListModel *model; - QTextCharFormat normalFormat, - invalidFormat; }; diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 004833cab..027550082 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -278,7 +278,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) vector> singleInputs = geom->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getAttribute().c_str()); + egsInformation(" single %s\n", inp->getTag().c_str()); for (auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } @@ -290,7 +290,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) vector> singleInputs = block->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getAttribute().c_str()); + egsInformation(" single %s\n", inp->getTag().c_str()); for (auto&& val : vals) { egsInformation(" %s\n", val.c_str()); } From 212a9f228f152f8ac0fb8585f3294020d7e6279a Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 13 Mar 2020 15:24:49 -0400 Subject: [PATCH 07/40] Add egs_view editor input dependency checking --- HEN_HOUSE/egs++/egs_input_struct.cpp | 21 ++- HEN_HOUSE/egs++/egs_input_struct.h | 5 +- HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp | 4 +- .../egs_cd_geometry/egs_cd_geometry.cpp | 8 +- .../egs++/geometry/egs_cones/egs_cones.cpp | 129 ++++++++++++++---- HEN_HOUSE/egs++/view/egs_editor.cpp | 120 +++++++++------- HEN_HOUSE/egs++/view/egs_editor.h | 2 +- 7 files changed, 207 insertions(+), 82 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index b8e5ea2b9..add5943aa 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -135,6 +135,20 @@ vector> EGS_BlockInput::getBlockInputs() { return blockInputs; } +vector> EGS_BlockInput::getBlockInputs(string title) { + if(egsEquivStr(this->getTitle(), title)) { + return blockInputs; + } else { + for(auto &block: blockInputs) { + if(egsEquivStr(block->getTitle(), title)) { + return block->getBlockInputs(); + } + } + } + + return {}; +} + shared_ptr EGS_BlockInput::getSingleInput(string inputTag) { for(auto& inp : singleInputs) { // TODO: this assumes unique inputTag @@ -255,9 +269,10 @@ EGS_SingleInput::EGS_SingleInput(string inputTag, bool isReq, const string desc, EGS_SingleInput::~EGS_SingleInput() {} -void EGS_SingleInput::addDependency(shared_ptr inp, string val) { +void EGS_SingleInput::addDependency(shared_ptr inp, string val, bool isAntiDependency) { dependencyInp.push_back(inp); dependencyVal.push_back(val); + dependencyAnti.push_back(isAntiDependency); } vector> EGS_SingleInput::getDependencyInp() { @@ -268,6 +283,10 @@ vector EGS_SingleInput::getDependencyVal() { return dependencyVal; } +vector EGS_SingleInput::getDependencyAnti() { + return dependencyAnti; +} + string EGS_SingleInput::getTag() { return tag; } diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index 7ba723e9c..6db6cc7bd 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -60,9 +60,10 @@ class EGS_EXPORT EGS_SingleInput { bool getRequired(); const vector getValues(); string getDescription(); - void addDependency(shared_ptr inp, string val=""); + void addDependency(shared_ptr inp, string val="", bool isAntiDependency = false); vector> getDependencyInp(); vector getDependencyVal(); + vector getDependencyAnti(); private: @@ -73,6 +74,7 @@ class EGS_EXPORT EGS_SingleInput { vector values; vector> dependencyInp; vector dependencyVal; + vector dependencyAnti; }; class EGS_EXPORT EGS_BlockInput @@ -89,6 +91,7 @@ class EGS_EXPORT EGS_BlockInput vector> getSingleInputs(); vector> getSingleInputs(string title); vector> getBlockInputs(); + vector> getBlockInputs(string title); shared_ptr getSingleInput(string inputTag); shared_ptr getSingleInput(string inputTag, string title); shared_ptr getBlockInput(string title); diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp index 82a827020..8f4473d55 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -82,8 +82,8 @@ extern "C" { setBaseGeometryInputs(); // Format: name, isRequired, description, vector string of allowed values - blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso", vector(1, typeStr)); - blockInput->addSingleInput("box size", true, "1 number defining the side-length of a cube, or 3 numbers defining the x, y, and z side-lengths"); + blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso.", vector(1, typeStr)); + blockInput->addSingleInput("box size", true, "1 number defining the side-length of a cube, or 3 numbers defining the x, y, and z side-lengths."); } EGS_BOX_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp index 157949974..c11087b13 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp @@ -121,11 +121,11 @@ extern "C" { setBaseGeometryInputs(false); // Format: name, isRequired, description, vector string of allowed values - blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso", vector(1, typeStr)); + blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso.", vector(1, typeStr)); - blockInput->addSingleInput("base geometry", true, "The name of the geometry that defines regions for this 'cutting device'. It is within these regions that other geometries will be placed to create a composite geometry"); - blockInput->addSingleInput("set geometry", true, "The region number in the base geometry, followed by the name of the geometry to place in that region. If this geometry extends beyond the region boundaries, it will be cut to size"); - blockInput->addSingleInput("new indexing style", false, "Set to 1 to use a new region numbering algorithm. Defaults to 0, to use the original indexing style"); + blockInput->addSingleInput("base geometry", true, "The name of the geometry that defines regions for this 'cutting device'. It is within these regions that other geometries will be placed to create a composite geometry."); + blockInput->addSingleInput("set geometry", true, "The region number in the base geometry, followed by the name of the geometry to place in that region. If this geometry extends beyond the region boundaries, it will be cut to size."); + blockInput->addSingleInput("new indexing style", false, "Set to 1 to use a new region numbering algorithm. Defaults to 0, to use the original indexing style."); } EGS_CDGEOMETRY_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp index b9a952d4d..5c75ad43a 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -256,42 +256,121 @@ extern "C" { setBaseGeometryInputs(false); // Format: name, isRequired, description, vector string of allowed values - blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso", {"EGS_Cones"}); - auto typePtr = blockInput->addSingleInput("type", true, "The type of cone", {"EGS_SimpleCone", "EGS_ParallelCones", "EGS_ConeSet", "EGS_ConeStack"}); + blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso.", {"EGS_Cones"}); + auto typePtr = blockInput->addSingleInput("type", true, "The type of cone.", {"EGS_ConeStack", "EGS_SimpleCone", "EGS_ParallelCones", "EGS_ConeSet"}); - blockInput->addSingleInput("axis", false, "The unit vector defining the axis along the length of the cones. Layers or cones are added sequentially in the vector direction"); + blockInput->addSingleInput("axis", false, "The unit vector defining the axis along the length of the cones. Layers or cones are added sequentially in the vector direction."); - auto inpPtr = blockInput->addSingleInput("apex", false, "TODO"); - inpPtr->addDependency(typePtr,"EGS_SimpleCone"); - inpPtr->addDependency(typePtr,"EGS_ParallelCones"); - inpPtr->addDependency(typePtr,"EGS_ConeSet"); + auto inpPtr = blockInput->addSingleInput("apex", false, "The position of the cone apex (x, y, z). For EGS_ParallelCones, this is the position of the first cone apex."); + inpPtr->addDependency(typePtr, "EGS_SimpleCone"); + inpPtr->addDependency(typePtr, "EGS_ParallelCones"); + inpPtr->addDependency(typePtr, "EGS_ConeSet"); + // EGS_ConeStack auto blockPtr = blockInput->addBlockInput("layer"); - blockPtr->addDependency(typePtr,"EGS_ConeStack"); - blockPtr->addSingleInput("thickness", true, "TODO"); - blockPtr->addSingleInput("top radii", false, "TODO"); - blockPtr->addSingleInput("bottom radii", true, "TODO"); - blockPtr->addSingleInput("media", true, "TODO"); + blockPtr->addDependency(typePtr, "EGS_ConeStack"); + blockPtr->addSingleInput("thickness", true, "The thickness of the layer."); + blockPtr->addSingleInput("top radii", false, "A list of the top cone radii. If omitted, the top radii are assumed to be the same as a bottom radii from the previous layer. This improves the algorithm efficiency."); + blockPtr->addSingleInput("bottom radii", true, "A list of the bottom cone radii."); + blockPtr->addSingleInput("media", true, "A list of media names, one for each region."); // EGS_ConeSet - //auto anglesPtr = blockInput->addSingleInput("opening angles", false, "TODO")->addDependency(typePtr, "EGS_ConeSet"); -// inpPtr = blockInput->addSingleInput("opening angles in radian", false, "TODO")->addDependency(typePtr, "EGS_ConeSet"); - //inpPtr->addDependency(anglesPtr, "", true); - + auto anglesPtr = blockInput->addSingleInput("opening angles", false, "A list of angles in degrees."); + anglesPtr->addDependency(typePtr, "EGS_ConeSet"); + auto anglesRadPtr = blockInput->addSingleInput("opening angles in radian", false, "A list of angles in radians."); + anglesRadPtr->addDependency(typePtr, "EGS_ConeSet"); + // Only one of these inputs two can be included + anglesRadPtr->addDependency(anglesPtr, "", true); + anglesPtr->addDependency(anglesRadPtr, "", true); + blockInput->addSingleInput("flag", false, "0 or 1 or 2. This input affects the region numbering algorithm; see the documentation for details.")->addDependency(typePtr, "EGS_ConeSet"); + + // EGS_SimpleCone + auto anglePtr = blockInput->addSingleInput("opening angle", false, "The opening angle of the cone in degrees."); + anglePtr->addDependency(typePtr, "EGS_SimpleCone"); + anglePtr->addDependency(typePtr, "EGS_ParallelCones"); + blockInput->addSingleInput("height", false, "The height of the cone."); + + // EGS_ParallelCones + blockInput->addSingleInput("apex distances", false, "A list of distances from the first apex."); } EGS_CONES_EXPORT string getExample(string type) { string example; example = {R"( - :start geometry: - library = EGS_CDGeometry - name = my_cd - base geometry = my_regions - # set geometry = 1 geom means: - # in region 1 of the basegeometry, use geometry named "geom" - set geometry = 0 my_geom1 - set geometry = 1 my_geom2 + # Examples of each of the egs_cones types follow + # Simply uncomment the :start line for the example that you + # wish to use + + # EGS_ConeStack example + #:start geometry: + library = egs_cones + type = EGS_ConeStack + name = my_conestack + axis = 1.2417 0 0 -1 0 0 + :start layer: + thickness = 0.0417 + top radii = 0. + bottom radii = 0.0858 + media = water + :stop layer: + :start layer: + thickness = 0.1283 + top radii = 0. 0.0858 + bottom radii = 0.3125 0.35 + media = air water + :stop layer: + :start layer: + thickness = 0.2217 + bottom radii = 0.3125 0.35 + media = air water + :stop layer: + :start layer: + thickness = 2.05 + top radii = 0.050 0.3125 0.35 + bottom radii = 0.050 0.3125 0.35 + media = water air water + :stop layer: + :stop geometry: + + # EGS_SimpleCone example + #:start geometry: + library = egs_cones + type = EGS_SimpleCone + name = my_simple_cone + apex = 0 0 3 + axis = 0 0 -1 + height = 4 + opening angle = 30 # deg + :start media input: + media = water + :stop media input: + :stop geometry: + + # EGS_ParallelCones example + #:start geometry: + library = egs_cones + type = EGS_ParallelCones + name = my_parallel_cones + apex = 0 0 6 + axis = 0 0 -1 + apex distances = 1 2 3 + opening angle = 30 # deg + :stop geometry: + + # EGS_ConeSet example + #:start geometry: + name = my_coneset + library = egs_cones + type = EGS_ConeSet + apex = 0 0 3 + axis = 0 0 -1 + opening angles = 10 20 30 + :start media input: + media = water air water + set medium = 1 1 + set medium = 2 2 + :stop media input: :stop geometry: )"}; return example; @@ -367,7 +446,7 @@ extern "C" { return 0; } - // adjust lable region numbering in each layer + // adjust label region numbering in each layer int count=0; for (size_t i=0; i> singleInputs = inputBlockTemplate->getSingleInputs(blockTitle.toStdString()); + vector> blockInputs = inputBlockTemplate->getBlockInputs(blockTitle.toStdString()); + // Populate the popup list QStringList itemList; @@ -369,6 +371,9 @@ void EGS_Editor::autoComplete() { itemList << QString((inp->getTag() + " = ").c_str()); } } + for(auto &block: blockInputs) { + itemList << QString((":start " + block->getTitle() + ":").c_str()); + } if(itemList.size() > 0) { model->setStringList(itemList); } @@ -432,10 +437,8 @@ void EGS_Editor::autoComplete() { QTextCharFormat format; format.setUnderlineStyle(QTextCharFormat::NoUnderline); - cout << "test " << blockTitle.toLatin1().data() << endl; auto inputPtr = inputBlockTemplate->getBlockInput(blockTitle.toStdString()); if(!inputPtr) { - cout << "test2 " << blockTitle.toLatin1().data() << endl; // Red underline the input tag // Select the input tag selection.cursor.movePosition(QTextCursor::StartOfBlock); @@ -476,7 +479,8 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { return nullptr; } - QString library = getInputValue("library", textCursor().block()); + bool foundTag; + QString library = getInputValue("library", textCursor().block(), foundTag); // If we couldn't find a library tag in the current block, // try searching the containing block (if there is one) @@ -497,11 +501,9 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { blockEnd = blockEnd.next(); // Check for the library tag here - library = getInputValue("library", blockEnd); + library = getInputValue("library", blockEnd, foundTag); } - cout << "test getBlockInput " << blockTitle.toLatin1().data() << " " << library.toLatin1().data() << endl; - // If we got the library tag, we can directly look up this input block structure if(library.size() > 0) { shared_ptr inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); @@ -558,10 +560,11 @@ QString EGS_Editor::getBlockTitle() { return blockTitle; } -QString EGS_Editor::getInputValue(QString inp, QTextBlock currentBlock) { +QString EGS_Editor::getInputValue(QString inp, QTextBlock currentBlock, bool &foundTag) { QString value; vector innerList; bool withinOtherBlock = false; + foundTag = false; // Get the last textblock in this input block // so that we search all the inputs in the block @@ -581,12 +584,16 @@ QString EGS_Editor::getInputValue(QString inp, QTextBlock currentBlock) { // Only look for the library tag if we're not in a sub-block int pos; if(!withinOtherBlock) { - pos = line.lastIndexOf(inp.simplified()); + pos = line.lastIndexOf(inp); if(pos >= 0) { int pos2 = line.lastIndexOf("="); if(pos2 > pos) { - value = line.right(line.size()-pos2-1).simplified(); - break; + QString tag = line.left(pos2).simplified(); + if(egsEquivStr(tag.toStdString(), inp.simplified().toStdString())) { + foundTag = true; + value = line.right(line.size()-pos2-1).simplified(); + break; + } } } } @@ -681,64 +688,81 @@ bool EGS_Editor::inputHasDependency(shared_ptr inp) { } } -/*bool EGS_Editor::inputHasDependency(shared_ptr inp) { - auto dependencyInp = inp->getDependencyInp(); - if(!dependencyInp) { - return false; - } else { - return true; - } -}*/ - bool EGS_Editor::inputDependencySatisfied(shared_ptr inp) { + // This is a list of inputs that the current input depends on auto dependencyInp = inp->getDependencyInp(); if(dependencyInp.size() < 1) { return false; } + // This is a list of values, that each of the dependencies above must match + // These are like the required input parameters that we are checking against auto dependencyVal = inp->getDependencyVal(); + auto dependencyAnti = inp->getDependencyAnti(); // Loop through the dependencies - bool satisfied = false; - size_t i = 0; - for(auto &depInp: dependencyInp) { + vector previousSatisfied; + bool satisfied = true; + string previousTag; + for(size_t i = 0; i < dependencyInp.size(); ++i) { + if(!satisfied) { + break; + } - string depTag = depInp->getTag(); + string depTag = dependencyInp[i]->getTag(); // Get the value from the input file - QString val = getInputValue(QString::fromStdString(depTag), textCursor().block()); + bool foundTag; + QString val = getInputValue(QString::fromStdString(depTag), textCursor().block(), foundTag); - // Do an OR operation - if(egsEquivStr(val.toLatin1().data(), dependencyVal[i])) { - return true; + if(foundTag && !dependencyAnti[i]) { + if(egsEquivStr(val.toLatin1().data(), dependencyVal[i])) { + satisfied = true; + } else { + satisfied = false; + } + } else { + // If this is an anti dependency, then we didn't want to find the tag + if(!foundTag && dependencyAnti[i]) { + satisfied = true; + } else { + satisfied = false; + } } - ++i; + // Look ahead, if the following inputs have the same tag as this one (i) + for(size_t j = i+1; j < dependencyInp.size(); ++j) { + if(egsEquivStr(dependencyInp[j]->getTag(), depTag)) { + // If we already were satisfied by the first one, just skip + // ahead. + // This is because dependencies with the same tag are treated + // with an OR operation + if(satisfied) { + // If we hit the end because all the tags matched, reset i + if(j == dependencyInp.size()-1) { + i = j-1; + } + continue; + } else { + if(egsEquivStr(val.toLatin1().data(), dependencyVal[j])) { + satisfied = true; + // If we hit the end because all the tags matched, reset i + if(j == dependencyInp.size()-1) { + i = j-1; + } + continue; + } + } + } else { + i = j-1; + break; + } + } } return satisfied; } -/*bool EGS_Editor::inputDependencySatisfied(shared_ptr inp) { - - shared_ptr dependencyInp = inp->getDependencyInp(); - if(!dependencyInp) { - return false; - } - - // Get the input tag that we're looking for - string dependencyTag = dependencyInp->getTag(); - string dependencyVal = inp->getDependencyVal(); - - QString val = getInputValue(QString::fromStdString(dependencyTag), textCursor().block()); - - if(egsEquivStr(val.toLatin1().data(), dependencyVal.c_str())) { - return true; - } else { - return false; - } -}*/ - void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) { QPainter painter(lineNumberArea); //painter.fillRect(event->rect(), QColor(Qt::lightGray).lighter(110)); diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h index ff29a3826..8a20c1bfd 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.h +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -41,7 +41,7 @@ private slots: private: shared_ptr getBlockInput(QString &blockTitle); QString getBlockTitle(); - QString getInputValue(QString inp, QTextBlock currentBlock); + QString getInputValue(QString inp, QTextBlock currentBlock, bool &foundTag); QTextBlock getBlockEnd(QTextBlock currentBlock); bool inputHasDependency(shared_ptr inp); bool inputDependencySatisfied(shared_ptr inp); From b7da362269eddc830bfc900e5f3d08dc629b749d Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 13 Mar 2020 16:28:52 -0400 Subject: [PATCH 08/40] Start adding egs_view editor definition blocks --- HEN_HOUSE/egs++/egs_base_geometry.h | 1 + HEN_HOUSE/egs++/egs_input_struct.cpp | 29 ++++++++- HEN_HOUSE/egs++/egs_input_struct.h | 11 ++-- HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp | 3 +- .../egs_cd_geometry/egs_cd_geometry.cpp | 4 +- .../egs++/geometry/egs_cones/egs_cones.cpp | 3 +- HEN_HOUSE/egs++/view/egs_editor.cpp | 61 +++++++++++++++++-- HEN_HOUSE/egs++/view/viewcontrol.cpp | 14 ++++- 8 files changed, 109 insertions(+), 17 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_base_geometry.h b/HEN_HOUSE/egs++/egs_base_geometry.h index 1d1fca46d..d388007a6 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -76,6 +76,7 @@ class label { static shared_ptr blockInput = make_shared("geometry"); static void setBaseGeometryInputs(bool includeMediaBlock = true) { + blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso."); blockInput->addSingleInput("name", true, "The user-declared unique name of this geometry. This is the name you may refer to elsewhere in the input file"); if(includeMediaBlock) { diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index add5943aa..ebf8b41f5 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -42,7 +42,13 @@ EGS_InputStruct::EGS_InputStruct() {} EGS_InputStruct::~EGS_InputStruct() {} -void EGS_InputStruct::addBlockInput(shared_ptr block) { +shared_ptr EGS_InputStruct::addBlockInput(string blockTit, bool isReq) { + blockInputs.push_back(make_shared(blockTit, isReq, nullptr)); + + return blockInputs.back(); +} + +shared_ptr EGS_InputStruct::addBlockInput(shared_ptr block) { blockInputs.push_back(block); } @@ -54,6 +60,16 @@ vector> EGS_InputStruct::getBlockInputs() { return blockInputs; } +shared_ptr EGS_InputStruct::getBlockInput(string title) { + for(auto &block: blockInputs) { + if(egsEquivStr(block->getTitle(), title)) { + return block; + } + } + + return nullptr; +} + shared_ptr EGS_InputStruct::getLibraryBlock(string blockTitle, string libraryName) { // Loop through each input block in the structure to find the library with // the matching name @@ -112,6 +128,13 @@ shared_ptr EGS_BlockInput::addBlockInput(string blockTit, bool i return blockInputs.back(); } +shared_ptr EGS_BlockInput::addBlockInput(shared_ptr block) { + block->setParent(shared_from_this()); + blockInputs.push_back(block); + + return blockInputs.back(); +} + vector> EGS_BlockInput::getSingleInputs() { return singleInputs; } @@ -299,6 +322,10 @@ const vector EGS_SingleInput::getValues() { return values; } +void EGS_SingleInput::setValues(const vector vals) { + values = vals; +} + string EGS_SingleInput::getDescription() { return description; } diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index 6db6cc7bd..a5b70007b 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -58,12 +58,13 @@ class EGS_EXPORT EGS_SingleInput { string getTag(); bool getRequired(); - const vector getValues(); - string getDescription(); void addDependency(shared_ptr inp, string val="", bool isAntiDependency = false); vector> getDependencyInp(); vector getDependencyVal(); vector getDependencyAnti(); + const vector getValues(); + void setValues(const vector vals); + string getDescription(); private: @@ -88,6 +89,7 @@ class EGS_EXPORT EGS_BlockInput string getTitle(); shared_ptr addSingleInput(string inputTag, bool isReq, const string desc, const vector vals = vector()); shared_ptr addBlockInput(string blockTit, bool isReq = false); + shared_ptr addBlockInput(shared_ptr block); vector> getSingleInputs(); vector> getSingleInputs(string title); vector> getBlockInputs(); @@ -121,10 +123,11 @@ class EGS_EXPORT EGS_InputStruct { EGS_InputStruct(); ~EGS_InputStruct(); - void addBlockInput(shared_ptr block); - //void addBlockInput(string blockTit, bool isReq); + shared_ptr addBlockInput(string blockTit, bool isReq = false); + shared_ptr addBlockInput(shared_ptr block); void addBlockInputs(vector> blocks); vector> getBlockInputs(); + shared_ptr getBlockInput(string title); shared_ptr getLibraryBlock(string blockTitle, string libraryName); vector getLibraryOptions(string blockTitle); diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp index 8f4473d55..2ae38cff9 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -81,8 +81,9 @@ extern "C" { setBaseGeometryInputs(); + blockInput->getSingleInput("library")->setValues(vector(1, typeStr)); + // Format: name, isRequired, description, vector string of allowed values - blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso.", vector(1, typeStr)); blockInput->addSingleInput("box size", true, "1 number defining the side-length of a cube, or 3 numbers defining the x, y, and z side-lengths."); } diff --git a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp index c11087b13..295c9b99a 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp @@ -120,9 +120,9 @@ extern "C" { setBaseGeometryInputs(false); - // Format: name, isRequired, description, vector string of allowed values - blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso.", vector(1, typeStr)); + blockInput->getSingleInput("library")->setValues(vector(1, typeStr)); + // Format: name, isRequired, description, vector string of allowed values blockInput->addSingleInput("base geometry", true, "The name of the geometry that defines regions for this 'cutting device'. It is within these regions that other geometries will be placed to create a composite geometry."); blockInput->addSingleInput("set geometry", true, "The region number in the base geometry, followed by the name of the geometry to place in that region. If this geometry extends beyond the region boundaries, it will be cut to size."); blockInput->addSingleInput("new indexing style", false, "Set to 1 to use a new region numbering algorithm. Defaults to 0, to use the original indexing style."); diff --git a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp index 5c75ad43a..9e8d83a4e 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -255,8 +255,9 @@ extern "C" { setBaseGeometryInputs(false); + blockInput->getSingleInput("library")->setValues({"EGS_Cones"}); + // Format: name, isRequired, description, vector string of allowed values - blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso.", {"EGS_Cones"}); auto typePtr = blockInput->addSingleInput("type", true, "The type of cone.", {"EGS_ConeStack", "EGS_SimpleCone", "EGS_ParallelCones", "EGS_ConeSet"}); blockInput->addSingleInput("axis", false, "The unit vector defining the axis along the length of the cones. Layers or cones are added sequentially in the vector direction."); diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 770c41b76..012dc4c29 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -371,8 +371,14 @@ void EGS_Editor::autoComplete() { itemList << QString((inp->getTag() + " = ").c_str()); } } + + // Store the block titles in a set to remove duplicates + QSet blockTitles; for(auto &block: blockInputs) { - itemList << QString((":start " + block->getTitle() + ":").c_str()); + blockTitles << QString((":start " + block->getTitle() + ":").c_str()); + } + for(auto &title: blockTitles) { + itemList << title; } if(itemList.size() > 0) { model->setStringList(itemList); @@ -416,12 +422,12 @@ void EGS_Editor::autoComplete() { if(inputBlockTemplate) { // Get the block title - QString blockTitle; + QString blockTit; int pos = selectedText.lastIndexOf(":start "); pos += 7; int endPos = selectedText.indexOf(":",pos); if(endPos > 0) { - blockTitle = selectedText.mid(pos, endPos-pos); + blockTit = selectedText.mid(pos, endPos-pos); } QList extraSelections = this->extraSelections(); @@ -437,7 +443,7 @@ void EGS_Editor::autoComplete() { QTextCharFormat format; format.setUnderlineStyle(QTextCharFormat::NoUnderline); - auto inputPtr = inputBlockTemplate->getBlockInput(blockTitle.toStdString()); + auto inputPtr = inputBlockTemplate->getBlockInput(blockTit.toStdString()); if(!inputPtr) { // Red underline the input tag // Select the input tag @@ -464,6 +470,47 @@ void EGS_Editor::autoComplete() { extraSelections.append(selection); setExtraSelections(extraSelections); } + + // For geometry and source blocks that don't contain a library line, + // add 'library =' as an option in the popup + } else if(egsEquivStr(blockTitle, "geometry")) { + + // Populate the popup list + QStringList itemList; + itemList << "library"; + if(itemList.size() > 0) { + model->setStringList(itemList); + } + + popup->setModel(model); + popup->setFont(this->font()); + + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } + } + + // Create a selection popup + int maxVisibleItems = 6; + int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = popup->horizontalScrollBar(); + if (hsb && hsb->isVisible()) { + h += popup->horizontalScrollBar()->sizeHint().height(); + } + + QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + int w = 20 + strLength * fm.horizontalAdvance('9'); + + popup->setGeometry(pos.x(), pos.y(), w, h); + + // Show the popup + if (!popup->isVisible()) { + popup->show(); + } } } @@ -512,7 +559,11 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { } } - return nullptr; + // If we didn't get the library tag, we might be in a top-level block + // like a geometry definition. Just return the block with the matching title + shared_ptr inputBlock = inputStruct->getBlockInput(blockTitle.toStdString()); + + return inputBlock; } QString EGS_Editor::getBlockTitle() { diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 027550082..0774087a4 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -248,7 +248,16 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) QStringList libraries = directory.entryList(QStringList() << (lib_prefix+"*"+lib_suffix).c_str(), QDir::Files); QStringList geomLibs, sourceLibs; - shared_ptr inputStruct(new EGS_InputStruct); + // The input template structure + inputStruct = make_shared(); + + // Geometry definition block + auto geomDefPtr = inputStruct->addBlockInput("geometry definition"); + geomDefPtr->addSingleInput("simulation geometry", true, "The name of the geometry that will be used in the simulation, or to be viewed in egs_view. If you have created a composite geometry using many other geometries, name the final composite geometry here. Note that in some applications, the calculation geometry input block overrides this input, but it is still required."); + + // Source definition block + auto srcDefPtr = inputStruct->addBlockInput("source definition"); + srcDefPtr->addSingleInput("simulation source", true, "The name of the source that will be used in the simulation. If you have created a composite source using many other sources, name the final composite source here."); // For each library, try to load it and determine if it is geometry or source for (const auto &lib : libraries) { @@ -273,7 +282,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) shared_ptr geom = getInputs(); if (geom) { - geomTemplates.push_back(geom); + geomDefPtr->addBlockInput(geom); vector> singleInputs = geom->getSingleInputs(); for (auto &inp : singleInputs) { @@ -315,7 +324,6 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } - inputStruct->addBlockInputs(geomTemplates); egsinpEdit->setInputStruct(inputStruct); // Populate the geometry and simulation template lists From 618c6f07524699e0e5c85da8c0ad40e215520d79 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 31 Mar 2020 11:32:26 -0400 Subject: [PATCH 09/40] Add egs_view editor source and shape support --- HEN_HOUSE/egs++/Makefile | 9 +- HEN_HOUSE/egs++/egs_base_geometry.h | 8 +- HEN_HOUSE/egs++/egs_base_source.h | 64 +++ HEN_HOUSE/egs++/egs_input_struct.cpp | 35 +- HEN_HOUSE/egs++/egs_input_struct.h | 7 + HEN_HOUSE/egs++/egs_shapes.h | 24 + HEN_HOUSE/egs++/egs_spectra.cpp | 4 +- HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp | 8 +- .../egs_cd_geometry/egs_cd_geometry.cpp | 10 +- .../egs++/geometry/egs_cones/egs_cones.cpp | 24 +- .../egs_isotropic_source.cpp | 65 +++ HEN_HOUSE/egs++/view/egs_editor.cpp | 453 +++++++++++++----- HEN_HOUSE/egs++/view/egs_editor.h | 39 +- HEN_HOUSE/egs++/view/egs_highlighter.cpp | 2 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 59 ++- HEN_HOUSE/egs++/view/viewcontrol.h | 2 +- 16 files changed, 632 insertions(+), 181 deletions(-) diff --git a/HEN_HOUSE/egs++/Makefile b/HEN_HOUSE/egs++/Makefile index d283ed24b..0ec024bd8 100644 --- a/HEN_HOUSE/egs++/Makefile +++ b/HEN_HOUSE/egs++/Makefile @@ -80,7 +80,8 @@ lib_objects = $(addprefix $(DSO1), $(addsuffix .$(obje), $(all_libs))) #****************************************************************************** -all: $(EGS_BINDIR)egspp$(EXE) $(ABS_DSO)$(libpre)egspp$(libext) $(ABS_DSO)$(libpre)egs_input_struct$(libext) glibs slibs shapes aobjects gtest +#all: $(EGS_BINDIR)egspp$(EXE) $(ABS_DSO)$(libpre)egspp$(libext) $(ABS_DSO)$(libpre)egs_input_struct$(libext) glibs slibs shapes aobjects gtest +all: $(EGS_BINDIR)egspp$(EXE) $(ABS_DSO)$(libpre)egspp$(libext) glibs slibs shapes aobjects gtest $(EGS_BINDIR)egspp$(EXE): $(dso) $(DSO1)egspp.$(obje) $(ABS_DSO)$(libpre)egspp$(libext) $(CXX) $(INC1) $(DEF1) $(opt) $(EOUT)$@ $(DSO1)egspp.$(obje) $(lib_link1) $(link2_prefix)egspp$(link2_suffix) @@ -92,8 +93,8 @@ $(DSO1)egspp.$(obje): egspp.cpp egs_application.h egs_base_geometry.h egs_vector egs_math.h egs_library.h $(config1h) $(CXX) $(INC1) $(DEF1) $(opt) -c $(COUT)$@ $(notdir $(basename $@)).cpp -$(ABS_DSO)$(libpre)egs_input_struct$(libext): $(dso) $(DSO1)egs_input_struct.$(obje) - $(CXX) $(INC1) $(DEFS) $(opt) $(shared) $(DSO1)egs_input_struct.$(obje) $(extra) +#$(ABS_DSO)$(libpre)egs_input_struct$(libext): $(dso) $(DSO1)egs_input_struct.$(obje) $(egspp_objects) +# $(CXX) $(INC1) $(DEFS) $(opt) $(shared) $(DSO1)egs_input_struct.$(obje) $(egspp_objects) $(extra) $(DSO1)egs_interpolator.$(obje): egs_interpolator.cpp egs_interpolator.h \ $(config1h) @@ -139,7 +140,7 @@ $(DSO1)egs_base_source.$(obje): egs_base_source.cpp egs_base_source.h \ egs_vector.h $(config1h) egs_object_factory.h egs_input.h $(DSO1)egs_ensdf.$(obje): egs_ensdf.cpp egs_ensdf.h \ - $(config1h) egs_functions.h egs_math.h egs_alias_table.h egs_atomic_relaxations.h + $(config1h) egs_math.h egs_alias_table.h egs_atomic_relaxations.h $(DSO1)egs_input_struct.$(obje): egs_input_struct.cpp egs_input_struct.h \ $(config1h) diff --git a/HEN_HOUSE/egs++/egs_base_geometry.h b/HEN_HOUSE/egs++/egs_base_geometry.h index d388007a6..a23c5ef7f 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -74,13 +74,13 @@ class label { vector regions; }; -static shared_ptr blockInput = make_shared("geometry"); +static shared_ptr geomBlockInput = make_shared("geometry"); static void setBaseGeometryInputs(bool includeMediaBlock = true) { - blockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso."); - blockInput->addSingleInput("name", true, "The user-declared unique name of this geometry. This is the name you may refer to elsewhere in the input file"); + geomBlockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso."); + geomBlockInput->addSingleInput("name", true, "The user-declared unique name of this geometry. This is the name you may refer to elsewhere in the input file"); if(includeMediaBlock) { - shared_ptr mediaBlock = blockInput->addBlockInput("media input"); + shared_ptr mediaBlock = geomBlockInput->addBlockInput("media input"); mediaBlock->addSingleInput("media", true, "A list of media that are used in this geometry"); mediaBlock->addSingleInput("set medium", false, "TODO"); } diff --git a/HEN_HOUSE/egs++/egs_base_source.h b/HEN_HOUSE/egs++/egs_base_source.h index e509bac1a..2b9f32a0c 100644 --- a/HEN_HOUSE/egs++/egs_base_source.h +++ b/HEN_HOUSE/egs++/egs_base_source.h @@ -45,6 +45,7 @@ #include "egs_vector.h" #include "egs_object_factory.h" #include "egs_functions.h" +#include "egs_input_struct.h" #include #include @@ -55,6 +56,69 @@ using namespace std; class EGS_Input; class EGS_RandomGenerator; +static shared_ptr srcBlockInput = make_shared("source"); +static void setBaseSourceInputs(bool isSimpleSource = true, bool includeSpectrumBlock = true) { + srcBlockInput->addSingleInput("library", true, "The type of source, loaded by shared library in egs++/dso."); + srcBlockInput->addSingleInput("name", true, "The user-declared unique name of this source. This is the name you may refer to elsewhere in the input file"); + + if(isSimpleSource) { + includeSpectrumBlock = true; + srcBlockInput->addSingleInput("charge", true, "The type of particle to emit from the source, as defined by the charge. Use 0 for photons, -1 for electrons and 1 for positrons."); + } + if(includeSpectrumBlock) { + shared_ptr specBlock = srcBlockInput->addBlockInput("spectrum"); + auto typePtr = specBlock->addSingleInput("type", true, "The type of energy distribution for the spectrum.", {"monoenergetic", "Gaussian", "Double Gaussian", "uniform", "tabulated spectrum", "radionuclide"}); + + // Monoenergetic + specBlock->addSingleInput("energy", false, "The kinetic energy of the source particles in MeV.")->addDependency(typePtr, "monoenergetic"); + + // Gaussian & double Gaussian + specBlock->addSingleInput("mean energy", false, "The mean kinetic energy of the source particles in MeV.")->addDependency(typePtr, "Gaussian"); + auto sigmaPtr = specBlock->addSingleInput("sigma", false, "The sigma of the spectrum. For a double Gaussian, input two values."); + sigmaPtr->addDependency(typePtr, "Gaussian"); + sigmaPtr->addDependency(typePtr, "Double Gaussian"); + auto fwhmPtr = specBlock->addSingleInput("fwhm", false, "The full-width-at-half-maximum of the spectrum. For a double Gaussian, input two values."); + fwhmPtr->addDependency(typePtr, "Gaussian"); + fwhmPtr->addDependency(typePtr, "Double Gaussian"); + fwhmPtr->addDependency(sigmaPtr, "", true); + sigmaPtr->addDependency(fwhmPtr, "", true); + + // Uniform + auto rangePtr = specBlock->addSingleInput("range", false, "The minimum and maximum energy for the spectrum, in MeV."); + rangePtr->addDependency(typePtr, "uniform"); + auto minEPtr = specBlock->addSingleInput("minimum energy", false, "The minimum energy for the spectrum, in MeV."); + minEPtr->addDependency(typePtr, "uniform"); + auto maxEPtr = specBlock->addSingleInput("maximum energy", false, "The maximum energy for the spectrum, in MeV."); + maxEPtr->addDependency(typePtr, "uniform"); + minEPtr->addDependency(rangePtr, "", true); + maxEPtr->addDependency(rangePtr, "", true); + rangePtr->addDependency(minEPtr, "", true); + rangePtr->addDependency(maxEPtr, "", true); + + // Tabulated + auto specFilePtr = specBlock->addSingleInput("spectrum file", false, "The full file path to the spectrum file. See documentation for the format of the file."); + specFilePtr->addDependency(typePtr, "tabulated spectrum"); + auto modePtr = specBlock->addSingleInput("spectrum mode", false, "The mode number that denotes how to create the spectrum. Use 0 for histogram counts/bin, 1 for counts/MeV, 2 for a line spectrum and 3 for an interpolated spectrum."); + modePtr->addDependency(typePtr, "tabulated spectrum"); + auto energiesPtr = specBlock->addSingleInput("energies", false, "A list of energies for the spectrum, in MeV. When applicable, this is the upper edge of the bin."); + energiesPtr->addDependency(typePtr, "tabulated spectrum"); + auto probsPtr = specBlock->addSingleInput("probabilities", false, "A list of probabilities for the spectrum. Does not need to be normalized."); + probsPtr->addDependency(typePtr, "tabulated spectrum"); + modePtr->addDependency(specFilePtr, "", true); + energiesPtr->addDependency(specFilePtr, "", true); + probsPtr->addDependency(specFilePtr, "", true); + + // Radionuclide + specBlock->addSingleInput("nuclide", true, "The name of the nuclide to model, e.g. Co-60 or Tc-99m. If the 'ensdf file' input is not specified, then the ENSDF file will be searched for as $HEN_HOUSE/spectra/lnhb/ensdf/nuclide.txt, where nuclide is the text you input. Note that a radionuclide spectrum is ONLY compatible with a radionuclide source.")->addDependency(typePtr, "radionuclide"); + specBlock->addSingleInput("ensdf file", false, "The full path to the ENSDF file to use.")->addDependency(typePtr, "radionuclide"); + specBlock->addSingleInput("relative activity", false, "If multiple radionuclide spectra are specified for a single radionuclide source, this is the relative weight of this spectrum. Defaults to 1.")->addDependency(typePtr, "radionuclide"); + specBlock->addSingleInput("atomic relaxations", false, "The model to use for atomic relaxations resulting from radionuclide decay. Defaults to EADL.", {"eadl", "ensdf", "off"})->addDependency(typePtr, "radionuclide"); + specBlock->addSingleInput("output beta spectra", false, "Whether or not to output as files the beta spectra that are used for sampling beta decay energies. Defaults to No.", {"yes", "no"})->addDependency(typePtr, "radionuclide"); + specBlock->addSingleInput("alpha scoring", false, "The model to use for scoring alpha particles during radionuclide decay. Defaults to Discard.", {"local", "discard"})->addDependency(typePtr, "radionuclide"); + specBlock->addSingleInput("extra transition approximation", false, "Whether or not to use the option that automatically balances transition intensities. Defaults to Off.", {"on","off"})->addDependency(typePtr, "radionuclide"); + } +} + /*! \brief Base source class. All particle sources must be derived from this class. diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index ebf8b41f5..311f143ed 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -89,16 +89,22 @@ vector EGS_InputStruct::getLibraryOptions(string blockTitle) { // E.g. find all the geometry libraries vector libOptions; for(auto& block : blockInputs) { - if(block && block->getTitle() == blockTitle) { - string lib = block->getSingleInput("library")->getValues().front(); - if(lib.size() > 0) { - libOptions.push_back(lib); + egsInformation("test getLibOpt %s %s\n",block->getTitle().c_str(),blockTitle.c_str() ); + // We only search the 2nd-level blocks + // i.e. don't look at the geometry definition block, look at the geometries + for(auto& block2 : block->getBlockInputs()) { + if(block2 && block2->getTitle() == blockTitle) { + string lib = block2->getSingleInput("library")->getValues().front(); + if(lib.size() > 0) { + libOptions.push_back(lib); + } } } } return libOptions; } + EGS_BlockInput::EGS_BlockInput() {} EGS_BlockInput::EGS_BlockInput(string blockTit, bool isReq, shared_ptr par) { @@ -180,6 +186,14 @@ shared_ptr EGS_BlockInput::getSingleInput(string inputTag) { } } + // If not found in the top level, search recursively + for(auto &block: blockInputs) { + auto inp = block->getSingleInput(inputTag); + if(inp) { + return inp; + } + } + return nullptr; } @@ -298,6 +312,11 @@ void EGS_SingleInput::addDependency(shared_ptr inp, string val, dependencyAnti.push_back(isAntiDependency); } +void EGS_SingleInput::addDependency(shared_ptr block, bool isAntiDependency) { + dependencyBlock = block; + dependencyBlockAnti = isAntiDependency; +} + vector> EGS_SingleInput::getDependencyInp() { return dependencyInp; } @@ -310,6 +329,14 @@ vector EGS_SingleInput::getDependencyAnti() { return dependencyAnti; } +shared_ptr EGS_SingleInput::getDependencyBlock() { + return dependencyBlock; +} + +bool EGS_SingleInput::getDependencyBlockAnti() { + return dependencyBlockAnti; +} + string EGS_SingleInput::getTag() { return tag; } diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index a5b70007b..0012ea49b 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -49,6 +49,8 @@ using namespace std; +class EGS_BlockInput; + class EGS_EXPORT EGS_SingleInput { public: @@ -59,9 +61,12 @@ class EGS_EXPORT EGS_SingleInput { string getTag(); bool getRequired(); void addDependency(shared_ptr inp, string val="", bool isAntiDependency = false); + void addDependency(shared_ptr block, bool isAntiDependency = false); vector> getDependencyInp(); vector getDependencyVal(); vector getDependencyAnti(); + shared_ptr getDependencyBlock(); + bool getDependencyBlockAnti(); const vector getValues(); void setValues(const vector vals); string getDescription(); @@ -76,6 +81,8 @@ class EGS_EXPORT EGS_SingleInput { vector> dependencyInp; vector dependencyVal; vector dependencyAnti; + shared_ptr dependencyBlock; + bool dependencyBlockAnti; }; class EGS_EXPORT EGS_BlockInput diff --git a/HEN_HOUSE/egs++/egs_shapes.h b/HEN_HOUSE/egs++/egs_shapes.h index 437c57062..7345c647b 100644 --- a/HEN_HOUSE/egs++/egs_shapes.h +++ b/HEN_HOUSE/egs++/egs_shapes.h @@ -43,12 +43,36 @@ #include "egs_transformations.h" #include "egs_rndm.h" #include "egs_object_factory.h" +#include "egs_input_struct.h" #include using std::string; class EGS_Input; +static void setShapeInputs(shared_ptr shapePtr) { + auto typePtr = shapePtr->addSingleInput("type", true, "The type of shape - this input includes only a small set of simple shapes. For more options, use the 'library' input instead.", {"point", "box", "sphere", "cylinder"}); + + // Point + shapePtr->addSingleInput("position", false, "The x, y, z position that the source will emit particles from.")->addDependency(typePtr, "point"); + + // Box + shapePtr->addSingleInput("box size", false, "The side lengths of the box, in cm. Enter 1 number for a cube, or 3 numbers to denote the x, y, and z side lengths.")->addDependency(typePtr, "box"); + + // Sphere + auto radiusPtr = shapePtr->addSingleInput("radius", false, "The radius of the sphere or cylinder, in cm."); + radiusPtr->addDependency(typePtr, "sphere"); + auto midPtr = shapePtr->addSingleInput("midpoint", false, "The x, y and z coordinates of the midpoint of the sphere or cylinder, in cm. Defaults to 0, 0, 0."); + midPtr->addDependency(typePtr, "sphere"); + + // Cylinder + radiusPtr->addDependency(typePtr, "cylinder"); + midPtr->addDependency(typePtr, "cylinder"); + shapePtr->addSingleInput("height", false, "The height of the cylinder, in cm.")->addDependency(typePtr, "cylinder"); + shapePtr->addSingleInput("phi range", false, "The minimum and maximum phi values, in degrees. This allows you restrict the cylinder to a shape like a slice of pie!")->addDependency(typePtr, "cylinder"); + shapePtr->addSingleInput("axis", false, "A unit vector that defines the axis of the cylinder.")->addDependency(typePtr, "cylinder"); +} + /*! \defgroup Shapes Shapes \brief Shapes are objects that can pick random points within a certain area or volume. diff --git a/HEN_HOUSE/egs++/egs_spectra.cpp b/HEN_HOUSE/egs++/egs_spectra.cpp index 17cdd3922..4e361a4b6 100644 --- a/HEN_HOUSE/egs++/egs_spectra.cpp +++ b/HEN_HOUSE/egs++/egs_spectra.cpp @@ -370,10 +370,10 @@ A spectrum is defined inline as follows: type = tabulated spectrum energies = list of discrete energies or bin edges probabilities = list of probabilities - spectrum type = 0 or 1 or 2 or 3 + spectrum mode = 0 or 1 or 2 or 3 :stop spectrum: \endverbatim -where the meaning of the spectrum type is the same as the mode of a +where the meaning of the spectrum mode is the same as the mode of a spectrum file. */ class EGS_EXPORT EGS_TabulatedSpectrum : public EGS_BaseSpectrum { diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp index 2ae38cff9..28a98d825 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -66,7 +66,7 @@ InputOptions inp; // Process inputs from the egsinp file EGS_BOX_LOCAL int processInputs(EGS_Input *input) { int err = input->getInput(ebox_key1,inp.boxSize); - if(err && blockInput->getSingleInput(ebox_key1)->getRequired()) { + if(err && geomBlockInput->getSingleInput(ebox_key1)->getRequired()) { egsWarning(ebox_message1,ebox_message3); return 0; } @@ -81,10 +81,10 @@ extern "C" { setBaseGeometryInputs(); - blockInput->getSingleInput("library")->setValues(vector(1, typeStr)); + geomBlockInput->getSingleInput("library")->setValues(vector(1, typeStr)); // Format: name, isRequired, description, vector string of allowed values - blockInput->addSingleInput("box size", true, "1 number defining the side-length of a cube, or 3 numbers defining the x, y, and z side-lengths."); + geomBlockInput->addSingleInput("box size", true, "1 number defining the side-length of a cube, or 3 numbers defining the x, y, and z side-lengths."); } EGS_BOX_EXPORT string getExample() { @@ -106,7 +106,7 @@ extern "C" { if(!inputSet) { setInputs(); } - return blockInput; + return geomBlockInput; } EGS_BOX_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp index 295c9b99a..cda3c596b 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp @@ -120,12 +120,12 @@ extern "C" { setBaseGeometryInputs(false); - blockInput->getSingleInput("library")->setValues(vector(1, typeStr)); + geomBlockInput->getSingleInput("library")->setValues(vector(1, typeStr)); // Format: name, isRequired, description, vector string of allowed values - blockInput->addSingleInput("base geometry", true, "The name of the geometry that defines regions for this 'cutting device'. It is within these regions that other geometries will be placed to create a composite geometry."); - blockInput->addSingleInput("set geometry", true, "The region number in the base geometry, followed by the name of the geometry to place in that region. If this geometry extends beyond the region boundaries, it will be cut to size."); - blockInput->addSingleInput("new indexing style", false, "Set to 1 to use a new region numbering algorithm. Defaults to 0, to use the original indexing style."); + geomBlockInput->addSingleInput("base geometry", true, "The name of the geometry that defines regions for this 'cutting device'. It is within these regions that other geometries will be placed to create a composite geometry."); + geomBlockInput->addSingleInput("set geometry", true, "The region number in the base geometry, followed by the name of the geometry to place in that region. If this geometry extends beyond the region boundaries, it will be cut to size."); + geomBlockInput->addSingleInput("new indexing style", false, "Set to 1 to use a new region numbering algorithm. Defaults to 0, to use the original indexing style."); } EGS_CDGEOMETRY_EXPORT string getExample() { @@ -148,7 +148,7 @@ extern "C" { if(!inputSet) { setInputs(); } - return blockInput; + return geomBlockInput; } EGS_CDGEOMETRY_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp index 9e8d83a4e..92c4fecfa 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -255,20 +255,20 @@ extern "C" { setBaseGeometryInputs(false); - blockInput->getSingleInput("library")->setValues({"EGS_Cones"}); + geomBlockInput->getSingleInput("library")->setValues({"EGS_Cones"}); // Format: name, isRequired, description, vector string of allowed values - auto typePtr = blockInput->addSingleInput("type", true, "The type of cone.", {"EGS_ConeStack", "EGS_SimpleCone", "EGS_ParallelCones", "EGS_ConeSet"}); + auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of cone.", {"EGS_ConeStack", "EGS_SimpleCone", "EGS_ParallelCones", "EGS_ConeSet"}); - blockInput->addSingleInput("axis", false, "The unit vector defining the axis along the length of the cones. Layers or cones are added sequentially in the vector direction."); + geomBlockInput->addSingleInput("axis", false, "The unit vector defining the axis along the length of the cones. Layers or cones are added sequentially in the vector direction."); - auto inpPtr = blockInput->addSingleInput("apex", false, "The position of the cone apex (x, y, z). For EGS_ParallelCones, this is the position of the first cone apex."); + auto inpPtr = geomBlockInput->addSingleInput("apex", false, "The position of the cone apex (x, y, z). For EGS_ParallelCones, this is the position of the first cone apex."); inpPtr->addDependency(typePtr, "EGS_SimpleCone"); inpPtr->addDependency(typePtr, "EGS_ParallelCones"); inpPtr->addDependency(typePtr, "EGS_ConeSet"); // EGS_ConeStack - auto blockPtr = blockInput->addBlockInput("layer"); + auto blockPtr = geomBlockInput->addBlockInput("layer"); blockPtr->addDependency(typePtr, "EGS_ConeStack"); blockPtr->addSingleInput("thickness", true, "The thickness of the layer."); blockPtr->addSingleInput("top radii", false, "A list of the top cone radii. If omitted, the top radii are assumed to be the same as a bottom radii from the previous layer. This improves the algorithm efficiency."); @@ -276,23 +276,23 @@ extern "C" { blockPtr->addSingleInput("media", true, "A list of media names, one for each region."); // EGS_ConeSet - auto anglesPtr = blockInput->addSingleInput("opening angles", false, "A list of angles in degrees."); + auto anglesPtr = geomBlockInput->addSingleInput("opening angles", false, "A list of angles in degrees."); anglesPtr->addDependency(typePtr, "EGS_ConeSet"); - auto anglesRadPtr = blockInput->addSingleInput("opening angles in radian", false, "A list of angles in radians."); + auto anglesRadPtr = geomBlockInput->addSingleInput("opening angles in radian", false, "A list of angles in radians."); anglesRadPtr->addDependency(typePtr, "EGS_ConeSet"); // Only one of these inputs two can be included anglesRadPtr->addDependency(anglesPtr, "", true); anglesPtr->addDependency(anglesRadPtr, "", true); - blockInput->addSingleInput("flag", false, "0 or 1 or 2. This input affects the region numbering algorithm; see the documentation for details.")->addDependency(typePtr, "EGS_ConeSet"); + geomBlockInput->addSingleInput("flag", false, "0 or 1 or 2. This input affects the region numbering algorithm; see the documentation for details.")->addDependency(typePtr, "EGS_ConeSet"); // EGS_SimpleCone - auto anglePtr = blockInput->addSingleInput("opening angle", false, "The opening angle of the cone in degrees."); + auto anglePtr = geomBlockInput->addSingleInput("opening angle", false, "The opening angle of the cone in degrees."); anglePtr->addDependency(typePtr, "EGS_SimpleCone"); anglePtr->addDependency(typePtr, "EGS_ParallelCones"); - blockInput->addSingleInput("height", false, "The height of the cone."); + geomBlockInput->addSingleInput("height", false, "The height of the cone."); // EGS_ParallelCones - blockInput->addSingleInput("apex distances", false, "A list of distances from the first apex."); + geomBlockInput->addSingleInput("apex distances", false, "A list of distances from the first apex."); } EGS_CONES_EXPORT string getExample(string type) { @@ -381,7 +381,7 @@ extern "C" { if(!inputSet) { setInputs(); } - return blockInput; + return geomBlockInput; } EGS_CONES_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { diff --git a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp index 4f87e06f6..b469961fa 100644 --- a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp @@ -28,6 +28,7 @@ # Randle Taylor # Marc Chamberland # Ernesto Mainegra-Hing +# Reid Townson # ############################################################################### */ @@ -42,6 +43,9 @@ #include "egs_input.h" #include "egs_math.h" +static string EGS_ISOTROPIC_SOURCE_LOCAL typeStr("EGS_Isotropic_Source"); +static bool EGS_ISOTROPIC_SOURCE_LOCAL inputSet = false; + EGS_IsotropicSource::EGS_IsotropicSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), shape(0), geom(0), regions(0), min_theta(0), max_theta(M_PI), min_phi(0), max_phi(2*M_PI), @@ -152,6 +156,67 @@ void EGS_IsotropicSource::setUp() { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(); + + srcBlockInput->getSingleInput("library")->setValues(vector(1, typeStr)); + + auto shapePtr = srcBlockInput->addBlockInput("shape"); + /* Commented out because I don't think this input is used + Also at this point dependency of a block on an input hasn't been implemented + auto shapeNamePtr = srcBlockInput->addSingleInput("shape name", false, "TODO"); + shapeNamePtr->addDependency(shapePtr, true); + shapePtr->addDependency(shapeNamePtr, true);*/ + + setShapeInputs(shapePtr); + + auto geomPtr = srcBlockInput->addSingleInput("geometry", false, "The name of a geometry, used for complex source shapes. Only particles generated inside the geometry or some of its regions are used."); + auto regPtr = srcBlockInput->addSingleInput("region selection", false, "Include or exclude regions from the named geometry, to define a volume for source particle generation.", {"IncludeAll", "ExcludeAll","IncludeSelected","ExcludeSelected"}); + regPtr->addDependency(geomPtr); + auto selPtr = srcBlockInput->addSingleInput("selected regions", false, "If region selection = IncludeSelected or ExcludeSelected, then this is a list of the regions in the named geometry to include or exclude."); + selPtr->addDependency(geomPtr); + selPtr->addDependency(regPtr); + srcBlockInput->addSingleInput("min theta", false, "The minimum theta angle in degrees, to restrict the directions of source particles. Defaults to 0."); + srcBlockInput->addSingleInput("max theta", false, "The maximum theta angle in degrees, to restrict the directions of source particles. Defaults to 180."); + srcBlockInput->addSingleInput("min phi", false, "The minimum phi angle in degrees, to restrict the directions of source particles. Defaults to 0."); + srcBlockInput->addSingleInput("max phi", false, "The maximum phi angle in degrees, to restrict the directions of source particles. Defaults to 360."); + } + + EGS_ISOTROPIC_SOURCE_EXPORT string getExample() { + string example +{R"( + :start source: + name = my_source + library = egs_isotropic_source + charge = 0 + geometry = my_envelope + region selection = IncludeSelected + selected regions = 1 2 + :start shape: + type = box + box size = 1 2 3 + :start media input: + media = H2O521ICRU + :stop media input: + :stop shape: + :start spectrum: + type = monoenergetic + energy = 1 + :stop spectrum: + :stop source: +)"}; + return example; + } + + EGS_ISOTROPIC_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_ISOTROPIC_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 012dc4c29..a9569ef48 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -1,3 +1,33 @@ +/* +############################################################################### +# +# EGSnrc egs++ egsinp editor +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc 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 Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Reid Townson, 2020 +# +# Contributors: +# +############################################################################### +*/ + #include "egs_editor.h" #include "egs_functions.h" @@ -141,20 +171,22 @@ int EGS_Editor::countStartingWhitespace(const QString &s) { return i; } -void EGS_Editor::autoComplete() { - // Get the text of the current line +void EGS_Editor::validateEntireInput() { + // This actually validates from the current cursor position, + // but we only call this upon loading the file so the cursor is already at the top QTextCursor cursor = textCursor(); - QString selectedText = cursor.block().text().simplified(); - - // If the first character is a "#", ignore this line - if(selectedText.startsWith("#")) { - return; + for (QTextBlock it = cursor.document()->begin(); it != cursor.document()->end(); it = it.next()) { + cursor.movePosition(QTextCursor::NextBlock); + validateLine(cursor); } +} - // Get the input structure - QString blockTitle; - shared_ptr inputBlockTemplate = getBlockInput(blockTitle); +void EGS_Editor::validateLine(QTextCursor cursor) { + QString selectedText = cursor.block().text().simplified(); + QString blockTitle; + shared_ptr inputBlockTemplate = getBlockInput(blockTitle, cursor); + // If we aren't inside an input block, ignore this line if(blockTitle.size() < 1) { return; @@ -166,6 +198,7 @@ void EGS_Editor::autoComplete() { if(equalsPos != -1) { QString inputTag = selectedText.left(equalsPos).simplified(); QString inputVal = selectedText.right(selectedText.size() - equalsPos - 1).simplified(); + egsInformation("test foundEquals %s\n",inputTag.toLatin1().data()); // If we found a template for this type of input block, // check that the input tag (LHS) is valid @@ -173,7 +206,7 @@ void EGS_Editor::autoComplete() { QList extraSelections = this->extraSelections(); QTextEdit::ExtraSelection selection; - selection.cursor = textCursor(); + selection.cursor = cursor; selection.cursor.joinPreviousEditBlock(); // Select the whole line @@ -210,7 +243,7 @@ void EGS_Editor::autoComplete() { // Check if this input has any dependencies // and then confirm that the dependencies are satisfied - if(inputHasDependency(inputPtr) && inputDependencySatisfied(inputPtr) == false) { + if(inputHasDependency(inputPtr) && inputDependencySatisfied(inputPtr, cursor) == false) { // Red underline the input tag // Select the input tag selection.cursor.movePosition(QTextCursor::StartOfBlock); @@ -240,6 +273,43 @@ void EGS_Editor::autoComplete() { extraSelections.append(selection); setExtraSelections(extraSelections); } + } +} + +void EGS_Editor::autoComplete() { + // Get the text of the current line + QTextCursor cursor = textCursor(); + QString selectedText = cursor.block().text().simplified(); + + // Clear the popup string list + model->setStringList(QStringList{}); + popup->setModel(model); + + // If the first character is a "#", ignore this line + if(selectedText.startsWith("#")) { + return; + } + + // Get the input structure + QString blockTitle; + shared_ptr inputBlockTemplate = getBlockInput(blockTitle); + egsInformation("testA %s\n", blockTitle.toLatin1().data()); + + // If we aren't inside an input block, ignore this line + if(blockTitle.size() < 1) { + return; + } + + // Check the validity of the inputs + // If this line contains an "=" then it should match a single input + int equalsPos = selectedText.indexOf("="); + if(equalsPos != -1) { + QString inputTag = selectedText.left(equalsPos).simplified(); + QString inputVal = selectedText.right(selectedText.size() - equalsPos - 1).simplified(); + egsInformation("test foundEquals %s\n",inputTag.toLatin1().data()); + + // Check that the line is valid + validateLine(cursor); // Return if the input value (RHS) is already filled // This way we only offer options for blank inputs @@ -261,36 +331,37 @@ void EGS_Editor::autoComplete() { } if(itemList.size() > 0) { model->setStringList(itemList); - } + - popup->setModel(model); - popup->setFont(this->font()); + popup->setModel(model); + popup->setFont(this->font()); - // Get max string length - int strLength = 0; - for (auto &item: itemList) { - if (item.size() > strLength) { - strLength = item.size(); + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } } - } - // Create a selection popup - int maxVisibleItems = 6; - int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; - QScrollBar *hsb = popup->horizontalScrollBar(); - if (hsb && hsb->isVisible()) { - h += popup->horizontalScrollBar()->sizeHint().height(); - } + // Create a selection popup + int maxVisibleItems = 6; + int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = popup->horizontalScrollBar(); + if (hsb && hsb->isVisible()) { + h += popup->horizontalScrollBar()->sizeHint().height(); + } - QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); - QFontMetrics fm(popup->font()); - int w = 20 + strLength * fm.horizontalAdvance('9'); + QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + int w = 20 + strLength * fm.horizontalAdvance('9'); - popup->setGeometry(pos.x(), pos.y(), w, h); + popup->setGeometry(pos.x(), pos.y(), w, h); - // Show the popup - if (!popup->isVisible()) { - popup->show(); + // Show the popup + if (!popup->isVisible()) { + popup->show(); + } } } else { @@ -300,7 +371,7 @@ void EGS_Editor::autoComplete() { } // Check for this input tag in the template - shared_ptr inp = inputBlockTemplate->getSingleInput(inputTag.toStdString()); + shared_ptr inp = inputBlockTemplate->getSingleInput(inputTag.toStdString(), blockTitle.toStdString()); // Return if we didn't find this input in the template if(!inp) { @@ -322,36 +393,37 @@ void EGS_Editor::autoComplete() { } if(itemList.size() > 0) { model->setStringList(itemList); - } + - popup->setModel(model); - popup->setFont(this->font()); + popup->setModel(model); + popup->setFont(this->font()); - // Get max string length - int strLength = 0; - for (auto &item: itemList) { - if (item.size() > strLength) { - strLength = item.size(); + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } } - } - // Create a selection popup - int maxVisibleItems = 6; - int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; - QScrollBar *hsb = popup->horizontalScrollBar(); - if (hsb && hsb->isVisible()) { - h += popup->horizontalScrollBar()->sizeHint().height(); - } + // Create a selection popup + int maxVisibleItems = 6; + int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = popup->horizontalScrollBar(); + if (hsb && hsb->isVisible()) { + h += popup->horizontalScrollBar()->sizeHint().height(); + } - QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); - QFontMetrics fm(popup->font()); - int w = 20 + strLength * fm.horizontalAdvance('9'); + QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + int w = 20 + strLength * fm.horizontalAdvance('9'); - popup->setGeometry(pos.x(), pos.y(), w, h); + popup->setGeometry(pos.x(), pos.y(), w, h); - // Show the popup - if (!popup->isVisible()) { - popup->show(); + // Show the popup + if (!popup->isVisible()) { + popup->show(); + } } } @@ -368,6 +440,11 @@ void EGS_Editor::autoComplete() { // Add all the single inputs for the top level block for(auto &inp: singleInputs) { if(!egsEquivStr(inp->getTag(), "library")) { + // Skip any inputs that have a dependency which is not satisfied + if(inputHasDependency(inp) && inputDependencySatisfied(inp, cursor) == false) { + continue; + } + itemList << QString((inp->getTag() + " = ").c_str()); } } @@ -382,36 +459,36 @@ void EGS_Editor::autoComplete() { } if(itemList.size() > 0) { model->setStringList(itemList); - } - popup->setModel(model); - popup->setFont(this->font()); + popup->setModel(model); + popup->setFont(this->font()); - // Get max string length - int strLength = 0; - for (auto &item: itemList) { - if (item.size() > strLength) { - strLength = item.size(); + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } } - } - // Create a selection popup - int maxVisibleItems = 6; - int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; - QScrollBar *hsb = popup->horizontalScrollBar(); - if (hsb && hsb->isVisible()) { - h += popup->horizontalScrollBar()->sizeHint().height(); - } + // Create a selection popup + int maxVisibleItems = 6; + int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = popup->horizontalScrollBar(); + if (hsb && hsb->isVisible()) { + h += popup->horizontalScrollBar()->sizeHint().height(); + } - QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); - QFontMetrics fm(popup->font()); - int w = 20 + strLength * fm.horizontalAdvance('9'); + QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + int w = 20 + strLength * fm.horizontalAdvance('9'); - popup->setGeometry(pos.x(), pos.y(), w, h); + popup->setGeometry(pos.x(), pos.y(), w, h); - // Show the popup - if (!popup->isVisible()) { - popup->show(); + // Show the popup + if (!popup->isVisible()) { + popup->show(); + } } // If this is the start of an input block, check that it belongs here @@ -432,7 +509,7 @@ void EGS_Editor::autoComplete() { QList extraSelections = this->extraSelections(); QTextEdit::ExtraSelection selection; - selection.cursor = textCursor(); + selection.cursor = cursor; selection.cursor.joinPreviousEditBlock(); // Select the whole line @@ -473,43 +550,43 @@ void EGS_Editor::autoComplete() { // For geometry and source blocks that don't contain a library line, // add 'library =' as an option in the popup - } else if(egsEquivStr(blockTitle, "geometry")) { + } else if(selectedText.size() == 0 && (egsEquivStr(blockTitle.toStdString(), "geometry") || egsEquivStr(blockTitle.toStdString(), "source"))) { // Populate the popup list QStringList itemList; - itemList << "library"; + itemList << "library = "; if(itemList.size() > 0) { model->setStringList(itemList); - } - popup->setModel(model); - popup->setFont(this->font()); + popup->setModel(model); + popup->setFont(this->font()); - // Get max string length - int strLength = 0; - for (auto &item: itemList) { - if (item.size() > strLength) { - strLength = item.size(); + // Get max string length + int strLength = 0; + for (auto &item: itemList) { + if (item.size() > strLength) { + strLength = item.size(); + } } - } - // Create a selection popup - int maxVisibleItems = 6; - int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; - QScrollBar *hsb = popup->horizontalScrollBar(); - if (hsb && hsb->isVisible()) { - h += popup->horizontalScrollBar()->sizeHint().height(); - } + // Create a selection popup + int maxVisibleItems = 6; + int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = popup->horizontalScrollBar(); + if (hsb && hsb->isVisible()) { + h += popup->horizontalScrollBar()->sizeHint().height(); + } - QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); - QFontMetrics fm(popup->font()); - int w = 20 + strLength * fm.horizontalAdvance('9'); + QPoint pos = this->viewport()->mapToGlobal(this->cursorRect().bottomRight()); + QFontMetrics fm(popup->font()); + int w = 20 + strLength * fm.horizontalAdvance('9'); - popup->setGeometry(pos.x(), pos.y(), w, h); + popup->setGeometry(pos.x(), pos.y(), w, h); - // Show the popup - if (!popup->isVisible()) { - popup->show(); + // Show the popup + if (!popup->isVisible()) { + popup->show(); + } } } } @@ -519,15 +596,18 @@ void EGS_Editor::insertCompletion(QModelIndex index) { insertPlainText(model->data(index).toString()); } -shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { +shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextCursor cursor) { + if(cursor == QTextCursor()) { + cursor = textCursor(); + } - blockTitle = getBlockTitle(); + blockTitle = getBlockTitle(cursor); if(blockTitle.size() < 1) { return nullptr; } bool foundTag; - QString library = getInputValue("library", textCursor().block(), foundTag); + QString library = getInputValue("library", cursor.block(), foundTag); // If we couldn't find a library tag in the current block, // try searching the containing block (if there is one) @@ -535,10 +615,10 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { // If we're current on a :start line, start searching on the next line // so that we're actually starting within the block QTextBlock blockEnd; - if(textCursor().block().text().contains(":start ")) { - blockEnd = getBlockEnd(textCursor().block().next()); + if(cursor.block().text().contains(":start ")) { + blockEnd = getBlockEnd(cursor.block().next()); } else { - blockEnd = getBlockEnd(textCursor().block()); + blockEnd = getBlockEnd(cursor.block()); } if(!blockEnd.isValid()) { return nullptr; @@ -549,10 +629,12 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { // Check for the library tag here library = getInputValue("library", blockEnd, foundTag); + egsInformation("test searching containing block %s\n", library.toLatin1().data()); } // If we got the library tag, we can directly look up this input block structure if(library.size() > 0) { + egsInformation("test getBlockInput %s %s\n", blockTitle.toLatin1().data(), library.toLatin1().data()); shared_ptr inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); if(inputBlock) { return inputBlock; @@ -566,14 +648,18 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle) { return inputBlock; } -QString EGS_Editor::getBlockTitle() { +QString EGS_Editor::getBlockTitle(QTextCursor cursor) { + if(cursor == QTextCursor()) { + cursor = textCursor(); + } + vector innerList; QString blockTitle; bool withinOtherBlock = false; // Starting at the current line, starting iterating in reverse through // the previous lines - for(QTextBlock block = textCursor().block(); block.isValid(); block = block.previous()) { + for(QTextBlock block = cursor.block(); block.isValid(); block = block.previous()) { QString line = block.text().simplified(); // Get block title @@ -658,7 +744,9 @@ QString EGS_Editor::getInputValue(QString inp, QTextBlock currentBlock, bool &fo QString blockTitle = line.mid(pos, endPos-pos); if(innerList.size() > 0 && blockTitle == innerList.back()) { innerList.pop_back(); - withinOtherBlock = false; + if(innerList.size() == 0) { + withinOtherBlock = false; + } } else { // If we got to the start of the block, // then we failed to find the input @@ -732,20 +820,23 @@ QTextBlock EGS_Editor::getBlockEnd(QTextBlock currentBlock) { bool EGS_Editor::inputHasDependency(shared_ptr inp) { auto dependencyInp = inp->getDependencyInp(); - if(dependencyInp.size() < 1) { + auto dependencyBlock = inp->getDependencyBlock(); + if(dependencyInp.size() < 1 && !dependencyBlock) { return false; } else { return true; } } -bool EGS_Editor::inputDependencySatisfied(shared_ptr inp) { +bool EGS_Editor::inputDependencySatisfied(shared_ptr inp, QTextCursor cursor) { + if(cursor == QTextCursor()) { + cursor = textCursor(); + } + bool satisfied = true; // This is a list of inputs that the current input depends on auto dependencyInp = inp->getDependencyInp(); - if(dependencyInp.size() < 1) { - return false; - } + // This is a list of values, that each of the dependencies above must match // These are like the required input parameters that we are checking against auto dependencyVal = inp->getDependencyVal(); @@ -753,7 +844,6 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp) { // Loop through the dependencies vector previousSatisfied; - bool satisfied = true; string previousTag; for(size_t i = 0; i < dependencyInp.size(); ++i) { if(!satisfied) { @@ -764,16 +854,21 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp) { // Get the value from the input file bool foundTag; - QString val = getInputValue(QString::fromStdString(depTag), textCursor().block(), foundTag); + QString val = getInputValue(QString::fromStdString(depTag), cursor.block(), foundTag); if(foundTag && !dependencyAnti[i]) { - if(egsEquivStr(val.toLatin1().data(), dependencyVal[i])) { - satisfied = true; + if(dependencyVal[i].size() > 0) { + if(egsEquivStr(val.toLatin1().data(), dependencyVal[i])) { + satisfied = true; + } else { + satisfied = false; + } } else { - satisfied = false; + satisfied = true; } } else { // If this is an anti dependency, then we didn't want to find the tag + // Note that we don't check the value, only whether or not the input tag is used if(!foundTag && dependencyAnti[i]) { satisfied = true; } else { @@ -791,7 +886,7 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp) { if(satisfied) { // If we hit the end because all the tags matched, reset i if(j == dependencyInp.size()-1) { - i = j-1; + i = j; } continue; } else { @@ -799,21 +894,113 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp) { satisfied = true; // If we hit the end because all the tags matched, reset i if(j == dependencyInp.size()-1) { - i = j-1; + i = j; } continue; } } } else { - i = j-1; + i = j; break; } } } + // Check for any input blocks that this input depends on + // We are doing an AND between the input-type dependencies and the block-type ones + // So we can skip this section if the input-type dependencies failed + if(satisfied) { + auto dependencyBlock = inp->getDependencyBlock(); + + if(dependencyBlock) { + auto dependencyBlockAnti = inp->getDependencyBlockAnti(); + + QTextBlock depBlock = findSiblingBlock(QString::fromStdString(dependencyBlock->getTitle()), cursor.block()); + + if(depBlock.isValid()) { + if(dependencyBlockAnti) { + satisfied = false; + } else { + satisfied = true; + } + } else { + if(dependencyBlockAnti) { + satisfied = true; + } else { + satisfied = false; + } + } + } + } + return satisfied; } +QTextBlock EGS_Editor::findSiblingBlock(QString title, QTextBlock currentBlock) { + vector innerList; + bool withinOtherBlock = false; + + // Get the last textblock in this input block + // so that we search all the inputs in the block + QTextBlock blockEnd = getBlockEnd(currentBlock); + if(!blockEnd.isValid()) { + return QTextBlock(); + } + + // Starting at the last line, start iterating in reverse through + // the previous lines + blockEnd = blockEnd.previous(); + for(QTextBlock block = blockEnd; block.isValid(); block = block.previous()) { + QString line = block.text().simplified(); + + // Find a sibling block with the title we're looking for + // Here we expect to be within another block because the start line counts as inside the block + int pos; + if(withinOtherBlock) { + pos = line.lastIndexOf(":start " + title + ":"); + if(pos >= 0) { + return block; + } + } + + // Get block title + pos = line.lastIndexOf(":start "); + if(pos >= 0) { + pos += 7; + int endPos = line.indexOf(":",pos); + if(endPos > 0) { + QString blockTitle = line.mid(pos, endPos-pos); + if(innerList.size() > 0 && blockTitle == innerList.back()) { + innerList.pop_back(); + if(innerList.size() == 0) { + withinOtherBlock = false; + } + } else { + // If we got to the start of the current block, + // then we failed to find the target block + return QTextBlock(); + } + } + } + + // Save a vector of blocks that have already been closed + // This means both a matching :start and :stop are above the cursor + // so we're not inside the block + pos = line.lastIndexOf(":stop "); + if(pos >= 0) { + pos += 6; + int endPos = line.indexOf(":",pos); + if(endPos > 0) { + QString stopTitle = line.mid(pos, endPos-pos); + innerList.push_back(stopTitle); + withinOtherBlock = true; + } + } + } + + return QTextBlock(); +} + void EGS_Editor::lineNumberAreaPaintEvent(QPaintEvent *event) { QPainter painter(lineNumberArea); //painter.fillRect(event->rect(), QColor(Qt::lightGray).lighter(110)); @@ -891,7 +1078,8 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { QString stopLine; int pos = line.lastIndexOf(":start "); - if(pos > -1) { + int posInBlock = cursor.positionInBlock(); + if(pos > -1 && posInBlock > pos) { stopLine = line.replace(pos, 7, ":stop "); } @@ -912,7 +1100,8 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { // Skip the usual return event! So we have to handle it here return true; } - } else if(event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { + //} else if(event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { + } else if(event->type() == QEvent::FocusOut) { popup->hide(); } diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h index 8a20c1bfd..e7bd2ad85 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.h +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -1,3 +1,33 @@ +/* +############################################################################### +# +# EGSnrc egs++ egsinp editor +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc 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 Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Reid Townson, 2020 +# +# Contributors: +# +############################################################################### +*/ + #ifndef EGS_EDITOR_H #define EGS_EDITOR_H @@ -26,6 +56,7 @@ class EGS_Editor : public QPlainTextEdit { void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth(); void setInputStruct(shared_ptr inp); + void validateEntireInput(); protected: void resizeEvent(QResizeEvent *event) override; @@ -34,17 +65,19 @@ class EGS_Editor : public QPlainTextEdit { private slots: void updateLineNumberAreaWidth(int newBlockCount); void highlightCurrentLine(); + void validateLine(QTextCursor line); void autoComplete(); void insertCompletion(QModelIndex index); void updateLineNumberArea(const QRect &, int); private: - shared_ptr getBlockInput(QString &blockTitle); - QString getBlockTitle(); + shared_ptr getBlockInput(QString &blockTitle, QTextCursor cursor = QTextCursor()); + QString getBlockTitle(QTextCursor cursor = QTextCursor()); QString getInputValue(QString inp, QTextBlock currentBlock, bool &foundTag); QTextBlock getBlockEnd(QTextBlock currentBlock); bool inputHasDependency(shared_ptr inp); - bool inputDependencySatisfied(shared_ptr inp); + bool inputDependencySatisfied(shared_ptr inp, QTextCursor cursor = QTextCursor()); + QTextBlock findSiblingBlock(QString title, QTextBlock currentBlock); int countStartingWhitespace(const QString &s); QWidget *lineNumberArea; diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.cpp b/HEN_HOUSE/egs++/view/egs_highlighter.cpp index 2724f1cf5..3b9abf87e 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.cpp +++ b/HEN_HOUSE/egs++/view/egs_highlighter.cpp @@ -64,7 +64,7 @@ EGS_Highlighter::EGS_Highlighter(QTextDocument *parent) : QSyntaxHighlighter(par nameFormat.setForeground(Qt::darkBlue); nameFormat.setFontWeight(QFont::Bold); - rule.pattern = QRegularExpression("name.*=.*"); + rule.pattern = QRegularExpression("( )*name( )*=.*"); rule.format = nameFormat; highlightingRules.append(rule); diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 0774087a4..c45750055 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -72,7 +72,7 @@ using namespace std; typedef EGS_Application *(*createAppFunction)(int argc, char **argv); typedef EGS_BaseGeometry *(*createGeomFunction)(); -typedef EGS_BaseSource *(*isSourceFunction)(); +typedef EGS_BaseSource *(*createSourceFunction)(); typedef shared_ptr (*getInputsFunction)(); typedef string (*getExampleFunction)(); @@ -273,8 +273,8 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) continue; } - createGeomFunction createGeom = (createGeomFunction) egs_lib.resolve("createGeometry"); - if (createGeom) { + createGeomFunction isGeom = (createGeomFunction) egs_lib.resolve("createGeometry"); + if (isGeom) { egsInformation(" testgeom %s\n",libName.toLatin1().data()); getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); @@ -318,9 +318,49 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } - bool isSource = (bool) egs_lib.resolve("createSource"); + createSourceFunction isSource = (createSourceFunction) egs_lib.resolve("createSource"); if (isSource) { - sourceLibs.append(libName); + egsInformation(" testsrc %s\n",libName.toLatin1().data()); + + getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); + if (getInputs) { + + shared_ptr src = getInputs(); + if (src) { + srcDefPtr->addBlockInput(src); + + vector> singleInputs = src->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + + vector> inputBlocks = src->getBlockInputs(); + for (auto &block : inputBlocks) { + egsInformation(" block %s\n", block->getTitle().c_str()); + vector> singleInputs = block->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + } + } + } + + getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); + if (getExample) { + // Only add geometries to the list that have a function + // to get the input example + sourceLibs.append(libName); + + sourceExamples.push_back(getExample()); + } } } @@ -569,6 +609,7 @@ bool GeometryViewControl::loadInput(bool reloading, EGS_BaseGeometry *simGeom) { // Load the egsinp file into the editor if (file.open(QFile::ReadOnly | QFile::Text)) { egsinpEdit->setPlainText(file.readAll()); + egsinpEdit->validateEntireInput(); } return true; @@ -3156,9 +3197,9 @@ void GeometryViewControl::insertGeomTemplate(int ind) { } void GeometryViewControl::insertSimTemplate(int ind) { - QString selection = comboBox_simTemplate->itemText(ind); - - QTextCursor cursor(egsinpEdit->textCursor()); - egsinpEdit->insertPlainText(selection); + if(ind > 0) { + QTextCursor cursor(egsinpEdit->textCursor()); + egsinpEdit->insertPlainText(QString::fromStdString(sourceExamples[ind-1])); + } } diff --git a/HEN_HOUSE/egs++/view/viewcontrol.h b/HEN_HOUSE/egs++/view/viewcontrol.h index 68e4057a0..fd743b485 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -207,7 +207,7 @@ public slots: vector> scoreArrays; vector geometryNames; vector geomExamples; - vector> geomTemplates; + vector sourceExamples; EGS_BaseGeometry *origSimGeom; EGS_Editor *egsinpEdit; EGS_Highlighter *highlighter; From 406f1742e0b4c9673124c99b1d5f2f3c0f90bd6a Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 3 Apr 2020 14:42:24 -0400 Subject: [PATCH 10/40] Add egs_editor input example menu bar --- HEN_HOUSE/egs++/view/egs_editor.cpp | 59 ++++++++++++++------- HEN_HOUSE/egs++/view/viewcontrol.cpp | 46 +++++++---------- HEN_HOUSE/egs++/view/viewcontrol.h | 8 +-- HEN_HOUSE/egs++/view/viewcontrol.ui | 77 +--------------------------- 4 files changed, 65 insertions(+), 125 deletions(-) diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index a9569ef48..a38707b90 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -216,6 +216,8 @@ void EGS_Editor::validateLine(QTextCursor cursor) { // Reset the format to have no red underline QTextCharFormat format; format.setUnderlineStyle(QTextCharFormat::NoUnderline); + format.setToolTip(""); + selection.cursor.setCharFormat(format); // Check that the input block template contains this type of input // If the input isn't defined, it will return nullptr @@ -239,32 +241,53 @@ void EGS_Editor::validateLine(QTextCursor cursor) { format.setUnderlineColor(QColor("red")); format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); } else { - QTextCharFormat newFormat; + + // Get the description for this input + string desc = inputPtr->getDescription(); // Check if this input has any dependencies // and then confirm that the dependencies are satisfied - if(inputHasDependency(inputPtr) && inputDependencySatisfied(inputPtr, cursor) == false) { - // Red underline the input tag - // Select the input tag - selection.cursor.movePosition(QTextCursor::StartOfBlock); - - // If whitespace was trimmed from the start of the line, - // we account for it so only the input tag is underlined - int originalEqualsPos = cursor.block().text().indexOf("="); - int numWhitespace = countStartingWhitespace(cursor.block().text()); - if(numWhitespace > 0) { - selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, numWhitespace); + if(inputHasDependency(inputPtr)) { + // Add the list of dependencies to the description tooltip + desc += "\nDependencies: "; + auto vals = inputPtr->getDependencyVal(); + int i = 0; + for(auto &inp: inputPtr->getDependencyInp()) { + if(vals[i].size() > 0) { + desc += "'" + inp->getTag() + "=" + vals[i] + "' "; + } else { + desc += "'" + inp->getTag() + "' "; + } + ++i; + } + auto depBlock = inputPtr->getDependencyBlock(); + if(depBlock) { + desc += "':start " + depBlock->getTitle() + ":'"; } - selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, originalEqualsPos - numWhitespace); + if(inputDependencySatisfied(inputPtr, cursor) == false) { + // Red underline the input tag + // Select the input tag + selection.cursor.movePosition(QTextCursor::StartOfBlock); + + // If whitespace was trimmed from the start of the line, + // we account for it so only the input tag is underlined + int originalEqualsPos = cursor.block().text().indexOf("="); + int numWhitespace = countStartingWhitespace(cursor.block().text()); + if(numWhitespace > 0) { + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, numWhitespace); + } + + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, originalEqualsPos - numWhitespace); - // Set the format to have a red underline - format.setUnderlineColor(QColor("red")); - format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); + // Set the format to have a red underline + format.setUnderlineColor(QColor("red")); + format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); + } } // If the input is valid, add the description as a tooltip - format.setToolTip(QString::fromStdString(inputPtr->getDescription())); + format.setToolTip(QString::fromStdString(desc)); } selection.cursor.setCharFormat(format); @@ -900,7 +923,7 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp, QText } } } else { - i = j; + i = j-1; break; } } diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index c45750055..2044c4bdb 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -246,7 +247,14 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) QDir directory(dso_dir.c_str()); QStringList libraries = directory.entryList(QStringList() << (lib_prefix+"*"+lib_suffix).c_str(), QDir::Files); - QStringList geomLibs, sourceLibs; + + // Create an examples drop down menu on the editor tab + QMenuBar* menuBar = new QMenuBar(); + QMenu *exampleMenu = new QMenu("Insert example..."); + menuBar->addMenu(exampleMenu); + QMenu *geomMenu = exampleMenu->addMenu("Geometries"); + QMenu *sourceMenu = exampleMenu->addMenu("Sources"); + editorLayout->setMenuBar(menuBar); // The input template structure inputStruct = make_shared(); @@ -310,11 +318,9 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { - // Only add geometries to the list that have a function - // to get the input example - geomLibs.append(libName); - - geomExamples.push_back(getExample()); + QAction *action = geomMenu->addAction(libName); + action->setData(QString::fromStdString(getExample())); + connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); } } @@ -355,20 +361,14 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { - // Only add geometries to the list that have a function - // to get the input example - sourceLibs.append(libName); - - sourceExamples.push_back(getExample()); + QAction *action = sourceMenu->addAction(libName); + action->setData(QString::fromStdString(getExample())); + connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); } } } egsinpEdit->setInputStruct(inputStruct); - - // Populate the geometry and simulation template lists - comboBox_geomTemplate->addItems(geomLibs); - comboBox_simTemplate->addItems(sourceLibs); } GeometryViewControl::~GeometryViewControl() { @@ -3187,19 +3187,11 @@ void GeometryViewControl::setFontSize(int size) { controlsText->setTextCursor(cursor); } -void GeometryViewControl::insertGeomTemplate(int ind) { - //QString selection = comboBox_geomTemplate->itemText(ind); +void GeometryViewControl::insertInputExample() { + QAction *pAction = qobject_cast(sender()); - if(ind > 0) { - QTextCursor cursor(egsinpEdit->textCursor()); - egsinpEdit->insertPlainText(QString::fromStdString(geomExamples[ind-1])); - } + QTextCursor cursor(egsinpEdit->textCursor()); + egsinpEdit->insertPlainText(pAction->data().toString()); } -void GeometryViewControl::insertSimTemplate(int ind) { - if(ind > 0) { - QTextCursor cursor(egsinpEdit->textCursor()); - egsinpEdit->insertPlainText(QString::fromStdString(sourceExamples[ind-1])); - } -} diff --git a/HEN_HOUSE/egs++/view/viewcontrol.h b/HEN_HOUSE/egs++/view/viewcontrol.h index fd743b485..d0c6c8b90 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -148,8 +148,7 @@ public slots: virtual void changeTrackMaxE(int t); virtual void changeTrackMaxPo(int t); virtual void updateTracks(vector ntracks); - virtual void insertGeomTemplate(int ind); - virtual void insertSimTemplate(int ind); + virtual void insertInputExample(); private: @@ -206,12 +205,13 @@ public slots: energyScaling; vector> scoreArrays; vector geometryNames; - vector geomExamples; - vector sourceExamples; + vector inputExamples; EGS_BaseGeometry *origSimGeom; EGS_Editor *egsinpEdit; EGS_Highlighter *highlighter; EGS_AdvancedApplication *egsApp; + shared_ptr inputStruct; + QMenu *exampleMenu; protected slots: diff --git a/HEN_HOUSE/egs++/view/viewcontrol.ui b/HEN_HOUSE/egs++/view/viewcontrol.ui index 5c206ac72..edcba3f42 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui +++ b/HEN_HOUSE/egs++/view/viewcontrol.ui @@ -1677,50 +1677,7 @@ p, li { white-space: pre-wrap; } Editor - - - - - - - QLayout::SetMaximumSize - - - - - - 0 - 0 - - - - Insert template: - - - - - - - - Geometry - - - - - - - - - Simulation - - - - - - - - - + @@ -2488,38 +2445,6 @@ p, li { white-space: pre-wrap; } - - comboBox_simTemplate - activated(int) - GeometryViewControl - insertSimTemplate(int) - - - 20 - 20 - - - 20 - 20 - - - - - comboBox_geomTemplate - activated(int) - GeometryViewControl - insertGeomTemplate(int) - - - 20 - 20 - - - 20 - 20 - - - ambientLight sliderPressed() From 31d2374135a85555c4e10b3244d825b84a0676bf Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Wed, 13 May 2020 16:11:12 -0400 Subject: [PATCH 11/40] Temp --- HEN_HOUSE/egs++/egs_input_struct.cpp | 40 ++++++++------- HEN_HOUSE/egs++/egs_input_struct.h | 4 +- HEN_HOUSE/egs++/egs_shapes.h | 7 ++- .../egs++/shapes/egs_circle/egs_circle.cpp | 34 ++++++++++++- .../egs_isotropic_source.cpp | 2 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 49 +++++++++++++++++++ 6 files changed, 115 insertions(+), 21 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index 311f143ed..93b2a75a9 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -50,12 +50,20 @@ shared_ptr EGS_InputStruct::addBlockInput(string blockTit, bool shared_ptr EGS_InputStruct::addBlockInput(shared_ptr block) { blockInputs.push_back(block); + + return blockInputs.back(); } void EGS_InputStruct::addBlockInputs(vector> blocks) { blockInputs.insert(blockInputs.end(), blocks.begin(), blocks.end()); } +shared_ptr EGS_InputStruct::addFloatingBlock(shared_ptr block) { + floatingBlocks.push_back(block); + + return floatingBlocks.back(); +} + vector> EGS_InputStruct::getBlockInputs() { return blockInputs; } @@ -94,9 +102,11 @@ vector EGS_InputStruct::getLibraryOptions(string blockTitle) { // i.e. don't look at the geometry definition block, look at the geometries for(auto& block2 : block->getBlockInputs()) { if(block2 && block2->getTitle() == blockTitle) { - string lib = block2->getSingleInput("library")->getValues().front(); - if(lib.size() > 0) { - libOptions.push_back(lib); + vector libAr = block2->getSingleInput("library")->getValues(); + for(auto& lib : libAr) { + if(lib.size() > 0) { + libOptions.push_back(lib); + } } } } @@ -243,22 +253,18 @@ shared_ptr EGS_BlockInput::getParent() { shared_ptr EGS_BlockInput::getLibraryBlock(string blockTitle, string libraryName) { // First search the singleInputs for the library name - // only if the block title matches (e.g. it's a geometry, or a source) - // TODO: remove blockTitle from input params?? - //if(this->getTitle() == blockTitle) { - for(auto &inp: singleInputs) { - if(!inp) { - continue; - } - if(egsEquivStr(inp->getTag(), "library")) { - if(inp->getValues().size() && egsEquivStr(inp->getValues().front(), libraryName)) { - return shared_from_this(); - } else { - break; - } + for(auto &inp: singleInputs) { + if(!inp) { + continue; + } + if(egsEquivStr(inp->getTag(), "library")) { + if(inp->getValues().size() && egsEquivStr(inp->getValues().front(), libraryName)) { + return shared_from_this(); + } else { + break; } } - //} + } // If not found, go through input blocks for(auto &block: blockInputs) { diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index 0012ea49b..8288509c6 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -60,7 +60,7 @@ class EGS_EXPORT EGS_SingleInput { string getTag(); bool getRequired(); - void addDependency(shared_ptr inp, string val="", bool isAntiDependency = false); + void addDependency(shared_ptr inp, string val = "", bool isAntiDependency = false); void addDependency(shared_ptr block, bool isAntiDependency = false); vector> getDependencyInp(); vector getDependencyVal(); @@ -133,6 +133,7 @@ class EGS_EXPORT EGS_InputStruct { shared_ptr addBlockInput(string blockTit, bool isReq = false); shared_ptr addBlockInput(shared_ptr block); void addBlockInputs(vector> blocks); + shared_ptr addFloatingBlock(shared_ptr block); vector> getBlockInputs(); shared_ptr getBlockInput(string title); shared_ptr getLibraryBlock(string blockTitle, string libraryName); @@ -141,6 +142,7 @@ class EGS_EXPORT EGS_InputStruct { private: vector> blockInputs; + vector> floatingBlocks; }; diff --git a/HEN_HOUSE/egs++/egs_shapes.h b/HEN_HOUSE/egs++/egs_shapes.h index 7345c647b..1e0d2ec27 100644 --- a/HEN_HOUSE/egs++/egs_shapes.h +++ b/HEN_HOUSE/egs++/egs_shapes.h @@ -51,7 +51,12 @@ using std::string; class EGS_Input; static void setShapeInputs(shared_ptr shapePtr) { - auto typePtr = shapePtr->addSingleInput("type", true, "The type of shape - this input includes only a small set of simple shapes. For more options, use the 'library' input instead.", {"point", "box", "sphere", "cylinder"}); + auto libPtr = shapePtr->addSingleInput("library", false, "The type of shape, loaded by shared library in egs++/dso."); + auto typePtr = shapePtr->addSingleInput("type", false, "The type of shape - this input includes only a small set of simple shapes. For more options, use the 'library' input instead.", {"point", "box", "sphere", "cylinder"}); + + // Only one of "library" or "type" are allowed + libPtr->addDependency(typePtr, "", true); + typePtr->addDependency(libPtr, "", true); // Point shapePtr->addSingleInput("position", false, "The x, y, z position that the source will emit particles from.")->addDependency(typePtr, "point"); diff --git a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp index 2bd369d39..2ab934e4a 100644 --- a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Reid Townson # ############################################################################### */ @@ -38,8 +38,40 @@ #include "egs_input.h" #include "egs_functions.h" +static string EGS_CIRCLE_LOCAL typeStr("EGS_Circle"); +static bool EGS_CIRCLE_LOCAL inputSet = false; +static shared_ptr EGS_CIRCLE_LOCAL shapeBlockInput = make_shared("shape"); + extern "C" { + static void setInputs() { + inputSet = true; + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", vector(1, typeStr)); + shapeBlockInput->addSingleInput("radius", false, "The radius of the circle."); + shapeBlockInput->addSingleInput("midpoint", false, "The x, y midpoint of the circle, which is in the x-y plane located at z=0. Use an EGS_AffineTransform block to translate or rotate the shape."); + shapeBlockInput->addSingleInput("inner radius", false, "The inner radius, to define a ring. Points will only be sampled within the ring between the 'inner radius' and 'radius'."); + } + + EGS_CIRCLE_EXPORT string getExample() { + string example +{R"( + :start shape: + library = egs_circle + radius = the circle radius + midpoint = Ox, Oy (optional) + inner radius = the inner radius (optional) + :stop shape: +)"}; + return example; + } + + EGS_CIRCLE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_CIRCLE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp index b469961fa..b967fdb67 100644 --- a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp @@ -166,7 +166,7 @@ extern "C" { auto shapePtr = srcBlockInput->addBlockInput("shape"); /* Commented out because I don't think this input is used Also at this point dependency of a block on an input hasn't been implemented - auto shapeNamePtr = srcBlockInput->addSingleInput("shape name", false, "TODO"); + auto shapeNamePtr = srcBlockInput->addSingleInput("shape name", false, "..."); shapeNamePtr->addDependency(shapePtr, true); shapePtr->addDependency(shapeNamePtr, true);*/ diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 2044c4bdb..6e1e9f1f9 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -39,6 +39,7 @@ #include "egs_libconfig.h" #include "egs_functions.h" #include "egs_base_geometry.h" +#include "egs_shapes.h" #include "egs_visualizer.h" #include "egs_timer.h" #include "egs_input.h" @@ -74,6 +75,7 @@ using namespace std; typedef EGS_Application *(*createAppFunction)(int argc, char **argv); typedef EGS_BaseGeometry *(*createGeomFunction)(); typedef EGS_BaseSource *(*createSourceFunction)(); +typedef EGS_BaseShape *(*createShapeFunction)(); typedef shared_ptr (*getInputsFunction)(); typedef string (*getExampleFunction)(); @@ -254,6 +256,10 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) menuBar->addMenu(exampleMenu); QMenu *geomMenu = exampleMenu->addMenu("Geometries"); QMenu *sourceMenu = exampleMenu->addMenu("Sources"); + QMenu *shapeMenu = exampleMenu->addMenu("Shapes"); + QMenu *ausgabMenu = exampleMenu->addMenu("Ausgab/Output"); + QMenu *mediaMenu = exampleMenu->addMenu("Media"); + QMenu *runMenu = exampleMenu->addMenu("Run Control"); editorLayout->setMenuBar(menuBar); // The input template structure @@ -366,6 +372,49 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); } } + + createShapeFunction isShape = (createShapeFunction) egs_lib.resolve("createShape"); + if (isShape) { + egsInformation(" testshape %s\n",libName.toLatin1().data()); + + getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); + if (getInputs) { + + shared_ptr shape = getInputs(); + if (shape) { + inputStruct->addFloatingBlock(shape); + + vector> singleInputs = shape->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + + vector> inputBlocks = shape->getBlockInputs(); + for (auto &block : inputBlocks) { + egsInformation(" block %s\n", block->getTitle().c_str()); + vector> singleInputs = block->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + } + } + } + + getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); + if (getExample) { + QAction *action = shapeMenu->addAction(libName); + action->setData(QString::fromStdString(getExample())); + connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); + } + } } egsinpEdit->setInputStruct(inputStruct); From d6fca0769a93b8f84c433ec2400265024b06efd8 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 7 Jul 2020 12:06:15 -0400 Subject: [PATCH 12/40] Add egs_editor support for transformations --- HEN_HOUSE/egs++/egs_input_struct.cpp | 29 +++++++++++--- HEN_HOUSE/egs++/egs_input_struct.h | 3 +- HEN_HOUSE/egs++/egs_shapes.h | 2 + HEN_HOUSE/egs++/egs_transformations.h | 10 +++++ HEN_HOUSE/egs++/view/egs_editor.cpp | 58 +++++++++++++++++++++++---- HEN_HOUSE/egs++/view/viewcontrol.cpp | 5 ++- 6 files changed, 90 insertions(+), 17 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index 93b2a75a9..fd36f78af 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -58,12 +58,6 @@ void EGS_InputStruct::addBlockInputs(vector> blocks) blockInputs.insert(blockInputs.end(), blocks.begin(), blocks.end()); } -shared_ptr EGS_InputStruct::addFloatingBlock(shared_ptr block) { - floatingBlocks.push_back(block); - - return floatingBlocks.back(); -} - vector> EGS_InputStruct::getBlockInputs() { return blockInputs; } @@ -111,6 +105,23 @@ vector EGS_InputStruct::getLibraryOptions(string blockTitle) { } } } + + // If nothing was found on the 2nd level blocks, search the top level ones + // This is the case for shapes + if(libOptions.size() < 1) { + for(auto& block : blockInputs) { + egsInformation("test getLibOpt2 %s %s\n",block->getTitle().c_str(),blockTitle.c_str() ); + if(block && block->getTitle() == blockTitle) { + vector libAr = block->getSingleInput("library")->getValues(); + for(auto& lib : libAr) { + if(lib.size() > 0) { + libOptions.push_back(lib); + } + } + } + } + } + return libOptions; } @@ -236,6 +247,12 @@ shared_ptr EGS_BlockInput::getBlockInput(string title) { for(auto &block: blockInputs) { if(egsEquivStr(block->getTitle(), title)) { return block; + } else { + // Do a recursive search + auto foundBlock = block->getBlockInput(title); + if(foundBlock) { + return foundBlock; + } } } } diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index 8288509c6..4263487d8 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -133,7 +133,6 @@ class EGS_EXPORT EGS_InputStruct { shared_ptr addBlockInput(string blockTit, bool isReq = false); shared_ptr addBlockInput(shared_ptr block); void addBlockInputs(vector> blocks); - shared_ptr addFloatingBlock(shared_ptr block); vector> getBlockInputs(); shared_ptr getBlockInput(string title); shared_ptr getLibraryBlock(string blockTitle, string libraryName); @@ -142,7 +141,7 @@ class EGS_EXPORT EGS_InputStruct { private: vector> blockInputs; - vector> floatingBlocks; + vector> generalBlocks; }; diff --git a/HEN_HOUSE/egs++/egs_shapes.h b/HEN_HOUSE/egs++/egs_shapes.h index 1e0d2ec27..087dd1ccd 100644 --- a/HEN_HOUSE/egs++/egs_shapes.h +++ b/HEN_HOUSE/egs++/egs_shapes.h @@ -76,6 +76,8 @@ static void setShapeInputs(shared_ptr shapePtr) { shapePtr->addSingleInput("height", false, "The height of the cylinder, in cm.")->addDependency(typePtr, "cylinder"); shapePtr->addSingleInput("phi range", false, "The minimum and maximum phi values, in degrees. This allows you restrict the cylinder to a shape like a slice of pie!")->addDependency(typePtr, "cylinder"); shapePtr->addSingleInput("axis", false, "A unit vector that defines the axis of the cylinder.")->addDependency(typePtr, "cylinder"); + + addTransformationBlock(shapePtr); } /*! \defgroup Shapes Shapes diff --git a/HEN_HOUSE/egs++/egs_transformations.h b/HEN_HOUSE/egs++/egs_transformations.h index 7f471a6ef..2fdaa7d7c 100644 --- a/HEN_HOUSE/egs++/egs_transformations.h +++ b/HEN_HOUSE/egs++/egs_transformations.h @@ -46,6 +46,7 @@ #include "egs_libconfig.h" #include "egs_math.h" #include "egs_functions.h" +#include "egs_input_struct.h" #include @@ -53,6 +54,15 @@ using namespace std; class EGS_Input; +static void addTransformationBlock(shared_ptr blockPtr) { + shared_ptr transBlock = blockPtr->addBlockInput("transformation"); + transBlock->addSingleInput("translation", false, "The x, y, z translation offsets in cm."); + auto vecPtr = transBlock->addSingleInput("rotation vector", false, "Defines a rotation which, when applied to the 3D vector defined by this input, transforms it into a vector along the positive z-axis."); + auto rotPtr = transBlock->addSingleInput("rotation", false, "2, 3 or 9 floating point numbers define a rotation. See the documentation for details."); + vecPtr->addDependency(rotPtr, "", true); + rotPtr->addDependency(vecPtr, "", true); +} + /*! \brief A class for vector rotations. \ingroup egspp_main diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index a38707b90..2a7f0b7ea 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -457,19 +457,21 @@ void EGS_Editor::autoComplete() { vector> blockInputs = inputBlockTemplate->getBlockInputs(blockTitle.toStdString()); + //vector> generalInputs = inputBlockTemplate->getGeneralBlock(blockTitle.toStdString()); + // Populate the popup list QStringList itemList; // Add all the single inputs for the top level block for(auto &inp: singleInputs) { - if(!egsEquivStr(inp->getTag(), "library")) { + //if(!egsEquivStr(inp->getTag(), "library")) { // Skip any inputs that have a dependency which is not satisfied if(inputHasDependency(inp) && inputDependencySatisfied(inp, cursor) == false) { continue; } itemList << QString((inp->getTag() + " = ").c_str()); - } + //} } // Store the block titles in a set to remove duplicates @@ -543,6 +545,7 @@ void EGS_Editor::autoComplete() { QTextCharFormat format; format.setUnderlineStyle(QTextCharFormat::NoUnderline); + egsInformation("testQQ %s %s\n",blockTit.toLatin1().data(), selectedText.toLatin1().data()); auto inputPtr = inputBlockTemplate->getBlockInput(blockTit.toStdString()); if(!inputPtr) { // Red underline the input tag @@ -635,14 +638,25 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // If we couldn't find a library tag in the current block, // try searching the containing block (if there is one) if(library.size() < 1) { - // If we're current on a :start line, start searching on the next line + egsInformation("test searching containing block %s\n", blockTitle.toLatin1().data()); + + // If we're currently on a :start line, start searching on the next line // so that we're actually starting within the block QTextBlock blockEnd; - if(cursor.block().text().contains(":start ")) { - blockEnd = getBlockEnd(cursor.block().next()); - } else { - blockEnd = getBlockEnd(cursor.block()); + blockEnd = cursor.block(); + int loopGuard = 10000; + int i = 0; + while(blockEnd.text().contains(":start ")) { + blockEnd = getBlockEnd(blockEnd.next()); + if(++i > loopGuard) { + egsInformation("Warning: Encountered infinite loop while processing the input file. Contact the developers to report this bug.\n"); + break; + } + if(blockEnd.isValid()) { + blockEnd = blockEnd.next(); + } } + blockEnd = getBlockEnd(blockEnd); if(!blockEnd.isValid()) { return nullptr; } @@ -652,7 +666,35 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // Check for the library tag here library = getInputValue("library", blockEnd, foundTag); - egsInformation("test searching containing block %s\n", library.toLatin1().data()); + + // If we still didn't find the library, search one block higher + if(library.size() < 1) { + egsInformation("test searching containing block2 %s\n", blockTitle.toLatin1().data()); + // If we're currently on a :start line, start searching on the next line + // so that we're actually starting within the block + int loopGuard = 10000; + int i = 0; + while(blockEnd.text().contains(":start ")) { + blockEnd = getBlockEnd(blockEnd.next()); + if(++i > loopGuard) { + egsInformation("Warning: Encountered infinite loop while processing the input file. Contact the developers to report this bug.\n"); + break; + } + if(blockEnd.isValid()) { + blockEnd = blockEnd.next(); + } + } + blockEnd = getBlockEnd(blockEnd); + if(!blockEnd.isValid()) { + return nullptr; + } + + // Go to the line after the end of the current input block + blockEnd = blockEnd.next(); + + // Check for the library tag here + library = getInputValue("library", blockEnd, foundTag); + } } // If we got the library tag, we can directly look up this input block structure diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 6e1e9f1f9..7fdb215dd 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -287,6 +287,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) continue; } + // Geometries createGeomFunction isGeom = (createGeomFunction) egs_lib.resolve("createGeometry"); if (isGeom) { egsInformation(" testgeom %s\n",libName.toLatin1().data()); @@ -330,6 +331,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } + // Sources createSourceFunction isSource = (createSourceFunction) egs_lib.resolve("createSource"); if (isSource) { egsInformation(" testsrc %s\n",libName.toLatin1().data()); @@ -373,6 +375,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } + // Shapes createShapeFunction isShape = (createShapeFunction) egs_lib.resolve("createShape"); if (isShape) { egsInformation(" testshape %s\n",libName.toLatin1().data()); @@ -382,7 +385,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) shared_ptr shape = getInputs(); if (shape) { - inputStruct->addFloatingBlock(shape); + inputStruct->addBlockInput(shape); vector> singleInputs = shape->getSingleInputs(); for (auto &inp : singleInputs) { From 916f1f0215f2746522e9af3b319ca16210d3cd5e Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Mon, 20 Jul 2020 10:21:15 -0400 Subject: [PATCH 13/40] Start adding egs_editor run control support --- HEN_HOUSE/egs++/egs_application.cpp | 1 - HEN_HOUSE/egs++/egs_application.h | 6 +++++ HEN_HOUSE/egs++/egs_base_geometry.h | 2 +- HEN_HOUSE/egs++/egs_input_struct.cpp | 1 + HEN_HOUSE/egs++/egs_run_control.h | 11 +++++++++ HEN_HOUSE/egs++/egs_shapes.h | 10 ++++---- HEN_HOUSE/egs++/view/egs_editor.cpp | 37 ++++++++++++++++------------ HEN_HOUSE/egs++/view/view.pro | 8 +++--- HEN_HOUSE/egs++/view/viewcontrol.cpp | 27 +++++++++++++++++--- 9 files changed, 72 insertions(+), 31 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_application.cpp b/HEN_HOUSE/egs++/egs_application.cpp index 5ed337f77..12866c0e7 100644 --- a/HEN_HOUSE/egs++/egs_application.cpp +++ b/HEN_HOUSE/egs++/egs_application.cpp @@ -44,7 +44,6 @@ #include "egs_input.h" #include "egs_base_source.h" #include "egs_rndm.h" -#include "egs_run_control.h" #include "egs_base_source.h" #include "egs_simple_container.h" #include "egs_ausgab_object.h" diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index 03e4f59e0..de2574cf2 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -45,6 +45,7 @@ #include "egs_simple_container.h" #include "egs_interpolator.h" #include "egs_input_struct.h" +#include "egs_run_control.h" #include #include @@ -1227,6 +1228,11 @@ class EGS_EXPORT EGS_Application { APP_EXPORT EGS_Application* createApplication(int argc, char **argv) {\ return new app_name(argc,argv);\ }\ + APP_EXPORT shared_ptr getAppInputs() {\ + shared_ptr inpPtr;\ + addRunControlBlock(inpPtr);\ + return inpPtr;\ + }\ } diff --git a/HEN_HOUSE/egs++/egs_base_geometry.h b/HEN_HOUSE/egs++/egs_base_geometry.h index a23c5ef7f..9a35b9e9c 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -82,7 +82,7 @@ static void setBaseGeometryInputs(bool includeMediaBlock = true) { if(includeMediaBlock) { shared_ptr mediaBlock = geomBlockInput->addBlockInput("media input"); mediaBlock->addSingleInput("media", true, "A list of media that are used in this geometry"); - mediaBlock->addSingleInput("set medium", false, "TODO"); + mediaBlock->addSingleInput("set medium", false, "2, 3 or 4 integers defining the medium for a region or range of regions.\nFor 2: region #, medium index from the media list for this geometry (starts at 0). For 3: start region, stop region, medium index. For 4: Same as 3, plus a step size for the region range.\nNeglect this input for a homogeneous geometry of the first medium in the media list. Repeat this input to specify each medium."); } } diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index fd36f78af..48555243b 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -64,6 +64,7 @@ vector> EGS_InputStruct::getBlockInputs() { shared_ptr EGS_InputStruct::getBlockInput(string title) { for(auto &block: blockInputs) { + egsInformation("test struct getBlockInput %s\n", block->getTitle().c_str()); if(egsEquivStr(block->getTitle(), title)) { return block; } diff --git a/HEN_HOUSE/egs++/egs_run_control.h b/HEN_HOUSE/egs++/egs_run_control.h index caf91e75d..f7fe6ddf0 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -42,6 +42,7 @@ #include "egs_libconfig.h" #include "egs_timer.h" +#include "egs_input_struct.h" #include using namespace std; @@ -49,6 +50,16 @@ using namespace std; class EGS_Application; class EGS_Input; +static void addRunControlBlock(shared_ptr blockPtr) { + shared_ptr runBlock = blockPtr->addBlockInput("run control"); + runBlock->addSingleInput("ncase", true, "The number of histories to simulate."); + runBlock->addSingleInput("nbatch", false, "The number of batches to divide the simulation into. After each batch, a checkpoint is created to allow for simulation restarts. Defaults to 10."); + runBlock->addSingleInput("max cpu hours allowed", false, "The number hours after which the simulation will be haulted. Defaults to -1, which is no limit."); + runBlock->addSingleInput("statistical accuracy sought", false, "The statistical uncertainty for a particular quantity of interest, below which the simulation will be haulted. Note that the quantity must be defined by the application (e.g. the cavity dose in egs_chamber), and in general is undefined."); + runBlock->addSingleInput("geometry error limit", false, "The number of geometry errors that will be allowed to occur, before haulting the simulation. Defaults to 0."); + runBlock->addSingleInput("calculation", false, "The calculation type: first (default, runs a new simulation), restart (resumes a terminated simulation), analyze (prints results), combine (combines results from a parallel run). Defaults to 'first'.", {"first", "restart", "analyze", "combine"}); +} + /*! \brief A simple run control object for advanced EGSnrc C++ applications. \ingroup egspp_main diff --git a/HEN_HOUSE/egs++/egs_shapes.h b/HEN_HOUSE/egs++/egs_shapes.h index 087dd1ccd..d78129cd8 100644 --- a/HEN_HOUSE/egs++/egs_shapes.h +++ b/HEN_HOUSE/egs++/egs_shapes.h @@ -59,13 +59,13 @@ static void setShapeInputs(shared_ptr shapePtr) { typePtr->addDependency(libPtr, "", true); // Point - shapePtr->addSingleInput("position", false, "The x, y, z position that the source will emit particles from.")->addDependency(typePtr, "point"); + shapePtr->addSingleInput("position", true, "The x, y, z position that the source will emit particles from.")->addDependency(typePtr, "point"); // Box - shapePtr->addSingleInput("box size", false, "The side lengths of the box, in cm. Enter 1 number for a cube, or 3 numbers to denote the x, y, and z side lengths.")->addDependency(typePtr, "box"); + shapePtr->addSingleInput("box size", true, "The side lengths of the box, in cm. Enter 1 number for a cube, or 3 numbers to denote the x, y, and z side lengths.")->addDependency(typePtr, "box"); // Sphere - auto radiusPtr = shapePtr->addSingleInput("radius", false, "The radius of the sphere or cylinder, in cm."); + auto radiusPtr = shapePtr->addSingleInput("radius", true, "The radius of the sphere or cylinder, in cm."); radiusPtr->addDependency(typePtr, "sphere"); auto midPtr = shapePtr->addSingleInput("midpoint", false, "The x, y and z coordinates of the midpoint of the sphere or cylinder, in cm. Defaults to 0, 0, 0."); midPtr->addDependency(typePtr, "sphere"); @@ -73,9 +73,9 @@ static void setShapeInputs(shared_ptr shapePtr) { // Cylinder radiusPtr->addDependency(typePtr, "cylinder"); midPtr->addDependency(typePtr, "cylinder"); - shapePtr->addSingleInput("height", false, "The height of the cylinder, in cm.")->addDependency(typePtr, "cylinder"); + shapePtr->addSingleInput("height", true, "The height of the cylinder, in cm.")->addDependency(typePtr, "cylinder"); shapePtr->addSingleInput("phi range", false, "The minimum and maximum phi values, in degrees. This allows you restrict the cylinder to a shape like a slice of pie!")->addDependency(typePtr, "cylinder"); - shapePtr->addSingleInput("axis", false, "A unit vector that defines the axis of the cylinder.")->addDependency(typePtr, "cylinder"); + shapePtr->addSingleInput("axis", true, "A unit vector that defines the axis of the cylinder.")->addDependency(typePtr, "cylinder"); addTransformationBlock(shapePtr); } diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 2a7f0b7ea..f241d49ed 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -245,6 +245,11 @@ void EGS_Editor::validateLine(QTextCursor cursor) { // Get the description for this input string desc = inputPtr->getDescription(); + bool isRequired = inputPtr->getRequired(); + if(isRequired) { + desc += "\nRequired."; + } + // Check if this input has any dependencies // and then confirm that the dependencies are satisfied if(inputHasDependency(inputPtr)) { @@ -317,6 +322,9 @@ void EGS_Editor::autoComplete() { QString blockTitle; shared_ptr inputBlockTemplate = getBlockInput(blockTitle); egsInformation("testA %s\n", blockTitle.toLatin1().data()); + if(inputBlockTemplate) { + egsInformation("test foundtemplate\n"); + } // If we aren't inside an input block, ignore this line if(blockTitle.size() < 1) { @@ -657,15 +665,13 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC } } blockEnd = getBlockEnd(blockEnd); - if(!blockEnd.isValid()) { - return nullptr; - } - - // Go to the line after the end of the current input block - blockEnd = blockEnd.next(); + if(blockEnd.isValid()) { + // Go to the line after the end of the current input block + blockEnd = blockEnd.next(); - // Check for the library tag here - library = getInputValue("library", blockEnd, foundTag); + // Check for the library tag here + library = getInputValue("library", blockEnd, foundTag); + } // If we still didn't find the library, search one block higher if(library.size() < 1) { @@ -685,15 +691,13 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC } } blockEnd = getBlockEnd(blockEnd); - if(!blockEnd.isValid()) { - return nullptr; - } - - // Go to the line after the end of the current input block - blockEnd = blockEnd.next(); + if(blockEnd.isValid()) { + // Go to the line after the end of the current input block + blockEnd = blockEnd.next(); - // Check for the library tag here - library = getInputValue("library", blockEnd, foundTag); + // Check for the library tag here + library = getInputValue("library", blockEnd, foundTag); + } } } @@ -709,6 +713,7 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // If we didn't get the library tag, we might be in a top-level block // like a geometry definition. Just return the block with the matching title shared_ptr inputBlock = inputStruct->getBlockInput(blockTitle.toStdString()); + egsInformation("test returning top level block\n"); return inputBlock; } diff --git a/HEN_HOUSE/egs++/view/view.pro b/HEN_HOUSE/egs++/view/view.pro index 8eb7fa42d..adf929600 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -58,7 +58,7 @@ win32 { DEFINES += WIN32 DEFINES += VDEBUG RC_FILE = egs_view.rc - LIBS += ../dso/$$my_machine/egspp.lib ../dso/$$my_machine/egs_input_struct.lib + LIBS += ../dso/$$my_machine/egspp.lib DESTDIR = ../dso/$$my_machine TARGET = egs_view } @@ -66,7 +66,7 @@ win32 { unix { CONFIG += qt warn_on release $$my_build macx { - LIBS += -L../dso/$$my_machine -legspp -legs_input_struct + LIBS += -L../dso/$$my_machine -legspp TARGET = ../../bin/$$my_machine/egs_view } !macx { @@ -74,13 +74,13 @@ unix { !contains( CONFIG, static ){ message( "Dynamic build..." ) TARGET = egs_view - LIBS += -L../dso/$$my_machine -Wl,-rpath,$$hhouse/egs++/dso/$$my_machine -legspp -legs_input_struct + LIBS += -L../dso/$$my_machine -Wl,-rpath,$$hhouse/egs++/dso/$$my_machine -legspp } contains( CONFIG, static ){ message( "Static build ..." ) DESTDIR = ../../pieces/linux #LIBS += -L../dso/$$my_machine -Wl,-rpath,$$hhouse/egs++/dso/$$my_machine -legspp # Fixes path to library - LIBS += -L$$hhouse/egs++/dso/$$my_machine -legspp -legs_input_struct # Relies on LD_LIBRARY_PATH + LIBS += -L$$hhouse/egs++/dso/$$my_machine -legspp # Relies on LD_LIBRARY_PATH UNAME = $$system(getconf LONG_BIT) contains( UNAME, 64 ){ message( "-> 64 bit ($$SNAME)" ) diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 7fdb215dd..462342edc 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -222,13 +222,13 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) lib_dir += CONFIG_NAME; lib_dir += fs; - EGS_Library egs_lib(app_name.c_str(),lib_dir.c_str()); - if (!egs_lib.load()) egsFatal("\n%s: Failed to load the %s application library from %s\n\n", + EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); + if (!app_lib.load()) egsFatal("\n%s: Failed to load the %s application library from %s\n\n", appv[0],app_name.c_str(),lib_dir.c_str()); - createAppFunction createApp = (createAppFunction) egs_lib.resolve("createApplication"); + createAppFunction createApp = (createAppFunction) app_lib.resolve("createApplication"); if (!createApp) egsFatal("\n%s: Failed to resolve the address of the 'createApplication' function" - " in the application library %s\n\n",appv[0],egs_lib.libraryFile()); + " in the application library %s\n\n",appv[0],app_lib.libraryFile()); /*TODO left here crash 'cause tutor7pp isn't compiled <======================= EGS_Application *app = createApp(appc,appv); if (!app) { @@ -265,6 +265,25 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // The input template structure inputStruct = make_shared(); + // Get the application level input blocks + getInputsFunction getAppInputs = (getInputsFunction) app_lib.resolve("getAppInputs"); + egsInformation("getInputs test0\n"); + if(getAppInputs) { + egsInformation("getInputs test1\n"); + shared_ptr inpBlock = getAppInputs(); + /* if(inpBlock) { + egsInformation("getInputs test2\n"); + for (auto &inp : inpBlock->getSingleInputs()) { + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + inputStruct->addBlockInput(inpBlock); + } */ + } + // Geometry definition block auto geomDefPtr = inputStruct->addBlockInput("geometry definition"); geomDefPtr->addSingleInput("simulation geometry", true, "The name of the geometry that will be used in the simulation, or to be viewed in egs_view. If you have created a composite geometry using many other geometries, name the final composite geometry here. Note that in some applications, the calculation geometry input block overrides this input, but it is still required."); From e320166354a7a82ad11c0c3b8847bd6160d89090 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 23 Jul 2020 11:15:55 -0400 Subject: [PATCH 14/40] Finish adding run control inputs to egs_editor --- HEN_HOUSE/egs++/egs_application.h | 7 +++---- HEN_HOUSE/egs++/egs_run_control.h | 2 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 28 +++++++++++++++------------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index de2574cf2..2e0240f57 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -1228,12 +1228,11 @@ class EGS_EXPORT EGS_Application { APP_EXPORT EGS_Application* createApplication(int argc, char **argv) {\ return new app_name(argc,argv);\ }\ - APP_EXPORT shared_ptr getAppInputs() {\ - shared_ptr inpPtr;\ - addRunControlBlock(inpPtr);\ - return inpPtr;\ + APP_EXPORT void getAppInputs(shared_ptr inpPtr) {\ + addRunControlBlock(inpPtr);\ }\ } #endif + diff --git a/HEN_HOUSE/egs++/egs_run_control.h b/HEN_HOUSE/egs++/egs_run_control.h index f7fe6ddf0..ae7a53b94 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -50,7 +50,7 @@ using namespace std; class EGS_Application; class EGS_Input; -static void addRunControlBlock(shared_ptr blockPtr) { +static void addRunControlBlock(shared_ptr blockPtr) { shared_ptr runBlock = blockPtr->addBlockInput("run control"); runBlock->addSingleInput("ncase", true, "The number of histories to simulate."); runBlock->addSingleInput("nbatch", false, "The number of batches to divide the simulation into. After each batch, a checkpoint is created to allow for simulation restarts. Defaults to 10."); diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 462342edc..8d5814525 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -76,6 +76,7 @@ typedef EGS_Application *(*createAppFunction)(int argc, char **argv); typedef EGS_BaseGeometry *(*createGeomFunction)(); typedef EGS_BaseSource *(*createSourceFunction)(); typedef EGS_BaseShape *(*createShapeFunction)(); +typedef void (*getAppInputsFunction)(shared_ptr inpPtr); typedef shared_ptr (*getInputsFunction)(); typedef string (*getExampleFunction)(); @@ -266,22 +267,23 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) inputStruct = make_shared(); // Get the application level input blocks - getInputsFunction getAppInputs = (getInputsFunction) app_lib.resolve("getAppInputs"); - egsInformation("getInputs test0\n"); + getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); if(getAppInputs) { - egsInformation("getInputs test1\n"); - shared_ptr inpBlock = getAppInputs(); - /* if(inpBlock) { - egsInformation("getInputs test2\n"); - for (auto &inp : inpBlock->getSingleInputs()) { - const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); + getAppInputs(inputStruct); + if(inputStruct) { + vector> inputBlocks = inputStruct->getBlockInputs(); + for (auto &block : inputBlocks) { + egsInformation(" block %s\n", block->getTitle().c_str()); + vector> singleInputs = block->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } } } - inputStruct->addBlockInput(inpBlock); - } */ + } } // Geometry definition block From 85326e6fdc8cb7dc58807b0f96b11117b539574e Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 30 Jul 2020 09:42:46 -0400 Subject: [PATCH 15/40] Improve egs_editor undo history --- HEN_HOUSE/egs++/view/egs_editor.cpp | 6 ++++++ HEN_HOUSE/egs++/view/egs_highlighter.cpp | 12 +++++------- HEN_HOUSE/egs++/view/egs_highlighter.h | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index f241d49ed..92965e288 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -196,6 +196,8 @@ void EGS_Editor::validateLine(QTextCursor cursor) { // If this line contains an "=" then it should match a single input int equalsPos = selectedText.indexOf("="); if(equalsPos != -1) { + cursor.beginEditBlock(); + QString inputTag = selectedText.left(equalsPos).simplified(); QString inputVal = selectedText.right(selectedText.size() - equalsPos - 1).simplified(); egsInformation("test foundEquals %s\n",inputTag.toLatin1().data()); @@ -301,6 +303,7 @@ void EGS_Editor::validateLine(QTextCursor cursor) { extraSelections.append(selection); setExtraSelections(extraSelections); } + cursor.endEditBlock(); } } @@ -626,8 +629,11 @@ void EGS_Editor::autoComplete() { } void EGS_Editor::insertCompletion(QModelIndex index) { + QTextCursor cursor = textCursor(); + cursor.beginEditBlock(); this->moveCursor(QTextCursor::EndOfBlock); insertPlainText(model->data(index).toString()); + cursor.endEditBlock(); } shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextCursor cursor) { diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.cpp b/HEN_HOUSE/egs++/view/egs_highlighter.cpp index 3b9abf87e..4654e34f3 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.cpp +++ b/HEN_HOUSE/egs++/view/egs_highlighter.cpp @@ -80,15 +80,14 @@ EGS_Highlighter::EGS_Highlighter(QTextDocument *parent) : QSyntaxHighlighter(par // Comment highlighting must come last singleLineCommentFormat.setForeground(Qt::gray); - rule.pattern = QRegularExpression("#[^\n]*"); + rule.pattern = QRegularExpression("(#|//|!)[^\n]*"); rule.format = singleLineCommentFormat; highlightingRules.append(rule); // For multi-line comments - //multiLineCommentFormat.setForeground(Qt::red); - - //commentStartExpression = QRegularExpression("/\\*"); - //commentEndExpression = QRegularExpression("\\*/"); + multiLineCommentFormat.setForeground(Qt::gray); + commentStartExpression = QRegularExpression("/\\*"); + commentEndExpression = QRegularExpression("\\*/"); } void EGS_Highlighter::highlightBlock(const QString &text) { @@ -101,7 +100,6 @@ void EGS_Highlighter::highlightBlock(const QString &text) { } setCurrentBlockState(0); - /* //For multi-line comments int startIndex = 0; if (previousBlockState() != 1) @@ -120,5 +118,5 @@ void EGS_Highlighter::highlightBlock(const QString &text) { } setFormat(startIndex, commentLength, multiLineCommentFormat); startIndex = text.indexOf(commentStartExpression, startIndex + commentLength); - }*/ + } } diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.h b/HEN_HOUSE/egs++/view/egs_highlighter.h index 322024166..a6eadc49e 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.h +++ b/HEN_HOUSE/egs++/view/egs_highlighter.h @@ -61,10 +61,10 @@ class EGS_Highlighter : public QSyntaxHighlighter { definitionFormat, nameFormat, singleLineCommentFormat, + multiLineCommentFormat, quotationFormat, squotationFormat, functionFormat; - //QTextCharFormat multiLineCommentFormat; signals: From 4d2895c1a6a348815e99be8054b7aa3902dd2ab6 Mon Sep 17 00:00:00 2001 From: Gallop Date: Tue, 2 Feb 2021 13:52:41 -0500 Subject: [PATCH 16/40] Add Geometry Input Validation Add support for all of the geometries in the egs_view editor. --- .../egs_autoenvelope/egs_autoenvelope.cpp | 29 +++- .../egs++/geometry/egs_conez/egs_conez.cpp | 28 ++++ .../geometry/egs_cylinders/egs_cylinders.cpp | 64 ++++++++ .../egs_elliptic_cylinders.cpp | 33 +++- .../egs_genvelope/egs_envelope_geometry.cpp | 38 +++++ .../egs++/geometry/egs_glib/egs_glib.cpp | 34 +++++ .../egs_gstack/egs_stack_geometry.cpp | 38 +++++ .../egs_gtransformed/egs_gtransformed.cpp | 48 ++++++ .../geometry/egs_iplanes/egs_iplanes.cpp | 65 ++++++++ .../egs_nd_geometry/egs_nd_geometry.cpp | 143 +++++++++++++++++- .../egs++/geometry/egs_octree/egs_octree.cpp | 30 +++- .../egs++/geometry/egs_planes/egs_planes.cpp | 75 +++++++++ .../egs++/geometry/egs_prism/egs_prism.cpp | 45 ++++++ .../geometry/egs_pyramid/egs_pyramid.cpp | 47 ++++++ .../egs_roundrect_cylinders.cpp | 53 ++++++- HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp | 68 +++++++++ .../egs_smart_envelope/egs_smart_envelope.cpp | 21 +++ .../egs++/geometry/egs_space/egs_space.cpp | 18 +++ .../geometry/egs_spheres/egs_spheres.cpp | 42 +++++ .../geometry/egs_union/egs_union_geometry.cpp | 39 ++++- HEN_HOUSE/egs++/view/viewcontrol.cpp | 22 ++- 21 files changed, 965 insertions(+), 15 deletions(-) diff --git a/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp b/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp index 6af9dc297..e16a7a325 100644 --- a/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp @@ -71,6 +71,7 @@ static char EGS_AENVELOPE_LOCAL transformations_keyword[] = "transformations"; static char EGS_AENVELOPE_LOCAL type_keyword[] = "type"; static char EGS_AENVELOPE_LOCAL transformation_keyword[] = "transformation"; +static bool EGS_AENVELOPE_LOCAL inputSet = false; EGS_AEnvelope::EGS_AEnvelope(EGS_BaseGeometry *base_geom, const vector inscribed, const string &Name, bool debug, string output_vc_file) : @@ -804,7 +805,7 @@ EGS_ASwitchedEnvelope::EGS_ASwitchedEnvelope(EGS_BaseGeometry *base_geom, }; -//TODO: this gets called a lot and is probably quite slow. Instead fo doing a +//TODO: this gets called a lot and is probably quite slow. Instead of doing a //set intersection on every call we can probably do it once when activated //geometries change and cache it vector EGS_ASwitchedEnvelope::getGeomsInRegion(int ireg) { @@ -934,6 +935,32 @@ vector EGS_AEnvelope::createTransforms(EGS_Input *input) extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_AEnvelope"}); + + // Format: name, isRequired, description, vector string of allowed values + geomBlockInput->addSingleInput("type", false, "The type of auto envelope", {"EGS_ASwitchedEnvelope"}); + + geomBlockInput->addSingleInput("incribed geometries", true, "A list of predefined geometries"); + geomBlockInput->addSingleInput("base geometry", true, "The name of a predefined geometry"); + + auto blockPtr = geomBlockInput->addBlockInput("transformation"); + blockPtr->addSingleInput("translation", false, "The translation for the geometry (x, y ,z)"); + auto rotPtr = blockPtr->addSingleInput("rotation", false, "2, 3, or 9 floating point numbers"); + auto vectPtr = blockPtr->addSingleInput("rotation vector", false, "3 floating point numbers"); + } + + EGS_AENVELOPE_EXPORT shared_ptr getInputs() { + if (!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_AENVELOPE_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp b/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp index 8ae3fa39c..43ca3cfb9 100644 --- a/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp @@ -25,6 +25,7 @@ # # Contributors: Marc Chamberland # Frederic Tessier +# Contributors: Hannah Gallop # ############################################################################### */ @@ -38,8 +39,35 @@ string YProjector::type = "EGS_Yconez"; string ZProjector::type = "EGS_Zconez"; string Projector::type = "EGS_conez"; +static bool EGS_CONEZ_LOCAL inputSet = false; + extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_Conez"}); + + // Format: name, description, isRequired, vector string of allowed values + auto typePtr = geomBlockInput->addSingleInput("type", true,"The type of cone", {"EGS_Xconez", "EGS_Yconez", "EGS_Zcones", "EGS_conez"}); + + geomBlockInput->addSingleInput("apex", false, "The position of the cone apex (x, y, z)"); + geomBlockInput->addSingleInput("opening angles", false, "A list of angles in degrees"); + + // EGS_Conez + auto inpPtr = geomBlockInput->addSingleInput("axis", true, "The unit vector defining the length along the conez"); + inpPtr->addDependency(typePtr, "EGS_conez"); + } + + EGS_CONEZ_EXPORT shared_ptr getInputs() { + if (!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_CONEZ_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { // valid input diff --git a/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp b/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp index 1f9ea3a2b..4e1c175cc 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Marc Chamberland # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -39,8 +40,71 @@ #include "egs_cylinders.h" #include "egs_input.h" +static bool EGS_CYLINDERS_LOCAL inputSet = false; + extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_Cylinders"}); + + // Format: name, isRequired, description, vector string of allowd values + auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of cylinder.", {"EGS_XCylinders", "EGS_YCylinders", "EGS_ZCylinders", "EGS_Cylinders"}); + + geomBlockInput->addSingleInput("radii", true, "A list of cylinder radii, must be in increasing order"); + geomBlockInput->addSingleInput("midpoint", false, "The position of the midpoint of the cylinder (x, y, z)"); + + // EGS_Cylinders + auto inpPtr = geomBlockInput->addSingleInput("axis", true, "The unit vector defining the axis along the length of the cylinder."); + inpPtr->addDependency(typePtr, "EGS_Cylinders"); + } + + EGS_CYLINDERS_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Examples of the egs_cylinders to follow + + # EGS_XCylinder example + #:start geometry: + library = egs_cylinders + type = EGS_XCylinders + name = my_xcylinders + radii = 1 2 3 + midpoint = 0 + :start media input: + media = water air water + set medium = 1 1 + set medium = 2 2 + :stop media input: + :stop geometry: + + # EGS_Cylinder example + #:start geometry: + library = egs_cylinders + type = EGS_Cylinders + name = my_cylinder + radii = 7 + axis = 4 3 2 + midpoint = 0 0 0 + :start media input: + media = water + :stop media input: + :stop geometry: +)"}; + return example; + } + + EGS_CYLINDERS_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_CYLINDERS_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { // check for valid input if (!input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.cpp b/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.cpp index 3ff6e585e..847506dae 100644 --- a/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2006 # # Contributors: Marc Chamberland +# Hannah Gallop # ############################################################################### # @@ -44,10 +45,38 @@ #include "egs_elliptic_cylinders.h" #include "egs_input.h" +static bool EGS_ELLIPTIC_CYLINDERS_LOCAL inputSet = false; + extern "C" { - EGS_ELLIPTIC_CYLINDERS_EXPORT - EGS_BaseGeometry *createGeometry(EGS_Input *input) { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_EllipticCylinders"}); + + // Format: name, isRequired, description, vector string of allowed values + auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of elliptic cylinder", {"EGS_EllipticCylindersXY", "EGS_EllipticCylindersXZ", "EGS_EllipticCylindersYZ", "EGS_EllipticCylinders"}); + + geomBlockInput->addSingleInput("midpoint", false, "The midpoint of the cylinder (x, y, z)"); + geomBlockInput->addSingleInput("x-radii", true, "The x radii of the cylinder"); + geomBlockInput->addSingleInput("y-radii", true, "The y radii of the cylinder"); + + auto xaxPtr = geomBlockInput->addSingleInput("x-axis", true, "The x-axis of the cylider (x, y, z)"); + xaxPtr->addDependency(typePtr, "EGS_EllipticCylinders"); + auto yaxPtr = geomBlockInput->addSingleInput("y-axis", true, "The y-axis of the cylinder (x, y, z)"); + yaxPtr->addDependency(typePtr, "EGS_EllipticCylinders"); + } + + EGS_ELLIPTIC_CYLINDERS_EXPORT shared_ptr getInputs() { + if (!inputSet) { + setInputs(); + } + return geomBlockInput; + } + + EGS_ELLIPTIC_CYLINDERS_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { // check for valid input if (!input) { egsWarning("createGeometry(elliptic cylinders): null input?\n"); diff --git a/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp index 56c869d50..8a2d5b6ec 100644 --- a/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Ernesto Mainegra-Hing # Marc Chamberland +# Hannah Gallop # ############################################################################### */ @@ -47,6 +48,8 @@ using namespace std; string EGS_ENVELOPEG_LOCAL EGS_EnvelopeGeometry::type = "EGS_EnvelopeGeometry"; string EGS_ENVELOPEG_LOCAL EGS_FastEnvelope::type = "EGS_FastEnvelope"; +static bool EGS_ENVELOPEG_LOCAL inputSet = false; + void EGS_EnvelopeGeometry::setMedia(EGS_Input *,int,const int *) { egsWarning("EGS_EnvelopeGeometry::setMedia: don't use this method. Use the\n" " setMedia() methods of the geometry objects that make up this geometry\n"); @@ -359,6 +362,41 @@ static char EGS_ENVELOPEG_LOCAL eeg_keyword2[] = "geometry"; static char EGS_ENVELOPEG_LOCAL eeg_keyword3[] = "inscribed geometries"; extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_GEnvelope"}); + + // Format: name, isRequired, description, vector string of allowed values + auto typePtr = geomBlockInput->addSingleInput("type", false, "The type of envelope", {"EGS_FastEnvelope"}); + geomBlockInput->addSingleInput("base geometry", true, "The name of a previously defined geometry"); + geomBlockInput->addSingleInput("inscribed geometries", true, "A list of names of previously defined geometries, must be stictly inside the envelope"); + } + + EGS_ENVELOPEG_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_genvelope + #:start geometry: + name = my_envelope + library = egs_genvelope + base_geometry = my_box + inscribed geometries: geom1 geom2 + # create geometries geom1 geom2 + #:stop geometry: +)"}; + return example; + } + + EGS_ENVELOPEG_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } EGS_ENVELOPEG_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_glib/egs_glib.cpp b/HEN_HOUSE/egs++/geometry/egs_glib/egs_glib.cpp index e8cf786d9..24db6b099 100644 --- a/HEN_HOUSE/egs++/geometry/egs_glib/egs_glib.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_glib/egs_glib.cpp @@ -27,6 +27,7 @@ # Contributors: Marc Chamberland # Rowan Thomson # Dave Rogers +# Hannah Gallop # ############################################################################### # @@ -50,9 +51,42 @@ #include "egs_functions.h" #include "egs_glib.h" +static bool EGS_GLIB_LOCAL inputSet = false; extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_Glib"}); + + // Format: name, isRequired, description, vector string of allowed values + geomBlockInput->addSingleInput("include file", true, "The path to some geometry."); + } + + EGS_GLIB_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_glib + #:start geometry: + name = my_glib + library = egs_glib + include file = /path to some external file/ + :stop geometry: +)"}; + return example; + } + + EGS_GLIB_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } + /*! createGeometry function for glib shim */ EGS_GLIB_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp index 3bd1cb47c..1599f066d 100644 --- a/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp @@ -27,6 +27,7 @@ # Marc Chamberland # Ernesto Mainegra-Hing # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -44,6 +45,8 @@ string EGS_StackGeometry::type = "EGS_StackGeometry"; +static bool EGS_STACKG_LOCAL inputSet = false; + EGS_StackGeometry::EGS_StackGeometry(const vector &geoms, const string &Name) : EGS_BaseGeometry(Name) { if (geoms.size() < 2) egsFatal("EGS_StackGeometry::EGS_StackGeometry: " @@ -123,6 +126,41 @@ void EGS_StackGeometry::setBScaling(EGS_Input *) { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_GStack"}); + + // Format: name, isRequired, description, vector string of allowed values + geomBlockInput->addSingleInput("geometries", true, "A list of names of previously defined geometries"); + geomBlockInput->addSingleInput("tolerance", false, "A small floating number boundaryTolerance"); + } + + EGS_STACKG_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_gstack + :start geometry: + name = my_gstack + library = egs_gstack + geometries = geom1 geom2 + # create geometries called geom1 geom2 + tolerance = 1e-4 + :stop geometry: +)"}; + return example; + } + + EGS_STACKG_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_STACKG_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { egsWarning("createGeometry(stack): null input?\n"); diff --git a/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp b/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp index 3215adc54..5b5377b65 100644 --- a/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp @@ -27,6 +27,7 @@ # Ernesto Mainegra-Hing # Hubert Ho # Marc Chamberland +# Hannah Gallop # ############################################################################### */ @@ -42,6 +43,8 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_GTRANSFORMED_LOCAL inputSet = false; + void EGS_TransformedGeometry::setMedia(EGS_Input *,int,const int *) { egsWarning("EGS_TransformedGeometry::setMedia: don't use this method. Use the\n" " setMedia() methods of the geometry objects that make up this geometry\n"); @@ -69,6 +72,51 @@ void EGS_TransformedGeometry::setBScaling(EGS_Input *) { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_GTransformed"}); + + // Format: name, isRequired, description, vector string of allowed values + geomBlockInput->addSingleInput("my geometry", true, "The name of a previously defined geometry"); + + auto blockPtr = geomBlockInput->addBlockInput("transformation"); + blockPtr->addSingleInput("translation", false, "The translation for the geometry (x, y ,z)"); + auto rotPtr = blockPtr->addSingleInput("rotation", false, "2, 3, or 9 floating point numbers"); + auto vectPtr = blockPtr->addSingleInput("rotation vector", false, "3 floating point numbers"); + // Can either have "rotation" or "rotation vector" + rotPtr->addDependency(vectPtr, "", true); + vectPtr->addDependency(rotPtr, "", true); + } + + EGS_GTRANSFORMED_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_gtransformed + #:start geometry: + name = my_gtransform + library = egs_gtransformed + my geometry = geom + # created a geometry called geom + :start transformation: + translation = 0 0.5 0 + rotation = 0.05 0 -1 + :stop transformation: + :stop geometry: +)"}; + return example; + } + + EGS_GTRANSFORMED_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_GTRANSFORMED_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { EGS_BaseGeometry *g = 0; EGS_Input *ij = input->takeInputItem("geometry",false); diff --git a/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp b/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp index 42b5aa5df..ffca4097b 100644 --- a/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp @@ -25,6 +25,7 @@ # # Contributors: Frederic Tessier # Marc Chamberland +# Hannah Gallop # ############################################################################### */ @@ -48,6 +49,8 @@ using namespace std; string EGS_IPlanes::type = "EGS_IPlanes"; string EGS_RadialRepeater::type = "EGS_RadialRepeater"; +static bool EGS_IPLANES_LOCAL inputSet = false; + EGS_IPlanes::EGS_IPlanes(const EGS_Vector &Xo, const EGS_Vector &A, int np, const EGS_Float *angles, const string &Name, bool degree) : EGS_BaseGeometry(Name), xo(Xo), axis(A) { @@ -258,6 +261,68 @@ void EGS_RadialRepeater::printInfo() const { } extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_IPlanes"}); + + // Format: name, isRequired, description, vector string of allowed values + auto typePtr = geomBlockInput->addSingleInput("type", false, "The type of iplane", {"EGS_RadialRepeater"}); + + geomBlockInput->addSingleInput("axis", true, "A list of three coordinates of a point on the axis and three direction cosines defining the axis direction"); + + // EGS_IPlane + auto anglesPtr = geomBlockInput->addSingleInput("angles", false, "A list of angles of rotation around the axis for the planes in degrees, must be in increasing order and between 0 and 180"); + auto anglesRadPtr = geomBlockInput->addSingleInput("angles in radian", false, "A list of angles of ratation around the axis for the planes in degrees, in increasing order"); + // Only one of these two inputs can be included + anglesRadPtr->addDependency(anglesPtr, "", true); + anglesRadPtr->addDependency(typePtr, "", true); + anglesPtr->addDependency(anglesRadPtr, "", true); + anglesPtr->addDependency(typePtr, "", true); + + // EGS_RadialRepeater + auto geoPtr = geomBlockInput->addSingleInput("repeated geometry", true, "The exsisting geometry that is repeated"); + geoPtr->addDependency(typePtr, "EGS_RadialRepeater"); + auto numPtr = geomBlockInput->addSingleInput("number of repetitions", true, "The number of times the geometry is repeated"); + numPtr->addDependency(typePtr, "EGS_RadialRepeater"); + auto medPtr = geomBlockInput->addSingleInput("medium", false, "The medium with which the space outside the replicated geometry is filled"); + medPtr->addDependency(typePtr, "EGS_RadialRepeater"); + auto firstanglePtr = geomBlockInput->addSingleInput("first angle", false, "First angle, phi_o"); + firstanglePtr->addDependency(typePtr, "EGS_RadialRepeater"); + } + + EGS_IPLANES_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_iplanes + #:start geometry: + library = egs_iplanes + name = my_iplane + axis = 0 0 0 0 0 1 + angles = 0 30 60 90 120 150 + :stop geometry: + + # Example of EGS_RadialRepeater + #:start geometry: + library = egs_iplanes + type = EGS_RadialRepeater + axis = 0 0 1 0 0 1 + number of repetitions = 5 + repeated geometry = my_geom + # use with geometry called my_geom +)"}; + return example; + } + + EGS_IPLANES_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } EGS_IPLANES_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp index 39ab38c6f..e85221f59 100644 --- a/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp @@ -31,6 +31,7 @@ # Manuel Stoeckl # Marc Chamberland # Martin Martinov +# Hannah Gallop # ############################################################################### */ @@ -1079,9 +1080,149 @@ const char *err_msg1 = "createGeometry(EGS_XYZRepeater)"; #endif -string EGS_NDGeometry::type = "EGS_NDGeometry"; +static string EGS_NDG_LOCAL typeStr("EGS_NDGeometry"); +string EGS_NDGeometry::type(typeStr); + +static bool EGS_NDG_LOCAL inputSet = false; extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_NDGeometry"}); + + // Format: name, isRequired, description, vector string of allowed values + auto typePtr = geomBlockInput->addSingleInput("type", false, "type of nd_geometry", {"EGS_XYZGeometry", "EGS_XYZRepeater"}); + + auto dimPtr = geomBlockInput->addSingleInput("dimensions", true, "A list of previously defined geometries."); + dimPtr->addDependency(typePtr, "", true); + auto hownPtr = geomBlockInput->addSingleInput("hownear method", false, "0(for orthogonal constituent geometries) or 1"); + hownPtr->addDependency(typePtr, "", true); + + // EGS_XYZGeometry + // First method + auto xPtr = geomBlockInput->addSingleInput("x-planes", false, "A list of the x-plane positions"); + xPtr->addDependency(typePtr, "EGS_XYZGeometry"); + auto yPtr = geomBlockInput->addSingleInput("y-planes", false, "A list of the y-plane positions"); + yPtr->addDependency(typePtr, "EGS_XYZGeometry"); + auto zPtr = geomBlockInput->addSingleInput("z-planes", false, "A list of the z-plane positions"); + zPtr->addDependency(typePtr, "EGS_XYZGeometry"); + + // Second method + auto densityPtr = geomBlockInput->addSingleInput("density matrix", false, "Density file"); + densityPtr->addDependency(typePtr, "EGS_XYZGeometry"); + auto ctPtr = geomBlockInput->addSingleInput("ct ramp", false, "Ramp file"); + ctPtr->addDependency(typePtr, "EGS_XYZGeometry"); + auto phantPtr = geomBlockInput->addSingleInput("egsphant file", false, "An egsphant file"); + phantPtr->addDependency(typePtr, "EGS_XYZGeometry"); + + // For second method, must either use "ct ramp" or "egsphant file" + densityPtr->addDependency(phantPtr, "", true); + phantPtr->addDependency(densityPtr, "", true); + + // Third method + auto xslabPtr = geomBlockInput->addSingleInput("x-slabs", false, "Xo Dx Nx"); + xslabPtr->addDependency(typePtr, "EGS_XYZGeometry"); + auto yslabPtr = geomBlockInput->addSingleInput("y-slabs", false, "Yo Dy Ny"); + yslabPtr->addDependency(typePtr, "EGS_XYZGeometry"); + auto zslabPtr = geomBlockInput->addSingleInput("z-slabs", false, "Zo Dz Nz"); + zslabPtr->addDependency(typePtr, "EGS_XYZGeometry"); + + // Can only use one method + xPtr->addDependency(densityPtr, "", true); + yPtr->addDependency(densityPtr, "", true); + zPtr->addDependency(densityPtr, "", true); + xPtr->addDependency(ctPtr, "", true); + yPtr->addDependency(ctPtr, "", true); + zPtr->addDependency(ctPtr, "", true); + xPtr->addDependency(phantPtr, "", true); + yPtr->addDependency(phantPtr, "", true); + zPtr->addDependency(phantPtr, "", true); + xPtr->addDependency(xslabPtr, "", true); + yPtr->addDependency(xslabPtr, "", true); + zPtr->addDependency(xslabPtr, "", true); + xPtr->addDependency(yslabPtr, "", true); + yPtr->addDependency(yslabPtr, "", true); + zPtr->addDependency(yslabPtr, "", true); + xPtr->addDependency(zslabPtr, "", true); + yPtr->addDependency(zslabPtr, "", true); + zPtr->addDependency(zslabPtr, "", true); + densityPtr->addDependency(xPtr, "", true); + ctPtr->addDependency(xPtr, "", true); + phantPtr->addDependency(xPtr, "", true); + densityPtr->addDependency(yPtr, "", true); + ctPtr->addDependency(yPtr, "", true); + phantPtr->addDependency(yPtr, "", true); + densityPtr->addDependency(zPtr, "", true); + ctPtr->addDependency(zPtr, "", true); + phantPtr->addDependency(zPtr, "", true); + densityPtr->addDependency(xslabPtr, "", true); + ctPtr->addDependency(xslabPtr, "", true); + phantPtr->addDependency(xslabPtr, "", true); + densityPtr->addDependency(yslabPtr, "", true); + ctPtr->addDependency(yslabPtr, "", true); + phantPtr->addDependency(yslabPtr, "", true); + densityPtr->addDependency(zslabPtr, "", true); + ctPtr->addDependency(zslabPtr, "", true); + phantPtr->addDependency(zslabPtr, "", true); + xslabPtr->addDependency(xPtr, "", true); + xslabPtr->addDependency(yPtr, "", true); + xslabPtr->addDependency(zPtr, "", true); + xslabPtr->addDependency(densityPtr, "", true); + xslabPtr->addDependency(ctPtr, "", true); + xslabPtr->addDependency(phantPtr, "", true); + yslabPtr->addDependency(xPtr, "", true); + yslabPtr->addDependency(yPtr, "", true); + yslabPtr->addDependency(zPtr, "", true); + yslabPtr->addDependency(densityPtr, "", true); + yslabPtr->addDependency(ctPtr, "", true); + yslabPtr->addDependency(phantPtr, "", true); + zslabPtr->addDependency(xPtr, "", true); + zslabPtr->addDependency(yPtr, "", true); + zslabPtr->addDependency(zPtr, "", true); + zslabPtr->addDependency(densityPtr, "", true); + zslabPtr->addDependency(ctPtr, "", true); + zslabPtr->addDependency(phantPtr, "", true); + + + // EGS_XYZRepeater + auto regeomPtr = geomBlockInput->addSingleInput("repeated geometry", true, "The name of a previously defined geometry"); + regeomPtr->addDependency(typePtr, "EGS_XYZRepeater"); + auto medPtr = geomBlockInput->addSingleInput("medium", false, "The medium the space between xmin..xmax, ymin..ymax, and zmin..zmax is filled with"); + medPtr->addDependency(typePtr, "EGS_XYZRepeater"); + auto rexPtr = geomBlockInput->addSingleInput("repeat x", true, "xmin xmax Nx"); + rexPtr->addDependency(typePtr, "EGS_XYZRepeater"); + auto reyPtr = geomBlockInput->addSingleInput("repeat y", true, "ymin ymax Ny"); + reyPtr->addDependency(typePtr, "EGS_XYZRepeater"); + auto rezPtr = geomBlockInput->addSingleInput("repeat z", true, "zmin zmax Nz"); + rezPtr->addDependency(typePtr, "EGS_XYZRepeater"); + } + + EGS_NDG_EXPORT string getExample() { + string example; + example = { + R"( + # Example of egs_ndgeometry + #:start geometry: + library = EGS_NDGeometry + name = my_ndgeometry + dimensions = geom1 geom2 + :start media input: + media = water + :stop media input: + :stop geometry: +)"}; + return example; + } + + EGS_NDG_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } EGS_NDG_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { #ifdef EXPLICIT_XYZ diff --git a/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.cpp b/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.cpp index cc65c50b1..316a09a9d 100644 --- a/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.cpp @@ -26,6 +26,7 @@ # Contributors: Iwan Kawrakow # Hubert Ho # Marc Chamberland +# Hannah Gallop # ############################################################################### */ @@ -195,7 +196,7 @@ static char EGS_OCTREE_LOCAL eoctree_message2[] = "null input?"; static char EGS_OCTREE_LOCAL eoctree_message5[] = "wrong/missing 'min' or input?"; static char EGS_OCTREE_LOCAL eoctree_message6[] = "expecting 3 float inputs for 'box min' input"; static char EGS_OCTREE_LOCAL eoctree_message7[] = "wrong/missing 'max' or input?"; -static char EGS_OCTREE_LOCAL eoctree_message8[] = "expecting 3 float inputs for 'max max' input"; +static char EGS_OCTREE_LOCAL eoctree_message8[] = "expecting 3 float inputs for 'box max' input"; static char EGS_OCTREE_LOCAL eoctree_message9[] = "wrong or missing 'resolution' input?"; static char EGS_OCTREE_LOCAL eoctree_message10[] = "expecting 3 integer inputs for 'resolution' input"; static char EGS_OCTREE_LOCAL eoctree_message11[] = "wrong or missing 'discard child' input?"; @@ -213,8 +214,35 @@ static char EGS_OCTREE_LOCAL eoctree_key4[] = "child geometry"; static char EGS_OCTREE_LOCAL eoctree_key5[] = "discard child"; static char EGS_OCTREE_LOCAL eoctree_key6[] = "prune tree"; +static bool EGS_OCTREE_LOCAL inputSet = false; + extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_Octree"}); + + // Format: name, isRequired, description, vector string of allowed values + geomBlockInput->addSingleInput("child geometry", true, "The name of child geometry"); + geomBlockInput->addSingleInput("discard child", true, "yes or no"); + geomBlockInput->addSingleInput("prune tree", false, "yes or no"); + + auto blockPtr = geomBlockInput->addBlockInput("octree box"); + blockPtr->addSingleInput("box min", true, "(x, y, z)"); + blockPtr->addSingleInput("box max", true, "(x, y, z)"); + blockPtr->addSingleInput("resolution", true, "A specified resolution (x, y, z)"); + } + + EGS_OCTREE_EXPORT shared_ptr getInputs() { + if (!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_OCTREE_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { EGS_Input *i; diff --git a/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp b/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp index 9e788d639..124e619cb 100644 --- a/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Marc Chamberland # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -49,6 +50,8 @@ const string EGS_PLANES_LOCAL yproj_type("EGS_Yplanes"); const string EGS_PLANES_LOCAL zproj_type("EGS_Zplanes"); const string EGS_PLANES_LOCAL proj_type("EGS_Planes"); +static bool EGS_PLANES_LOCAL inputSet = false; + string EGS_PlaneCollection::type = "EGS_PlaneCollection"; EGS_PlaneCollection::EGS_PlaneCollection(int Np, const EGS_Float *pos, @@ -89,6 +92,78 @@ void EGS_PlaneCollection::printInfo() const { } extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_Planes"}); + + // Format: name, isRequired, description, vector string of allowed values + auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of plane.", {"EGS_XPlanes", "EGS_YPlanes", "EGS_ZPlanes", "EGS_Planes", "EGS_PlaneCollection"}); + + auto posPtr = geomBlockInput->addSingleInput("positions", false, "A list of plane co-ordinates"); + + // EGS_Planes + auto norPtr = geomBlockInput->addSingleInput("normal", true, "The plane normal (x, y, z)"); + norPtr->addDependency(typePtr, "EGS_Planes"); + + // EGS_PlaneCollection + auto normsPtr = geomBlockInput->addSingleInput("normals", true, "3N number inputs For each plane's normal"); + normsPtr->addDependency(typePtr, "EGS_PlaneCollection"); + + // Alternative definition of the plane position + auto fpPtr = geomBlockInput->addSingleInput("first plane", false, "The position of the first plane."); + auto slabPtr = geomBlockInput->addSingleInput("slab thickness", false, "A list of the thickness between each set of planes"); + auto numPtr = geomBlockInput->addSingleInput("number of slabs", false, "A list of the number of slabs"); + + // Either positions or the alternatives must be used, not both + fpPtr->addDependency(posPtr, "", true); + slabPtr->addDependency(posPtr, "", true); + numPtr->addDependency(posPtr, "", true); + posPtr->addDependency(fpPtr, "", true); + posPtr->addDependency(slabPtr, "", true); + posPtr->addDependency(numPtr, "", true); + } + + EGS_PLANES_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Examples of the egs_planes + + # EGS_Plane example + #:start geometry: + library = egs_planes + type = EGS_Planes + name = my_plane + positions = 2 2 2 + normal = 0 + :stop geometry: + + # EGS_PlaneCollection example + #:start geometry: + library = egs_planes + type = EGS_PlaneCollection + name = my_plane_collection + normals = 0 0 1 0.1 -0.1 1 -0.1 -0.3 1 0 0 1 + positions = -5 -2 2 12 + :start media input: + media = air water air + set medium = 1 1 + set medium = 2 2 + :stop media input: + :stop geometry: +)"}; + return example; + } + + EGS_PLANES_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } EGS_PLANES_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { string type; diff --git a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp index 349a5e511..0852ddfa3 100644 --- a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Marc Chamberland # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -47,8 +48,52 @@ static EGS_PRISM_LOCAL string __prismY("EGS_PrismY"); static EGS_PRISM_LOCAL string __prismZ("EGS_PrismZ"); static EGS_PRISM_LOCAL string __prism("EGS_Prism"); +static bool EGS_PRISM_LOCAL inputSet = false; + extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_Prism"}); + + // Format: name, isRequired, description, vector string of allowed values + auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of prism", {"EGS_PrismX", "EGS_PrismY", "EGS_PrismZ", "EGS_Prism"}); + + geomBlockInput->addSingleInput("closed", false, "Two inputs that define the distance from the top and bottom prism plane to the plane used to define the polygon"); + geomBlockInput->addSingleInput("points", true, "A list of 2D or 3D positions."); + } + + EGS_PRISM_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_prisms + + # EGS_PrismZ example + #:start geometry: + name = my_prism + library = egs_prism + type = EGS_PrismZ + points = 1 1 -1 1 -1 -1 4 -1 + closed = 1 4 + :start media input: + media = air + :stop media input: + :stop geometry: +)"}; + return example; + } + + EGS_PRISM_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_PRISM_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp index 311fc397e..cdcb00afc 100644 --- a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Marc Chamberland # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -48,6 +49,8 @@ static EGS_PYRAMID_LOCAL string __pyrY = "EGS_PyramidY"; static EGS_PYRAMID_LOCAL string __pyrZ = "EGS_PyramidZ"; static EGS_PYRAMID_LOCAL string __pyr = "EGS_Pyramid"; +static bool EGS_PYRAMID_LOCAL inputSet = false; + template EGS_PyramidT::EGS_PyramidT(T *P, const EGS_Vector &Xo, bool O, const string &Name) : EGS_BaseGeometry(Name), p(P), xo(Xo), @@ -96,6 +99,50 @@ void EGS_PyramidT::printInfo() const { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_Pyramid"}); + + // Format: name, isRequired, description, vector string of allowed values + auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of pyramid", {"EGS_PyramidX", "EGS_PyramidY", "EGS_PyramidZ", "EGS_Pyramid"}); + + geomBlockInput->addSingleInput("points", true, "A list of 2D or 3D positions"); + geomBlockInput->addSingleInput("tip", true, "The 3D position of the tip of the pyramid (x, y ,z)"); + geomBlockInput->addSingleInput("closed", false, "0 (open) or 1 (closed)"); + } + + EGS_PYRAMID_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_pyramid + + # EGS_PyramidZ example + #:start geometry: + name = my_pyramid + library = egs_pyramid + type = EGS_PyramidZ + points = 1 1 -1 1 -1 -1 4 -1 + tip = 0 0 7 + closed = 0 + :start media input: + media = air + :stop media input: + :stop geometry: +)"}; + return example; + } + + EGS_PYRAMID_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_PYRAMID_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp b/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp index 626f5437f..aeceae3c3 100644 --- a/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp @@ -23,7 +23,7 @@ # # Author: Manuel Stoeckl, 2016 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### # @@ -41,7 +41,58 @@ #include "egs_roundrect_cylinders.h" #include "egs_input.h" +static bool EGS_ROUNDRECT_CYLINDERS_LOCAL inputSet = false; + extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_RoundRect_Cylinders"}); + + // Format: name, isRequired, description, vector string of allowed inputs + auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of rounded rectangle cylinder", {"EGS_RoundRectCylinders", "EGS_RoundRectCylindersXY", "EGS_RoundRectCylindersYZ", "EGS_RoundRectCylindersXZ"}); + + geomBlockInput->addSingleInput("x-widths", true, "A list of cylinder half-widths in the x-direction, must be in increasing order"); + geomBlockInput->addSingleInput("y-widths", true, "A list of cylinder half-widths in the y-direction, must be in increasing order"); + geomBlockInput->addSingleInput("radii", true, "A list of fillet radii, must be in increasing order"); + geomBlockInput->addSingleInput("midpoint", false, "The position of the midpoint (x, y, z)"); + + // EGS_RoundRectCylinders + auto inpPtr = geomBlockInput->addSingleInput("x-axis", true, "x-axis of rounded rectangle (x, y, z)"); + inpPtr->addDependency(typePtr, "EGS_RoundRectCylinders"); + auto yinpPtr = geomBlockInput->addSingleInput("y-axis", true, "y-axis of rounded rectangle (x, y, z)"); + yinpPtr->addDependency(typePtr, "EGS_RoundRectCylinders"); + } + + EGS_ROUNDRECT_CYLINDERS_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of rounded reactangle cylinder + #:start geometry: + name = my_roundedrectcylinder + library = egs_roundrect_cylinders + type = EGS_RoundRectCylindersXY + x-widths = 1 2 + y-widths = 0.5 1 + radii = 0.1 0.5 + :start media input: + media = air water + set medium = 1 1 + :stop media input: + :stop geometry: +)"}; + return example; + } + + EGS_ROUNDRECT_CYLINDERS_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } EGS_ROUNDRECT_CYLINDERS_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp b/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp index 82e97990f..6f79047eb 100644 --- a/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp @@ -28,6 +28,7 @@ # Rowan Thomson # Dave Rogers # Martin Martinov +# Hannah Gallop # ############################################################################### # @@ -48,6 +49,7 @@ #include "../egs_cylinders/egs_cylinders.h" #include "../egs_planes/egs_planes.h" +static bool EGS_RZ_LOCAL inputSet = false; string EGS_RZGeometry::RZType = "EGS_RZ"; @@ -226,6 +228,72 @@ bool allIncreasing(vector vec) { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_RZ"}); + + // Format: name, isRequired, description, vector string of allowed values + auto radPtr = geomBlockInput->addSingleInput("radii", false, "A list of radii, must be in increasing order"); + auto planePtr = geomBlockInput->addSingleInput("z-planes", false, "Input for z-planes"); + + // Or can define using slabs and shells + auto num_shellPtr = geomBlockInput->addSingleInput("number of shells", false, "A list of the number of shells"); + auto shellPtr = geomBlockInput->addSingleInput("shell thickness", false, "A list of shell thicknesses"); + auto firstPtr = geomBlockInput->addSingleInput("first plane", false, "first plane"); + auto num_slabPtr = geomBlockInput->addSingleInput("number of slabs", false, "A list of the number of slabs"); + auto slabPtr = geomBlockInput->addSingleInput("slab thickness", false, "A list of the slab thicknesses"); + + // Can only use one method + radPtr->addDependency(num_shellPtr, "", true); + radPtr->addDependency(shellPtr, "", true); + radPtr->addDependency(firstPtr, "", true); + radPtr->addDependency(num_slabPtr, "", true); + radPtr->addDependency(slabPtr, "", true); + planePtr->addDependency(num_shellPtr, "", true); + planePtr->addDependency(shellPtr, "", true); + planePtr->addDependency(firstPtr, "", true); + planePtr->addDependency(num_slabPtr, "", true); + planePtr->addDependency(slabPtr, "", true); + num_shellPtr->addDependency(radPtr, "", true); + num_shellPtr->addDependency(planePtr, "", true); + shellPtr->addDependency(radPtr, "", true); + shellPtr->addDependency(planePtr, "", true); + firstPtr->addDependency(radPtr, "", true); + firstPtr->addDependency(planePtr, "", true); + num_slabPtr->addDependency(radPtr, "", true); + num_slabPtr->addDependency(planePtr, "", true); + slabPtr->addDependency(radPtr, "", true); + slabPtr->addDependency(planePtr, "", true); + } + + EGS_RZ_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_rz + :start geometry: + name = my_rz + library = egs_rz + radii = 1 2 3 + z-planes= -4 -3 -2 -1 0 1 2 3 4 + :start media input: + media = water + :stop media input: + :stop geometry: +)"}; + return example; + } + + EGS_RZ_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_RZ_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { diff --git a/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp b/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp index 0d839a9f6..014d2ccf5 100644 --- a/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp @@ -66,6 +66,8 @@ using namespace std; string EGS_SMART_ENVELOPE_LOCAL EGS_SmartEnvelope::type = "EGS_SmartEnvelope"; +static bool EGS_SMART_ENVELOPE_LOCAL inputSet = false; + void EGS_SmartEnvelope::setMedia(EGS_Input *,int,const int *) { egsWarning("EGS_SmartEnvelope::setMedia: don't use this method. Use the\n" " setMedia() methods of the geometry objects that make up this geometry\n"); @@ -255,6 +257,25 @@ static char EGS_SMART_ENVELOPE_LOCAL eeg_keyword2[] = "geometry"; extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_SmartEnvelope"}); + + // Format: name, isRequired, description, vector string of allowed values + geomBlockInput->addSingleInput("base geometry", true, "The name of a previously defined geometry"); + geomBlockInput->addSingleInput("inscribed geometries", true, "A list of previously defined geometries"); + } + + EGS_SMART_ENVELOPE_EXPORT shared_ptr getInputs() { + if (!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_SMART_ENVELOPE_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { egsWarning(eeg_message1,eeg_message2); diff --git a/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp b/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp index 04c76b5e1..22a0f5edf 100644 --- a/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp @@ -25,6 +25,7 @@ # # Contributors: Frederic Tessier # Marc Chamberland +# Hannah Gallop # ############################################################################### */ @@ -40,8 +41,25 @@ string EGS_Space::type = "EGS_Space"; +static bool EGS_SPACE_LOCAL inputSet = false; + extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_Space"}); + } + + EGS_SPACE_EXPORT shared_ptr getInputs() { + if (!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_SPACE_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { EGS_Space *g = new EGS_Space(""); g->setName(input); diff --git a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp index 8d01871e1..b4a173b6a 100644 --- a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp @@ -29,6 +29,7 @@ # Randle Taylor # Marc Chamberland # Martin Martinov +# Hannah Gallop # ############################################################################### */ @@ -48,6 +49,8 @@ using std::vector; string EGS_cSpheres::type = "EGS_cSpheres"; +static bool EGS_SPHERES_LOCAL inputSet = false; + // generate the concentric spheres EGS_cSpheres::EGS_cSpheres(int ns, const EGS_Float *radius, const EGS_Vector &position, const string &Name) : @@ -681,6 +684,45 @@ void EGS_cSphericalShell::printInfo() const { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_Spheres"}); + + // Format: name, isRequired, description, vector string of allowed values + geomBlockInput->addSingleInput("radii", true, "A of list of sphere radii in increasing order."); + geomBlockInput->addSingleInput("midpoint", false, "The position of the middle of the sphere (x, y, z)"); + } + + EGS_SPHERES_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_spheres + #:start geometry: + name = my_spheres + library = egs_spheres + midpoint = 0 0 0 + radii = 1 2 3 + :start media input: + media = air water air + set medium = 1 1 + set medium = 2 2 + :stop media input: + :stop geometry input: +)"}; + return example; + } + + EGS_SPHERES_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } + EGS_SPHERES_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { egsWarning("createGeometry(spheres): null input?\n"); diff --git a/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp index 5a6d8a698..488b2e357 100644 --- a/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp @@ -27,6 +27,7 @@ # Ernesto Mainegra-Hing # Hubert Ho # Marc Chamberland +# Hannah Gallop # ############################################################################### */ @@ -45,6 +46,8 @@ using namespace std; string EGS_UNIONG_LOCAL EGS_UnionGeometry::type = "EGS_UnionGeometry"; +static bool EGS_UNIONG_LOCAL inputSet = false; + void EGS_UnionGeometry::setMedia(EGS_Input *,int,const int *) { egsWarning("EGS_UnionGeometry::setMedia: don't use this method. Use the\n" " setMedia() methods of the geometry objects that make up this geometry\n"); @@ -168,6 +171,38 @@ void EGS_UnionGeometry::printInfo() const { } extern "C" { + static void setInputs() { + inputSet = true; + + setBaseGeometryInputs(false); + + geomBlockInput->getSingleInput("library")->setValues({"EGS_gunion"}); + + // Format: name, isRequired, description, vector string of allowed values + geomBlockInput->addSingleInput("geometries", true, "A list of names of previously defined geometries"); + geomBlockInput->addSingleInput("priorities", false, "A list of integers defining the geometry priorities"); + } + + EGS_UNIONG_EXPORT string getExample(string type) { + string example; + example = { + R"( + # Example of egs_gunion + #:start geometry: + name = my_union + library = egs_union + geometries = my_box my_sphere + :stop geometry: +)"}; + return example; + } + + EGS_UNIONG_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return geomBlockInput; + } EGS_UNIONG_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { if (!input) { @@ -204,8 +239,8 @@ extern "C" { } } else egsWarning("createGeometry(union): the number of priorities (%d)" - " is not the same as the number of geometries (%d) => ignoring\n", - pri.size(),geoms.size()); + " is not the same as the number of geometries (%d) => ignoring\n", + pri.size(),geoms.size()); } EGS_BaseGeometry *result = new EGS_UnionGeometry(geoms,p); result->setName(input); diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 8d5814525..72d74edfe 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -223,13 +223,13 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) lib_dir += CONFIG_NAME; lib_dir += fs; - EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); + /*EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); if (!app_lib.load()) egsFatal("\n%s: Failed to load the %s application library from %s\n\n", appv[0],app_name.c_str(),lib_dir.c_str()); createAppFunction createApp = (createAppFunction) app_lib.resolve("createApplication"); if (!createApp) egsFatal("\n%s: Failed to resolve the address of the 'createApplication' function" - " in the application library %s\n\n",appv[0],app_lib.libraryFile()); + " in the application library %s\n\n",appv[0],app_lib.libraryFile()); */ /*TODO left here crash 'cause tutor7pp isn't compiled <======================= EGS_Application *app = createApp(appc,appv); if (!app) { @@ -267,7 +267,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) inputStruct = make_shared(); // Get the application level input blocks - getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); + /*getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); if(getAppInputs) { getAppInputs(inputStruct); if(inputStruct) { @@ -284,7 +284,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } - } + } */ // Geometry definition block auto geomDefPtr = inputStruct->addBlockInput("geometry definition"); @@ -302,14 +302,19 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) libName = libName.right(libName.length() - lib_prefix.length()); egsInformation("testlib trying %s\n", libName.toLatin1().data()); + if (lib.startsWith("Qt5")) { + continue; + } EGS_Library egs_lib(libName.toLatin1().data(),dso_dir.c_str()); if (!egs_lib.load()) { continue; } + egsInformation("testlib2 trying %s\n", libName.toLatin1().data()); // Geometries createGeomFunction isGeom = (createGeomFunction) egs_lib.resolve("createGeometry"); + egsInformation("testlib4 trying \n"); if (isGeom) { egsInformation(" testgeom %s\n",libName.toLatin1().data()); @@ -343,7 +348,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } - + egsInformation("testlib5 trying \n"); getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { QAction *action = geomMenu->addAction(libName); @@ -353,6 +358,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } // Sources + egsInformation("testlib6 trying \n"); createSourceFunction isSource = (createSourceFunction) egs_lib.resolve("createSource"); if (isSource) { egsInformation(" testsrc %s\n",libName.toLatin1().data()); @@ -387,7 +393,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } - + //egsInformation("testlib7 trying \n"); getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { QAction *action = sourceMenu->addAction(libName); @@ -397,6 +403,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } // Shapes + egsInformation("testlib8 trying \n"); createShapeFunction isShape = (createShapeFunction) egs_lib.resolve("createShape"); if (isShape) { egsInformation(" testshape %s\n",libName.toLatin1().data()); @@ -431,6 +438,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } + //egsInformation("testlib9 trying \n"); getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { @@ -440,7 +448,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } - + egsInformation("testlib3 trying \n"); egsinpEdit->setInputStruct(inputStruct); } From 1d65c15357a1ea840613a383d58a00cc1628ad6d Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Wed, 10 Feb 2021 14:57:48 -0500 Subject: [PATCH 17/40] Add sources, ausgab, other egs_view editor support --- .../egs_dose_scoring/egs_dose_scoring.cpp | 36 ++++++++ .../egs_phsp_scoring/egs_phsp_scoring.cpp | 83 +++++++++++++++++++ .../egs_radiative_splitting.cpp | 22 ++++- .../egs_track_scoring/egs_track_scoring.cpp | 45 ++++++++++ HEN_HOUSE/egs++/egs_ausgab_object.h | 7 ++ HEN_HOUSE/egs++/egs_base_source.h | 2 +- .../egs_autoenvelope/egs_autoenvelope.cpp | 1 + .../geometry/egs_cylinders/egs_cylinders.cpp | 2 +- .../egs_elliptic_cylinders.cpp | 2 +- .../egs_nd_geometry/egs_nd_geometry.cpp | 2 +- .../egs++/geometry/egs_prism/egs_prism.cpp | 2 +- .../geometry/egs_pyramid/egs_pyramid.cpp | 2 +- .../egs_roundrect_cylinders.cpp | 2 +- .../egs_smart_envelope/egs_smart_envelope.cpp | 1 + .../geometry/egs_spheres/egs_spheres.cpp | 2 +- .../egs++/shapes/egs_ellipse/egs_ellipse.cpp | 34 +++++++- .../shapes/egs_line_shape/egs_line_shape.cpp | 32 ++++++- .../egs_polygon_shape/egs_polygon_shape.cpp | 30 +++++++ .../shapes/egs_rectangle/egs_rectangle.cpp | 31 ++++++- .../egs_angular_spread_source.cpp | 39 ++++++++- .../egs_beam_source/egs_beam_source.cpp | 42 ++++++++++ .../egs_collimated_source.cpp | 54 ++++++++++++ .../egs_dynamic_source/egs_dynamic_source.cpp | 47 ++++++++++- .../egs_fano_source/egs_fano_source.cpp | 52 ++++++++++++ .../egs_parallel_beam/egs_parallel_beam.cpp | 51 ++++++++++++ .../egs_phsp_source/egs_phsp_source.cpp | 44 ++++++++++ .../egs_point_source/egs_point_source.cpp | 41 ++++++++- .../egs_radionuclide_source.cpp | 80 ++++++++++++++++++ .../egs_source_collection.cpp | 38 +++++++++ .../egs_transformed_source.cpp | 48 ++++++++++- HEN_HOUSE/egs++/view/viewcontrol.cpp | 45 ++++++++++ 31 files changed, 903 insertions(+), 16 deletions(-) diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp index 986fd2594..f4fe8e1d7 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp @@ -29,6 +29,7 @@ # Blake Walters # Max Orok # Martin Martinov +# Hannah Gallop # ############################################################################### # @@ -98,6 +99,8 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_DOSE_SCORING_LOCAL inputSet = false; + EGS_DoseScoring::EGS_DoseScoring(const string &Name, EGS_ObjectFactory *f) : EGS_AusgabObject(Name,f), dose(0), doseM(0), doseF(0), @@ -591,6 +594,39 @@ void EGS_DoseScoring::resetCounter() { //********************************************************************** extern "C" { + static void setInputs() { + inputSet = true; + + setBaseAusgabObjectInputs(); + + ausBlockInput->getSingleInput("library")->setValues({"EGS_Dose_Scoring"}); + + // Format: name, isRequired, description, vector string of allowed values + ausBlockInput->addSingleInput("medium dose", false, "Requests the dose deposited in each medium to be scored, default is no", {"yes", "no"}); + ausBlockInput->addSingleInput("region dose", false, "Requests the dose deposited in each region to be scored, default is yes", {"yes", "no"}); + ausBlockInput->addSingleInput("volume", false, "Either a unique volume, which will be the same for all regions or a list of individual volumes for each region, default is 1g/cm3"); + auto dosePtr = ausBlockInput->addSingleInput("dose regions", false, "A list of individual regions"); + auto startPtr = ausBlockInput->addSingleInput("dose start region", false, "A list of starts for regions"); + auto stopPtr = ausBlockInput->addSingleInput("dose stop region", false, "A list of stops for regions"); + + dosePtr->addDependency(startPtr, "", true); + dosePtr->addDependency(stopPtr, "", true); + startPtr->addDependency(dosePtr, "", true); + stopPtr->addDependency(dosePtr, "", true); + + // This can only be used if one of the geometries is an EGS_XYZGeometry + auto blockPtr = ausBlockInput->addBlockInput("output dose file"); + blockPtr->addSingleInput("geometry name", true, "The name of a predefined EGS_XYZGeometry"); + blockPtr->addSingleInput("file type", true, "The type of file", {"3ddose"}); + } + + EGS_DOSE_SCORING_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return ausBlockInput; + } + EGS_DOSE_SCORING_EXPORT EGS_AusgabObject *createAusgabObject(EGS_Input *input, EGS_ObjectFactory *f) { const static char *func = "createAusgabObject(dose_scoring)"; diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_phsp_scoring/egs_phsp_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_phsp_scoring/egs_phsp_scoring.cpp index 496f69b6a..fc2a7cadd 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_phsp_scoring/egs_phsp_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_phsp_scoring/egs_phsp_scoring.cpp @@ -24,6 +24,7 @@ # Author: Blake Walters, 2018 # # Contributors: Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -44,6 +45,8 @@ #include "egs_functions.h" #include "iaea_phsp.h" +static bool EGS_PHSP_SCORING_LOCAL inputSet = false; + EGS_PhspScoring::EGS_PhspScoring(const string &Name, EGS_ObjectFactory *f) : EGS_AusgabObject(Name,f), phsp_index(0), store_max(1000), phsp_file(), @@ -519,6 +522,86 @@ bool EGS_PhspScoring::addState(istream &data) { //********************************************************************** extern "C" { + static void setInputs() { + inputSet = true; + + setBaseAusgabObjectInputs(); + + ausBlockInput->getSingleInput("library")->setValues({"EGS_Phsp_Scoring"}); + + // Format: name, isRequired, description, vector string of allowed values + auto formatPtr = ausBlockInput->addSingleInput("output format", false, "The type of file the data is output to", {"EGSnrc", "IAEA"}); + + auto xPtr = ausBlockInput->addSingleInput("constant X", false, "X values(cm) at which all particles are scored."); + xPtr->addDependency(formatPtr, "IAEA"); + auto yPtr = ausBlockInput->addSingleInput("constant Y", false, "Y values(cm) at which all particles are scored."); + yPtr->addDependency(formatPtr, "IAEA"); + auto zPtr = ausBlockInput->addSingleInput("constant Z", false, "Z values(cm) at which all particles are scored."); + zPtr->addDependency(formatPtr, "IAEA"); + auto muPtr = ausBlockInput->addSingleInput("score mu", false, "Default is no", {"yes", "no"}); + muPtr->addDependency(formatPtr, "IAEA"); + + auto multiPtr = ausBlockInput->addSingleInput("score multiple crossers", false, "Default is no", {"yes", "no"}); + multiPtr->addDependency(formatPtr, "EGSnrc"); + + ausBlockInput->addSingleInput("particle type", true, "The type of particle", {"all", "photons", "charged"}); + ausBlockInput->addSingleInput("output directory", true, "The name of output directory"); + + // Method 1: Score particles on entry to/exit from a predefined geometry + auto spacePtr = ausBlockInput->addSingleInput("phase space geometry", true, "The name of a previously defined geometry"); + auto scorePtr = ausBlockInput->addSingleInput("score particles on", false, "entry, exit, entry and exit", {"entry", "exit", "entry and exit"}); + + // Method 2: Score particles on exiting one region and entering another + auto fromPtr = ausBlockInput->addSingleInput("from regions", true, "A list of exit region numbers"); + auto toPtr = ausBlockInput->addSingleInput("to regions", true, "A list of entry region numbers"); + + // Can only use one method + spacePtr->addDependency(fromPtr, "", true); + spacePtr->addDependency(toPtr, "", true); + scorePtr->addDependency(fromPtr, "", true); + scorePtr->addDependency(toPtr, "", true); + fromPtr->addDependency(spacePtr, "", true); + fromPtr->addDependency(scorePtr, "", true); + toPtr->addDependency(spacePtr, "", true); + toPtr->addDependency(scorePtr, "", true); + } + + EGS_PHSP_SCORING_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_phsp_scoring + #:start ausgab object: + library = egs_phsp_scoring + name = test + from regions = 0 2 + to regions = 3 5 + output format = IAEA + constant Z = 10.0 + particle type = all + score mu = no + :stop ausgab object: + + #:start ausgab object: + library = egs_phsp_scoring + name = test2 + phase space geometry = scoreplane + output format = EGSnrc + particle type = all + score particles on = entry + score multiple crossers = yes + :stop ausgab object: +)"}; + return example; + } + + EGS_PHSP_SCORING_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return ausBlockInput; + } + EGS_PHSP_SCORING_EXPORT EGS_AusgabObject *createAusgabObject(EGS_Input *input, EGS_ObjectFactory *f) { const static char *func = "createAusgabObject(phsp_scoring)"; diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp index 613b70c9f..a5f31554e 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp @@ -23,7 +23,7 @@ # # Author: Ernesto Mainegra-Hing, 2018 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### # @@ -50,6 +50,8 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_RADIATIVE_SPLITTING_LOCAL inputSet = false; + EGS_RadiativeSplitting::EGS_RadiativeSplitting(const string &Name, EGS_ObjectFactory *f) : nsplit(1) { @@ -111,6 +113,24 @@ void EGS_RadiativeSplitting::setApplication(EGS_Application *App) { //********************************************************************** extern "C" { + static void setInputs() { + inputSet = true; + + setBaseAusgabObjectInputs(); + + ausBlockInput->getSingleInput("library")->setValues({"EGS_Radiative_Splitting"}); + + // Format: name, isRequired, description, vector string of allowed values + ausBlockInput->addSingleInput("splitting", false, "N-split"); + } + + EGS_RADIATIVE_SPLITTING_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return ausBlockInput; + } + EGS_RADIATIVE_SPLITTING_EXPORT EGS_AusgabObject *createAusgabObject(EGS_Input *input, EGS_ObjectFactory *f) { const static char *func = "createAusgabObject(radiative_splitting)"; diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp index bfcb82721..da331ef42 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2009 # # Contributors: Georgi Gerganov +# Hannah Gallop # ############################################################################### */ @@ -38,6 +39,8 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_TRACK_SCORING_LOCAL inputSet = false; + EGS_TrackScoring::EGS_TrackScoring(const string &Name, EGS_ObjectFactory *f) : EGS_AusgabObject(Name,f), m_pts(0), m_start(0), m_stop(1024), m_lastCase(-1), m_nScore(0), m_bufSize(16), m_score(false), m_didScore(false), @@ -117,6 +120,48 @@ void EGS_TrackScoring::reportResults() { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseAusgabObjectInputs(); + + ausBlockInput->getSingleInput("library")->setValues({"EGS_Track_Scoring"}); + + // Format: name, isRequired, description, vector string of allowed values + ausBlockInput->addSingleInput("score photons", false, "Score photons? Default is yes.", {"yes", "no"}); + ausBlockInput->addSingleInput("score electrons", false, "Score the elctrons? Default is yes.", {"yes", "no"}); + ausBlockInput->addSingleInput("score positrons", false, "Score positrons? Default is yes.", {"yes", "no"}); + ausBlockInput->addSingleInput("start scoring", false, "Event_number, default is 0."); + ausBlockInput->addSingleInput("stop scoring", false, "Event_number, default is 1024."); + ausBlockInput->addSingleInput("buffer size", false, "Size, default is 1024."); + ausBlockInput->addSingleInput("file name addition", false, "A string that constructs the output file name"); + } + + EGS_TRACK_SCORING_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_track_scoring + #:start ausgab object: + library = egs_track_scoring + name = my_score + score photons = yes + score electrons = yes + score positrons = yes + start scoring = 0 + stop scoring = 1024 + :stop ausgab object: +)"}; + return example; + } + + EGS_TRACK_SCORING_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return ausBlockInput; + } + EGS_TRACK_SCORING_EXPORT EGS_AusgabObject *createAusgabObject(EGS_Input *input, EGS_ObjectFactory *f) { const static char *func = "createAusgabObject(track_scoring)"; diff --git a/HEN_HOUSE/egs++/egs_ausgab_object.h b/HEN_HOUSE/egs++/egs_ausgab_object.h index 975759c3a..087904eb5 100644 --- a/HEN_HOUSE/egs++/egs_ausgab_object.h +++ b/HEN_HOUSE/egs++/egs_ausgab_object.h @@ -39,6 +39,7 @@ #include "egs_application.h" #include "egs_object_factory.h" +#include "egs_input_struct.h" #include #include @@ -61,6 +62,12 @@ using namespace std; class EGS_Input; class EGS_Application; +static shared_ptr ausBlockInput = make_shared("ausgab object"); +static void setBaseAusgabObjectInputs() { + ausBlockInput->addSingleInput("library", true, "The type of ausgab object, loaded by shared library in egs++/dso."); + ausBlockInput->addSingleInput("name", true, "The user-declared unique name of this ausgab object. This is the name you may refer to elsewhere in the input file."); +} + class EGS_EXPORT EGS_AusgabObject : public EGS_Object { public: diff --git a/HEN_HOUSE/egs++/egs_base_source.h b/HEN_HOUSE/egs++/egs_base_source.h index 2b9f32a0c..1f14c1886 100644 --- a/HEN_HOUSE/egs++/egs_base_source.h +++ b/HEN_HOUSE/egs++/egs_base_source.h @@ -63,7 +63,7 @@ static void setBaseSourceInputs(bool isSimpleSource = true, bool includeSpectrum if(isSimpleSource) { includeSpectrumBlock = true; - srcBlockInput->addSingleInput("charge", true, "The type of particle to emit from the source, as defined by the charge. Use 0 for photons, -1 for electrons and 1 for positrons."); + srcBlockInput->addSingleInput("charge", true, "The type of particle to emit from the source, as defined by the charge. Use 0 for photons, -1 for electrons and 1 for positrons.", {"0", "1", "-1"}); } if(includeSpectrumBlock) { shared_ptr specBlock = srcBlockInput->addBlockInput("spectrum"); diff --git a/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp b/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp index e16a7a325..5d415f0f8 100644 --- a/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp @@ -28,6 +28,7 @@ # Rowan Thomson # Dave Rogers # Martin Martinov +# Hannah Gallop # ############################################################################### # diff --git a/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp b/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp index 4e1c175cc..44e808e79 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp @@ -47,7 +47,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_Cylinders"}); diff --git a/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.cpp b/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.cpp index 847506dae..f8591a9fa 100644 --- a/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.cpp @@ -52,7 +52,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_EllipticCylinders"}); diff --git a/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp index e85221f59..ca31227c1 100644 --- a/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp @@ -1089,7 +1089,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_NDGeometry"}); diff --git a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp index 0852ddfa3..1048947e0 100644 --- a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp @@ -55,7 +55,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_Prism"}); diff --git a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp index cdcb00afc..cec874721 100644 --- a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp @@ -102,7 +102,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_Pyramid"}); diff --git a/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp b/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp index aeceae3c3..4b51868d3 100644 --- a/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp @@ -47,7 +47,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_RoundRect_Cylinders"}); diff --git a/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp b/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp index 014d2ccf5..9c5e204df 100644 --- a/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Ernesto Mainegra-Hing # Marc Chamberland +# Hannah Gallop # ############################################################################### # diff --git a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp index b4a173b6a..99fc71bab 100644 --- a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp @@ -687,7 +687,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_Spheres"}); diff --git a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp index b675e2903..b2bf00ede 100644 --- a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -38,8 +38,40 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_ELLIPSE_LOCAL inputSet = false; +static shared_ptr EGS_ELLIPSE_LOCAL shapeBlockInput = make_shared("shape"); + extern "C" { + static void setInputs() { + inputSet = true; + + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Ellipse"}); + shapeBlockInput->addSingleInput("halfaxis", true, "The two half axis of the ellipse."); + shapeBlockInput->addSingleInput("midpoint", false, "The midpoint of the ellipse, (x, y)."); + } + + EGS_ELLIPSE_EXPORT string getExample() { + string example; + example = +{R"( + # Example fo egs_ellipse + #:start shape: + library = egs_ellipse + halfway = the two half axis of the ellipse + midpoint = Ox, Oy (optional) + :stop shape: +)"}; + return example; + } + + EGS_ELLIPSE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_ELLIPSE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp index 47349105a..0f84a3985 100644 --- a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -38,6 +38,9 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_LINE_SHAPE_LOCAL inputSet = false; +static shared_ptr EGS_LINE_SHAPE_LOCAL shapeBlockInput = make_shared("shape"); + EGS_LineShape::EGS_LineShape(const vector &points, const string &Name, EGS_ObjectFactory *f) : EGS_BaseShape(Name,f) { int np = points.size(); @@ -63,6 +66,33 @@ EGS_LineShape::EGS_LineShape(const vector &points, extern "C" { + static void setInputs() { + inputSet = true; + + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Line_Shape"}); + shapeBlockInput->addSingleInput("points", true, "A list of 2D positions, at least 2 required"); + } + + EGS_LINE_SHAPE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_line_shape + :start shape: + library = egs_line_shape + points = list of 2D positions + :stop shape: +)"}; + return example; + } + + EGS_LINE_SHAPE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_LINE_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp index b20d6e2ff..8a9182ddd 100644 --- a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp @@ -25,6 +25,7 @@ # # Contributors: Randle Taylor # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -41,6 +42,9 @@ #include "egs_functions.h" #include "egs_math.h" +static bool EGS_POLYGON_SHAPE_LOCAL inputSet = false; +static shared_ptr EGS_POLYGON_SHAPE_LOCAL shapeBlockInput = make_shared("shape"); + EGS_TriangleShape::EGS_TriangleShape(const vector &points, const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) { xo = points[0]; @@ -141,6 +145,32 @@ EGS_PolygonShape::EGS_PolygonShape(const vector &points, extern "C" { + static void setInputs() { + inputSet = true; + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Polygon_Shape"}); + shapeBlockInput->addSingleInput("points", true, "A list of at least 3 2D points (at least 6 floating numbers)"); + } + + EGS_POLYGON_SHAPE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_polygon_shape + #:start shape: + library = egs_polygon_shape + points = list of 2D points + :stop shape: +)"}; + return example; + } + + EGS_POLYGON_SHAPE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_POLYGON_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp index bac351ce4..29235a61f 100644 --- a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -38,6 +38,9 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_RECTANGLE_LOCAL inputSet = false; +static shared_ptr EGS_RECTANGLE_LOCAL shapeBlockInput = make_shared("shape"); + EGS_RectangularRing::EGS_RectangularRing(EGS_Float xmin, EGS_Float xmax, EGS_Float ymin, EGS_Float ymax, EGS_Float xmin_i, EGS_Float xmax_i, EGS_Float ymin_i, EGS_Float ymax_i, const string &Name, @@ -97,6 +100,32 @@ EGS_RectangularRing::~EGS_RectangularRing() { extern "C" { + static void setInputs() { + inputSet = true; + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Rectangle"}); + shapeBlockInput->addSingleInput("rectangle", true, "x1 y1 x2 y2"); + shapeBlockInput->addSingleInput("inner rectangle", false, "xp1 yp1 xp2 yp2"); + } + + EGS_RECTANGLE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_rectangle + #:start shape: + library = egs_rectangle + reactangle = -.1 -.1 .1 .1 +)"}; + return example; + } + + EGS_RECTANGLE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_RECTANGLE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp b/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp index 455ceae83..9faec6e85 100644 --- a/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2009 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -38,6 +38,8 @@ #include "egs_input.h" #include "egs_math.h" +static bool EGS_ANGULAR_SPREAD_SOURCE_LOCAL inputSet = false; + EGS_AngularSpreadSource::EGS_AngularSpreadSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSource(input,f), source(0), sigma(0) { EGS_Input *isource = input->takeInputItem("source",false); @@ -81,6 +83,41 @@ void EGS_AngularSpreadSource::setUp() { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(false, false); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Angular_Spread_Source"}); + + // Format: name, isRequired, description, vector string of allowed values + srcBlockInput->addSingleInput("source name", true, "The name of a previously defined source."); + srcBlockInput->addSingleInput("sigma", false, "Angular spread in degrees."); + } + + EGS_ANGULAR_SPREAD_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_angular_spread_source + #:start source: + library = egs_angular_spread_source + name = my_source + sigma = 10 + source name = my_parallel_source + #create source called my_parallel_source + :stop source: +)"}; + return example; + } + + EGS_ANGULAR_SPREAD_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_ANGULAR_SPREAD_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return diff --git a/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp b/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp index 813489d2e..9018780eb 100644 --- a/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp @@ -27,6 +27,7 @@ # Frederic Tessier # Reid Townson # Ernesto Mainegra-Hing +# Hannah Gallop # ############################################################################### */ @@ -51,6 +52,8 @@ #define F77_NAME(fname,FNAME) STRINGIFY(F77_OBJ(fname,FNAME)) #define F77_NAME_(fname,FNAME) STRINGIFY(F77_OBJ_(fname,FNAME)) +static bool EGS_BEAM_SOURCE_LOCAL inputSet = false; + EGS_BeamSource::EGS_BeamSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSource(input,f) { n_reuse_photon = 0; @@ -338,6 +341,45 @@ EGS_BeamSource::~EGS_BeamSource() { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(false, false); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Beam_Source"}); + + // Format: name, isRequired, description, vector string of allowed values + srcBlockInput->addSingleInput("beam code", true, "The name of the BEAMnrc user code"); + srcBlockInput->addSingleInput("pegs file", true, "The name of the PEGS file to be used in the BEAMnrc simulation"); + srcBlockInput->addSingleInput("input file", true, "The name of the input file specifying the BEAMnrc simulation"); + srcBlockInput->addSingleInput("cutout", false, "Cutout of a rectangle defined by x1, y1, x2, y2"); + srcBlockInput->addSingleInput("particle type", false, "The type of particle.", {"all", "electrons", "photons", "positrons", "charged"}); + srcBlockInput->addSingleInput("weight window", true, "wmin wmax"); + } + + EGS_BEAM_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_beam_source + #:start source: + library = egs_beam_source + name = my_source + beam code = BEAM_EX10MeVe + pegs file = 521icru + particle type = all + :stop source: +)"}; + return example; + } + + EGS_BEAM_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_BEAM_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return diff --git a/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp b/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp index 144825bf0..d25d24625 100644 --- a/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp @@ -25,6 +25,7 @@ # # Contributors: Hubert Ho # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -38,6 +39,8 @@ #include "egs_collimated_source.h" #include "egs_input.h" +static bool EGS_COLLIMATED_SOURCE_LOCAL inputSet = false; + EGS_CollimatedSource::EGS_CollimatedSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), source_shape(0), target_shape(0), ctry(0), dist(1) { @@ -121,6 +124,57 @@ void EGS_CollimatedSource::setUp() { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Collimated_Source"}); + + // Format: name, isRequired, description, vector string of allowed values + auto source_shapePtr = srcBlockInput->addBlockInput("source shape"); + auto target_shapePtr = srcBlockInput->addBlockInput("target shape"); + + setShapeInputs(source_shapePtr); + setShapeInputs(target_shapePtr); + + srcBlockInput->addSingleInput("distance", false, "source-target minimum distance"); + } + + EGS_COLLIMATED_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_collimated_source + #:start source: + library = egs_collimated_source + name = my_source + :start source shape: + type = point + position = 0 0 5 + :stop source shape: + :start target shape: + library = egs_rectangle + rectangle = -1 -1 1 1 + :stop target shape: + distance = 5 + charge = -1 + :start spectrum: + type = monoenergetic + energy = 20 + :stop spectrum: + :stop source: +)"}; + return example; + } + + EGS_COLLIMATED_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_COLLIMATED_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return diff --git a/HEN_HOUSE/egs++/sources/egs_dynamic_source/egs_dynamic_source.cpp b/HEN_HOUSE/egs++/sources/egs_dynamic_source/egs_dynamic_source.cpp index 114e44a1f..0317b4039 100644 --- a/HEN_HOUSE/egs++/sources/egs_dynamic_source/egs_dynamic_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_dynamic_source/egs_dynamic_source.cpp @@ -23,7 +23,7 @@ # # Author: Blake Walters, 2017 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -37,6 +37,8 @@ #include "egs_dynamic_source.h" #include "egs_input.h" +static bool EGS_DYNAMIC_SOURCE_LOCAL inputSet = false; + EGS_DynamicSource::EGS_DynamicSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSource(input,f), source(0), valid(true) { EGS_Input *isource = input->takeInputItem("source",false); @@ -180,6 +182,49 @@ int EGS_DynamicSource::getCoord(EGS_Float rand, EGS_ControlPoint &ipt) { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(false, false); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Dynamic_Source"}); + + // Format:name, isRequired, description, vector string of allowed + srcBlockInput->addSingleInput("source name", true, "The name of a previously defined source"); + srcBlockInput->addSingleInput("synchronize motion", false, "yes or no", {"yes", "no"}); + + auto motionPtr = srcBlockInput->addBlockInput("motion"); + motionPtr->addSingleInput("control point 1", false, "xiso(1) yiso(1) ziso(1) dsource(1) theta(1) phi(1) phicol(1) mu(1)"); + } + + EGS_DYNAMIC_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_dynamic_source + #:start source: + library = egs_dynamic_source + name = my_source + source name = my_parallel_source + #create a soource called my_parallel_source + :start motion: + control point 1 = 0 0 0 100 0 0 0 0 + control point 2 = 0 0 0 100 360 0 0 0.5 + control point 3 = 0 0 0 100 90 0 0 0.5 + control point 4 = 0 0 0 100 90 360 0 1.0 + :stop motion: + :stop source: +)"}; + return example; + } + + EGS_DYNAMIC_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_DYNAMIC_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return diff --git a/HEN_HOUSE/egs++/sources/egs_fano_source/egs_fano_source.cpp b/HEN_HOUSE/egs++/sources/egs_fano_source/egs_fano_source.cpp index 285cd94f0..410e858f3 100644 --- a/HEN_HOUSE/egs++/sources/egs_fano_source/egs_fano_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_fano_source/egs_fano_source.cpp @@ -25,6 +25,7 @@ # Hugo Bouchard, 2016 # # Contributors: Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -41,6 +42,8 @@ #include "egs_math.h" #include +static bool EGS_FANO_SOURCE_LOCAL inputSet = false; + EGS_FanoSource::EGS_FanoSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), shape(0), geom(0), @@ -144,6 +147,55 @@ void EGS_FanoSource::setUp() { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Fano_Source"}); + + // Format: name, isRequired, description, vector string of allowed values + auto shapePtr = srcBlockInput->addBlockInput("shape"); + setShapeInputs(shapePtr); + + srcBlockInput->addSingleInput("geometry", true, "The name of a predefined geometry"); + srcBlockInput->addSingleInput("max mass density", true, "The maximum mass density"); + } + + EGS_FANO_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_fano_source + #:start source: + library = egs_fano_source + name = my_fano_source + :start shape: + type = box + box size = 1 2 3 + :start media input: + media = water + :stop media input: + :stop shape: + :start spectrum: + type = monoenergetic + energy = 1 + :stop spectrum: + charge = 0 + max mass density = 1.2 + geometry = some_name + #create a geometry called some_name +)"}; + return example; + } + + EGS_FANO_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_FANO_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return createSourceTemplate(input, f, "fano source"); diff --git a/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp b/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp index fc12f7adc..9e42209db 100644 --- a/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp +++ b/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -37,6 +38,8 @@ #include "egs_parallel_beam.h" #include "egs_input.h" +static bool EGS_PARALLEL_BEAM_LOCAL inputSet = false; + EGS_ParallelBeam::EGS_ParallelBeam(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), shape(0), uo(0,0,1) { vector dir; @@ -109,6 +112,54 @@ void EGS_ParallelBeam::setUp() { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Parallel_Beam"}); + + // Format: name, isRequired, description, vector string of allowed values + auto shapePtr = srcBlockInput->addBlockInput("shape"); + + setShapeInputs(shapePtr); + + srcBlockInput->addSingleInput("direction", true, "Direction of the beam (x, y, z)"); + } + + EGS_PARALLEL_BEAM_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_parallel_beam + #:start source: + library = egs_parallel_beam + name = my_source + :start shape: + type = cylinder + radius = 1 + height = 2 + axis = 0 0 1 + midpoint = 0 + :stop shape: + direction = 0 0 1 + charge = 0 + :start spectrum: + type = monoenergetic + energy = 6 + :stop spectrum: + :stop source: +)"}; + return example; + } + + EGS_PARALLEL_BEAM_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_PARALLEL_BEAM_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return createSourceTemplate(input,f,"parallel beam"); diff --git a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp index 63363dcd9..5a35ea340 100644 --- a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp @@ -26,6 +26,7 @@ # Contributors: Ernesto Mainegra-Hing # Frederic Tessier # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -41,6 +42,8 @@ #include "egs_functions.h" #include "egs_application.h" +static bool EGS_PHSP_SOURCE_LOCAL inputSet = false; + EGS_PhspSource::EGS_PhspSource(const string &phsp_file, const string &Name, EGS_ObjectFactory *f) : EGS_BaseSource(Name,f) { init(); @@ -517,6 +520,47 @@ void EGS_PhspSource::setFilter(int type, int nbit1, int nbit2, const int *bits) extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(false, false); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Phsp_Source"}); + + // Format: name, isRequired, description, vector string of allowed values + srcBlockInput->addSingleInput("phase space file", true, "The name of the phase space file."); + srcBlockInput->addSingleInput("particle type", true, "The type of particle", {"all", "charged", "electrons", "positrons", "photons"}); + srcBlockInput->addSingleInput("cutout", false, "A rectagular cutout defined by x1, x2, y1, y2"); + srcBlockInput->addSingleInput("weight window", false, "wmin, wmax, the min and max particle weights to use. If the particle is not in this range, it is rejected."); + srcBlockInput->addSingleInput("recyle photons", false, "The number of time to recycle each photon"); + srcBlockInput->addSingleInput("recycle electrons", false, "The number of times to recycle each electron"); + } + + EGS_PHSP_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_phsp_soure + #:start source: + name = my_source + library = egs_phsp_source + phase space file = ../BEAM_EX16MVp/EX16MVp.egsphsp1 + particle type = all + cutout = -1 1 -2 2 + recycle photons = 10 + recycle electrons = 10 + :stop source: +)"}; + return example; + } + + EGS_PHSP_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_PHSP_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return diff --git a/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp b/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp index d99501c6b..6747cbcf7 100644 --- a/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -37,6 +37,8 @@ #include "egs_point_source.h" #include "egs_input.h" +static bool EGS_POINT_SOURCE_LOCAL inputSet = false; + EGS_PointSource::EGS_PointSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), xo(), valid(true) { vector pos; @@ -77,6 +79,43 @@ void EGS_PointSource::setUp() { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Point_Source"}); + + // Format: name, isRequired, description, vector string of allowed values + srcBlockInput->addSingleInput("position", true, "The position of the point source, (x, y, z)"); + } + + EGS_POINT_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_point_source + #:start source: + library = egs_point_source + name = my_source + position = 0 0 0 + :start spectrum: + type = monoenergetic + energy = 1 + :stop spectrum: + charge = 0 + :stop source: +)"}; + return example; + } + + EGS_POINT_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_POINT_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return createSourceTemplate(input,f,"point source"); diff --git a/HEN_HOUSE/egs++/sources/egs_radionuclide_source/egs_radionuclide_source.cpp b/HEN_HOUSE/egs++/sources/egs_radionuclide_source/egs_radionuclide_source.cpp index 17b2460db..285b81a7e 100644 --- a/HEN_HOUSE/egs++/sources/egs_radionuclide_source/egs_radionuclide_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_radionuclide_source/egs_radionuclide_source.cpp @@ -25,6 +25,7 @@ # # Contributors: Martin Martinov # Ernesto Mainegra-Hing +# Hannah Gallop # ############################################################################### */ @@ -40,6 +41,8 @@ #include "egs_math.h" #include "egs_application.h" +static bool EGS_RADIONUCLIDE_SOURCE_LOCAL inputSet = false; + EGS_RadionuclideSource::EGS_RadionuclideSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSource(input,f), baseSource(0), q_allowed(0), decays(0), activity(1), sCount(0) { @@ -354,6 +357,83 @@ bool EGS_RadionuclideSource::setState(istream &data) { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Radionuclide_Source"}); + + // Format: name, isRequired, description, vector string of allowed values + srcBlockInput->addSingleInput("activity", false, "The total activity of mixture, assumed constant."); + srcBlockInput->addSingleInput("experiment time", false, "Time length of the experiment"); + auto srcPtr = srcBlockInput->addSingleInput("source type", false, "Either isotropic or collimated", {"isotropic", "collimated"}); + + // If source type is isotropic + auto geomPtr = srcBlockInput->addSingleInput("geometry", false, "The name of a geometry, used for complex source shapes. Only particles generated inside the geometry or some of its regions are used."); + geomPtr->addDependency(srcPtr, "isotropic"); + geomPtr->addDependency(srcPtr, ""); + auto regPtr = srcBlockInput->addSingleInput("region selection", false, "Include or exclude regions from the named geometry, to define a volume for source particle generation.", {"IncludeAll", "ExcludeAll","IncludeSelected","ExcludeSelected"}); + regPtr->addDependency(geomPtr); + auto selPtr = srcBlockInput->addSingleInput("selected regions", false, "If region selection = IncludeSelected or ExcludeSelected, then this is a list of the regions in the named geometry to include or exclude."); + selPtr->addDependency(geomPtr); + selPtr->addDependency(regPtr, "IncludeSelected"); + selPtr->addDependency(regPtr, "ExcludeSelected"); + + auto shapePtr = srcBlockInput->addBlockInput("shape"); + shapePtr->addDependency(srcPtr, "isotropic"); + + setShapeInputs(shapePtr); + + // If source is collimated + auto disPtr = srcBlockInput->addSingleInput("distance", false, "The source-target minimum distance"); + disPtr->addDependency(srcPtr, "collimated"); + + auto src_shapePtr = srcBlockInput->addBlockInput("source shape"); + src_shapePtr->addDependency(srcPtr, "collimated"); + auto targetPtr = srcBlockInput->addBlockInput("target shape"); + targetPtr->addDependency(srcPtr, "collimated"); + + setShapeInputs(src_shapePtr); + setShapeInputs(targetPtr); + } + + EGS_RADIONUCLIDE_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_radionuclide_source + #:start source: + name = my_source + library = egs_radionuclide_source + activity = 28e6 + geometry = my_envelope + #create geometry called my_envelope + region selection = IncludeSelected + selected regions = 1 2 + :start shape: + type = box + box size = 1 2 3 + :start media input: + media = H2O521ICRU + :stop media input: + :stop shape: + :start spectrum: + type = radionuclide + nuclide = Ir-192 + :stop spectrum: + :stop source: +)"}; + return example; + } + + EGS_RADIONUCLIDE_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_RADIONUCLIDE_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return diff --git a/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp b/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp index 71deba851..b3d2586ed 100644 --- a/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp +++ b/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp @@ -25,6 +25,7 @@ # # Contributors: Marc Chamberland # Blake Walters +# Hannah Gallop # ############################################################################### */ @@ -38,6 +39,8 @@ #include "egs_source_collection.h" #include "egs_input.h" +static bool EGS_SOURCE_COLLECTION_LOCAL inputSet = false; + EGS_SourceCollection::EGS_SourceCollection(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSource(input,f), nsource(0), count(0) { vector s; @@ -137,6 +140,41 @@ void EGS_SourceCollection::setUp(const vector &S, extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(false, false); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Source_Collection"}); + + // Format: name, isRequired, description, vector string of allowed values + srcBlockInput->addSingleInput("source names", true, "A list of names of previously defined sources."); + srcBlockInput->addSingleInput("weights", true, "A list of weights for the sources"); + } + + EGS_SOURCE_COLLECTION_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_source_collection + :start source: + library = egs_source_collection + name = my_source + source name = p1 p2 + # create sources called p1 and p2 + weights = 0.1 0.9 + :stop source: +)"}; + return example; + } + + EGS_SOURCE_COLLECTION_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_SOURCE_COLLECTION_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return diff --git a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp index 752378241..34a9edabd 100644 --- a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -37,6 +37,8 @@ #include "egs_transformed_source.h" #include "egs_input.h" +static bool EGS_TRANSFORMED_SOURCE_LOCAL inputSet = false; + EGS_TransformedSource::EGS_TransformedSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSource(input,f), source(0), T(0) { EGS_Input *isource = input->takeInputItem("source",false); @@ -76,6 +78,50 @@ void EGS_TransformedSource::setUp(EGS_AffineTransform *t) { extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(false, false); + + srcBlockInput->getSingleInput("library")->setValues({"EGS_Transformed_Source"}); + + // Format: name, isRequired, description, vector striing of allowed values + srcBlockInput->addSingleInput("source name", true, "The name of a previously defined source."); + + auto blockPtr = srcBlockInput->addBlockInput("transformation"); + blockPtr->addSingleInput("translation", false, "The translation for the geometry (x, y ,z)"); + auto rotPtr = blockPtr->addSingleInput("rotation", false, "2, 3, or 9 floating point numbers"); + auto vectPtr = blockPtr->addSingleInput("rotation vector", false, "3 floating point numbers"); + // Can either have "rotation" or "rotation vector" + rotPtr->addDependency(vectPtr, "", true); + vectPtr->addDependency(rotPtr, "", true); + } + + EGS_TRANSFORMED_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_transformed_source + #:start source: + library = egs_transformed_source + name = my_source + source_name = my_parallel_source + #create source called my_parallel_source + :start transformation: + rotation vector = 0 -1 1 + :stop transformation: + :stop source: +)"}; + return example; + } + + EGS_TRANSFORMED_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + EGS_TRANSFORMED_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 72d74edfe..7befdc358 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -27,6 +27,7 @@ # Ernesto Mainegra-Hing # Manuel Stoeckl # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -76,6 +77,7 @@ typedef EGS_Application *(*createAppFunction)(int argc, char **argv); typedef EGS_BaseGeometry *(*createGeomFunction)(); typedef EGS_BaseSource *(*createSourceFunction)(); typedef EGS_BaseShape *(*createShapeFunction)(); +typedef EGS_AusgabObject *(*createAusgabObjectFunction)(); typedef void (*getAppInputsFunction)(shared_ptr inpPtr); typedef shared_ptr (*getInputsFunction)(); typedef string (*getExampleFunction)(); @@ -294,6 +296,10 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) auto srcDefPtr = inputStruct->addBlockInput("source definition"); srcDefPtr->addSingleInput("simulation source", true, "The name of the source that will be used in the simulation. If you have created a composite source using many other sources, name the final composite source here."); + // Ausgab Object definition block + auto ausDefPtr = inputStruct->addBlockInput("ausgab object definition"); + ausDefPtr->addSingleInput("simulation ausgab object", true, "The name of the ausgab object that will be used in the simulation."); + // For each library, try to load it and determine if it is geometry or source for (const auto &lib : libraries) { // Remove the extension @@ -447,6 +453,45 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); } } + + // Ausgab Objects + createAusgabObjectFunction isAusgabObject = (createAusgabObjectFunction) egs_lib.resolve("createAusgabObject"); + if (isAusgabObject) { + + getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); + if (getInputs) { + + shared_ptr aus = getInputs(); + if(aus){ + ausDefPtr->addBlockInput(aus); + + vector> singleInputs = aus->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + + vector> inputBlocks = aus->getBlockInputs(); + for (auto &block : inputBlocks) { + vector> singleInputs = block->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + } + } + } + getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); + if (getExample) { + QAction *action = sourceMenu->addAction(libName); + action->setData(QString::fromStdString(getExample())); + connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); + } + } } egsInformation("testlib3 trying \n"); egsinpEdit->setInputStruct(inputStruct); From 0f59cd30d270ff96188f6115653221745508efc2 Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Mon, 15 Feb 2021 09:15:04 -0500 Subject: [PATCH 18/40] Add support for shapes in egs_view editor --- .../egs_conical_shell/egs_conical_shell.cpp | 53 +++++++++++++++++++ .../egs_extended_shape/egs_extended_shape.cpp | 36 ++++++++++++- .../egs_gaussian_shape/egs_gaussian_shape.cpp | 37 ++++++++++++- .../egs_shape_collection.cpp | 43 +++++++++++++++ .../egs_spherical_shell.cpp | 39 ++++++++++++++ .../egs_voxelized_shape.cpp | 31 +++++++++++ 6 files changed, 237 insertions(+), 2 deletions(-) diff --git a/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp b/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp index efe53f5a3..764095205 100644 --- a/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp @@ -27,6 +27,7 @@ # Contributors: Marc Chamberland # Rowan Thomson # Dave Rogers +# Hannah Gallop # ############################################################################### # @@ -48,6 +49,8 @@ #include #include +static bool EGS_CONICAL_SHELL_LOCAL inputSet = false; +static shared_ptr EGS_CONICAL_SHELL_LOCAL shapeBlockInput = make_shared("shape"); CSSSLayer::CSSSLayer(EGS_Float t, EGS_Float rit, EGS_Float rot, EGS_Float rib, EGS_Float rob, EGS_Float z): thick(t), ri_top(rit), ro_top(rot), ri_bot(rib), ro_bot(rob), zo(z) { @@ -191,6 +194,56 @@ void EGS_ConicalShellStackShape::setLayerSampler() { extern "C" { + static void setInputs() { + inputSet = true; + + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Conical_Shell"}); + shapeBlockInput->addSingleInput("radius", false, "The radius"); + shapeBlockInput->addSingleInput("midpoint", false, "The midpoint of the concical shell."); + + auto blockPtr = shapeBlockInput->addBlockInput("layer"); + blockPtr->addSingleInput("thickness", true, "The thickness of the layer"); + blockPtr->addSingleInput("top radii", false, "1 (outer radius, inner radius assumed to be 0) or 2 (outer and inner radius) inputs, only required for top layer"); + blockPtr->addSingleInput("bottom radii", true, "1 (outer radius, inner radius assumed to be 0) or 2 (outer and inner radius) inputs"); + } + + EGS_CONICAL_SHELL_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_conical_shell + #:start shape: + library = egs_conical_shell + midpoint = 0 0 -1 + :start layer: + thickness = 0.5 + top radii = 0 1 + bottom radii = 0.5 2 + :stop layer: + :start layer: + thickness = 0.5 + bottom radii = 0.25 1 + :stop layer: + :start layer: + thickness = 0.5 + bottom radii = 0.5 + :stop layer: + :start layer: + thickness = 0.5 + bottom radii = 2 + :stop layer: + :stop shape: +)"}; + return example; + } + + EGS_CONICAL_SHELL_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_CONICAL_SHELL_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp index 92400c69e..beefce956 100644 --- a/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -38,8 +38,42 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_EXTENDED_SHAPE_LOCAL inputSet = false; +static shared_ptr EGS_EXTENDED_SHAPE_LOCAL shapeBlockInput = make_shared("shape"); + extern "C" { + static void setInputs() { + inputSet = true; + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Extended_Shape"}); + shapeBlockInput->addSingleInput("extension", true, "Adds delta z to the z-component of the position vector (z1, z2)"); + + auto shapePtr = shapeBlockInput->addBlockInput("shape"); + setShapeInputs(shapePtr); + } + + EGS_EXTENDED_SHAPE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_extended_shape + #:start shape: + library = egs_extended_shape + :start shape: + definition of the shape to be 'extended' + :stop shape: + extension = z1 z2 +)"}; + return example; + } + + EGS_EXTENDED_SHAPE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_EXTENDED_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp index 810b89a34..a1a6aafbd 100644 --- a/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -38,8 +38,43 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_GAUSSIAN_SHAPE_LOCAL inputSet = false; +static shared_ptr EGS_GAUSSIAN_SHAPE_LOCAL shapeBlockInput = make_shared("shape"); + extern "C" { + static void setInputs() { + inputSet = true; + + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Gaussian_Shape"}); + shapeBlockInput->addSingleInput("sigma", true, "1 or 2 or 3 inputs"); + + auto shapePtr = shapeBlockInput->addBlockInput("shape"); + setShapeInputs(shapePtr); + } + + EGS_GAUSSIAN_SHAPE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_gaussiam_shape + #:start shape: + library = egs_gaussian_shape + :start shape: + definition of the shape to be smeared + :stop shape: + sigma = 1, 2 or 3 inputs +)"}; + return example; + } + + EGS_GAUSSIAN_SHAPE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_GAUSSIAN_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp index b825e9b5d..c4d9eab38 100644 --- a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp @@ -25,6 +25,7 @@ # # Contributors: Marc Chamberland # Randle Taylor +# Hannah Gallop # ############################################################################### */ @@ -39,6 +40,9 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_SHAPE_COLLECTION_LOCAL inputSet = false; +static shared_ptr EGS_SHAPE_COLLECTION_LOCAL shapeBlockInput = make_shared("shape"); + EGS_ShapeCollection::EGS_ShapeCollection(const vector &Shapes, const vector &Probs, const string &Name, EGS_ObjectFactory *f) : EGS_BaseShape(Name,f), nshape(0) { @@ -61,6 +65,45 @@ EGS_ShapeCollection::EGS_ShapeCollection(const vector &Shapes, extern "C" { + static void setInputs() { + inputSet = true; + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Shape_Collection"}); + shapeBlockInput->addSingleInput("probabilities", true, "p1 p2 ... pn"); + + auto shapePtr = shapeBlockInput->addBlockInput("shape"); + setShapeInputs(shapePtr); + } + + EGS_SHAPE_COLLECTION_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_shape_collection + #:start shape: + library = egs_shape_sollection + :start shape: + definition of the first shape in the collection: + :stop shape: + :start shape: + definition of the second shape in the collection + :stop shape: + ... + :start shape: + definition of the last shape in the collection + :stop shape: + probablities = p1 p2 ... pn + :stop shape: +)"}; + return example; + } + + EGS_SHAPE_COLLECTION_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_SHAPE_COLLECTION_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp b/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp index 6a07e6870..61c39e5b6 100644 --- a/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp @@ -27,6 +27,7 @@ # Contributors: Marc Chamberland # Rowan Thomson # Dave Rogers +# Hannah Gallop # ############################################################################### # @@ -46,6 +47,9 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_SPHERICAL_SHELL_LOCAL inputSet = false; +static shared_ptr EGS_SPHERICAL_SHELL_LOCAL shapeBlockInput = make_shared("shape"); + EGS_SphericalShellShape::EGS_SphericalShellShape(EGS_Float ri, EGS_Float ro, int hemisph, EGS_Float halfangle, const EGS_Vector &Xo, const string &Name,EGS_ObjectFactory *f) : EGS_BaseShape(Name, f), r_inner(ri), r_outer(ro), hemisphere(hemisph), half_angle(halfangle), xo(Xo) { @@ -128,6 +132,41 @@ EGS_Float EGS_SphericalShellShape::area() const { extern "C" { + static void setInputs() { + inputSet = true; + + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Spherical_Shape"}); + shapeBlockInput->addSingleInput("midpoint", true, "The midpoint of the shape, (x y z)"); + shapeBlockInput->addSingleInput("inner radius", true, "The inner radius"); + shapeBlockInput->addSingleInput("outer radius", true, "The outer radius"); + shapeBlockInput->addSingleInput("hemisphere", false, "Hemisphere"); + shapeBlockInput->addSingleInput("hemisphere", false, "The half angle, in degrees"); + } + + EGS_SPHERICAL_SHELL_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_spherical_shell + #:start shape: + library = egs_spherical_shell + midpoint = 0 0 0 + innner radius = 0.5 + outer radius = 1 + hemisphere = 1 + half angle = 35 + :stop shape: +)"}; + return example; + } + + EGS_SPHERICAL_SHELL_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_SPHERICAL_SHELL_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { if (!input) { diff --git a/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp index a8f65d8a1..856c3efc5 100644 --- a/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp @@ -25,6 +25,7 @@ # # Contributors: Frederic Tessier # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -42,6 +43,9 @@ #include using namespace std; +static bool EGS_VOXELIZED_SHAPE_LOCAL inputSet = false; +static shared_ptr EGS_VOXELIZED_SHAPE_LOCAL shapeBlockInput = make_shared("shape"); + void EGS_VoxelizedShape::EGS_VoxelizedShapeFormat0(const char *fname, const string &Name,EGS_ObjectFactory *f) { prob=0; @@ -369,6 +373,33 @@ EGS_VoxelizedShape::~EGS_VoxelizedShape() { extern "C" { + static void setInputs() { + inputSet = true; + + shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Voxelized_Shape"}); + shapeBlockInput->addSingleInput("file name", true, "The name of a file that is in binary"); + } + + EGS_VOXELIZED_SHAPE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of egs_voxelized_shape + #:start shape: + library = egs_voxelized_shape + file name = some_file + :stop shape: +)"}; + return example; + } + + EGS_VOXELIZED_SHAPE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return shapeBlockInput; + } + EGS_VOXELIZED_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) { static const char *func = "createShape(voxelized shape)"; From 790ed98086063f056d3f7d56dff0b37c77132ca9 Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Fri, 26 Feb 2021 11:20:58 -0500 Subject: [PATCH 19/40] Add keystroke seletion to egs_editor --- HEN_HOUSE/egs++/view/egs_editor.cpp | 90 +++++++++++++++++------------ 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 92965e288..0c9849318 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -61,9 +61,10 @@ EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { popup->setSelectionBehavior(QAbstractItemView::SelectRows); popup->setSelectionMode(QAbstractItemView::SingleSelection); popup->setParent(nullptr); - popup->setFocusPolicy(Qt::NoFocus); + popup->setFocusPolicy(Qt::StrongFocus); popup->installEventFilter(this); + // The Qt::Popup option seems to take control of mouse + key inputs // essentially locking up the computer, beware! //popup->setWindowFlag(Qt::Popup); @@ -78,11 +79,11 @@ EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(autoComplete())); connect(popup, SIGNAL(clicked(QModelIndex)), this, SLOT(insertCompletion(QModelIndex))); - + connect(popup, SIGNAL(activated(QModelIndex)), this, SLOT(insertCompletion(QModelIndex))); // // QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), // this, SLOT(_q_completionSelected(QItemSelection))); - + //connect(this, SIGNAL(keyboardGrabber()), this, SIGNAL(QAbstractItemView::MoveDown)); } @@ -634,6 +635,7 @@ void EGS_Editor::insertCompletion(QModelIndex index) { this->moveCursor(QTextCursor::EndOfBlock); insertPlainText(model->data(index).toString()); cursor.endEditBlock(); + popup->QWidget::releaseKeyboard(); } shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextCursor cursor) { @@ -951,7 +953,6 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp, QText satisfied = false; } } - // Look ahead, if the following inputs have the same tag as this one (i) for(size_t j = i+1; j < dependencyInp.size(); ++j) { if(egsEquivStr(dependencyInp[j]->getTag(), depTag)) { @@ -1120,8 +1121,10 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { // Insert 4 spaces instead of tabs if (keyEvent->key() == Qt::Key_Tab) { - insertPlainText(" "); - return true; + if (!popup->isVisible()) { + insertPlainText(" "); + return true; + } } else if(keyEvent->key() == Qt::Key_Backtab) { // Delete 4 spaces from the front of the line QTextCursor cursor = textCursor(); @@ -1137,48 +1140,59 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { } return true; } else if(keyEvent->key() == Qt::Key_Return) { - QTextCursor cursor = textCursor(); - QString line = cursor.block().text(); + if (!popup->isVisible()) { - // Get the current indentation amount - QString indentation; - for(size_t i = 0; i < line.size(); ++i) { - if(line.at(i) == ' ') { - indentation += ' '; - } else if(line.at(i) == '\t') { - indentation += " "; - } else { - break; + QTextCursor cursor = textCursor(); + QString line = cursor.block().text(); + + // Get the current indentation amount + QString indentation; + for(size_t i = 0; i < line.size(); ++i) { + if(line.at(i) == ' ') { + indentation += ' '; + } else if(line.at(i) == '\t') { + indentation += " "; + } else { + break; + } } - } - QString stopLine; - int pos = line.lastIndexOf(":start "); - int posInBlock = cursor.positionInBlock(); - if(pos > -1 && posInBlock > pos) { - stopLine = line.replace(pos, 7, ":stop "); - } + QString stopLine; + int pos = line.lastIndexOf(":start "); + int posInBlock = cursor.positionInBlock(); + if(pos > -1 && posInBlock > pos) { + stopLine = line.replace(pos, 7, ":stop "); + } - // If we inserted the ":stop" line, then also insert a line between - // and leave the cursor there - if(stopLine.size() > 0) { - insertPlainText("\n" + indentation + " "); - insertPlainText("\n" + stopLine); - cursor.movePosition(QTextCursor::PreviousBlock); - cursor.movePosition(QTextCursor::EndOfBlock); - setTextCursor(cursor); + // If we inserted the ":stop" line, then also insert a line between + // and leave the cursor there + if(stopLine.size() > 0) { + insertPlainText("\n" + indentation + " "); + insertPlainText("\n" + stopLine); + cursor.movePosition(QTextCursor::PreviousBlock); + cursor.movePosition(QTextCursor::EndOfBlock); + setTextCursor(cursor); - // Normally, we just insert a new line with matching indentation - } else { - insertPlainText("\n" + indentation); - } + // Normally, we just insert a new line with matching indentation + } else { + insertPlainText("\n" + indentation); + } - // Skip the usual return event! So we have to handle it here - return true; + // Skip the usual return event! So we have to handle it here + return true; + } + } else if(keyEvent->key() == Qt::Key_Escape) { + popup->QWidget::releaseKeyboard(); + } else if(keyEvent->key() == Qt::Key_Right) { + if (popup->isVisible()) { + popup->QWidget::grabKeyboard(); + return true; + } } //} else if(event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { } else if(event->type() == QEvent::FocusOut) { popup->hide(); + popup->QWidget::releaseKeyboard(); } return QPlainTextEdit::eventFilter(obj, event); From dbcec3aef4add1ac78709db215eb4974f968d5a6 Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Mon, 26 Apr 2021 12:33:00 -0400 Subject: [PATCH 20/40] Add support for applications in egs_view editor --- HEN_HOUSE/egs++/egs_application.h | 51 ++++++++++++++-- HEN_HOUSE/egs++/egs_run_control.h | 2 +- HEN_HOUSE/egs++/egs_scoring.h | 41 +++++++++++++ HEN_HOUSE/egs++/view/egs_editor.cpp | 2 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 88 +++++++++++++++++++++++----- HEN_HOUSE/egs++/view/viewcontrol.h | 1 + 6 files changed, 162 insertions(+), 23 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index 2e0240f57..37912ece5 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -27,6 +27,7 @@ # Ernesto Mainegra-Hing # Blake Walters # Reid Townson +# Hannah Gallop # ############################################################################### */ @@ -46,6 +47,7 @@ #include "egs_interpolator.h" #include "egs_input_struct.h" #include "egs_run_control.h" +#include "egs_scoring.h" #include #include @@ -61,6 +63,47 @@ class EGS_AusgabObject; class EGS_Interpolator; //template class EGS_SimpleContainer; +static void addmcBlock(shared_ptr blockPtr) { + shared_ptr mcBlock = blockPtr->addBlockInput("MC transport parameter"); + mcBlock->addSingleInput("Global ECUT", false, "Global electron transport cutoff"); + mcBlock->addSingleInput("Global PCUT", false, "Global photon transport cutoff"); + mcBlock->addSingleInput("Global SMAX", false, "Global maximum step-size restriction for e-transport"); + mcBlock->addSingleInput("ESTEPE", false, "Default is 0.25"); + mcBlock->addSingleInput("XIMAX", false, "Default is 0.5, maximum value is 1."); + mcBlock->addSingleInput("Boundary crossing algorithm", false, "exact is default", {"exact", "PRESTA-I"}); + mcBlock->addSingleInput("Skin depth for BCA", false, "Default value is 3 for exact boundary crossing"); + mcBlock->addSingleInput("Electron-step algorithm", false, "Default is PRESTA-II", {"PRESTA_II", "PRESTA_I"}); + mcBlock->addSingleInput("Spin effects", false, "Default is On", {"On", "Off"}); + mcBlock->addSingleInput("Brems angular sampling", false, "Default is KM", {"KM", "Simple"}); + mcBlock->addSingleInput("Brems cross sections", false, "Default is BH", {"BH", "NIST"}); + mcBlock->addSingleInput("Pair angular crossing", false, "Default is Simple", {"Simple", "Off", "KM"}); + mcBlock->addSingleInput("Triplet production", false, "Default is On", {"On", "Off"}); + mcBlock->addSingleInput("Electron Impact Ionization", false, "Default is Off", {"On", "Off", "casnati", "kolbenstvedt", "gryzinski"}); + mcBlock->addSingleInput("Bound Compton scattering", false, "Default is norej", {"On", "Off", "Simple", "norej"}); + mcBlock->addSingleInput("Radiative Compton corrections", false, "Default is Off", {"On", "Off"}); + mcBlock->addSingleInput("Rayleigh scattering", false, "Default is off", {"On", "Off", "custom"}); + mcBlock->addSingleInput("Photoelectron angular sampling", false, "Default is on", {"On", "Off"}); + mcBlock->addSingleInput("Atomic relaxations", false, "Default is on", {"On", "Off"}); + mcBlock->addSingleInput("Photon cross sections", false, "Default is xcom, can also be user-supplied", {"si", "epdl", "xcom"}); + mcBlock->addSingleInput("Photon cross-sections output", false, "Default is off", {"On", "Off"}); + mcBlock->addSingleInput("Compton cross sections", false, "User-supplied, default is comp-xsections"); + mcBlock->addSingleInput("Photonuclear attenuation", false, "Default is off", {"On", "Off"}); + mcBlock->addSingleInput("Photonuclear cross sections", false, "Default is default, or is user-supplied", {"default"}); +} + +static void addvrBlock(shared_ptr blockPtr) { + shared_ptr vrBlock = blockPtr->addBlockInput("variance reduction"); + vrBlock->addSingleInput("photon splitting", false, "N_split"); + vrBlock->addSingleInput("TmpPhsp", false, "Score phase space, use once in each geometry"); + vrBlock->addSingleInput("cs enhancement", false, "0 (XCSE off) or >0 (XCSE on)"); + + shared_ptr rangePtr = vrBlock->addBlockInput("range rejection"); + rangePtr->addSingleInput("rejection", false, "N_r"); + rangePtr->addSingleInput("Esave", false, "E_save"); + rangePtr->addSingleInput("cavity geometry", false, "The name of a previously defined geometry"); + rangePtr->addSingleInput("rejection range medium", false, "index of the medium to calculate electron ranges"); +} + /*! \brief A structure holding the information of one particle \ingroup egspp_main */ @@ -1201,9 +1244,7 @@ class EGS_EXPORT EGS_Application { virtual void setLatch(int latch) {}; static unique_ptr inputStructure; - }; - #define APP_MAIN(app_name) \ int main(int argc, char **argv) { \ app_name app(argc,argv); \ @@ -1230,9 +1271,9 @@ class EGS_EXPORT EGS_Application { }\ APP_EXPORT void getAppInputs(shared_ptr inpPtr) {\ addRunControlBlock(inpPtr);\ + addmcBlock(inpPtr);\ + addvrBlock(inpPtr);\ + addScoringBlock(inpPtr);\ }\ - } - #endif - diff --git a/HEN_HOUSE/egs++/egs_run_control.h b/HEN_HOUSE/egs++/egs_run_control.h index ae7a53b94..f29a83e39 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -66,7 +66,7 @@ static void addRunControlBlock(shared_ptr blockPtr) { In EGSnrc applications derived from EGS_AdvancedApplication the program execution is controlled by a 'run control object' (RCO). The purpose of - the RCO is to tell the shower loop into how many 'chunks' the simulation + the RCO is to tell shower loop into how many 'chunks' the simulation should be split, how many particles to run per simulation chunk, into how many batches to split a simulation chunk, etc. In this way it is easy for EGSnrc C++ application developers to either use one of the RCO's diff --git a/HEN_HOUSE/egs++/egs_scoring.h b/HEN_HOUSE/egs++/egs_scoring.h index 5148cc697..7052d4542 100644 --- a/HEN_HOUSE/egs++/egs_scoring.h +++ b/HEN_HOUSE/egs++/egs_scoring.h @@ -40,10 +40,51 @@ #include "egs_libconfig.h" #include "egs_functions.h" #include "egs_math.h" +#include "egs_input_struct.h" #include using namespace std; +static void addScoringBlock(shared_ptr blockPtr) { + shared_ptr scoreBlock = blockPtr->addBlockInput("scoring options"); + scoreBlock->addSingleInput("pulse height regions", false, "A list of regions to score pulse height distributions"); + scoreBlock->addSingleInput("pulse height bins", false, "How many bins to use for each pulse height distribution. This must be either a single input, in which case all pulse height distributions will use this number of bins, or the same number of inputs as pulse height regions."); + scoreBlock->addSingleInput("silent", false, "0 (verbose output) or greater than 0 (short output)"); + scoreBlock->addSingleInput("calculation type", false, "Default is dose", {"Dose", "Awall", "Fano", "FAC", "HVL"}); + + shared_ptr calGeomPtr = scoreBlock->addBlockInput("calculation geometry"); + calGeomPtr->addSingleInput("geometry name", false, "The name of the base geometry"); + calGeomPtr->addSingleInput("cavity regions", true, "A list of cavity region indices"); + calGeomPtr->addSingleInput("cavity mass", true, "The total cavity mass in grams"); + calGeomPtr->addSingleInput("cavity geometry", true, "The name of geometry for range rejection"); + calGeomPtr->addSingleInput("enhance regions", false, "A list of enhancement region indicies"); + calGeomPtr->addSingleInput("enhancement", false, "A list of enhancement factors"); + + auto transPtr = calGeomPtr->addBlockInput("transformation"); + transPtr->addSingleInput("translation", false, "The translation for the geometry (x, y ,z)"); + + scoreBlock->addSingleInput("correlated geometries", false, "A list of geometries"); + + // input loops can also be used so avoid retyping things + auto inpPtr = scoreBlock->addBlockInput("input loop"); + inpPtr->addSingleInput("loop count", true, "The number of times the loop repeats"); + inpPtr->addSingleInput("loop variable", true, "The type (0 for integer, 1 for real, 2 for string), the variable name, then a list of the variable inputs"); + inpPtr->addSingleInput("correlated geometries", false, "A list of geometries"); + + auto geominpPtr = inpPtr->addBlockInput("calculation geometry"); + geominpPtr->addSingleInput("geometry name", false, "The name of the base geometry"); + geominpPtr->addSingleInput("cavity regions", true, "A list of cavity region indices"); + geominpPtr->addSingleInput("cavity mass", true, "The total cavity mass in grams"); + geominpPtr->addSingleInput("cavity geometry", true, "The name of geometry for range rejection"); + geominpPtr->addSingleInput("enhance regions", false, "A list of enhancement region indicies"); + geominpPtr->addSingleInput("enhancement", false, "A list of enhancement factors"); + geominpPtr->addSingleInput("subgeometries", false, "A list of identical geometries with material differences"); + geominpPtr->addSingleInput("sub geom regions", false, "A list of regions where composition changes"); + + auto transinpPtr = geominpPtr->addBlockInput("transformation"); + transinpPtr->addSingleInput("translation", false, "The translation for the geometry (x, y ,z)"); +} + /*! \brief A class for scoring a single quantity of interest in a Monte Carlo simulation. diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 0c9849318..b31213253 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -23,7 +23,7 @@ # # Author: Reid Townson, 2020 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 7befdc358..ae6727515 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -225,20 +225,20 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) lib_dir += CONFIG_NAME; lib_dir += fs; - /*EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); + EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); if (!app_lib.load()) egsFatal("\n%s: Failed to load the %s application library from %s\n\n", appv[0],app_name.c_str(),lib_dir.c_str()); createAppFunction createApp = (createAppFunction) app_lib.resolve("createApplication"); if (!createApp) egsFatal("\n%s: Failed to resolve the address of the 'createApplication' function" - " in the application library %s\n\n",appv[0],app_lib.libraryFile()); */ -/*TODO left here crash 'cause tutor7pp isn't compiled <======================= + " in the application library %s\n\n",appv[0],app_lib.libraryFile()); +//TODO left here crash 'cause tutor7pp isn't compiled <======================= EGS_Application *app = createApp(appc,appv); if (!app) { egsFatal("\n%s: Failed to construct the application %s\n\n",appv[0],app_name.c_str()); } egsInformation("Testapp %f\n",app->getRM()); - */ + // Get a list of all the libraries in the dso directory string dso_dir; @@ -263,13 +263,14 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) QMenu *ausgabMenu = exampleMenu->addMenu("Ausgab/Output"); QMenu *mediaMenu = exampleMenu->addMenu("Media"); QMenu *runMenu = exampleMenu->addMenu("Run Control"); + QMenu *appMenu = exampleMenu->addMenu("Applications"); editorLayout->setMenuBar(menuBar); // The input template structure inputStruct = make_shared(); // Get the application level input blocks - /*getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); + getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); if(getAppInputs) { getAppInputs(inputStruct); if(inputStruct) { @@ -286,7 +287,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } - } */ + } // Geometry definition block auto geomDefPtr = inputStruct->addBlockInput("geometry definition"); @@ -316,11 +317,9 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) if (!egs_lib.load()) { continue; } - egsInformation("testlib2 trying %s\n", libName.toLatin1().data()); // Geometries createGeomFunction isGeom = (createGeomFunction) egs_lib.resolve("createGeometry"); - egsInformation("testlib4 trying \n"); if (isGeom) { egsInformation(" testgeom %s\n",libName.toLatin1().data()); @@ -354,7 +353,6 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } - egsInformation("testlib5 trying \n"); getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { QAction *action = geomMenu->addAction(libName); @@ -364,7 +362,6 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } // Sources - egsInformation("testlib6 trying \n"); createSourceFunction isSource = (createSourceFunction) egs_lib.resolve("createSource"); if (isSource) { egsInformation(" testsrc %s\n",libName.toLatin1().data()); @@ -399,7 +396,6 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } - //egsInformation("testlib7 trying \n"); getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { QAction *action = sourceMenu->addAction(libName); @@ -409,7 +405,6 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } // Shapes - egsInformation("testlib8 trying \n"); createShapeFunction isShape = (createShapeFunction) egs_lib.resolve("createShape"); if (isShape) { egsInformation(" testshape %s\n",libName.toLatin1().data()); @@ -444,7 +439,6 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } - //egsInformation("testlib9 trying \n"); getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { @@ -493,7 +487,6 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } - egsInformation("testlib3 trying \n"); egsinpEdit->setInputStruct(inputStruct); } @@ -1015,6 +1008,8 @@ void GeometryViewControl::loadConfig(QString configFilename) { } // Load the particle track options + label_particles->hide(); + label_particle_colours->hide(); EGS_Input *iTracks = input->takeInputItem("tracks"); if (iTracks) { int show; @@ -1052,9 +1047,26 @@ void GeometryViewControl::loadConfig(QString configFilename) { showPositronsCheckbox->setCheckState(Qt::Unchecked); } } - delete iTracks; } + else { + label_particles->show(); + spin_tmaxp->hide(); + showPositronsCheckbox->hide(); + showPhotonsCheckbox->hide(); + showElectronsCheckbox->hide(); + spin_tminp->hide(); + spin_tmine->hide(); + spin_tmaxe->hide(); + spin_tminpo->hide(); + spin_tmaxpo->hide(); + + label_particle_colours->show(); + cPhotonsButton->hide(); + cElectronsButton->hide(); + cPositronsButton->hide(); + energyScalingCheckbox->hide(); + } // Load the overlay options EGS_Input *iOverlay = input->takeInputItem("overlay"); @@ -1235,6 +1247,22 @@ void GeometryViewControl::loadConfig(QString configFilename) { // Load the clipping planes EGS_Input *iClip = input->takeInputItem("clipping planes"); + // Set default clipped planes, along each axis + cplanes->setCell(0,0,1); + cplanes->setCell(0,1, 0); + cplanes->setCell(0,2,0); + cplanes->setCell(0,3,0); + cplanes->setCell(0,4,Qt::Unchecked); + cplanes->setCell(1,0,0); + cplanes->setCell(1,1,1); + cplanes->setCell(1,2,0); + cplanes->setCell(1,3,0); + cplanes->setCell(1,4,Qt::Unchecked); + cplanes->setCell(2,0,0); + cplanes->setCell(2,1,0); + cplanes->setCell(2,2,1); + cplanes->setCell(2,3,0); + cplanes->setCell(2,4,Qt::Unchecked); if (iClip) { for (int i=0; inumPlanes(); i++) { EGS_Input *iPlane = iClip->takeInputItem("plane"); @@ -1249,6 +1277,9 @@ void GeometryViewControl::loadConfig(QString configFilename) { if (!err) { cplanes->setCell(i,0,ax); } + /*else if (i == 0) { + cplanes->setCell(0, 0, 1); + }*/ else { cplanes->clearCell(i,0); } @@ -2063,6 +2094,16 @@ void GeometryViewControl::changeTransparency(int t) { updateView(true); } +void GeometryViewControl::changeGlobalTransparency(int t) { + int test = materialCB->count(); + for (int i = 0; i <= test; i++ ) { + int med = materialCB->count() - i; + QRgb c = m_colors[med]; + m_colors[med] = qRgba(qRed(c), qGreen(c), qBlue(c), t); + } + updateView(true); +} + void GeometryViewControl::changeDoseTransparency(int t) { #ifdef VIEW_DEBUG egsWarning("In changeDoseTransparency(%d)\n",t); @@ -2242,7 +2283,6 @@ void GeometryViewControl::loadTracksDialog() { if (filename_tracks.isEmpty()) { return; } - gview->loadTracks(filename_tracks); } @@ -2254,6 +2294,22 @@ void GeometryViewControl::updateTracks(vector ntracks) { #ifdef VIEW_DEBUG egsWarning("In updateTracks(%d %d %d)\n",ntracks[0], ntracks[1], ntracks[2]); #endif + label_particles->hide(); + spin_tmaxp->show(); + showPositronsCheckbox->show(); + showPhotonsCheckbox->show(); + showElectronsCheckbox->show(); + spin_tminp->show(); + spin_tmine->show(); + spin_tmaxe->show(); + spin_tminpo->show(); + spin_tmaxpo->show(); + + label_particle_colours->hide(); + cPhotonsButton->show(); + cElectronsButton->show(); + cPositronsButton->show(); + energyScalingCheckbox->show(); // Update maximum values for the track selection spin_tminp->setMaximum(ntracks[0]); diff --git a/HEN_HOUSE/egs++/view/viewcontrol.h b/HEN_HOUSE/egs++/view/viewcontrol.h index d0c6c8b90..762eaf9f2 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -110,6 +110,7 @@ public slots: virtual void phiRotation(int Phi); virtual void changeAmbientLight(int alight); virtual void changeTransparency(int t); + virtual void changeGlobalTransparency(int t); virtual void moveLightChanged(int toggle); virtual void setLightPosition(); virtual void setLookAt(); From ea05f21f8be1d80e020430c9cd11184127b1589e Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Fri, 30 Apr 2021 14:10:15 -0400 Subject: [PATCH 21/40] Add support for red line comments --- HEN_HOUSE/egs++/view/egs_editor.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index b31213253..e42a3b537 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -193,6 +193,10 @@ void EGS_Editor::validateLine(QTextCursor cursor) { return; } + if(selectedText.startsWith("#")) { + return; + } + // Check the validity of the inputs // If this line contains an "=" then it should match a single input int equalsPos = selectedText.indexOf("="); @@ -228,6 +232,7 @@ void EGS_Editor::validateLine(QTextCursor cursor) { if(!inputPtr) { // Red underline the input tag // Select the input tag + selection.cursor.movePosition(QTextCursor::StartOfBlock); // If whitespace was trimmed from the start of the line, From ecd69e22837667c5b4e6f45e0e5d4539bc9e8d48 Mon Sep 17 00:00:00 2001 From: Townson Date: Wed, 19 May 2021 14:15:50 -0400 Subject: [PATCH 22/40] Fix the recent egs_view ui changes Recent changes to egs_view were missing some necessary additions to the ui file. These have been included, along with a couple minor changes. Also set the compiler flags to use std=c++14 instead of std=c++11. --- HEN_HOUSE/egs++/view/viewcontrol.cpp | 67 +++-- HEN_HOUSE/egs++/view/viewcontrol.ui | 349 +++++++++++++++++---------- 2 files changed, 259 insertions(+), 157 deletions(-) diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index ae6727515..cf1032be7 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -193,6 +193,9 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) connect(gview, SIGNAL(leftMouseClick(int,int)), this, SLOT(reportViewSettings(int,int))); connect(gview, SIGNAL(leftDoubleClick(EGS_Vector)), this, SLOT(setRotationPoint(EGS_Vector))); connect(gview, SIGNAL(tracksLoaded(vector)), this, SLOT(updateTracks(vector))); + connect(global_transparency, SIGNAL(sliderReleased()), this, SLOT(endTransformation())); + connect(global_transparency, SIGNAL(sliderPressed()), this, SLOT(startTransformation())); + connect(global_transparency, SIGNAL(valueChanged(int)), this, SLOT(changeGlobalTransparency(int))); save_image = new SaveImage(this,"save image"); @@ -225,19 +228,29 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) lib_dir += CONFIG_NAME; lib_dir += fs; + // Load the application library + // We don't require the application to be compiled, just give a warning if it isn't. EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); - if (!app_lib.load()) egsFatal("\n%s: Failed to load the %s application library from %s\n\n", - appv[0],app_name.c_str(),lib_dir.c_str()); - - createAppFunction createApp = (createAppFunction) app_lib.resolve("createApplication"); - if (!createApp) egsFatal("\n%s: Failed to resolve the address of the 'createApplication' function" - " in the application library %s\n\n",appv[0],app_lib.libraryFile()); -//TODO left here crash 'cause tutor7pp isn't compiled <======================= - EGS_Application *app = createApp(appc,appv); - if (!app) { - egsFatal("\n%s: Failed to construct the application %s\n\n",appv[0],app_name.c_str()); + bool app_loaded = true; + if (!app_lib.load()) { + egsWarning("\n%s: Failed to load the %s application library from %s\n\n", appv[0],app_name.c_str(),lib_dir.c_str()); + app_loaded = false; + } else { + createAppFunction createApp = (createAppFunction) app_lib.resolve("createApplication"); + if (!createApp) { + egsWarning("\n%s: Failed to resolve the address of the 'createApplication' function in the application library %s\n\n",appv[0],app_lib.libraryFile()); + app_loaded = false; + } else { + EGS_Application *app = createApp(appc,appv); + if (!app) { + egsWarning("\n%s: Failed to construct the application %s\n\n",appv[0],app_name.c_str()); + app_loaded = false; + } + egsInformation("Testapp %f\n",app->getRM()); + } } - egsInformation("Testapp %f\n",app->getRM()); + + // Get a list of all the libraries in the dso directory @@ -270,19 +283,21 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) inputStruct = make_shared(); // Get the application level input blocks - getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); - if(getAppInputs) { - getAppInputs(inputStruct); - if(inputStruct) { - vector> inputBlocks = inputStruct->getBlockInputs(); - for (auto &block : inputBlocks) { - egsInformation(" block %s\n", block->getTitle().c_str()); - vector> singleInputs = block->getSingleInputs(); - for (auto &inp : singleInputs) { - const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); + if(app_loaded) { + getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); + if(getAppInputs) { + getAppInputs(inputStruct); + if(inputStruct) { + vector> inputBlocks = inputStruct->getBlockInputs(); + for (auto &block : inputBlocks) { + egsInformation(" block %s\n", block->getTitle().c_str()); + vector> singleInputs = block->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } } } } @@ -309,7 +324,9 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) libName = libName.right(libName.length() - lib_prefix.length()); egsInformation("testlib trying %s\n", libName.toLatin1().data()); - if (lib.startsWith("Qt5")) { + // Skip any library files that start with Qt + // For dynamic builds, there may be QtCore, QtWidgets, etc. files in the dso directory + if (lib.startsWith("Qt")) { continue; } diff --git a/HEN_HOUSE/egs++/view/viewcontrol.ui b/HEN_HOUSE/egs++/view/viewcontrol.ui index edcba3f42..bab7f3b0f 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui +++ b/HEN_HOUSE/egs++/view/viewcontrol.ui @@ -118,7 +118,7 @@ - 4 + 0 @@ -186,123 +186,6 @@ - - - - - 0 - 0 - - - - - 0 - 120 - - - - - 16777215 - 16777215 - - - - Particle tracks - - - - - - 1 - - - 1 - - - - - - - Positrons - - - true - - - - - - - Photons - - - true - - - - - - - Electrons - - - true - - - - - - - 1 - - - 1 - - - - - - - 1 - - - 1 - - - - - - - 1 - - - 1 - - - - - - - 1 - - - 1 - - - - - - - 1 - - - 1 - - - - - - @@ -382,6 +265,155 @@ + + + + + 0 + 0 + + + + + 0 + 120 + + + + + 16777215 + 16777215 + + + + Use egs_track_scoring to output a ptracks file + + + Particle tracks + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + 3 + + + + + Electrons + + + true + + + + + + + 1 + + + 1 + + + + + + + 1 + + + 1 + + + + + + + 1 + + + 1 + + + + + + + 1 + + + 1 + + + + + + + Photons + + + true + + + + + + + Positrons + + + true + + + + + + + 1 + + + 1 + + + + + + + 1 + + + 1 + + + + + + + + + No particle tracks found + + + Qt::AlignCenter + + + + + + @@ -410,16 +442,31 @@ 6 - - - 100 - - - 50 - - - Qt::Horizontal + + + Opacity + + + + + 100 + + + 50 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 10 + + + + @@ -427,7 +474,7 @@ - QFrame::Box + QFrame::NoFrame true @@ -437,8 +484,8 @@ 0 0 - 297 - 189 + 301 + 155 @@ -450,7 +497,7 @@ - No ausgab objects found + No dose files found Qt::AlignCenter @@ -553,7 +600,7 @@ - Transparency + Opacity @@ -578,6 +625,34 @@ + + + + Global Opacity + + + + + + 255 + + + 255 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 25 + + + + + + @@ -709,6 +784,16 @@ + + + + No particle tracks found + + + Qt::AlignCenter + + + From 81a28e47f29b790af2962c11d070b4c35fecc5ef Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 20 May 2021 16:35:01 -0400 Subject: [PATCH 23/40] Fix the egs_view dso link to be a relative path --- HEN_HOUSE/egs++/view/view.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HEN_HOUSE/egs++/view/view.pro b/HEN_HOUSE/egs++/view/view.pro index adf929600..d23ef7f53 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -80,7 +80,7 @@ unix { message( "Static build ..." ) DESTDIR = ../../pieces/linux #LIBS += -L../dso/$$my_machine -Wl,-rpath,$$hhouse/egs++/dso/$$my_machine -legspp # Fixes path to library - LIBS += -L$$hhouse/egs++/dso/$$my_machine -legspp # Relies on LD_LIBRARY_PATH + LIBS += -L../dso/$$my_machine -legspp # Relies on LD_LIBRARY_PATH UNAME = $$system(getconf LONG_BIT) contains( UNAME, 64 ){ message( "-> 64 bit ($$SNAME)" ) From 99b8ef4548466bc332a99587afb37833fa87e069 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Wed, 6 Apr 2022 12:24:14 -0400 Subject: [PATCH 24/40] Add iaea_phsp_source editor inputs Add egs_editor support for iaea_phsp_source. Also remove the c++14 flag for egs_view since it should already be included for all C++ in order for egs++ to compile. --- .../egs_phsp_source/egs_phsp_source.cpp | 2 +- .../iaea_phsp_source/iaea_phsp_source.cpp | 44 +++++++++++++++++++ HEN_HOUSE/egs++/view/viewcontrol.cpp | 5 +++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp index 5a35ea340..bde1b1961 100644 --- a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp @@ -530,7 +530,7 @@ extern "C" { // Format: name, isRequired, description, vector string of allowed values srcBlockInput->addSingleInput("phase space file", true, "The name of the phase space file."); srcBlockInput->addSingleInput("particle type", true, "The type of particle", {"all", "charged", "electrons", "positrons", "photons"}); - srcBlockInput->addSingleInput("cutout", false, "A rectagular cutout defined by x1, x2, y1, y2"); + srcBlockInput->addSingleInput("cutout", false, "A rectangular cutout defined by x1, x2, y1, y2"); srcBlockInput->addSingleInput("weight window", false, "wmin, wmax, the min and max particle weights to use. If the particle is not in this range, it is rejected."); srcBlockInput->addSingleInput("recyle photons", false, "The number of time to recycle each photon"); srcBlockInput->addSingleInput("recycle electrons", false, "The number of times to recycle each electron"); diff --git a/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp b/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp index 515b9f90e..5827fd15b 100644 --- a/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp +++ b/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp @@ -40,6 +40,8 @@ #include "egs_input.h" #include "egs_functions.h" +static bool IAEA_PHSP_SOURCE_LOCAL inputSet = false; + IAEA_PhspSource::IAEA_PhspSource(const string &phsp_file, const string &Name, EGS_ObjectFactory *f) : EGS_BaseSource(Name,f) { init(); @@ -538,6 +540,47 @@ void IAEA_PhspSource::setFilter(int type, int nbit1, int nbit2, const int *bits) extern "C" { + static void setInputs() { + inputSet = true; + + setBaseSourceInputs(false, false); + + srcBlockInput->getSingleInput("library")->setValues({"IAEA_Phsp_Source"}); + + // Format: name, isRequired, description, vector string of allowed values + srcBlockInput->addSingleInput("iaea phase space file", true, "The path to and name of the phase-space file, no extension. Both the .IAEAphsp and .IAEAheader file must be in the same directory."); + srcBlockInput->addSingleInput("particle type", true, "The type of particle to use from the phase-space", {"all", "charged", "electrons", "positrons", "photons"}); + srcBlockInput->addSingleInput("cutout", false, "A rectangular cutout defined by x1, x2, y1, y2"); + srcBlockInput->addSingleInput("weight window", false, "wmin, wmax; the min and max particle weights to use. If the particle is not in this (inclusive) range, it is rejected."); + srcBlockInput->addSingleInput("recycle photons", false, "The number of time to recycle each photon"); + srcBlockInput->addSingleInput("recycle electrons", false, "The number of times to recycle each electron"); + } + + IAEA_PHSP_SOURCE_EXPORT string getExample() { + string example; + example = +{R"( + # Example of iaea_phsp_soure + #:start source: + name = my_source + library = iaea_phsp_source + iaea phase space file = myPhsp # No extension, both .IAEAphsp and .IAEAheader must be present + particle type = all + cutout = -1 1 -2 2 + recycle photons = 10 + recycle electrons = 10 + :stop source: +)"}; + return example; + } + + IAEA_PHSP_SOURCE_EXPORT shared_ptr getInputs() { + if(!inputSet) { + setInputs(); + } + return srcBlockInput; + } + IAEA_PHSP_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, EGS_ObjectFactory *f) { return @@ -545,3 +588,4 @@ extern "C" { } } + diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index cf1032be7..2c56bbdbb 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -247,6 +247,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) app_loaded = false; } egsInformation("Testapp %f\n",app->getRM()); + delete app; } } @@ -413,6 +414,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) } } } + getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { QAction *action = sourceMenu->addAction(libName); @@ -523,6 +525,9 @@ GeometryViewControl::~GeometryViewControl() { delete EGS_AusgabObject::getObject(i); } } + if(egsinpEdit) { + delete egsinpEdit; + } if(highlighter) { delete highlighter; } From 2a2e60484be51f2c6786915d34bedd1692aeb816 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 7 Apr 2022 11:15:14 -0400 Subject: [PATCH 25/40] Remove old egs_view debug messages Remove or improve debug messages. Add handling of the EDITOR_DEBUG define for egs_editor debugging. --- HEN_HOUSE/egs++/egs_input_struct.cpp | 5 +- HEN_HOUSE/egs++/view/egs_editor.cpp | 49 ++++--- HEN_HOUSE/egs++/view/view.pro | 2 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 203 ++++++++++++++------------- HEN_HOUSE/egs++/view/viewcontrol.ui | 2 +- 5 files changed, 140 insertions(+), 121 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index 48555243b..a292be542 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -64,7 +64,6 @@ vector> EGS_InputStruct::getBlockInputs() { shared_ptr EGS_InputStruct::getBlockInput(string title) { for(auto &block: blockInputs) { - egsInformation("test struct getBlockInput %s\n", block->getTitle().c_str()); if(egsEquivStr(block->getTitle(), title)) { return block; } @@ -92,7 +91,7 @@ vector EGS_InputStruct::getLibraryOptions(string blockTitle) { // E.g. find all the geometry libraries vector libOptions; for(auto& block : blockInputs) { - egsInformation("test getLibOpt %s %s\n",block->getTitle().c_str(),blockTitle.c_str() ); + // We only search the 2nd-level blocks // i.e. don't look at the geometry definition block, look at the geometries for(auto& block2 : block->getBlockInputs()) { @@ -111,7 +110,7 @@ vector EGS_InputStruct::getLibraryOptions(string blockTitle) { // This is the case for shapes if(libOptions.size() < 1) { for(auto& block : blockInputs) { - egsInformation("test getLibOpt2 %s %s\n",block->getTitle().c_str(),blockTitle.c_str() ); + if(block && block->getTitle() == blockTitle) { vector libAr = block->getSingleInput("library")->getValues(); for(auto& lib : libAr) { diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index e42a3b537..244d94c71 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -187,7 +187,7 @@ void EGS_Editor::validateLine(QTextCursor cursor) { QString blockTitle; shared_ptr inputBlockTemplate = getBlockInput(blockTitle, cursor); - + // If we aren't inside an input block, ignore this line if(blockTitle.size() < 1) { return; @@ -205,7 +205,9 @@ void EGS_Editor::validateLine(QTextCursor cursor) { QString inputTag = selectedText.left(equalsPos).simplified(); QString inputVal = selectedText.right(selectedText.size() - equalsPos - 1).simplified(); - egsInformation("test foundEquals %s\n",inputTag.toLatin1().data()); +#ifdef EDITOR_DEBUG + egsInformation("EGS_Editor::validateLine: Found equals sign: %s\n",inputTag.toLatin1().data()); +#endif // If we found a template for this type of input block, // check that the input tag (LHS) is valid @@ -330,10 +332,6 @@ void EGS_Editor::autoComplete() { // Get the input structure QString blockTitle; shared_ptr inputBlockTemplate = getBlockInput(blockTitle); - egsInformation("testA %s\n", blockTitle.toLatin1().data()); - if(inputBlockTemplate) { - egsInformation("test foundtemplate\n"); - } // If we aren't inside an input block, ignore this line if(blockTitle.size() < 1) { @@ -346,7 +344,9 @@ void EGS_Editor::autoComplete() { if(equalsPos != -1) { QString inputTag = selectedText.left(equalsPos).simplified(); QString inputVal = selectedText.right(selectedText.size() - equalsPos - 1).simplified(); - egsInformation("test foundEquals %s\n",inputTag.toLatin1().data()); +#ifdef EDITOR_DEBUG + egsInformation("EGS_Editor::autoComplete: found equals sign: %s\n",inputTag.toLatin1().data()); +#endif // Check that the line is valid validateLine(cursor); @@ -371,7 +371,7 @@ void EGS_Editor::autoComplete() { } if(itemList.size() > 0) { model->setStringList(itemList); - + popup->setModel(model); popup->setFont(this->font()); @@ -433,7 +433,7 @@ void EGS_Editor::autoComplete() { } if(itemList.size() > 0) { model->setStringList(itemList); - + popup->setModel(model); popup->setFont(this->font()); @@ -562,7 +562,6 @@ void EGS_Editor::autoComplete() { QTextCharFormat format; format.setUnderlineStyle(QTextCharFormat::NoUnderline); - egsInformation("testQQ %s %s\n",blockTit.toLatin1().data(), selectedText.toLatin1().data()); auto inputPtr = inputBlockTemplate->getBlockInput(blockTit.toStdString()); if(!inputPtr) { // Red underline the input tag @@ -659,7 +658,9 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // If we couldn't find a library tag in the current block, // try searching the containing block (if there is one) if(library.size() < 1) { - egsInformation("test searching containing block %s\n", blockTitle.toLatin1().data()); +#ifdef EDITOR_DEBUG + egsInformation("EGS_Editor::getBlockInput: Searching containing block for library: %s\n", blockTitle.toLatin1().data()); +#endif // If we're currently on a :start line, start searching on the next line // so that we're actually starting within the block @@ -688,7 +689,9 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // If we still didn't find the library, search one block higher if(library.size() < 1) { - egsInformation("test searching containing block2 %s\n", blockTitle.toLatin1().data()); +#ifdef EDITOR_DEBUG + egsInformation("EGS_Editor::getBlockInput: Checking up a level...\n"); +#endif // If we're currently on a :start line, start searching on the next line // so that we're actually starting within the block int loopGuard = 10000; @@ -716,7 +719,9 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // If we got the library tag, we can directly look up this input block structure if(library.size() > 0) { - egsInformation("test getBlockInput %s %s\n", blockTitle.toLatin1().data(), library.toLatin1().data()); +#ifdef EDITOR_DEBUG + egsInformation("EGS_Editor::getBlockInput: Found library: %s\n", library.toLatin1().data()); +#endif shared_ptr inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); if(inputBlock) { return inputBlock; @@ -726,7 +731,10 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // If we didn't get the library tag, we might be in a top-level block // like a geometry definition. Just return the block with the matching title shared_ptr inputBlock = inputStruct->getBlockInput(blockTitle.toStdString()); - egsInformation("test returning top level block\n"); + +#ifdef EDITOR_DEBUG + egsInformation("EGS_Editor::getBlockInput: No library found, assuming '%s' is top-level block\n", blockTitle.toLatin1().data()); +#endif return inputBlock; } @@ -998,16 +1006,16 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp, QText auto dependencyBlockAnti = inp->getDependencyBlockAnti(); QTextBlock depBlock = findSiblingBlock(QString::fromStdString(dependencyBlock->getTitle()), cursor.block()); - + if(depBlock.isValid()) { if(dependencyBlockAnti) { - satisfied = false; + satisfied = false; } else { satisfied = true; } } else { if(dependencyBlockAnti) { - satisfied = true; + satisfied = true; } else { satisfied = false; } @@ -1187,6 +1195,7 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { return true; } } else if(keyEvent->key() == Qt::Key_Escape) { + popup->hide(); popup->QWidget::releaseKeyboard(); } else if(keyEvent->key() == Qt::Key_Right) { if (popup->isVisible()) { @@ -1195,9 +1204,9 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { } } //} else if(event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { - } else if(event->type() == QEvent::FocusOut) { - popup->hide(); - popup->QWidget::releaseKeyboard(); +// } else if(event->type() == QEvent::FocusOut) { // This seemed to block the key_right grab on linux, so commented out +// popup->hide(); +// popup->QWidget::releaseKeyboard(); } return QPlainTextEdit::eventFilter(obj, event); diff --git a/HEN_HOUSE/egs++/view/view.pro b/HEN_HOUSE/egs++/view/view.pro index d23ef7f53..ec7338ecf 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -96,7 +96,7 @@ unix { } # Debug options -#DEFINES += VIEW_DEBUG +#DEFINES += VIEW_DEBUG EDITOR_DEBUG #QMAKE_CXXFLAGS+="-fsanitize=address -fno-omit-frame-pointer" #QMAKE_CXXFLAGS+="-ggdb3" #QMAKE_LFLAGS+="-fsanitize=address" diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 2c56bbdbb..ca16e48d1 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -211,45 +211,46 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) editorLayout->addWidget(egsinpEdit); highlighter = new EGS_Highlighter(egsinpEdit->document()); - // Load an egs++ application to parse the input file - string app_name; +// TODO: This is an example of how to load an application for egs_editor inputs +// // Load an egs++ application to parse the input file +// string app_name; int appc = 5; char *appv[] = { "egspp", "-a", "tutor7pp", "-i", "tracks1.egsinp", "-p", "tutor_data"}; - - // Appv: %s -a application [-p pegs_file] [-i input_file] [-o output_file] [-b] [-P number_of_parallel_jobs] [-j job_index] - if (!EGS_Application::getArgument(appc,appv,"-a","--application",app_name)) { - egsFatal("test fail\n\n"); - } - - string lib_dir; - EGS_Application::checkEnvironmentVar(appc,appv,"-e","--egs-home","EGS_HOME",lib_dir); - lib_dir += "bin"; - lib_dir += fs; - lib_dir += CONFIG_NAME; - lib_dir += fs; - - // Load the application library - // We don't require the application to be compiled, just give a warning if it isn't. - EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); - bool app_loaded = true; - if (!app_lib.load()) { - egsWarning("\n%s: Failed to load the %s application library from %s\n\n", appv[0],app_name.c_str(),lib_dir.c_str()); - app_loaded = false; - } else { - createAppFunction createApp = (createAppFunction) app_lib.resolve("createApplication"); - if (!createApp) { - egsWarning("\n%s: Failed to resolve the address of the 'createApplication' function in the application library %s\n\n",appv[0],app_lib.libraryFile()); - app_loaded = false; - } else { - EGS_Application *app = createApp(appc,appv); - if (!app) { - egsWarning("\n%s: Failed to construct the application %s\n\n",appv[0],app_name.c_str()); - app_loaded = false; - } - egsInformation("Testapp %f\n",app->getRM()); - delete app; - } - } +// +// // Appv: %s -a application [-p pegs_file] [-i input_file] [-o output_file] [-b] [-P number_of_parallel_jobs] [-j job_index] +// if (!EGS_Application::getArgument(appc,appv,"-a","--application",app_name)) { +// egsFatal("test fail\n\n"); +// } +// +// string lib_dir; +// EGS_Application::checkEnvironmentVar(appc,appv,"-e","--egs-home","EGS_HOME",lib_dir); +// lib_dir += "bin"; +// lib_dir += fs; +// lib_dir += CONFIG_NAME; +// lib_dir += fs; +// +// // Load the application library +// // We don't require the application to be compiled, just give a warning if it isn't. +// EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); +// bool app_loaded = true; +// if (!app_lib.load()) { +// egsWarning("\n%s: Failed to load the %s application library from %s\n\n", appv[0],app_name.c_str(),lib_dir.c_str()); +// app_loaded = false; +// } else { +// createAppFunction createApp = (createAppFunction) app_lib.resolve("createApplication"); +// if (!createApp) { +// egsWarning("\n%s: Failed to resolve the address of the 'createApplication' function in the application library %s\n\n",appv[0],app_lib.libraryFile()); +// app_loaded = false; +// } else { +// EGS_Application *app = createApp(appc,appv); +// if (!app) { +// egsWarning("\n%s: Failed to construct the application %s\n\n",appv[0],app_name.c_str()); +// app_loaded = false; +// } +// egsInformation("Testapp %f\n",app->getRM()); +// delete app; +// } +// } @@ -283,27 +284,27 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // The input template structure inputStruct = make_shared(); - // Get the application level input blocks - if(app_loaded) { - getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); - if(getAppInputs) { - getAppInputs(inputStruct); - if(inputStruct) { - vector> inputBlocks = inputStruct->getBlockInputs(); - for (auto &block : inputBlocks) { - egsInformation(" block %s\n", block->getTitle().c_str()); - vector> singleInputs = block->getSingleInputs(); - for (auto &inp : singleInputs) { - const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } - } - } - } - } - } +// // Get the application level input blocks +// if(app_loaded) { +// getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); +// if(getAppInputs) { +// getAppInputs(inputStruct); +// if(inputStruct) { +// vector> inputBlocks = inputStruct->getBlockInputs(); +// for (auto &block : inputBlocks) { +// egsInformation(" block %s\n", block->getTitle().c_str()); +// vector> singleInputs = block->getSingleInputs(); +// for (auto &inp : singleInputs) { +// const vector vals = inp->getValues(); +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } +// } +// } +// } +// } +// } // Geometry definition block auto geomDefPtr = inputStruct->addBlockInput("geometry definition"); @@ -317,6 +318,10 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) auto ausDefPtr = inputStruct->addBlockInput("ausgab object definition"); ausDefPtr->addSingleInput("simulation ausgab object", true, "The name of the ausgab object that will be used in the simulation."); +#ifdef VIEW_DEBUG + egsInformation("Loading libraries for egs_editor...\n"); +#endif + // For each library, try to load it and determine if it is geometry or source for (const auto &lib : libraries) { // Remove the extension @@ -324,7 +329,9 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Remove the prefix (EGS_Library adds it automatically) libName = libName.right(libName.length() - lib_prefix.length()); - egsInformation("testlib trying %s\n", libName.toLatin1().data()); +#ifdef VIEW_DEBUG + egsInformation("Trying %s\n", libName.toLatin1().data()); +#endif // Skip any library files that start with Qt // For dynamic builds, there may be QtCore, QtWidgets, etc. files in the dso directory if (lib.startsWith("Qt")) { @@ -339,7 +346,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Geometries createGeomFunction isGeom = (createGeomFunction) egs_lib.resolve("createGeometry"); if (isGeom) { - egsInformation(" testgeom %s\n",libName.toLatin1().data()); + //egsInformation(" Geometry %s\n",libName.toLatin1().data()); getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); if (getInputs) { @@ -351,22 +358,22 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) vector> singleInputs = geom->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } vector> inputBlocks = geom->getBlockInputs(); for (auto &block : inputBlocks) { - egsInformation(" block %s\n", block->getTitle().c_str()); + //egsInformation(" block %s\n", block->getTitle().c_str()); vector> singleInputs = block->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } } } @@ -382,7 +389,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Sources createSourceFunction isSource = (createSourceFunction) egs_lib.resolve("createSource"); if (isSource) { - egsInformation(" testsrc %s\n",libName.toLatin1().data()); + //egsInformation(" Source %s\n",libName.toLatin1().data()); getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); if (getInputs) { @@ -394,22 +401,22 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) vector> singleInputs = src->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } vector> inputBlocks = src->getBlockInputs(); for (auto &block : inputBlocks) { - egsInformation(" block %s\n", block->getTitle().c_str()); + //egsInformation(" block %s\n", block->getTitle().c_str()); vector> singleInputs = block->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } } } @@ -426,7 +433,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Shapes createShapeFunction isShape = (createShapeFunction) egs_lib.resolve("createShape"); if (isShape) { - egsInformation(" testshape %s\n",libName.toLatin1().data()); + //egsInformation(" Shape %s\n",libName.toLatin1().data()); getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); if (getInputs) { @@ -438,22 +445,22 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) vector> singleInputs = shape->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } vector> inputBlocks = shape->getBlockInputs(); for (auto &block : inputBlocks) { - egsInformation(" block %s\n", block->getTitle().c_str()); + //egsInformation(" block %s\n", block->getTitle().c_str()); vector> singleInputs = block->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } } } @@ -470,6 +477,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Ausgab Objects createAusgabObjectFunction isAusgabObject = (createAusgabObjectFunction) egs_lib.resolve("createAusgabObject"); if (isAusgabObject) { + //egsInformation(" Ausgab %s\n",libName.toLatin1().data()); getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); if (getInputs) { @@ -481,26 +489,29 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) vector> singleInputs = aus->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } vector> inputBlocks = aus->getBlockInputs(); for (auto &block : inputBlocks) { + //egsInformation(" block %s\n", block->getTitle().c_str()); vector> singleInputs = block->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } } } } getExampleFunction getExample = (getExampleFunction) egs_lib.resolve("getExample"); if (getExample) { - QAction *action = sourceMenu->addAction(libName); + QAction *action = ausgabMenu->addAction(libName); action->setData(QString::fromStdString(getExample())); connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); } diff --git a/HEN_HOUSE/egs++/view/viewcontrol.ui b/HEN_HOUSE/egs++/view/viewcontrol.ui index bab7f3b0f..cab6a6176 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui +++ b/HEN_HOUSE/egs++/view/viewcontrol.ui @@ -1760,7 +1760,7 @@ p, li { white-space: pre-wrap; } - Editor + Editor (experimental) From 70be98aa33a74f7970cb2134198b33e156386749 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Mon, 2 May 2022 08:21:49 -0400 Subject: [PATCH 26/40] Improve egs_editor support for shapes --- HEN_HOUSE/egs++/egs_input_struct.cpp | 29 ++++++--- .../egs++/shapes/egs_circle/egs_circle.cpp | 1 + .../egs_conical_shell/egs_conical_shell.cpp | 2 + .../egs++/shapes/egs_ellipse/egs_ellipse.cpp | 1 + .../shapes/egs_line_shape/egs_line_shape.cpp | 1 + .../egs_polygon_shape/egs_polygon_shape.cpp | 1 + .../shapes/egs_rectangle/egs_rectangle.cpp | 1 + .../egs_spherical_shell.cpp | 1 + .../egs_voxelized_shape.cpp | 1 + HEN_HOUSE/egs++/view/egs_editor.cpp | 39 ++++++++++-- HEN_HOUSE/egs++/view/egs_editor.h | 3 +- HEN_HOUSE/egs++/view/view.pro | 2 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 61 +++++++++++-------- 13 files changed, 100 insertions(+), 43 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index a292be542..f5615e681 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -95,7 +95,7 @@ vector EGS_InputStruct::getLibraryOptions(string blockTitle) { // We only search the 2nd-level blocks // i.e. don't look at the geometry definition block, look at the geometries for(auto& block2 : block->getBlockInputs()) { - if(block2 && block2->getTitle() == blockTitle) { + if(block2 && (block2->getTitle() == blockTitle)) { vector libAr = block2->getSingleInput("library")->getValues(); for(auto& lib : libAr) { if(lib.size() > 0) { @@ -111,7 +111,9 @@ vector EGS_InputStruct::getLibraryOptions(string blockTitle) { if(libOptions.size() < 1) { for(auto& block : blockInputs) { - if(block && block->getTitle() == blockTitle) { + if(block && (block->getTitle() == blockTitle || + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + (egsEquivStr(block->getTitle(), "shape") && (egsEquivStr(blockTitle, "target shape") || egsEquivStr(blockTitle, "source shape"))))) { vector libAr = block->getSingleInput("library")->getValues(); for(auto& lib : libAr) { if(lib.size() > 0) { @@ -167,7 +169,9 @@ vector> EGS_BlockInput::getSingleInputs() { } vector> EGS_BlockInput::getSingleInputs(string title) { - if(egsEquivStr(blockTitle, title)) { + if(egsEquivStr(blockTitle, title) || + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { return singleInputs; } else { for(auto &block: blockInputs) { @@ -186,7 +190,9 @@ vector> EGS_BlockInput::getBlockInputs() { } vector> EGS_BlockInput::getBlockInputs(string title) { - if(egsEquivStr(this->getTitle(), title)) { + if(egsEquivStr(this->getTitle(), title) || + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { return blockInputs; } else { for(auto &block: blockInputs) { @@ -220,7 +226,9 @@ shared_ptr EGS_BlockInput::getSingleInput(string inputTag) { shared_ptr EGS_BlockInput::getSingleInput(string inputTag, string title) { // First search the top-level input block - if(egsEquivStr(blockTitle, title)) { + if(egsEquivStr(blockTitle, title) || + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { for(auto &inp: singleInputs) { // TODO: this assumes unique inputTag if(inp && egsEquivStr(inp->getTag(), inputTag)) { @@ -231,9 +239,11 @@ shared_ptr EGS_BlockInput::getSingleInput(string inputTag, stri // If not found, go through input lower level blocks for(auto &block: blockInputs) { - auto inp = block->getSingleInput(inputTag, title); - if(inp) { - return inp; + if(egsEquivStr(block->getTitle(), title)) { + auto inp = block->getSingleInput(inputTag, title); + if(inp) { + return inp; + } } } @@ -247,6 +257,9 @@ shared_ptr EGS_BlockInput::getBlockInput(string title) { for(auto &block: blockInputs) { if(egsEquivStr(block->getTitle(), title)) { return block; + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + } else if(egsEquivStr(block->getTitle(), "shape") && (egsEquivStr(title, "source shape") || egsEquivStr(title, "target shape"))) { + return block; } else { // Do a recursive search auto foundBlock = block->getBlockInput(title); diff --git a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp index 2ab934e4a..7c401d207 100644 --- a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp @@ -50,6 +50,7 @@ extern "C" { shapeBlockInput->addSingleInput("radius", false, "The radius of the circle."); shapeBlockInput->addSingleInput("midpoint", false, "The x, y midpoint of the circle, which is in the x-y plane located at z=0. Use an EGS_AffineTransform block to translate or rotate the shape."); shapeBlockInput->addSingleInput("inner radius", false, "The inner radius, to define a ring. Points will only be sampled within the ring between the 'inner radius' and 'radius'."); + setShapeInputs(shapeBlockInput); } EGS_CIRCLE_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp b/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp index 764095205..a7f998f02 100644 --- a/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp @@ -205,6 +205,8 @@ extern "C" { blockPtr->addSingleInput("thickness", true, "The thickness of the layer"); blockPtr->addSingleInput("top radii", false, "1 (outer radius, inner radius assumed to be 0) or 2 (outer and inner radius) inputs, only required for top layer"); blockPtr->addSingleInput("bottom radii", true, "1 (outer radius, inner radius assumed to be 0) or 2 (outer and inner radius) inputs"); + + setShapeInputs(shapeBlockInput); } EGS_CONICAL_SHELL_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp index b2bf00ede..70a80de9d 100644 --- a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp @@ -49,6 +49,7 @@ extern "C" { shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Ellipse"}); shapeBlockInput->addSingleInput("halfaxis", true, "The two half axis of the ellipse."); shapeBlockInput->addSingleInput("midpoint", false, "The midpoint of the ellipse, (x, y)."); + setShapeInputs(shapeBlockInput); } EGS_ELLIPSE_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp index 0f84a3985..39556aaaf 100644 --- a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp @@ -71,6 +71,7 @@ extern "C" { shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Line_Shape"}); shapeBlockInput->addSingleInput("points", true, "A list of 2D positions, at least 2 required"); + setShapeInputs(shapeBlockInput); } EGS_LINE_SHAPE_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp index 8a9182ddd..a3e297693 100644 --- a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp @@ -149,6 +149,7 @@ extern "C" { inputSet = true; shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Polygon_Shape"}); shapeBlockInput->addSingleInput("points", true, "A list of at least 3 2D points (at least 6 floating numbers)"); + setShapeInputs(shapeBlockInput); } EGS_POLYGON_SHAPE_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp index 29235a61f..86894ec86 100644 --- a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp @@ -105,6 +105,7 @@ extern "C" { shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Rectangle"}); shapeBlockInput->addSingleInput("rectangle", true, "x1 y1 x2 y2"); shapeBlockInput->addSingleInput("inner rectangle", false, "xp1 yp1 xp2 yp2"); + setShapeInputs(shapeBlockInput); } EGS_RECTANGLE_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp b/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp index 61c39e5b6..041ed82e8 100644 --- a/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp @@ -141,6 +141,7 @@ extern "C" { shapeBlockInput->addSingleInput("outer radius", true, "The outer radius"); shapeBlockInput->addSingleInput("hemisphere", false, "Hemisphere"); shapeBlockInput->addSingleInput("hemisphere", false, "The half angle, in degrees"); + setShapeInputs(shapeBlockInput); } EGS_SPHERICAL_SHELL_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp index 856c3efc5..950405e77 100644 --- a/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp @@ -378,6 +378,7 @@ extern "C" { shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"EGS_Voxelized_Shape"}); shapeBlockInput->addSingleInput("file name", true, "The name of a file that is in binary"); + setShapeInputs(shapeBlockInput); } EGS_VOXELIZED_SHAPE_EXPORT string getExample() { diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 244d94c71..0836fc77a 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -85,6 +85,7 @@ EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { // this, SLOT(_q_completionSelected(QItemSelection))); //connect(this, SIGNAL(keyboardGrabber()), this, SIGNAL(QAbstractItemView::MoveDown)); + popupGrabbing = false; } EGS_Editor::~EGS_Editor() { @@ -719,11 +720,30 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // If we got the library tag, we can directly look up this input block structure if(library.size() > 0) { + shared_ptr inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); + if(inputBlock) { #ifdef EDITOR_DEBUG egsInformation("EGS_Editor::getBlockInput: Found library: %s\n", library.toLatin1().data()); + vector> singleInputs = inputBlock->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + vector> inputBlocks = inputBlock->getBlockInputs(); + for (auto &block : inputBlocks) { + singleInputs = inputBlock->getSingleInputs(); + for (auto &inp : singleInputs) { + const vector vals = inp->getValues(); + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } + } + } #endif - shared_ptr inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); - if(inputBlock) { return inputBlock; } } @@ -1199,14 +1219,21 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { popup->QWidget::releaseKeyboard(); } else if(keyEvent->key() == Qt::Key_Right) { if (popup->isVisible()) { + popupGrabbing = true; popup->QWidget::grabKeyboard(); return true; } } - //} else if(event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { -// } else if(event->type() == QEvent::FocusOut) { // This seemed to block the key_right grab on linux, so commented out -// popup->hide(); -// popup->QWidget::releaseKeyboard(); +// } else if(event->type() == QEvent::FocusOut || event->type() == QEvent::Move || event->type() == QEvent::Resize || event->type() == QEvent::Scroll || event->type() == QEvent::WindowDeactivate) { + + //} else if(event->type() == QEvent::Wheel || event->type() == QEvent::WindowDeactivate) { + } else if(event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { + if(!popupGrabbing) { + popup->hide(); + popup->QWidget::releaseKeyboard(); + } + } else if(obj == popup && event->type() == QEvent::FocusIn) { + popupGrabbing = false; } return QPlainTextEdit::eventFilter(obj, event); diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h index e7bd2ad85..960a222ac 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.h +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -23,7 +23,7 @@ # # Author: Reid Townson, 2020 # -# Contributors: +# Contributors: # ############################################################################### */ @@ -84,6 +84,7 @@ private slots: shared_ptr inputStruct; QListView *popup; QStringListModel *model; + bool popupGrabbing; }; diff --git a/HEN_HOUSE/egs++/view/view.pro b/HEN_HOUSE/egs++/view/view.pro index ec7338ecf..813e20330 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -96,7 +96,7 @@ unix { } # Debug options -#DEFINES += VIEW_DEBUG EDITOR_DEBUG +DEFINES += VIEW_DEBUG EDITOR_DEBUG #QMAKE_CXXFLAGS+="-fsanitize=address -fno-omit-frame-pointer" #QMAKE_CXXFLAGS+="-ggdb3" #QMAKE_LFLAGS+="-fsanitize=address" diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index ca16e48d1..f7628b7bd 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -80,7 +80,7 @@ typedef EGS_BaseShape *(*createShapeFunction)(); typedef EGS_AusgabObject *(*createAusgabObjectFunction)(); typedef void (*getAppInputsFunction)(shared_ptr inpPtr); typedef shared_ptr (*getInputsFunction)(); -typedef string (*getExampleFunction)(); +typedef string(*getExampleFunction)(); #ifdef WIN32 #ifdef CYGWIN @@ -269,7 +269,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) QStringList libraries = directory.entryList(QStringList() << (lib_prefix+"*"+lib_suffix).c_str(), QDir::Files); // Create an examples drop down menu on the editor tab - QMenuBar* menuBar = new QMenuBar(); + QMenuBar *menuBar = new QMenuBar(); QMenu *exampleMenu = new QMenu("Insert example..."); menuBar->addMenu(exampleMenu); QMenu *geomMenu = exampleMenu->addMenu("Geometries"); @@ -316,9 +316,8 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Ausgab Object definition block auto ausDefPtr = inputStruct->addBlockInput("ausgab object definition"); - ausDefPtr->addSingleInput("simulation ausgab object", true, "The name of the ausgab object that will be used in the simulation."); -#ifdef VIEW_DEBUG +#ifdef EDITOR_DEBUG egsInformation("Loading libraries for egs_editor...\n"); #endif @@ -329,7 +328,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Remove the prefix (EGS_Library adds it automatically) libName = libName.right(libName.length() - lib_prefix.length()); -#ifdef VIEW_DEBUG +#ifdef EDITOR_DEBUG egsInformation("Trying %s\n", libName.toLatin1().data()); #endif // Skip any library files that start with Qt @@ -346,7 +345,9 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Geometries createGeomFunction isGeom = (createGeomFunction) egs_lib.resolve("createGeometry"); if (isGeom) { - //egsInformation(" Geometry %s\n",libName.toLatin1().data()); +#ifdef EDITOR_DEBUG + egsInformation(" Geometry %s\n",libName.toLatin1().data()); +#endif getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); if (getInputs) { @@ -382,14 +383,16 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) if (getExample) { QAction *action = geomMenu->addAction(libName); action->setData(QString::fromStdString(getExample())); - connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); + connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); } } // Sources createSourceFunction isSource = (createSourceFunction) egs_lib.resolve("createSource"); if (isSource) { - //egsInformation(" Source %s\n",libName.toLatin1().data()); +#ifdef EDITOR_DEBUG + egsInformation(" Source %s\n",libName.toLatin1().data()); +#endif getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); if (getInputs) { @@ -426,14 +429,16 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) if (getExample) { QAction *action = sourceMenu->addAction(libName); action->setData(QString::fromStdString(getExample())); - connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); + connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); } } // Shapes createShapeFunction isShape = (createShapeFunction) egs_lib.resolve("createShape"); if (isShape) { - //egsInformation(" Shape %s\n",libName.toLatin1().data()); +#ifdef EDITOR_DEBUG + egsInformation(" Shape %s\n",libName.toLatin1().data()); +#endif getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); if (getInputs) { @@ -445,22 +450,22 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) vector> singleInputs = shape->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); -// egsInformation(" single %s\n", inp->getTag().c_str()); -// for (auto&& val : vals) { -// egsInformation(" %s\n", val.c_str()); -// } + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } } vector> inputBlocks = shape->getBlockInputs(); for (auto &block : inputBlocks) { - //egsInformation(" block %s\n", block->getTitle().c_str()); + egsInformation(" block %s\n", block->getTitle().c_str()); vector> singleInputs = block->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); -// egsInformation(" single %s\n", inp->getTag().c_str()); -// for (auto&& val : vals) { -// egsInformation(" %s\n", val.c_str()); -// } + egsInformation(" single %s\n", inp->getTag().c_str()); + for (auto&& val : vals) { + egsInformation(" %s\n", val.c_str()); + } } } } @@ -470,20 +475,22 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) if (getExample) { QAction *action = shapeMenu->addAction(libName); action->setData(QString::fromStdString(getExample())); - connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); + connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); } } // Ausgab Objects createAusgabObjectFunction isAusgabObject = (createAusgabObjectFunction) egs_lib.resolve("createAusgabObject"); if (isAusgabObject) { - //egsInformation(" Ausgab %s\n",libName.toLatin1().data()); +#ifdef EDITOR_DEBUG + egsInformation(" Ausgab %s\n",libName.toLatin1().data()); +#endif getInputsFunction getInputs = (getInputsFunction) egs_lib.resolve("getInputs"); if (getInputs) { shared_ptr aus = getInputs(); - if(aus){ + if (aus) { ausDefPtr->addBlockInput(aus); vector> singleInputs = aus->getSingleInputs(); @@ -513,7 +520,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) if (getExample) { QAction *action = ausgabMenu->addAction(libName); action->setData(QString::fromStdString(getExample())); - connect(action, &QAction::triggered, this, [this]{ insertInputExample(); }); + connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); } } } @@ -536,10 +543,10 @@ GeometryViewControl::~GeometryViewControl() { delete EGS_AusgabObject::getObject(i); } } - if(egsinpEdit) { + if (egsinpEdit) { delete egsinpEdit; } - if(highlighter) { + if (highlighter) { delete highlighter; } } @@ -2129,7 +2136,7 @@ void GeometryViewControl::changeTransparency(int t) { void GeometryViewControl::changeGlobalTransparency(int t) { int test = materialCB->count(); - for (int i = 0; i <= test; i++ ) { + for (int i = 0; i <= test; i++) { int med = materialCB->count() - i; QRgb c = m_colors[med]; m_colors[med] = qRgba(qRed(c), qGreen(c), qBlue(c), t); @@ -3403,7 +3410,7 @@ void GeometryViewControl::setFontSize(int size) { } void GeometryViewControl::insertInputExample() { - QAction *pAction = qobject_cast(sender()); + QAction *pAction = qobject_cast(sender()); QTextCursor cursor(egsinpEdit->textCursor()); egsinpEdit->insertPlainText(pAction->data().toString()); From c8c35a9f4b9f244b08f1074e3c70104fbc833663 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 10 May 2022 16:17:53 -0400 Subject: [PATCH 27/40] Run astyle to fix formatting --- .../egs_dose_scoring/egs_dose_scoring.cpp | 2 +- .../egs_phsp_scoring/egs_phsp_scoring.cpp | 322 +++++++-------- .../egs_radiative_splitting.cpp | 2 +- .../egs_track_scoring/egs_track_scoring.cpp | 66 +-- HEN_HOUSE/egs++/egs_base_geometry.h | 2 +- HEN_HOUSE/egs++/egs_base_source.h | 6 +- HEN_HOUSE/egs++/egs_input_struct.cpp | 122 +++--- HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp | 6 +- .../egs_cd_geometry/egs_cd_geometry.cpp | 4 +- .../egs++/geometry/egs_cones/egs_cones.cpp | 4 +- .../egs++/shapes/egs_circle/egs_circle.cpp | 4 +- .../egs_conical_shell/egs_conical_shell.cpp | 4 +- .../egs++/shapes/egs_ellipse/egs_ellipse.cpp | 4 +- .../egs_extended_shape/egs_extended_shape.cpp | 4 +- .../egs_gaussian_shape/egs_gaussian_shape.cpp | 4 +- .../shapes/egs_line_shape/egs_line_shape.cpp | 4 +- .../egs_polygon_shape/egs_polygon_shape.cpp | 4 +- .../shapes/egs_rectangle/egs_rectangle.cpp | 4 +- .../egs_shape_collection.cpp | 6 +- .../egs_spherical_shell.cpp | 4 +- .../egs_voxelized_shape.cpp | 56 +-- .../egs_angular_spread_source.cpp | 4 +- .../egs_beam_source/egs_beam_source.cpp | 4 +- .../egs_collimated_source.cpp | 4 +- .../egs_dynamic_source/egs_dynamic_source.cpp | 4 +- .../egs_fano_source/egs_fano_source.cpp | 4 +- .../egs_isotropic_source.cpp | 4 +- .../egs_parallel_beam/egs_parallel_beam.cpp | 4 +- .../egs_phsp_source/egs_phsp_source.cpp | 4 +- .../egs_point_source/egs_point_source.cpp | 4 +- .../egs_radionuclide_source.cpp | 4 +- .../egs_source_collection.cpp | 4 +- .../egs_transformed_source.cpp | 4 +- .../iaea_phsp_source/iaea_phsp_source.cpp | 4 +- HEN_HOUSE/egs++/view/egs_editor.cpp | 385 ++++++++++-------- HEN_HOUSE/egs++/view/egs_highlighter.cpp | 6 +- 36 files changed, 558 insertions(+), 519 deletions(-) diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp index f4fe8e1d7..19419ab52 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp @@ -621,7 +621,7 @@ extern "C" { } EGS_DOSE_SCORING_EXPORT shared_ptr getInputs() { - if(!inputSet) { + if (!inputSet) { setInputs(); } return ausBlockInput; diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_phsp_scoring/egs_phsp_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_phsp_scoring/egs_phsp_scoring.cpp index fc2a7cadd..d4a572ee2 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_phsp_scoring/egs_phsp_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_phsp_scoring/egs_phsp_scoring.cpp @@ -568,8 +568,8 @@ extern "C" { EGS_PHSP_SCORING_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_phsp_scoring #:start ausgab object: library = egs_phsp_scoring @@ -605,187 +605,187 @@ extern "C" { EGS_PHSP_SCORING_EXPORT EGS_AusgabObject *createAusgabObject(EGS_Input *input, EGS_ObjectFactory *f) { const static char *func = "createAusgabObject(phsp_scoring)"; - if (!input) { - egsWarning("%s: null input?\n",func); - return 0; - } - string str; - EGS_BaseGeometry *phspgeom; - int iscoremc = 0; //default to not score multiple crossers - vector from_reg, to_reg; - int stype = 0; //default is to use scoring geom - int phspouttype; - int ptype; - int sdir=0; - int imuscore = 0; - float xyzconst[3]; - bool xyzisconst[3] = {false, false, false}; - string gname; - string outdir; - int err01 = input->getInput("phase space geometry",gname); - if (err01) { - stype = 1; - } - else { - phspgeom = EGS_BaseGeometry::getGeometry(gname); - if (!phspgeom) { - egsWarning("\nEGS_PhspScoring: %s does not name an existing geometry.\n" - "Will assume you want to use exit/entry region pairs.\n",gname.c_str()); + if (!input) { + egsWarning("%s: null input?\n",func); + return 0; + } + string str; + EGS_BaseGeometry *phspgeom; + int iscoremc = 0; //default to not score multiple crossers + vector from_reg, to_reg; + int stype = 0; //default is to use scoring geom + int phspouttype; + int ptype; + int sdir=0; + int imuscore = 0; + float xyzconst[3]; + bool xyzisconst[3] = {false, false, false}; + string gname; + string outdir; + int err01 = input->getInput("phase space geometry",gname); + if (err01) { stype = 1; } else { - if (input->getInput("score particles on", str) < 0) { - egsInformation("EGS_PhspScoring: No input for scoring direction.\n"); - egsInformation("Will score on entry and exit from phase space geometry.\n"); - sdir = 0; + phspgeom = EGS_BaseGeometry::getGeometry(gname); + if (!phspgeom) { + egsWarning("\nEGS_PhspScoring: %s does not name an existing geometry.\n" + "Will assume you want to use exit/entry region pairs.\n",gname.c_str()); + stype = 1; } else { - //get scoring direction - vector allowed_sdir; - allowed_sdir.push_back("entry and exit"); - allowed_sdir.push_back("entry"); - allowed_sdir.push_back("exit"); - sdir = input->getInput("score particles on",allowed_sdir,-1); - if (sdir < 0) { - egsFatal("\nEGS_PhspScoring: Invalid scoring direction.\n"); + if (input->getInput("score particles on", str) < 0) { + egsInformation("EGS_PhspScoring: No input for scoring direction.\n"); + egsInformation("Will score on entry and exit from phase space geometry.\n"); + sdir = 0; + } + else { + //get scoring direction + vector allowed_sdir; + allowed_sdir.push_back("entry and exit"); + allowed_sdir.push_back("entry"); + allowed_sdir.push_back("exit"); + sdir = input->getInput("score particles on",allowed_sdir,-1); + if (sdir < 0) { + egsFatal("\nEGS_PhspScoring: Invalid scoring direction.\n"); + } } } } - } - if (stype==1) { - // user wants to use exit/entry region pairs - int err05 = input->getInput("from regions",from_reg); - int err06 = input->getInput("to regions",to_reg); - if (err05 || err06) { - egsFatal("\nEGS_PhspScoring: Missing/incorrect input for scoring method\n" - "(scoring geometry or pairs of exit/entry regions)\n"); - } - else { - //run some checks on exit/entry region pairs - vector::iterator p,p1; - if (from_reg.size() > to_reg.size()) { - p = from_reg.begin(); - egsWarning("\nEGS_PhspScoring: Mismatch in no. of exit/entry regions.\n" - "Will only score for matched pairs.\n"); - p += to_reg.size(); - from_reg.erase(p,p+from_reg.size()-to_reg.size()); - } - else if (to_reg.size() > from_reg.size()) { - p = to_reg.begin(); - egsWarning("\nEGS_PhspScoring: Mismatch in no. of exit/entry regions.\n" - "Will only score for matched pairs.\n"); - p += from_reg.size(); - to_reg.erase(p,p+to_reg.size()-from_reg.size()); + if (stype==1) { + // user wants to use exit/entry region pairs + int err05 = input->getInput("from regions",from_reg); + int err06 = input->getInput("to regions",to_reg); + if (err05 || err06) { + egsFatal("\nEGS_PhspScoring: Missing/incorrect input for scoring method\n" + "(scoring geometry or pairs of exit/entry regions)\n"); } - //now go through and look for exit region = entry region - int i=0; - while (i::iterator p,p1; + if (from_reg.size() > to_reg.size()) { + p = from_reg.begin(); + egsWarning("\nEGS_PhspScoring: Mismatch in no. of exit/entry regions.\n" + "Will only score for matched pairs.\n"); + p += to_reg.size(); + from_reg.erase(p,p+from_reg.size()-to_reg.size()); } - else { - //advance counter - i++; + else if (to_reg.size() > from_reg.size()) { + p = to_reg.begin(); + egsWarning("\nEGS_PhspScoring: Mismatch in no. of exit/entry regions.\n" + "Will only score for matched pairs.\n"); + p += from_reg.size(); + to_reg.erase(p,p+to_reg.size()-from_reg.size()); + } + //now go through and look for exit region = entry region + int i=0; + while (igetInput("output format", str) < 0) { - egsInformation("EGS_PhspScoring: No input for output format type. Will default to EGSnrc.\n"); - phspouttype = 0; - } - else { - vector allowed_oformat; - allowed_oformat.push_back("EGSnrc"); - allowed_oformat.push_back("IAEA"); - phspouttype = input->getInput("output format", allowed_oformat, -1); - if (phspouttype < 0) { - egsFatal("\nEGS_PhspScoring: Invalid output format.\n"); + //now get common inputs for both scoring methods + if (input->getInput("output format", str) < 0) { + egsInformation("EGS_PhspScoring: No input for output format type. Will default to EGSnrc.\n"); + phspouttype = 0; } - //see if the user wants to specify constant X/Y/Z for IAEA format - if (phspouttype == 1) { - int err02 = input->getInput("constant X",xyzconst[0]); - int err03 = input->getInput("constant Y",xyzconst[1]); - int err04 = input->getInput("constant Z",xyzconst[2]); - if (!err02) { - xyzisconst[0] = true; - } - if (!err03) { - xyzisconst[1] = true; - } - if (!err04) { - xyzisconst[2] = true; + else { + vector allowed_oformat; + allowed_oformat.push_back("EGSnrc"); + allowed_oformat.push_back("IAEA"); + phspouttype = input->getInput("output format", allowed_oformat, -1); + if (phspouttype < 0) { + egsFatal("\nEGS_PhspScoring: Invalid output format.\n"); } - //see if user wants to score mu (if available) - //default is not to score - if (!input->getInput("score mu", str)) { - vector allowed_muscore; - allowed_muscore.push_back("no"); - allowed_muscore.push_back("yes"); - imuscore = input->getInput("score mu",allowed_muscore,-1); - if (imuscore < 0) { - egsWarning("\nEGS_PhspScoring: Invalid input for mu scoring. Will not score mu.\n"); - imuscore = 0; + //see if the user wants to specify constant X/Y/Z for IAEA format + if (phspouttype == 1) { + int err02 = input->getInput("constant X",xyzconst[0]); + int err03 = input->getInput("constant Y",xyzconst[1]); + int err04 = input->getInput("constant Z",xyzconst[2]); + if (!err02) { + xyzisconst[0] = true; + } + if (!err03) { + xyzisconst[1] = true; + } + if (!err04) { + xyzisconst[2] = true; + } + //see if user wants to score mu (if available) + //default is not to score + if (!input->getInput("score mu", str)) { + vector allowed_muscore; + allowed_muscore.push_back("no"); + allowed_muscore.push_back("yes"); + imuscore = input->getInput("score mu",allowed_muscore,-1); + if (imuscore < 0) { + egsWarning("\nEGS_PhspScoring: Invalid input for mu scoring. Will not score mu.\n"); + imuscore = 0; + } } } } - } - if (phspouttype == 0) { - //see if user wants to score multiple crossers - if (!input->getInput("score multiple crossers", str)) { - vector allowed_scoremc; - allowed_scoremc.push_back("no"); - allowed_scoremc.push_back("yes"); - iscoremc = input->getInput("score multiple crossers",allowed_scoremc,-1); - if (iscoremc < 0) { - egsWarning("\nEGS_PhspScoring: Invalid input for score multiple crossers. Will not score.\n"); - iscoremc = 0; + if (phspouttype == 0) { + //see if user wants to score multiple crossers + if (!input->getInput("score multiple crossers", str)) { + vector allowed_scoremc; + allowed_scoremc.push_back("no"); + allowed_scoremc.push_back("yes"); + iscoremc = input->getInput("score multiple crossers",allowed_scoremc,-1); + if (iscoremc < 0) { + egsWarning("\nEGS_PhspScoring: Invalid input for score multiple crossers. Will not score.\n"); + iscoremc = 0; + } } } - } - if (input->getInput("output directory",outdir) < 0) { - outdir=""; - } - if (input->getInput("particle type", str) < 0) { - egsInformation("EGS_PhspScoring: No input for particle type. Will score all.\n"); - ptype = 0; - } - else { - //get particle type - vector allowed_ptype; - allowed_ptype.push_back("all"); - allowed_ptype.push_back("photons"); - allowed_ptype.push_back("charged"); - ptype = input->getInput("particle type",allowed_ptype,-1); - if (ptype < 0) { - egsFatal("\nEGS_PhspScoring: Invalid particle type.\n"); + if (input->getInput("output directory",outdir) < 0) { + outdir=""; + } + if (input->getInput("particle type", str) < 0) { + egsInformation("EGS_PhspScoring: No input for particle type. Will score all.\n"); + ptype = 0; + } + else { + //get particle type + vector allowed_ptype; + allowed_ptype.push_back("all"); + allowed_ptype.push_back("photons"); + allowed_ptype.push_back("charged"); + ptype = input->getInput("particle type",allowed_ptype,-1); + if (ptype < 0) { + egsFatal("\nEGS_PhspScoring: Invalid particle type.\n"); + } } - } - //================================================= + //================================================= - /* Setup phsp scoring object with input parameters */ - EGS_PhspScoring *result = new EGS_PhspScoring("",f); - result->setName(input); - if (stype==0) { - result->setGeom(phspgeom); - } - else if (stype==1) { - result->setEntryExitReg(from_reg,to_reg); + /* Setup phsp scoring object with input parameters */ + EGS_PhspScoring *result = new EGS_PhspScoring("",f); + result->setName(input); + if (stype==0) { + result->setGeom(phspgeom); + } + else if (stype==1) { + result->setEntryExitReg(from_reg,to_reg); + } + result->setOType(phspouttype); + result->setXYZconst(xyzisconst,xyzconst); + result->setOutDir(outdir); + result->setParticleType(ptype); + result->setScoreDir(sdir); + result->setMuScore(imuscore); + result->setScoreMC(iscoremc); + return result; } - result->setOType(phspouttype); - result->setXYZconst(xyzisconst,xyzconst); - result->setOutDir(outdir); - result->setParticleType(ptype); - result->setScoreDir(sdir); - result->setMuScore(imuscore); - result->setScoreMC(iscoremc); - return result; } -} diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp index a5f31554e..08e5816ba 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp @@ -125,7 +125,7 @@ extern "C" { } EGS_RADIATIVE_SPLITTING_EXPORT shared_ptr getInputs() { - if(!inputSet) { + if (!inputSet) { setInputs(); } return ausBlockInput; diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp index da331ef42..6b81efd4a 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp @@ -139,8 +139,8 @@ extern "C" { EGS_TRACK_SCORING_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_track_scoring #:start ausgab object: library = egs_track_scoring @@ -165,36 +165,36 @@ extern "C" { EGS_TRACK_SCORING_EXPORT EGS_AusgabObject *createAusgabObject(EGS_Input *input, EGS_ObjectFactory *f) { const static char *func = "createAusgabObject(track_scoring)"; - if (!input) { - egsWarning("%s: null input?\n",func); - return 0; + if (!input) { + egsWarning("%s: null input?\n",func); + return 0; + } + vector sc_options; + sc_options.push_back("no"); + sc_options.push_back("yes"); + bool scph = input->getInput("score photons",sc_options,true); + bool scel = input->getInput("score electrons",sc_options,true); + bool scpo = input->getInput("score positrons",sc_options,true); + if (!scph && !scel && !scpo) { + return 0; + } + EGS_I64 first = 0, last = 1024; + input->getInput("start scoring",first); + input->getInput("stop scoring",last); + int bufSize = 1024; + input->getInput("buffer size",bufSize); + string fnExtra; + input->getInput("file name addition",fnExtra); + EGS_TrackScoring *result = new EGS_TrackScoring("",f); + result->setScorePhotons(scph); + result->setScoreElectrons(scel); + result->setScorePositrons(scpo); + result->setFirstEvent(first); + result->setLastEvent(last); + result->setBufferSize(bufSize); + result->setFileNameExtra(fnExtra); + result->setName(input); + return result; } - vector sc_options; - sc_options.push_back("no"); - sc_options.push_back("yes"); - bool scph = input->getInput("score photons",sc_options,true); - bool scel = input->getInput("score electrons",sc_options,true); - bool scpo = input->getInput("score positrons",sc_options,true); - if (!scph && !scel && !scpo) { - return 0; - } - EGS_I64 first = 0, last = 1024; - input->getInput("start scoring",first); - input->getInput("stop scoring",last); - int bufSize = 1024; - input->getInput("buffer size",bufSize); - string fnExtra; - input->getInput("file name addition",fnExtra); - EGS_TrackScoring *result = new EGS_TrackScoring("",f); - result->setScorePhotons(scph); - result->setScoreElectrons(scel); - result->setScorePositrons(scpo); - result->setFirstEvent(first); - result->setLastEvent(last); - result->setBufferSize(bufSize); - result->setFileNameExtra(fnExtra); - result->setName(input); - return result; - } -} + } diff --git a/HEN_HOUSE/egs++/egs_base_geometry.h b/HEN_HOUSE/egs++/egs_base_geometry.h index 9a35b9e9c..5c98a296c 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -79,7 +79,7 @@ static void setBaseGeometryInputs(bool includeMediaBlock = true) { geomBlockInput->addSingleInput("library", true, "The type of geometry, loaded by shared library in egs++/dso."); geomBlockInput->addSingleInput("name", true, "The user-declared unique name of this geometry. This is the name you may refer to elsewhere in the input file"); - if(includeMediaBlock) { + if (includeMediaBlock) { shared_ptr mediaBlock = geomBlockInput->addBlockInput("media input"); mediaBlock->addSingleInput("media", true, "A list of media that are used in this geometry"); mediaBlock->addSingleInput("set medium", false, "2, 3 or 4 integers defining the medium for a region or range of regions.\nFor 2: region #, medium index from the media list for this geometry (starts at 0). For 3: start region, stop region, medium index. For 4: Same as 3, plus a step size for the region range.\nNeglect this input for a homogeneous geometry of the first medium in the media list. Repeat this input to specify each medium."); diff --git a/HEN_HOUSE/egs++/egs_base_source.h b/HEN_HOUSE/egs++/egs_base_source.h index 1f14c1886..22ef73522 100644 --- a/HEN_HOUSE/egs++/egs_base_source.h +++ b/HEN_HOUSE/egs++/egs_base_source.h @@ -61,11 +61,11 @@ static void setBaseSourceInputs(bool isSimpleSource = true, bool includeSpectrum srcBlockInput->addSingleInput("library", true, "The type of source, loaded by shared library in egs++/dso."); srcBlockInput->addSingleInput("name", true, "The user-declared unique name of this source. This is the name you may refer to elsewhere in the input file"); - if(isSimpleSource) { + if (isSimpleSource) { includeSpectrumBlock = true; srcBlockInput->addSingleInput("charge", true, "The type of particle to emit from the source, as defined by the charge. Use 0 for photons, -1 for electrons and 1 for positrons.", {"0", "1", "-1"}); } - if(includeSpectrumBlock) { + if (includeSpectrumBlock) { shared_ptr specBlock = srcBlockInput->addBlockInput("spectrum"); auto typePtr = specBlock->addSingleInput("type", true, "The type of energy distribution for the spectrum.", {"monoenergetic", "Gaussian", "Double Gaussian", "uniform", "tabulated spectrum", "radionuclide"}); @@ -94,7 +94,7 @@ static void setBaseSourceInputs(bool isSimpleSource = true, bool includeSpectrum maxEPtr->addDependency(rangePtr, "", true); rangePtr->addDependency(minEPtr, "", true); rangePtr->addDependency(maxEPtr, "", true); - + // Tabulated auto specFilePtr = specBlock->addSingleInput("spectrum file", false, "The full file path to the spectrum file. See documentation for the format of the file."); specFilePtr->addDependency(typePtr, "tabulated spectrum"); diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index f5615e681..2f15cc860 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -63,8 +63,8 @@ vector> EGS_InputStruct::getBlockInputs() { } shared_ptr EGS_InputStruct::getBlockInput(string title) { - for(auto &block: blockInputs) { - if(egsEquivStr(block->getTitle(), title)) { + for (auto &block: blockInputs) { + if (egsEquivStr(block->getTitle(), title)) { return block; } } @@ -76,9 +76,9 @@ shared_ptr EGS_InputStruct::getLibraryBlock(string blockTitle, s // Loop through each input block in the structure to find the library with // the matching name auto libraryBlock = make_shared(); - for(auto& block : blockInputs) { + for (auto &block : blockInputs) { libraryBlock = block->getLibraryBlock(blockTitle, libraryName); - if(libraryBlock) { + if (libraryBlock) { break; } } @@ -90,15 +90,15 @@ vector EGS_InputStruct::getLibraryOptions(string blockTitle) { // library options that match the input block type // E.g. find all the geometry libraries vector libOptions; - for(auto& block : blockInputs) { + for (auto &block : blockInputs) { // We only search the 2nd-level blocks // i.e. don't look at the geometry definition block, look at the geometries - for(auto& block2 : block->getBlockInputs()) { - if(block2 && (block2->getTitle() == blockTitle)) { + for (auto &block2 : block->getBlockInputs()) { + if (block2 && (block2->getTitle() == blockTitle)) { vector libAr = block2->getSingleInput("library")->getValues(); - for(auto& lib : libAr) { - if(lib.size() > 0) { + for (auto &lib : libAr) { + if (lib.size() > 0) { libOptions.push_back(lib); } } @@ -108,15 +108,15 @@ vector EGS_InputStruct::getLibraryOptions(string blockTitle) { // If nothing was found on the 2nd level blocks, search the top level ones // This is the case for shapes - if(libOptions.size() < 1) { - for(auto& block : blockInputs) { + if (libOptions.size() < 1) { + for (auto &block : blockInputs) { - if(block && (block->getTitle() == blockTitle || - // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". - (egsEquivStr(block->getTitle(), "shape") && (egsEquivStr(blockTitle, "target shape") || egsEquivStr(blockTitle, "source shape"))))) { + if (block && (block->getTitle() == blockTitle || + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + (egsEquivStr(block->getTitle(), "shape") && (egsEquivStr(blockTitle, "target shape") || egsEquivStr(blockTitle, "source shape"))))) { vector libAr = block->getSingleInput("library")->getValues(); - for(auto& lib : libAr) { - if(lib.size() > 0) { + for (auto &lib : libAr) { + if (lib.size() > 0) { libOptions.push_back(lib); } } @@ -169,14 +169,15 @@ vector> EGS_BlockInput::getSingleInputs() { } vector> EGS_BlockInput::getSingleInputs(string title) { - if(egsEquivStr(blockTitle, title) || - // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". - (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { + if (egsEquivStr(blockTitle, title) || + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { return singleInputs; - } else { - for(auto &block: blockInputs) { + } + else { + for (auto &block: blockInputs) { auto inp = block->getSingleInputs(title); - if(inp.size() > 0) { + if (inp.size() > 0) { return inp; } } @@ -190,13 +191,14 @@ vector> EGS_BlockInput::getBlockInputs() { } vector> EGS_BlockInput::getBlockInputs(string title) { - if(egsEquivStr(this->getTitle(), title) || - // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". - (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { + if (egsEquivStr(this->getTitle(), title) || + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { return blockInputs; - } else { - for(auto &block: blockInputs) { - if(egsEquivStr(block->getTitle(), title)) { + } + else { + for (auto &block: blockInputs) { + if (egsEquivStr(block->getTitle(), title)) { return block->getBlockInputs(); } } @@ -206,17 +208,17 @@ vector> EGS_BlockInput::getBlockInputs(string title) } shared_ptr EGS_BlockInput::getSingleInput(string inputTag) { - for(auto& inp : singleInputs) { + for (auto &inp : singleInputs) { // TODO: this assumes unique inputTag - if(inp && egsEquivStr(inp->getTag(), inputTag)) { + if (inp && egsEquivStr(inp->getTag(), inputTag)) { return inp; } } // If not found in the top level, search recursively - for(auto &block: blockInputs) { + for (auto &block: blockInputs) { auto inp = block->getSingleInput(inputTag); - if(inp) { + if (inp) { return inp; } } @@ -226,22 +228,22 @@ shared_ptr EGS_BlockInput::getSingleInput(string inputTag) { shared_ptr EGS_BlockInput::getSingleInput(string inputTag, string title) { // First search the top-level input block - if(egsEquivStr(blockTitle, title) || - // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". - (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { - for(auto &inp: singleInputs) { + if (egsEquivStr(blockTitle, title) || + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { + for (auto &inp: singleInputs) { // TODO: this assumes unique inputTag - if(inp && egsEquivStr(inp->getTag(), inputTag)) { + if (inp && egsEquivStr(inp->getTag(), inputTag)) { return inp; } } } // If not found, go through input lower level blocks - for(auto &block: blockInputs) { - if(egsEquivStr(block->getTitle(), title)) { + for (auto &block: blockInputs) { + if (egsEquivStr(block->getTitle(), title)) { auto inp = block->getSingleInput(inputTag, title); - if(inp) { + if (inp) { return inp; } } @@ -251,19 +253,22 @@ shared_ptr EGS_BlockInput::getSingleInput(string inputTag, stri } shared_ptr EGS_BlockInput::getBlockInput(string title) { - if(egsEquivStr(blockTitle, title)) { + if (egsEquivStr(blockTitle, title)) { return shared_from_this(); - } else { - for(auto &block: blockInputs) { - if(egsEquivStr(block->getTitle(), title)) { + } + else { + for (auto &block: blockInputs) { + if (egsEquivStr(block->getTitle(), title)) { return block; - // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". - } else if(egsEquivStr(block->getTitle(), "shape") && (egsEquivStr(title, "source shape") || egsEquivStr(title, "target shape"))) { + // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". + } + else if (egsEquivStr(block->getTitle(), "shape") && (egsEquivStr(title, "source shape") || egsEquivStr(title, "target shape"))) { return block; - } else { + } + else { // Do a recursive search auto foundBlock = block->getBlockInput(title); - if(foundBlock) { + if (foundBlock) { return foundBlock; } } @@ -283,23 +288,24 @@ shared_ptr EGS_BlockInput::getParent() { shared_ptr EGS_BlockInput::getLibraryBlock(string blockTitle, string libraryName) { // First search the singleInputs for the library name - for(auto &inp: singleInputs) { - if(!inp) { + for (auto &inp: singleInputs) { + if (!inp) { continue; } - if(egsEquivStr(inp->getTag(), "library")) { - if(inp->getValues().size() && egsEquivStr(inp->getValues().front(), libraryName)) { + if (egsEquivStr(inp->getTag(), "library")) { + if (inp->getValues().size() && egsEquivStr(inp->getValues().front(), libraryName)) { return shared_from_this(); - } else { + } + else { break; } } } // If not found, go through input blocks - for(auto &block: blockInputs) { + for (auto &block: blockInputs) { auto libraryBlock = block->getLibraryBlock(blockTitle, libraryName); - if(libraryBlock) { + if (libraryBlock) { return libraryBlock; } } @@ -307,11 +313,11 @@ shared_ptr EGS_BlockInput::getLibraryBlock(string blockTitle, st } bool EGS_BlockInput::contains(string inputTag) { - for(auto &inp: singleInputs) { - if(!inp) { + for (auto &inp: singleInputs) { + if (!inp) { continue; } - if(egsEquivStr(inp->getTag(), inputTag)) { + if (egsEquivStr(inp->getTag(), inputTag)) { return true; } } diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp index 28a98d825..ee7402134 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -66,7 +66,7 @@ InputOptions inp; // Process inputs from the egsinp file EGS_BOX_LOCAL int processInputs(EGS_Input *input) { int err = input->getInput(ebox_key1,inp.boxSize); - if(err && geomBlockInput->getSingleInput(ebox_key1)->getRequired()) { + if (err && geomBlockInput->getSingleInput(ebox_key1)->getRequired()) { egsWarning(ebox_message1,ebox_message3); return 0; } @@ -88,8 +88,8 @@ extern "C" { } EGS_BOX_EXPORT string getExample() { - string example -{R"( + string example { + R"( :start geometry: library = EGS_Box name = my_box diff --git a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp index cda3c596b..ee6ba42e2 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp @@ -129,8 +129,8 @@ extern "C" { } EGS_CDGEOMETRY_EXPORT string getExample() { - string example -{R"( + string example { + R"( :start geometry: library = EGS_CDGeometry name = my_cd diff --git a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp index 92c4fecfa..d08729c0d 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -297,8 +297,8 @@ extern "C" { EGS_CONES_EXPORT string getExample(string type) { string example; - example = -{R"( + example = { + R"( # Examples of each of the egs_cones types follow # Simply uncomment the :start line for the example that you # wish to use diff --git a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp index 7c401d207..cd9ca06f8 100644 --- a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp @@ -54,8 +54,8 @@ extern "C" { } EGS_CIRCLE_EXPORT string getExample() { - string example -{R"( + string example { + R"( :start shape: library = egs_circle radius = the circle radius diff --git a/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp b/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp index a7f998f02..32ed1bcc9 100644 --- a/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_conical_shell/egs_conical_shell.cpp @@ -211,8 +211,8 @@ extern "C" { EGS_CONICAL_SHELL_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_conical_shell #:start shape: library = egs_conical_shell diff --git a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp index 70a80de9d..ecf7ddb80 100644 --- a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp @@ -54,8 +54,8 @@ extern "C" { EGS_ELLIPSE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example fo egs_ellipse #:start shape: library = egs_ellipse diff --git a/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp index beefce956..1c799aa10 100644 --- a/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp @@ -54,8 +54,8 @@ extern "C" { EGS_EXTENDED_SHAPE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_extended_shape #:start shape: library = egs_extended_shape diff --git a/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp index a1a6aafbd..e86dee9de 100644 --- a/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp @@ -55,8 +55,8 @@ extern "C" { EGS_GAUSSIAN_SHAPE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_gaussiam_shape #:start shape: library = egs_gaussian_shape diff --git a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp index 39556aaaf..f789ee0c6 100644 --- a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp @@ -76,8 +76,8 @@ extern "C" { EGS_LINE_SHAPE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_line_shape :start shape: library = egs_line_shape diff --git a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp index a3e297693..24231190c 100644 --- a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp @@ -154,8 +154,8 @@ extern "C" { EGS_POLYGON_SHAPE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_polygon_shape #:start shape: library = egs_polygon_shape diff --git a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp index 86894ec86..cb9c21381 100644 --- a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp @@ -110,8 +110,8 @@ extern "C" { EGS_RECTANGLE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_rectangle #:start shape: library = egs_rectangle diff --git a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp index c4d9eab38..5efdf04a5 100644 --- a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp @@ -76,8 +76,8 @@ extern "C" { EGS_SHAPE_COLLECTION_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_shape_collection #:start shape: library = egs_shape_sollection @@ -148,7 +148,7 @@ extern "C" { } if (shapes.size() != probs.size()) { egsWarning("createShape(shape collection): the number of shapes (%d)" - " is not the same as the number of input probabilities (%d)\n"); + " is not the same as the number of input probabilities (%d)\n"); ok = false; } for (unsigned int i=0; igetInput("file name",fname); - int file_format; - int err2 = input->getInput("file format",file_format); - if (err) { - egsWarning("%s: missing 'file name' input\n",func); - return 0; - } - if (err2) { - egsInformation("%s: 'file format' input missing. Using default 'binary'" - "file format \n",func); - file_format = 0; - } - EGS_VoxelizedShape *shape = new EGS_VoxelizedShape(file_format, fname.c_str()); - if (!shape->isValid()) { - delete shape; - return 0; + if (!input) { + egsWarning("%s: null input?\n",func); + return 0; + } + string fname; + int err = input->getInput("file name",fname); + int file_format; + int err2 = input->getInput("file format",file_format); + if (err) { + egsWarning("%s: missing 'file name' input\n",func); + return 0; + } + if (err2) { + egsInformation("%s: 'file format' input missing. Using default 'binary'" + "file format \n",func); + file_format = 0; + } + EGS_VoxelizedShape *shape = new EGS_VoxelizedShape(file_format, fname.c_str()); + if (!shape->isValid()) { + delete shape; + return 0; + } + shape->setName(input); + shape->setTransformation(input); + return shape; } - shape->setName(input); - shape->setTransformation(input); - return shape; - } -} + } diff --git a/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp b/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp index 9faec6e85..d57481fcb 100644 --- a/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp @@ -97,8 +97,8 @@ extern "C" { EGS_ANGULAR_SPREAD_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_angular_spread_source #:start source: library = egs_angular_spread_source diff --git a/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp b/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp index 9018780eb..265091b44 100644 --- a/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp @@ -359,8 +359,8 @@ extern "C" { EGS_BEAM_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_beam_source #:start source: library = egs_beam_source diff --git a/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp b/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp index d25d24625..bbd6fdb40 100644 --- a/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp @@ -143,8 +143,8 @@ extern "C" { EGS_COLLIMATED_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_collimated_source #:start source: library = egs_collimated_source diff --git a/HEN_HOUSE/egs++/sources/egs_dynamic_source/egs_dynamic_source.cpp b/HEN_HOUSE/egs++/sources/egs_dynamic_source/egs_dynamic_source.cpp index 0317b4039..15b849ebc 100644 --- a/HEN_HOUSE/egs++/sources/egs_dynamic_source/egs_dynamic_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_dynamic_source/egs_dynamic_source.cpp @@ -199,8 +199,8 @@ extern "C" { EGS_DYNAMIC_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_dynamic_source #:start source: library = egs_dynamic_source diff --git a/HEN_HOUSE/egs++/sources/egs_fano_source/egs_fano_source.cpp b/HEN_HOUSE/egs++/sources/egs_fano_source/egs_fano_source.cpp index 410e858f3..cf3acf03c 100644 --- a/HEN_HOUSE/egs++/sources/egs_fano_source/egs_fano_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_fano_source/egs_fano_source.cpp @@ -164,8 +164,8 @@ extern "C" { EGS_FANO_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_fano_source #:start source: library = egs_fano_source diff --git a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp index b967fdb67..372171e6f 100644 --- a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp @@ -185,8 +185,8 @@ extern "C" { } EGS_ISOTROPIC_SOURCE_EXPORT string getExample() { - string example -{R"( + string example { + R"( :start source: name = my_source library = egs_isotropic_source diff --git a/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp b/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp index 9e42209db..336c7d83a 100644 --- a/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp +++ b/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp @@ -129,8 +129,8 @@ extern "C" { EGS_PARALLEL_BEAM_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_parallel_beam #:start source: library = egs_parallel_beam diff --git a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp index bde1b1961..67ec536a4 100644 --- a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp @@ -538,8 +538,8 @@ extern "C" { EGS_PHSP_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_phsp_soure #:start source: name = my_source diff --git a/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp b/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp index 6747cbcf7..a9d2aca7f 100644 --- a/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp @@ -92,8 +92,8 @@ extern "C" { EGS_POINT_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_point_source #:start source: library = egs_point_source diff --git a/HEN_HOUSE/egs++/sources/egs_radionuclide_source/egs_radionuclide_source.cpp b/HEN_HOUSE/egs++/sources/egs_radionuclide_source/egs_radionuclide_source.cpp index 285b81a7e..22309780b 100644 --- a/HEN_HOUSE/egs++/sources/egs_radionuclide_source/egs_radionuclide_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_radionuclide_source/egs_radionuclide_source.cpp @@ -400,8 +400,8 @@ extern "C" { EGS_RADIONUCLIDE_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_radionuclide_source #:start source: name = my_source diff --git a/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp b/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp index b3d2586ed..dcf788a76 100644 --- a/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp +++ b/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp @@ -154,8 +154,8 @@ extern "C" { EGS_SOURCE_COLLECTION_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_source_collection :start source: library = egs_source_collection diff --git a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp index 34a9edabd..033435373 100644 --- a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp @@ -99,8 +99,8 @@ extern "C" { EGS_TRANSFORMED_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of egs_transformed_source #:start source: library = egs_transformed_source diff --git a/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp b/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp index 5827fd15b..cc6cc82b5 100644 --- a/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp +++ b/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp @@ -558,8 +558,8 @@ extern "C" { IAEA_PHSP_SOURCE_EXPORT string getExample() { string example; - example = -{R"( + example = { + R"( # Example of iaea_phsp_soure #:start source: name = my_source diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 0836fc77a..79994405b 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -89,13 +89,13 @@ EGS_Editor::EGS_Editor(QWidget *parent) : QPlainTextEdit(parent) { } EGS_Editor::~EGS_Editor() { - if(lineNumberArea) { + if (lineNumberArea) { delete lineNumberArea; } - if(popup) { + if (popup) { delete popup; } - if(model) { + if (model) { delete model; } } @@ -169,7 +169,7 @@ void EGS_Editor::highlightCurrentLine() { int EGS_Editor::countStartingWhitespace(const QString &s) { int i, l = s.size(); - for(i = 0; i < l && s[i] == ' ' || s[i] == '\t'; ++i); + for (i = 0; i < l && s[i] == ' ' || s[i] == '\t'; ++i); return i; } @@ -190,18 +190,18 @@ void EGS_Editor::validateLine(QTextCursor cursor) { shared_ptr inputBlockTemplate = getBlockInput(blockTitle, cursor); // If we aren't inside an input block, ignore this line - if(blockTitle.size() < 1) { + if (blockTitle.size() < 1) { return; } - if(selectedText.startsWith("#")) { + if (selectedText.startsWith("#")) { return; } // Check the validity of the inputs // If this line contains an "=" then it should match a single input int equalsPos = selectedText.indexOf("="); - if(equalsPos != -1) { + if (equalsPos != -1) { cursor.beginEditBlock(); QString inputTag = selectedText.left(equalsPos).simplified(); @@ -212,7 +212,7 @@ void EGS_Editor::validateLine(QTextCursor cursor) { // If we found a template for this type of input block, // check that the input tag (LHS) is valid - if(inputBlockTemplate) { + if (inputBlockTemplate) { QList extraSelections = this->extraSelections(); QTextEdit::ExtraSelection selection; @@ -232,7 +232,7 @@ void EGS_Editor::validateLine(QTextCursor cursor) { // Check that the input block template contains this type of input // If the input isn't defined, it will return nullptr shared_ptr inputPtr = inputBlockTemplate->getSingleInput(inputTag.toStdString(), blockTitle.toStdString()); - if(!inputPtr) { + if (!inputPtr) { // Red underline the input tag // Select the input tag @@ -242,7 +242,7 @@ void EGS_Editor::validateLine(QTextCursor cursor) { // we account for it so only the input tag is underlined int originalEqualsPos = cursor.block().text().indexOf("="); int numWhitespace = countStartingWhitespace(cursor.block().text()); - if(numWhitespace > 0) { + if (numWhitespace > 0) { selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, numWhitespace); } @@ -251,37 +251,39 @@ void EGS_Editor::validateLine(QTextCursor cursor) { // Set the format to have a red underline format.setUnderlineColor(QColor("red")); format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); - } else { + } + else { // Get the description for this input string desc = inputPtr->getDescription(); bool isRequired = inputPtr->getRequired(); - if(isRequired) { + if (isRequired) { desc += "\nRequired."; } // Check if this input has any dependencies // and then confirm that the dependencies are satisfied - if(inputHasDependency(inputPtr)) { + if (inputHasDependency(inputPtr)) { // Add the list of dependencies to the description tooltip desc += "\nDependencies: "; auto vals = inputPtr->getDependencyVal(); int i = 0; - for(auto &inp: inputPtr->getDependencyInp()) { - if(vals[i].size() > 0) { + for (auto &inp: inputPtr->getDependencyInp()) { + if (vals[i].size() > 0) { desc += "'" + inp->getTag() + "=" + vals[i] + "' "; - } else { + } + else { desc += "'" + inp->getTag() + "' "; } ++i; } auto depBlock = inputPtr->getDependencyBlock(); - if(depBlock) { + if (depBlock) { desc += "':start " + depBlock->getTitle() + ":'"; } - if(inputDependencySatisfied(inputPtr, cursor) == false) { + if (inputDependencySatisfied(inputPtr, cursor) == false) { // Red underline the input tag // Select the input tag selection.cursor.movePosition(QTextCursor::StartOfBlock); @@ -290,7 +292,7 @@ void EGS_Editor::validateLine(QTextCursor cursor) { // we account for it so only the input tag is underlined int originalEqualsPos = cursor.block().text().indexOf("="); int numWhitespace = countStartingWhitespace(cursor.block().text()); - if(numWhitespace > 0) { + if (numWhitespace > 0) { selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, numWhitespace); } @@ -326,7 +328,7 @@ void EGS_Editor::autoComplete() { popup->setModel(model); // If the first character is a "#", ignore this line - if(selectedText.startsWith("#")) { + if (selectedText.startsWith("#")) { return; } @@ -335,14 +337,14 @@ void EGS_Editor::autoComplete() { shared_ptr inputBlockTemplate = getBlockInput(blockTitle); // If we aren't inside an input block, ignore this line - if(blockTitle.size() < 1) { + if (blockTitle.size() < 1) { return; } // Check the validity of the inputs // If this line contains an "=" then it should match a single input int equalsPos = selectedText.indexOf("="); - if(equalsPos != -1) { + if (equalsPos != -1) { QString inputTag = selectedText.left(equalsPos).simplified(); QString inputVal = selectedText.right(selectedText.size() - equalsPos - 1).simplified(); #ifdef EDITOR_DEBUG @@ -354,7 +356,7 @@ void EGS_Editor::autoComplete() { // Return if the input value (RHS) is already filled // This way we only offer options for blank inputs - if(inputVal != "") { + if (inputVal != "") { return; } @@ -367,10 +369,10 @@ void EGS_Editor::autoComplete() { // Populate the popup list QStringList itemList; - for(auto &v: vals) { + for (auto &v: vals) { itemList << QString(v.c_str()); } - if(itemList.size() > 0) { + if (itemList.size() > 0) { model->setStringList(itemList); @@ -404,10 +406,11 @@ void EGS_Editor::autoComplete() { popup->show(); } } - } else { + } + else { // Return if we couldn't find a template for this input block - if(!inputBlockTemplate) { + if (!inputBlockTemplate) { return; } @@ -415,7 +418,7 @@ void EGS_Editor::autoComplete() { shared_ptr inp = inputBlockTemplate->getSingleInput(inputTag.toStdString(), blockTitle.toStdString()); // Return if we didn't find this input in the template - if(!inp) { + if (!inp) { return; } @@ -423,16 +426,16 @@ void EGS_Editor::autoComplete() { auto vals = inp->getValues(); // Return if we don't have a list of values to choose from - if(vals.size() == 0) { + if (vals.size() == 0) { return; } // Populate the popup list QStringList itemList; - for(auto &v: vals) { + for (auto &v: vals) { itemList << QString(v.c_str()); } - if(itemList.size() > 0) { + if (itemList.size() > 0) { model->setStringList(itemList); @@ -468,8 +471,9 @@ void EGS_Editor::autoComplete() { } } - // If this is just an empty line, we can offer suggestions of valid inputs - } else if(inputBlockTemplate && selectedText == "") { + // If this is just an empty line, we can offer suggestions of valid inputs + } + else if (inputBlockTemplate && selectedText == "") { vector> singleInputs = inputBlockTemplate->getSingleInputs(blockTitle.toStdString()); @@ -481,26 +485,26 @@ void EGS_Editor::autoComplete() { QStringList itemList; // Add all the single inputs for the top level block - for(auto &inp: singleInputs) { + for (auto &inp: singleInputs) { //if(!egsEquivStr(inp->getTag(), "library")) { - // Skip any inputs that have a dependency which is not satisfied - if(inputHasDependency(inp) && inputDependencySatisfied(inp, cursor) == false) { - continue; - } + // Skip any inputs that have a dependency which is not satisfied + if (inputHasDependency(inp) && inputDependencySatisfied(inp, cursor) == false) { + continue; + } - itemList << QString((inp->getTag() + " = ").c_str()); + itemList << QString((inp->getTag() + " = ").c_str()); //} } // Store the block titles in a set to remove duplicates QSet blockTitles; - for(auto &block: blockInputs) { + for (auto &block: blockInputs) { blockTitles << QString((":start " + block->getTitle() + ":").c_str()); } - for(auto &title: blockTitles) { + for (auto &title: blockTitles) { itemList << title; } - if(itemList.size() > 0) { + if (itemList.size() > 0) { model->setStringList(itemList); popup->setModel(model); @@ -534,19 +538,20 @@ void EGS_Editor::autoComplete() { } } - // If this is the start of an input block, check that it belongs here - } else if(selectedText.contains(":start ")) { + // If this is the start of an input block, check that it belongs here + } + else if (selectedText.contains(":start ")) { // If we're inside another input block that we have a template for, // Check to this that this is a valid input block to exist here - if(inputBlockTemplate) { + if (inputBlockTemplate) { // Get the block title QString blockTit; int pos = selectedText.lastIndexOf(":start "); pos += 7; int endPos = selectedText.indexOf(":",pos); - if(endPos > 0) { + if (endPos > 0) { blockTit = selectedText.mid(pos, endPos-pos); } @@ -564,7 +569,7 @@ void EGS_Editor::autoComplete() { format.setUnderlineStyle(QTextCharFormat::NoUnderline); auto inputPtr = inputBlockTemplate->getBlockInput(blockTit.toStdString()); - if(!inputPtr) { + if (!inputPtr) { // Red underline the input tag // Select the input tag selection.cursor.movePosition(QTextCursor::StartOfBlock); @@ -573,7 +578,7 @@ void EGS_Editor::autoComplete() { // we account for it so only the input tag is underlined int originalEqualsPos = cursor.block().text().lastIndexOf(":"); int numWhitespace = countStartingWhitespace(cursor.block().text()); - if(numWhitespace > 0) { + if (numWhitespace > 0) { selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, numWhitespace); } @@ -591,14 +596,15 @@ void EGS_Editor::autoComplete() { setExtraSelections(extraSelections); } - // For geometry and source blocks that don't contain a library line, - // add 'library =' as an option in the popup - } else if(selectedText.size() == 0 && (egsEquivStr(blockTitle.toStdString(), "geometry") || egsEquivStr(blockTitle.toStdString(), "source"))) { + // For geometry and source blocks that don't contain a library line, + // add 'library =' as an option in the popup + } + else if (selectedText.size() == 0 && (egsEquivStr(blockTitle.toStdString(), "geometry") || egsEquivStr(blockTitle.toStdString(), "source"))) { // Populate the popup list QStringList itemList; itemList << "library = "; - if(itemList.size() > 0) { + if (itemList.size() > 0) { model->setStringList(itemList); popup->setModel(model); @@ -644,12 +650,12 @@ void EGS_Editor::insertCompletion(QModelIndex index) { } shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextCursor cursor) { - if(cursor == QTextCursor()) { + if (cursor == QTextCursor()) { cursor = textCursor(); } blockTitle = getBlockTitle(cursor); - if(blockTitle.size() < 1) { + if (blockTitle.size() < 1) { return nullptr; } @@ -658,7 +664,7 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // If we couldn't find a library tag in the current block, // try searching the containing block (if there is one) - if(library.size() < 1) { + if (library.size() < 1) { #ifdef EDITOR_DEBUG egsInformation("EGS_Editor::getBlockInput: Searching containing block for library: %s\n", blockTitle.toLatin1().data()); #endif @@ -669,18 +675,18 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC blockEnd = cursor.block(); int loopGuard = 10000; int i = 0; - while(blockEnd.text().contains(":start ")) { + while (blockEnd.text().contains(":start ")) { blockEnd = getBlockEnd(blockEnd.next()); - if(++i > loopGuard) { + if (++i > loopGuard) { egsInformation("Warning: Encountered infinite loop while processing the input file. Contact the developers to report this bug.\n"); break; } - if(blockEnd.isValid()) { + if (blockEnd.isValid()) { blockEnd = blockEnd.next(); } } blockEnd = getBlockEnd(blockEnd); - if(blockEnd.isValid()) { + if (blockEnd.isValid()) { // Go to the line after the end of the current input block blockEnd = blockEnd.next(); @@ -689,7 +695,7 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC } // If we still didn't find the library, search one block higher - if(library.size() < 1) { + if (library.size() < 1) { #ifdef EDITOR_DEBUG egsInformation("EGS_Editor::getBlockInput: Checking up a level...\n"); #endif @@ -697,18 +703,18 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC // so that we're actually starting within the block int loopGuard = 10000; int i = 0; - while(blockEnd.text().contains(":start ")) { + while (blockEnd.text().contains(":start ")) { blockEnd = getBlockEnd(blockEnd.next()); - if(++i > loopGuard) { + if (++i > loopGuard) { egsInformation("Warning: Encountered infinite loop while processing the input file. Contact the developers to report this bug.\n"); break; } - if(blockEnd.isValid()) { + if (blockEnd.isValid()) { blockEnd = blockEnd.next(); } } blockEnd = getBlockEnd(blockEnd); - if(blockEnd.isValid()) { + if (blockEnd.isValid()) { // Go to the line after the end of the current input block blockEnd = blockEnd.next(); @@ -719,30 +725,30 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC } // If we got the library tag, we can directly look up this input block structure - if(library.size() > 0) { + if (library.size() > 0) { shared_ptr inputBlock = inputStruct->getLibraryBlock(blockTitle.toStdString(), library.toStdString()); - if(inputBlock) { + if (inputBlock) { #ifdef EDITOR_DEBUG egsInformation("EGS_Editor::getBlockInput: Found library: %s\n", library.toLatin1().data()); - vector> singleInputs = inputBlock->getSingleInputs(); - for (auto &inp : singleInputs) { - const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } - } - vector> inputBlocks = inputBlock->getBlockInputs(); - for (auto &block : inputBlocks) { - singleInputs = inputBlock->getSingleInputs(); - for (auto &inp : singleInputs) { - const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } - } - } +// vector> singleInputs = inputBlock->getSingleInputs(); +// for (auto &inp : singleInputs) { +// const vector vals = inp->getValues(); +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } +// } +// vector> inputBlocks = inputBlock->getBlockInputs(); +// for (auto &block : inputBlocks) { +// singleInputs = inputBlock->getSingleInputs(); +// for (auto &inp : singleInputs) { +// const vector vals = inp->getValues(); +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } +// } +// } #endif return inputBlock; } @@ -753,14 +759,14 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC shared_ptr inputBlock = inputStruct->getBlockInput(blockTitle.toStdString()); #ifdef EDITOR_DEBUG - egsInformation("EGS_Editor::getBlockInput: No library found, assuming '%s' is top-level block\n", blockTitle.toLatin1().data()); + egsInformation("EGS_Editor::getBlockInput: No library found, assuming '%s' is top-level block\n", blockTitle.toLatin1().data()); #endif return inputBlock; } QString EGS_Editor::getBlockTitle(QTextCursor cursor) { - if(cursor == QTextCursor()) { + if (cursor == QTextCursor()) { cursor = textCursor(); } @@ -770,21 +776,22 @@ QString EGS_Editor::getBlockTitle(QTextCursor cursor) { // Starting at the current line, starting iterating in reverse through // the previous lines - for(QTextBlock block = cursor.block(); block.isValid(); block = block.previous()) { + for (QTextBlock block = cursor.block(); block.isValid(); block = block.previous()) { QString line = block.text().simplified(); // Get block title int pos = line.lastIndexOf(":start "); - if(pos >= 0) { + if (pos >= 0) { pos += 7; int endPos = line.indexOf(":",pos); - if(endPos > 0) { + if (endPos > 0) { blockTitle = line.mid(pos, endPos-pos); - if(innerList.size() > 0 && blockTitle == innerList.back()) { + if (innerList.size() > 0 && blockTitle == innerList.back()) { innerList.pop_back(); blockTitle.clear(); withinOtherBlock = false; - } else { + } + else { break; } } @@ -794,10 +801,10 @@ QString EGS_Editor::getBlockTitle(QTextCursor cursor) { // This means both a matching :start and :stop are above the cursor // so we're not inside the block pos = line.lastIndexOf(":stop "); - if(pos >= 0) { + if (pos >= 0) { pos += 6; int endPos = line.indexOf(":",pos); - if(endPos > 0) { + if (endPos > 0) { QString stopTitle = line.mid(pos, endPos-pos); innerList.push_back(stopTitle); withinOtherBlock = true; @@ -817,27 +824,27 @@ QString EGS_Editor::getInputValue(QString inp, QTextBlock currentBlock, bool &fo // Get the last textblock in this input block // so that we search all the inputs in the block QTextBlock blockEnd = getBlockEnd(currentBlock); - if(!blockEnd.isValid()) { + if (!blockEnd.isValid()) { return ""; } // Starting at the last line, start iterating in reverse through // the previous lines blockEnd = blockEnd.previous(); - for(QTextBlock block = blockEnd; block.isValid(); block = block.previous()) { + for (QTextBlock block = blockEnd; block.isValid(); block = block.previous()) { QString line = block.text().simplified(); // Get block library for input blocks based on a shared library // e.g. geometries and sources // Only look for the library tag if we're not in a sub-block int pos; - if(!withinOtherBlock) { + if (!withinOtherBlock) { pos = line.lastIndexOf(inp); - if(pos >= 0) { + if (pos >= 0) { int pos2 = line.lastIndexOf("="); - if(pos2 > pos) { + if (pos2 > pos) { QString tag = line.left(pos2).simplified(); - if(egsEquivStr(tag.toStdString(), inp.simplified().toStdString())) { + if (egsEquivStr(tag.toStdString(), inp.simplified().toStdString())) { foundTag = true; value = line.right(line.size()-pos2-1).simplified(); break; @@ -847,18 +854,19 @@ QString EGS_Editor::getInputValue(QString inp, QTextBlock currentBlock, bool &fo } // Get block title - startPos = line.lastIndexOf(":start "); - if(startPos >= 0) { - startPos += 7; - int endPos = line.indexOf(":",startPos); - if(endPos > 0) { + pos = line.lastIndexOf(":start "); + if (pos >= 0) { + pos += 7; + int endPos = line.indexOf(":",pos); + if (endPos > 0) { QString blockTitle = line.mid(pos, endPos-pos); - if(innerList.size() > 0 && blockTitle == innerList.back()) { + if (innerList.size() > 0 && blockTitle == innerList.back()) { innerList.pop_back(); - if(innerList.size() == 0) { + if (innerList.size() == 0) { withinOtherBlock = false; } - } else { + } + else { // If we got to the start of the block, // then we failed to find the input return ""; @@ -870,10 +878,10 @@ QString EGS_Editor::getInputValue(QString inp, QTextBlock currentBlock, bool &fo // This means both a matching :start and :stop are above the cursor // so we're not inside the block pos = line.lastIndexOf(":stop "); - if(pos >= 0) { + if (pos >= 0) { pos += 6; int endPos = line.indexOf(":",pos); - if(endPos > 0) { + if (endPos > 0) { QString stopTitle = line.mid(pos, endPos-pos); innerList.push_back(stopTitle); withinOtherBlock = true; @@ -890,17 +898,17 @@ QTextBlock EGS_Editor::getBlockEnd(QTextBlock currentBlock) { // Starting at the current line, starting iterating in forward through // the next lines - for(QTextBlock block = currentBlock; block.isValid(); block = block.next()) { + for (QTextBlock block = currentBlock; block.isValid(); block = block.next()) { QString line = block.text().simplified(); // Save a vector of blocks that are contained within this input block // This means both a matching :start and :stop are below the cursor // so we're not inside the block int pos = line.lastIndexOf(":start "); - if(pos >= 0) { + if (pos >= 0) { pos += 7; int endPos = line.indexOf(":",pos); - if(endPos > 0) { + if (endPos > 0) { QString startTitle = line.mid(pos, endPos-pos); innerList.push_back(startTitle); withinOtherBlock = true; @@ -910,16 +918,17 @@ QTextBlock EGS_Editor::getBlockEnd(QTextBlock currentBlock) { // Save a vector of blocks that are contained within this input block // so that we can skip them pos = line.lastIndexOf(":stop "); - if(pos >= 0) { + if (pos >= 0) { pos += 6; int startPos = line.indexOf(":",pos); - if(startPos > 0) { + if (startPos > 0) { QString blockTitle = line.mid(pos, startPos-pos); - if(innerList.size() > 0 && blockTitle == innerList.back()) { + if (innerList.size() > 0 && blockTitle == innerList.back()) { innerList.pop_back(); blockTitle.clear(); withinOtherBlock = false; - } else { + } + else { return block; } } @@ -932,15 +941,16 @@ QTextBlock EGS_Editor::getBlockEnd(QTextBlock currentBlock) { bool EGS_Editor::inputHasDependency(shared_ptr inp) { auto dependencyInp = inp->getDependencyInp(); auto dependencyBlock = inp->getDependencyBlock(); - if(dependencyInp.size() < 1 && !dependencyBlock) { + if (dependencyInp.size() < 1 && !dependencyBlock) { return false; - } else { + } + else { return true; } } bool EGS_Editor::inputDependencySatisfied(shared_ptr inp, QTextCursor cursor) { - if(cursor == QTextCursor()) { + if (cursor == QTextCursor()) { cursor = textCursor(); } bool satisfied = true; @@ -956,8 +966,8 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp, QText // Loop through the dependencies vector previousSatisfied; string previousTag; - for(size_t i = 0; i < dependencyInp.size(); ++i) { - if(!satisfied) { + for (size_t i = 0; i < dependencyInp.size(); ++i) { + if (!satisfied) { break; } @@ -967,49 +977,55 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp, QText bool foundTag; QString val = getInputValue(QString::fromStdString(depTag), cursor.block(), foundTag); - if(foundTag && !dependencyAnti[i]) { - if(dependencyVal[i].size() > 0) { - if(egsEquivStr(val.toLatin1().data(), dependencyVal[i])) { + if (foundTag && !dependencyAnti[i]) { + if (dependencyVal[i].size() > 0) { + if (egsEquivStr(val.toLatin1().data(), dependencyVal[i])) { satisfied = true; - } else { + } + else { satisfied = false; } - } else { + } + else { satisfied = true; } - } else { + } + else { // If this is an anti dependency, then we didn't want to find the tag // Note that we don't check the value, only whether or not the input tag is used - if(!foundTag && dependencyAnti[i]) { + if (!foundTag && dependencyAnti[i]) { satisfied = true; - } else { + } + else { satisfied = false; } } // Look ahead, if the following inputs have the same tag as this one (i) - for(size_t j = i+1; j < dependencyInp.size(); ++j) { - if(egsEquivStr(dependencyInp[j]->getTag(), depTag)) { + for (size_t j = i+1; j < dependencyInp.size(); ++j) { + if (egsEquivStr(dependencyInp[j]->getTag(), depTag)) { // If we already were satisfied by the first one, just skip // ahead. // This is because dependencies with the same tag are treated // with an OR operation - if(satisfied) { + if (satisfied) { // If we hit the end because all the tags matched, reset i - if(j == dependencyInp.size()-1) { + if (j == dependencyInp.size()-1) { i = j; } continue; - } else { - if(egsEquivStr(val.toLatin1().data(), dependencyVal[j])) { + } + else { + if (egsEquivStr(val.toLatin1().data(), dependencyVal[j])) { satisfied = true; // If we hit the end because all the tags matched, reset i - if(j == dependencyInp.size()-1) { + if (j == dependencyInp.size()-1) { i = j; } continue; } } - } else { + } + else { i = j-1; break; } @@ -1019,24 +1035,27 @@ bool EGS_Editor::inputDependencySatisfied(shared_ptr inp, QText // Check for any input blocks that this input depends on // We are doing an AND between the input-type dependencies and the block-type ones // So we can skip this section if the input-type dependencies failed - if(satisfied) { + if (satisfied) { auto dependencyBlock = inp->getDependencyBlock(); - if(dependencyBlock) { + if (dependencyBlock) { auto dependencyBlockAnti = inp->getDependencyBlockAnti(); QTextBlock depBlock = findSiblingBlock(QString::fromStdString(dependencyBlock->getTitle()), cursor.block()); - if(depBlock.isValid()) { - if(dependencyBlockAnti) { + if (depBlock.isValid()) { + if (dependencyBlockAnti) { satisfied = false; - } else { + } + else { satisfied = true; } - } else { - if(dependencyBlockAnti) { + } + else { + if (dependencyBlockAnti) { satisfied = true; - } else { + } + else { satisfied = false; } } @@ -1053,39 +1072,40 @@ QTextBlock EGS_Editor::findSiblingBlock(QString title, QTextBlock currentBlock) // Get the last textblock in this input block // so that we search all the inputs in the block QTextBlock blockEnd = getBlockEnd(currentBlock); - if(!blockEnd.isValid()) { + if (!blockEnd.isValid()) { return QTextBlock(); } // Starting at the last line, start iterating in reverse through // the previous lines blockEnd = blockEnd.previous(); - for(QTextBlock block = blockEnd; block.isValid(); block = block.previous()) { + for (QTextBlock block = blockEnd; block.isValid(); block = block.previous()) { QString line = block.text().simplified(); // Find a sibling block with the title we're looking for // Here we expect to be within another block because the start line counts as inside the block int pos; - if(withinOtherBlock) { + if (withinOtherBlock) { pos = line.lastIndexOf(":start " + title + ":"); - if(pos >= 0) { + if (pos >= 0) { return block; } } // Get block title pos = line.lastIndexOf(":start "); - if(pos >= 0) { + if (pos >= 0) { pos += 7; int endPos = line.indexOf(":",pos); - if(endPos > 0) { + if (endPos > 0) { QString blockTitle = line.mid(pos, endPos-pos); - if(innerList.size() > 0 && blockTitle == innerList.back()) { + if (innerList.size() > 0 && blockTitle == innerList.back()) { innerList.pop_back(); - if(innerList.size() == 0) { + if (innerList.size() == 0) { withinOtherBlock = false; } - } else { + } + else { // If we got to the start of the current block, // then we failed to find the target block return QTextBlock(); @@ -1097,10 +1117,10 @@ QTextBlock EGS_Editor::findSiblingBlock(QString title, QTextBlock currentBlock) // This means both a matching :start and :stop are above the cursor // so we're not inside the block pos = line.lastIndexOf(":stop "); - if(pos >= 0) { + if (pos >= 0) { pos += 6; int endPos = line.indexOf(":",pos); - if(endPos > 0) { + if (endPos > 0) { QString stopTitle = line.mid(pos, endPos-pos); innerList.push_back(stopTitle); withinOtherBlock = true; @@ -1149,7 +1169,8 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { //openLinkAtCursorPosition(); return true; } - } else if(event->type() == QEvent::KeyPress) { + } + else if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); // Insert 4 spaces instead of tabs @@ -1158,21 +1179,24 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { insertPlainText(" "); return true; } - } else if(keyEvent->key() == Qt::Key_Backtab) { + } + else if (keyEvent->key() == Qt::Key_Backtab) { // Delete 4 spaces from the front of the line QTextCursor cursor = textCursor(); QString line = cursor.block().text(); - if(line.startsWith(" ")) { + if (line.startsWith(" ")) { cursor.movePosition(QTextCursor::StartOfBlock); cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 4); cursor.removeSelectedText(); - } else if(line.startsWith("\t")) { + } + else if (line.startsWith("\t")) { cursor.movePosition(QTextCursor::StartOfBlock); cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1); cursor.removeSelectedText(); } return true; - } else if(keyEvent->key() == Qt::Key_Return) { + } + else if (keyEvent->key() == Qt::Key_Return) { if (!popup->isVisible()) { QTextCursor cursor = textCursor(); @@ -1180,44 +1204,49 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { // Get the current indentation amount QString indentation; - for(size_t i = 0; i < line.size(); ++i) { - if(line.at(i) == ' ') { + for (size_t i = 0; i < line.size(); ++i) { + if (line.at(i) == ' ') { indentation += ' '; - } else if(line.at(i) == '\t') { + } + else if (line.at(i) == '\t') { indentation += " "; - } else { + } + else { break; - } + } } QString stopLine; int pos = line.lastIndexOf(":start "); int posInBlock = cursor.positionInBlock(); - if(pos > -1 && posInBlock > pos) { + if (pos > -1 && posInBlock > pos) { stopLine = line.replace(pos, 7, ":stop "); } // If we inserted the ":stop" line, then also insert a line between // and leave the cursor there - if(stopLine.size() > 0) { + if (stopLine.size() > 0) { insertPlainText("\n" + indentation + " "); insertPlainText("\n" + stopLine); cursor.movePosition(QTextCursor::PreviousBlock); cursor.movePosition(QTextCursor::EndOfBlock); setTextCursor(cursor); - // Normally, we just insert a new line with matching indentation - } else { + // Normally, we just insert a new line with matching indentation + } + else { insertPlainText("\n" + indentation); } // Skip the usual return event! So we have to handle it here return true; } - } else if(keyEvent->key() == Qt::Key_Escape) { + } + else if (keyEvent->key() == Qt::Key_Escape) { popup->hide(); popup->QWidget::releaseKeyboard(); - } else if(keyEvent->key() == Qt::Key_Right) { + } + else if (keyEvent->key() == Qt::Key_Right) { if (popup->isVisible()) { popupGrabbing = true; popup->QWidget::grabKeyboard(); @@ -1226,13 +1255,15 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { } // } else if(event->type() == QEvent::FocusOut || event->type() == QEvent::Move || event->type() == QEvent::Resize || event->type() == QEvent::Scroll || event->type() == QEvent::WindowDeactivate) { - //} else if(event->type() == QEvent::Wheel || event->type() == QEvent::WindowDeactivate) { - } else if(event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { - if(!popupGrabbing) { + //} else if(event->type() == QEvent::Wheel || event->type() == QEvent::WindowDeactivate) { + } + else if (event->type() == QEvent::Wheel || event->type() == QEvent::FocusOut) { + if (!popupGrabbing) { popup->hide(); popup->QWidget::releaseKeyboard(); } - } else if(obj == popup && event->type() == QEvent::FocusIn) { + } + else if (obj == popup && event->type() == QEvent::FocusIn) { popupGrabbing = false; } diff --git a/HEN_HOUSE/egs++/view/egs_highlighter.cpp b/HEN_HOUSE/egs++/view/egs_highlighter.cpp index 4654e34f3..6cb12704a 100644 --- a/HEN_HOUSE/egs++/view/egs_highlighter.cpp +++ b/HEN_HOUSE/egs++/view/egs_highlighter.cpp @@ -102,8 +102,9 @@ void EGS_Highlighter::highlightBlock(const QString &text) { //For multi-line comments int startIndex = 0; - if (previousBlockState() != 1) + if (previousBlockState() != 1) { startIndex = text.indexOf(commentStartExpression); + } while (startIndex >= 0) { QRegularExpressionMatch match = commentEndExpression.match(text, startIndex); @@ -112,7 +113,8 @@ void EGS_Highlighter::highlightBlock(const QString &text) { if (endIndex == -1) { setCurrentBlockState(1); commentLength = text.length() - startIndex; - } else { + } + else { commentLength = endIndex - startIndex + match.capturedLength(); } From c78965fe047845627ac71bd0378621d0b6cd92b8 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 28 Jun 2022 16:06:45 -0400 Subject: [PATCH 28/40] Fix a few typos in the egs_editor additions --- HEN_HOUSE/egs++/egs_run_control.h | 2 +- HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp | 2 +- .../shapes/egs_shape_collection/egs_shape_collection.cpp | 2 +- .../egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp | 2 +- .../sources/egs_transformed_source/egs_transformed_source.cpp | 4 ++-- HEN_HOUSE/egs++/view/view.pro | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_run_control.h b/HEN_HOUSE/egs++/egs_run_control.h index f29a83e39..ae7a53b94 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -66,7 +66,7 @@ static void addRunControlBlock(shared_ptr blockPtr) { In EGSnrc applications derived from EGS_AdvancedApplication the program execution is controlled by a 'run control object' (RCO). The purpose of - the RCO is to tell shower loop into how many 'chunks' the simulation + the RCO is to tell the shower loop into how many 'chunks' the simulation should be split, how many particles to run per simulation chunk, into how many batches to split a simulation chunk, etc. In this way it is easy for EGSnrc C++ application developers to either use one of the RCO's diff --git a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp index cb9c21381..633f7a7f5 100644 --- a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.cpp @@ -115,7 +115,7 @@ extern "C" { # Example of egs_rectangle #:start shape: library = egs_rectangle - reactangle = -.1 -.1 .1 .1 + rectangle = -.1 -.1 .1 .1 )"}; return example; } diff --git a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp index 5efdf04a5..4696fd1d1 100644 --- a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp @@ -80,7 +80,7 @@ extern "C" { R"( # Example of egs_shape_collection #:start shape: - library = egs_shape_sollection + library = egs_shape_collection :start shape: definition of the first shape in the collection: :stop shape: diff --git a/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp b/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp index 147b32615..8ff6552d4 100644 --- a/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_spherical_shell/egs_spherical_shell.cpp @@ -152,7 +152,7 @@ extern "C" { #:start shape: library = egs_spherical_shell midpoint = 0 0 0 - innner radius = 0.5 + inner radius = 0.5 outer radius = 1 hemisphere = 1 half angle = 35 diff --git a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp index 033435373..10455e1f4 100644 --- a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp @@ -85,7 +85,7 @@ extern "C" { srcBlockInput->getSingleInput("library")->setValues({"EGS_Transformed_Source"}); - // Format: name, isRequired, description, vector striing of allowed values + // Format: name, isRequired, description, vector string of allowed values srcBlockInput->addSingleInput("source name", true, "The name of a previously defined source."); auto blockPtr = srcBlockInput->addBlockInput("transformation"); @@ -105,7 +105,7 @@ extern "C" { #:start source: library = egs_transformed_source name = my_source - source_name = my_parallel_source + source name = my_parallel_source #create source called my_parallel_source :start transformation: rotation vector = 0 -1 1 diff --git a/HEN_HOUSE/egs++/view/view.pro b/HEN_HOUSE/egs++/view/view.pro index 813e20330..ec7338ecf 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -96,7 +96,7 @@ unix { } # Debug options -DEFINES += VIEW_DEBUG EDITOR_DEBUG +#DEFINES += VIEW_DEBUG EDITOR_DEBUG #QMAKE_CXXFLAGS+="-fsanitize=address -fno-omit-frame-pointer" #QMAKE_CXXFLAGS+="-ggdb3" #QMAKE_LFLAGS+="-fsanitize=address" From 868f84ca49b7eef723600f66d829e0caabe73cbd Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Mon, 4 Jul 2022 16:00:47 -0400 Subject: [PATCH 29/40] Update egs_input_struct documentation --- HEN_HOUSE/egs++/egs_input_struct.h | 133 +++++++++++++++++++++ HEN_HOUSE/egs++/geometry/egs_box/egs_box.h | 18 --- 2 files changed, 133 insertions(+), 18 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index 4263487d8..b1720ade9 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -51,24 +51,61 @@ using namespace std; class EGS_BlockInput; +/*! \brief A class to represent an egsinp single line input. + + \ingroup egspp_main + + The EGS_SingleInput class is used to represent an egsinp input parameter. The class contains the ability to link whether or not this input is required, depending on a different single input parameter or input block. If there are only a few possible options, they can be set so that input values can be validated. A description of the input can also be provided. +*/ class EGS_EXPORT EGS_SingleInput { public: EGS_SingleInput(); + + /*! \brief Construct a single input \a inputTag. + + The input by the name \a inputTag is optional when \a isReq is false. For cases where the input is only required depending on a different input, leave \a isReq false and then use \a addDependency(). A description can be provided in \a desc. A list of valid values for the input can be provided in \a vals. + */ EGS_SingleInput(string inputTag, bool isReq, const string desc, const vector vals); ~EGS_SingleInput(); + /*! \brief Get the name of the input. */ string getTag(); + + /*! \brief Get whether or not this input is required. */ bool getRequired(); + + /*! \brief Add a dependency for this input, by the name of \a inp. + + Optionally, the current input is only required if the dependency input has a value of \a val. If \a isAntiDependency is true, then the current input is required only if \a inp is not set. + */ void addDependency(shared_ptr inp, string val = "", bool isAntiDependency = false); + + /*! \brief Add a dependency on an input block (there can only be one). */ void addDependency(shared_ptr block, bool isAntiDependency = false); + + /*! \brief Get a list of all the dependencies for this input. */ vector> getDependencyInp(); + + /*! \brief Get a list of the required dependency values. */ vector getDependencyVal(); + + /*! \brief Get a list of whether or not these are anti-dependencies. */ vector getDependencyAnti(); + + /*! \brief Get the dependency block (can be only one). */ shared_ptr getDependencyBlock(); + + /*! \brief Get whether or not the block dependency is an anti-dependency. */ bool getDependencyBlockAnti(); + + /*! \brief Get the list of possible values for this input. */ const vector getValues(); + + /*! \brief Set the list of possible values for this input. */ void setValues(const vector vals); + + /*! \brief Get the description for this input. */ string getDescription(); private: @@ -85,31 +122,79 @@ class EGS_EXPORT EGS_SingleInput { bool dependencyBlockAnti; }; +/*! \brief A class to represent an egsinp input block. + + \ingroup egspp_main + + The EGS_BlockInput class is used to represent an egsinp input block. An input block has a title, may have a parent that it is nested within, and may contain child single inputs and input blocks. +*/ class EGS_EXPORT EGS_BlockInput : public std::enable_shared_from_this { public: EGS_BlockInput(); + + /*! \brief Construct a block input \a blockTit. + + The input by the name \a blockTit is optional when \a isReq is false. If this block is always nested, specify the parent with \a par. + */ EGS_BlockInput(string blockTit, bool isReq = false, shared_ptr par = nullptr); ~EGS_BlockInput(); + /*! \brief Set the title of the block. */ void setTitle(string blockTit); + + /*! \brief Get the title of the block. */ string getTitle(); + + /*! \brief Add a single input. */ shared_ptr addSingleInput(string inputTag, bool isReq, const string desc, const vector vals = vector()); + + /*! \brief Add an input block to be nested inside this one. */ shared_ptr addBlockInput(string blockTit, bool isReq = false); + + /*! \brief Add an already defined input block to be nested inside this one. */ shared_ptr addBlockInput(shared_ptr block); + + /*! \brief Get a list of the inputs for this input block. */ vector> getSingleInputs(); + + /*! \brief Get a list of the inputs for the nested input block \a title. */ vector> getSingleInputs(string title); + + /*! \brief Get a list of the nested input blocks for this input block. */ vector> getBlockInputs(); + + /*! \brief Get a list of the nested input blocks inside \a title. */ vector> getBlockInputs(string title); + + /*! \brief Get the input named \a inputTag. */ shared_ptr getSingleInput(string inputTag); + + /*! \brief Get the input named \a inputTag from the input block \a title. */ shared_ptr getSingleInput(string inputTag, string title); + + /*! \brief Get the input block \a title. */ shared_ptr getBlockInput(string title); + + /*! \brief Set the parent to be \a par. */ void setParent(shared_ptr par); + + /*! \brief Get the parent input block. */ shared_ptr getParent(); + + /*! \brief Get the input block containing the library tag matching \a libraryName. */ shared_ptr getLibraryBlock(string blockTitle, string libraryName); + + /*! \brief Check if this input block contains the input \a inputTag. */ bool contains(string inputTag); + + /*! \brief Add a dependency of this input block on input \a inp being value \a val. */ void addDependency(shared_ptr inp, string val=""); + + /*! \brief Get the input dependency. */ shared_ptr getDependencyInp(); + + /*! \brief Get the input dependency required value. */ string getDependencyVal(); @@ -125,17 +210,65 @@ class EGS_EXPORT EGS_BlockInput string dependencyVal; }; +/*! \brief A class to represent an egsinp input structure. + + \ingroup egspp_main + + The EGS_InputStruct class is used to represent the top level of the egsinp file structure. + + Example from egs_cylinders.cpp: + + \verbatim + static void setInputs() { + inputSet = true; + + // Get the inputs common to all geometries (name, library, media) + // Builds on the global geometry input block geomBlockInput + setBaseGeometryInputs(); + + // Get the 'library' input, and set the valid values to be only 'EGS_Cylinders' + geomBlockInput->getSingleInput("library")->setValues({"EGS_Cylinders"}); + + // Add the 'type' input, required, and set the valid options for it. + // Note that we save a reference to this input 'typePtr'. + auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of cylinder.", {"EGS_XCylinders", "EGS_YCylinders", "EGS_ZCylinders", "EGS_Cylinders"}); + + // Add other inputs, 'radii' and 'midpoint' + geomBlockInput->addSingleInput("radii", true, "A list of cylinder radii, must be in increasing order"); + geomBlockInput->addSingleInput("midpoint", false, "The position of the midpoint of the cylinder (x, y, z)"); + + // Add the 'axis' input, and save a reference to it 'inpPtr' + auto inpPtr = geomBlockInput->addSingleInput("axis", true, "The unit vector defining the axis along the length of the cylinder."); + + // Set a dependency for 'inpPtr' on 'typePrt' being set to the value 'EGS_Cylinders'. This makes it so that 'axis' is only required if 'type = EGS_Cylinders'. + inpPtr->addDependency(typePtr, "EGS_Cylinders"); + } + \endverbatim +*/ class EGS_EXPORT EGS_InputStruct { public: EGS_InputStruct(); ~EGS_InputStruct(); + /*! \brief Add an input block named \a blockTit. */ shared_ptr addBlockInput(string blockTit, bool isReq = false); + + /*! \brief Add an input block that is already defined as \a block. */ shared_ptr addBlockInput(shared_ptr block); + + /*! \brief Add a list of input blocks that are already defined as \a blocks */ void addBlockInputs(vector> blocks); + + /*! \brief Get the list of input blocks. */ vector> getBlockInputs(); + + /*! \brief Get the input block named \a title. */ shared_ptr getBlockInput(string title); + + /*! \brief Get the input block \a blockTitle that contains the library \a libraryName. */ shared_ptr getLibraryBlock(string blockTitle, string libraryName); + + /*! \brief Get the possible values for the library tag for the block \a blockTitle. */ vector getLibraryOptions(string blockTitle); private: diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h index 4aaf55622..b63a33bcb 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h @@ -109,13 +109,6 @@ class EGS_BOX_EXPORT EGS_Box : public EGS_BaseGeometry { public: -// EGS_Box() : EGS_BaseGeometry("empty") { -// inputBlock.addBlockInput("geometry", true); -// inputBlock.addSingleInput("library", true, {"egs_box"}); -// inputBlock.addSingleInput("name", true); -// }; - //static EGS_BlockInput getInputs(); - EGS_Box(EGS_Float a, const EGS_AffineTransform *t = 0, const string &Name = "") : EGS_BaseGeometry(Name), ax(a), ay(a), az(a), T(0) { @@ -141,17 +134,6 @@ class EGS_BOX_EXPORT EGS_Box : public EGS_BaseGeometry { } }; - // Build the input structure that this class will adhere to - // Any new input parameters should be included here -// EGS_BlockInput getInputBlock() { -// //inputBlock = new EGS_BlockInput("geometry"); -// /*inputBlock->addBlockInput("geometry", true); -// inputBlock->addSingleInput("library", true, {"egs_box"}); -// inputBlock->addSingleInput("name", true);*/ -// -// return inputBlock; -// }; - bool isInside(const EGS_Vector &x) { EGS_Vector xp = T ? x*(*T) : x; if (2*xp.x + ax < 0 || 2*xp.x - ax > 0) { From 85a78cffe2e02e8615ea2a98425f879c928ef271 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 5 Jul 2022 09:45:24 -0400 Subject: [PATCH 30/40] Tidy up egs_view debug output --- HEN_HOUSE/egs++/view/viewcontrol.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index f7628b7bd..9233e398a 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -450,22 +450,22 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) vector> singleInputs = shape->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } vector> inputBlocks = shape->getBlockInputs(); for (auto &block : inputBlocks) { - egsInformation(" block %s\n", block->getTitle().c_str()); + //egsInformation(" block %s\n", block->getTitle().c_str()); vector> singleInputs = block->getSingleInputs(); for (auto &inp : singleInputs) { const vector vals = inp->getValues(); - egsInformation(" single %s\n", inp->getTag().c_str()); - for (auto&& val : vals) { - egsInformation(" %s\n", val.c_str()); - } +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } } } } From 9549983b8e500039178525776b3522bc8ab8b250 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 9 Nov 2023 14:08:57 -0500 Subject: [PATCH 31/40] Fix egs_view image scaling when reloading or saving --- HEN_HOUSE/egs++/view/viewcontrol.cpp | 61 ++++++++++++++-------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 9233e398a..1234f5921 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -19,7 +19,7 @@ # You should have received a copy of the GNU Affero General Public License # along with EGSnrc. If not, see . # -############################################################################### +####################################################################8########### # # Author: Iwan Kawrakow, 2005 # @@ -2797,39 +2797,38 @@ int GeometryViewControl::setGeometry( axesmax = pmax + EGS_Vector(size, size, size)*0.3; - if (!justReloading) { - distance = size*3.5; // ~2*sqrt(3); - look_at = center; - look_at_home = look_at; - setLookAtLineEdit(); - if (distance > 60000) { - egsWarning("too big: %g\n",size); - distance = 9999; - } - else { - zoomlevel = -112; - } - setProjectionLineEdit(); - //p_light = look_at+EGS_Vector(s_theta*s_phi,s_theta*s_phi,c_theta)*distance; - p_light = look_at+EGS_Vector(s_theta*s_phi,s_theta*s_phi,c_theta)*3*distance; - setLightLineEdit(); - camera = p_light; - screen_xo = look_at-EGS_Vector(s_theta*s_phi,s_theta*s_phi,c_theta)*distance; - screen_v1 = EGS_Vector(c_phi,-s_phi,0); - screen_v2 = EGS_Vector(c_theta*s_phi,c_theta*c_phi,-s_theta); + // Set or reset the viewing window + distance = size*3.5; // ~2*sqrt(3); + look_at = center; + look_at_home = look_at; + setLookAtLineEdit(); + if (distance > 60000) { + egsWarning("too big: %g\n",size); + distance = 9999; + } + else { + zoomlevel = -112; + } + setProjectionLineEdit(); + //p_light = look_at+EGS_Vector(s_theta*s_phi,s_theta*s_phi,c_theta)*distance; + p_light = look_at+EGS_Vector(s_theta*s_phi,s_theta*s_phi,c_theta)*3*distance; + setLightLineEdit(); + camera = p_light; + screen_xo = look_at-EGS_Vector(s_theta*s_phi,s_theta*s_phi,c_theta)*distance; + screen_v1 = EGS_Vector(c_phi,-s_phi,0); + screen_v2 = EGS_Vector(c_theta*s_phi,c_theta*c_phi,-s_theta); - // camera orientation vectors (same as the screen vectors) - camera_v1 = screen_v1; - camera_v2 = screen_v2; + // camera orientation vectors (same as the screen vectors) + camera_v1 = screen_v1; + camera_v2 = screen_v2; - // save camera home position - camera_home = camera; - camera_home_v1 = camera_v1; - camera_home_v2 = camera_v2; - zoomlevel_home = zoomlevel; + // save camera home position + camera_home = camera; + camera_home_v1 = camera_v1; + camera_home_v2 = camera_v2; + zoomlevel_home = zoomlevel; - setCameraLineEdit(); - } + setCameraLineEdit(); updateView(); From be3fe92a6c040f192c534f2ea60e25f3a7871ac4 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 9 Nov 2023 14:38:26 -0500 Subject: [PATCH 32/40] Add the library auto complete for ausgab objects --- HEN_HOUSE/egs++/view/egs_editor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 79994405b..e80170f80 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -596,10 +596,11 @@ void EGS_Editor::autoComplete() { setExtraSelections(extraSelections); } - // For geometry and source blocks that don't contain a library line, + // For geometry, source and ausgab object blocks that don't contain a library line, // add 'library =' as an option in the popup } - else if (selectedText.size() == 0 && (egsEquivStr(blockTitle.toStdString(), "geometry") || egsEquivStr(blockTitle.toStdString(), "source"))) { + else if (selectedText.size() == 0 && (egsEquivStr(blockTitle.toStdString(), "geometry") || egsEquivStr(blockTitle.toStdString(), "source") + || egsEquivStr(blockTitle.toStdString(), "ausgab object"))) { // Populate the popup list QStringList itemList; From d25148307548c55f124cdc5a5903765fa34275ec Mon Sep 17 00:00:00 2001 From: Xuan Zheng <91241583+Xuan-Zheng05@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:04:45 -0400 Subject: [PATCH 33/40] Add more egs_editor completion and examples Add auto-completion for apps, ausgab objects, materials and run control. Add dropdown for user to select application in egs_editor. Full support for pegsless materials not quite done. --- .../egs_dose_scoring/egs_dose_scoring.cpp | 19 +- .../egs_fluence_scoring.cpp | 32 ++- .../egs_radiative_splitting.cpp | 16 +- .../egs_track_scoring/egs_track_scoring.cpp | 2 +- HEN_HOUSE/egs++/egs_application.h | 177 +++++++++++- HEN_HOUSE/egs++/egs_input_struct.cpp | 40 ++- HEN_HOUSE/egs++/egs_input_struct.h | 17 +- HEN_HOUSE/egs++/egs_rndm.h | 22 +- HEN_HOUSE/egs++/egs_run_control.h | 17 +- HEN_HOUSE/egs++/egs_scoring.h | 6 +- .../egs++/geometry/egs_cones/egs_cones.cpp | 11 +- .../egs++/geometry/egs_conez/egs_conez.cpp | 3 +- .../geometry/egs_iplanes/egs_iplanes.cpp | 2 +- .../egs++/geometry/egs_planes/egs_planes.cpp | 6 +- .../egs_roundrect_cylinders.cpp | 4 +- HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp | 2 +- .../egs++/geometry/egs_space/egs_space.cpp | 2 +- HEN_HOUSE/egs++/view/egs_editor.cpp | 67 ++++- HEN_HOUSE/egs++/view/egs_editor.h | 3 +- HEN_HOUSE/egs++/view/viewcontrol.cpp | 253 ++++++++++++++---- HEN_HOUSE/egs++/view/viewcontrol.h | 6 +- HEN_HOUSE/user_codes/cavity/cavity.cpp | 125 ++++++++- HEN_HOUSE/user_codes/egs_cbct/egs_cbct.cpp | 73 ++++- .../user_codes/egs_chamber/egs_chamber.cpp | 154 ++++++++++- HEN_HOUSE/user_codes/egs_fac/egs_fac.cpp | 79 +++++- HEN_HOUSE/user_codes/egs_kerma/egs_kerma.cpp | 69 +++++ HEN_HOUSE/user_codes/egs_phd/egs_phd.cpp | 42 ++- HEN_HOUSE/user_codes/mevegs/mevegs.cpp | 37 ++- HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp | 45 +++- 29 files changed, 1224 insertions(+), 107 deletions(-) diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp index 19419ab52..53abfb63e 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp @@ -620,6 +620,23 @@ extern "C" { blockPtr->addSingleInput("file type", true, "The type of file", {"3ddose"}); } + EGS_DOSE_SCORING_EXPORT string getExample() { + string example; + example = { + R"( + # Example of egs_dose_scoring + :start ausgab object: + library = egs_dose_scoring + name = my_score + medium dose = yes # no (default) + region dose = no # yes (default) + volume = v1 ... vn # in cm**3 + dose regions = ir1 ... irn # individual regions + :stop ausgab object: +)"}; + return example; + } + EGS_DOSE_SCORING_EXPORT shared_ptr getInputs() { if (!inputSet) { setInputs(); @@ -768,4 +785,4 @@ extern "C" { } return result; } -} +} \ No newline at end of file diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_fluence_scoring/egs_fluence_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_fluence_scoring/egs_fluence_scoring.cpp index 03ff4aac2..b0f06834b 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_fluence_scoring/egs_fluence_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_fluence_scoring/egs_fluence_scoring.cpp @@ -41,6 +41,8 @@ #include "egs_input.h" #include "egs_functions.h" +static bool EGS_FLUENCE_SCORING_LOCAL inputSet = false; + #define REGIONS_ENTRIES 100 #define REGIONS_PER_LINE 25 @@ -1845,4 +1847,32 @@ extern "C" { } } -} + // Not finished + // static void setInputs() { + // inputSet = true; + + // setBaseAusgabObjectInputs(); + + // ausBlockInput->getSingleInput("library")->setValues({"EGS_Fluence_Scoring"}); + + // // Format: name, isRequired, description, vector string of allowed values + + // } + +// EGS_FLUENCE_SCORING_EXPORT string getExample() { +// string example; +// example = { +// R"( + +// )"}; + // return example; + // } + + // EGS_FLUENCE_SCORING_EXPORT shared_ptr getInputs() { + // if (!inputSet) { + // setInputs(); + // } + // return ausBlockInput; + // } + +} \ No newline at end of file diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp index 08e5816ba..9779a9949 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_radiative_splitting/egs_radiative_splitting.cpp @@ -124,6 +124,20 @@ extern "C" { ausBlockInput->addSingleInput("splitting", false, "N-split"); } + EGS_RADIATIVE_SPLITTING_EXPORT string getExample() { + string example; + example = { + R"( + # Example of egs_radiative_splitting + :start ausgab object: + library = egs_radiative_splitting + name = my_score + splitting = n_split + :stop ausgab object: +)"}; + return example; + } + EGS_RADIATIVE_SPLITTING_EXPORT shared_ptr getInputs() { if (!inputSet) { setInputs(); @@ -151,4 +165,4 @@ extern "C" { result->setName(input); return result; } -} +} \ No newline at end of file diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp index 6b81efd4a..9928a0013 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp @@ -142,7 +142,7 @@ extern "C" { example = { R"( # Example of egs_track_scoring - #:start ausgab object: + :start ausgab object: library = egs_track_scoring name = my_score score photons = yes diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index 37912ece5..bdf874a91 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -48,10 +48,12 @@ #include "egs_input_struct.h" #include "egs_run_control.h" #include "egs_scoring.h" +#include "egs_rndm.h" #include #include #include +#include using namespace std; class EGS_Input; @@ -63,6 +65,54 @@ class EGS_AusgabObject; class EGS_Interpolator; //template class EGS_SimpleContainer; +// Looks into \EGSnrc\HEN_HOUSE\pegs4\density_corrections\compounds for the density correction files +// returns a string vector of the file names +static vector findDensityCorrectionInputs() { + vector fileList; + #ifdef WIN32 + const char fs = '\\'; + #else + const char fs = '/'; + #endif + + string compound_dir = "C:"; + compound_dir += fs; + compound_dir += "EGSnrc"; + compound_dir += fs; + compound_dir += "HEN_HOUSE"; + compound_dir += fs; + compound_dir += "pegs4"; + compound_dir += fs; + compound_dir += "density_corrections"; + compound_dir += fs; + compound_dir += "compounds"; + + DIR *dir; + struct dirent *ent; + + if ((dir = opendir(compound_dir.c_str())) != NULL) { + while ((ent = readdir(dir)) != NULL) { + string filename = ent->d_name; + + // removes the .density at the end of the file + if (filename.find(".density") != string::npos) { + filename = filename.substr(0, filename.find(".density")); + fileList.push_back(filename); + } + } + closedir(dir); + } else { + egsInformation("Failed to open density correction files directory\n"); + } + + // egsInformation("Printing file titles \n"); + // for (const auto& file : fileList) { + // egsInformation("%s\n", file.c_str()); + // } + + return fileList; +} + static void addmcBlock(shared_ptr blockPtr) { shared_ptr mcBlock = blockPtr->addBlockInput("MC transport parameter"); mcBlock->addSingleInput("Global ECUT", false, "Global electron transport cutoff"); @@ -76,7 +126,7 @@ static void addmcBlock(shared_ptr blockPtr) { mcBlock->addSingleInput("Spin effects", false, "Default is On", {"On", "Off"}); mcBlock->addSingleInput("Brems angular sampling", false, "Default is KM", {"KM", "Simple"}); mcBlock->addSingleInput("Brems cross sections", false, "Default is BH", {"BH", "NIST"}); - mcBlock->addSingleInput("Pair angular crossing", false, "Default is Simple", {"Simple", "Off", "KM"}); + mcBlock->addSingleInput("Pair angular sampling", false, "Default is Simple", {"Simple", "Off", "KM"}); mcBlock->addSingleInput("Triplet production", false, "Default is On", {"On", "Off"}); mcBlock->addSingleInput("Electron Impact Ionization", false, "Default is Off", {"On", "Off", "casnati", "kolbenstvedt", "gryzinski"}); mcBlock->addSingleInput("Bound Compton scattering", false, "Default is norej", {"On", "Off", "Simple", "norej"}); @@ -104,6 +154,101 @@ static void addvrBlock(shared_ptr blockPtr) { rangePtr->addSingleInput("rejection range medium", false, "index of the medium to calculate electron ranges"); } +static void addMediaDefBlock(shared_ptr blockPtr) { + shared_ptr mediaBlockInput = blockPtr->addBlockInput("media definition"); + mediaBlockInput->addSingleInput("ae", false, "lowest energy for electron production (kinetic+0.511)"); + mediaBlockInput->addSingleInput("ap", false, "lowest energy for photon production (kinetic)"); + mediaBlockInput->addSingleInput("ue", false, "maximum energy for electrons (kinetic+0.511)"); + mediaBlockInput->addSingleInput("up", false, "maximum energy for photons (kinetic)"); + + shared_ptr mediumBlock = mediaBlockInput->addBlockInput("pegsless"); + mediumBlock->addSingleInput("elements", false, ""); + mediumBlock->addSingleInput("number of atoms", false, ""); + mediumBlock->addSingleInput("mass fractions", false, ""); + mediumBlock->addSingleInput("rho", false, ""); + mediumBlock->addSingleInput("sterncid", false, ""); + mediumBlock->addSingleInput("stopping powers", false, "{restricted total, unrestricted collision, unrestricted collision and radiative, unrestricted collision and restricted radiative, restricted collision and unrestricted radiative, unrestricted radiative}"); + mediumBlock->addSingleInput("bremsstrahlung correction", false, ""); + mediumBlock->addSingleInput("gas pressure", false, ""); + + vector densityCorrectionFiles = findDensityCorrectionInputs(); + mediumBlock->addSingleInput("density correction file", false, "", densityCorrectionFiles); + + mediumBlock->addSingleInput("e- stopping power output file", false, ""); +} + +static string addmcExample() { + string example = { + R"( +:start MC transport parameter: + Global ECUT = 0.521 # Global electron transport cutoff + Global PCUT = 0.001 # Global photon transport cutoff + Global SMAX = 1e10 # Global maximum step-size restriction for e- transport + ESTEPE = 0.25 # Default is 0.25 + XIMAX = 0.5 # Default is 0.5, max. value is 1. + Boundary crossing algorithm = exact # exact (default), PRESTA-I + Skin depth for BCA = 3 # Default value is 3 for exact boundary crossing + Electron-step algorithm = PRESTA-II # PRESTA-II (default),PRESTA-I + Spin effects = On # On (default),Off + Brems angular sampling = KM # Simple,KM (default) + Brems cross sections = BH # BH (default), NIST, NRC + Pair angular sampling = Simple # Off, Simple (default),KM + Triplet production = Off # On or Off (default) + Electron Impact Ionization = Off # On, Off (default), casnati, kolbenstvedt, gryzinski + Bound Compton scattering = norej # On, Off, Simple, norej (default) + Radiative Compton corrections = Off # On, Off (default) + Rayleigh scattering = Off # On ,Off (default), custom + Photoelectron angular sampling = On # On (default),Off + Atomic relaxations = On # On (default),Off + Photon cross sections = xcom # si, epdl, xcom (default) or user-supplied + Photon cross-sections output = Off # Off (default) or On + Compton cross sections = comp_xsections # user-supplied + Photonuclear attenuation = Off # Off (default) or On + Photonuclear cross sections = default # default (default) or user-supplied +:stop MC transport parameter: +)"}; + return example; +} + +static string addMediaExample() { + string example = { + // Not completed yet, need to fill in numbers for example + R"( +:start media definition: + ae = 0.1 # lowest energy for electron production (kinetic+0.511) + ap = 0.1 # lowest energy for photon production (kinetic) + ue = 0.1 # maximum energy for electrons (kinetic+0.511) + up = 0.1 # maximum energy for photons (kinetic) + :start pegsless: + elements = + number of atoms = + mass fractions = + rho = + sterncid = + stopping powers = + bremsstrahlung correction = + gas pressure = + density correction file = + e- stopping power output file = + :stop pegsless: +:stop media definition: + +# Here is an example for defining a material named water +:start media definition: + ae = 0.521 + ap = 0.01 + ue = 50.511 + up = 50 + + :start water: + density correction file = water_liquid.density + :stop water: + +:stop media definition: +)"}; + return example; +} + /*! \brief A structure holding the information of one particle \ingroup egspp_main */ @@ -1267,13 +1412,29 @@ class EGS_EXPORT EGS_Application { #define APP_LIB(app_name) \ extern "C" {\ APP_EXPORT EGS_Application* createApplication(int argc, char **argv) {\ - return new app_name(argc,argv);\ + return new app_name(argc, argv);\ + }\ + APP_EXPORT shared_ptr getAppInputs() {\ + shared_ptr appInputStruct = make_shared();\ + addmcBlock(appInputStruct);\ + addvrBlock(appInputStruct);\ + addRngDefinitionBlock(appInputStruct);\ + addRunControlBlock(appInputStruct);\ + addMediaDefBlock(appInputStruct);\ + return appInputStruct;\ + }\ + APP_EXPORT string getmcExample() {\ + return addmcExample();\ + }\ + APP_EXPORT string getRunControlExample() {\ + return addRunControlExample();\ + }\ + APP_EXPORT string getRngDefinitionExample() {\ + return addRngDefinitionExample();\ }\ - APP_EXPORT void getAppInputs(shared_ptr inpPtr) {\ - addRunControlBlock(inpPtr);\ - addmcBlock(inpPtr);\ - addvrBlock(inpPtr);\ - addScoringBlock(inpPtr);\ + APP_EXPORT string getMediaExample() {\ + return addMediaExample();\ }\ + }\ -#endif +#endif \ No newline at end of file diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index 2f15cc860..1cb8cee97 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -58,6 +58,28 @@ void EGS_InputStruct::addBlockInputs(vector> blocks) blockInputs.insert(blockInputs.end(), blocks.begin(), blocks.end()); } +void EGS_InputStruct::removeBlockInput(string title) { + auto it = blockInputs.begin(); + while (it != blockInputs.end()) { + if ((*it)->getTitle() == title) { + it = blockInputs.erase(it); + } else { + ++it; + } + } +} + +void EGS_InputStruct::removeBlockInputByApp(string appName) { + auto it = blockInputs.begin(); + while (it != blockInputs.end()) { + if ((*it)->getAppName() == appName) { + it = blockInputs.erase(it); + } else { + ++it; + } + } +} + vector> EGS_InputStruct::getBlockInputs() { return blockInputs; } @@ -134,6 +156,7 @@ EGS_BlockInput::EGS_BlockInput(string blockTit, bool isReq, shared_ptr EGS_BlockInput::addSingleInput(string inputTag, bool isReq, const string desc, const vector vals) { singleInputs.push_back(make_shared(inputTag, isReq, desc, vals)); return singleInputs.back(); @@ -153,7 +184,7 @@ shared_ptr EGS_BlockInput::addSingleInput(string inputTag, bool shared_ptr EGS_BlockInput::addBlockInput(string blockTit, bool isReq) { blockInputs.push_back(make_shared(blockTit, isReq, shared_from_this())); - + return blockInputs.back(); } @@ -397,9 +428,4 @@ void EGS_SingleInput::setValues(const vector vals) { string EGS_SingleInput::getDescription() { return description; -} - - - - - +} \ No newline at end of file diff --git a/HEN_HOUSE/egs++/egs_input_struct.h b/HEN_HOUSE/egs++/egs_input_struct.h index b1720ade9..396c2105f 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.h +++ b/HEN_HOUSE/egs++/egs_input_struct.h @@ -146,6 +146,12 @@ class EGS_EXPORT EGS_BlockInput /*! \brief Get the title of the block. */ string getTitle(); + /*! \brief Set the appName of the block. */ + void setAppName(string appName); + + /*! \brief Get the application name of the block. */ + string getAppName(); + /*! \brief Add a single input. */ shared_ptr addSingleInput(string inputTag, bool isReq, const string desc, const vector vals = vector()); @@ -205,6 +211,7 @@ class EGS_EXPORT EGS_BlockInput shared_ptr parent; string blockTitle; bool isRequired; + string application; const string desc; shared_ptr dependencyInp; string dependencyVal; @@ -259,6 +266,12 @@ class EGS_EXPORT EGS_InputStruct { /*! \brief Add a list of input blocks that are already defined as \a blocks */ void addBlockInputs(vector> blocks); + /*! \brief Remove the input block named \a blockTitle. */ + void removeBlockInput(string blockTitle); + + /*! \brief Removes block inputs in input struct based on name of app variable*/ + void removeBlockInputByApp(string appName); + /*! \brief Get the list of input blocks. */ vector> getBlockInputs(); @@ -278,6 +291,4 @@ class EGS_EXPORT EGS_InputStruct { }; -#endif - - +#endif \ No newline at end of file diff --git a/HEN_HOUSE/egs++/egs_rndm.h b/HEN_HOUSE/egs++/egs_rndm.h index 5a63d6ffd..b8fe252ac 100644 --- a/HEN_HOUSE/egs++/egs_rndm.h +++ b/HEN_HOUSE/egs++/egs_rndm.h @@ -40,9 +40,29 @@ #include "egs_libconfig.h" #include "egs_math.h" #include "egs_functions.h" +#include "egs_input_struct.h" class EGS_Input; +static void addRngDefinitionBlock(shared_ptr blockPtr) { + shared_ptr rngBlock = blockPtr->addBlockInput("rng definition"); + rngBlock->addSingleInput("type", true, "Generator type (Only ranmar)"); + rngBlock->addSingleInput("inital seeds", true, "Two integers that represent the inital seed"); + rngBlock->addSingleInput("high resolution", false, "Default is no", {"No", "Yes"}); +} + +static string addRngDefinitionExample() { + string example = { + R"( +:start rng definition: + type = ranmar + initial seeds = 33 97 + high resolution = no +:stop rng definition: +)"}; + return example; +} + /*! \brief Base random number generator class. All random number generators * should be derived from this class. * @@ -300,4 +320,4 @@ class EGS_EXPORT EGS_RandomGenerator { }; -#endif +#endif \ No newline at end of file diff --git a/HEN_HOUSE/egs++/egs_run_control.h b/HEN_HOUSE/egs++/egs_run_control.h index ae7a53b94..555bbc8f9 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -60,6 +60,21 @@ static void addRunControlBlock(shared_ptr blockPtr) { runBlock->addSingleInput("calculation", false, "The calculation type: first (default, runs a new simulation), restart (resumes a terminated simulation), analyze (prints results), combine (combines results from a parallel run). Defaults to 'first'.", {"first", "restart", "analyze", "combine"}); } +static string addRunControlExample() { + string example = { + R"( +:start run control: + ncase = 1e4 + nbatch = 10 #[optional] + statistical accuracy sought = 5 #[optional] + max cpu hours allowed = 0.5 #[optional] + calculation = first #[optional] + geometry error limit = 2 #[optional] +:stop run control: +)"}; + return example; +} + /*! \brief A simple run control object for advanced EGSnrc C++ applications. \ingroup egspp_main @@ -412,4 +427,4 @@ class EGS_EXPORT EGS_UniformRunControl : public EGS_RunControl { bool watcher_job; // If true, job is a 'watcher' }; -#endif +#endif \ No newline at end of file diff --git a/HEN_HOUSE/egs++/egs_scoring.h b/HEN_HOUSE/egs++/egs_scoring.h index 7052d4542..aeb1e916f 100644 --- a/HEN_HOUSE/egs++/egs_scoring.h +++ b/HEN_HOUSE/egs++/egs_scoring.h @@ -45,7 +45,7 @@ #include using namespace std; -static void addScoringBlock(shared_ptr blockPtr) { +/*static void addScoringBlock(shared_ptr blockPtr) { shared_ptr scoreBlock = blockPtr->addBlockInput("scoring options"); scoreBlock->addSingleInput("pulse height regions", false, "A list of regions to score pulse height distributions"); scoreBlock->addSingleInput("pulse height bins", false, "How many bins to use for each pulse height distribution. This must be either a single input, in which case all pulse height distributions will use this number of bins, or the same number of inputs as pulse height regions."); @@ -83,7 +83,7 @@ static void addScoringBlock(shared_ptr blockPtr) { auto transinpPtr = geominpPtr->addBlockInput("transformation"); transinpPtr->addSingleInput("translation", false, "The translation for the geometry (x, y ,z)"); -} +}*/ /*! \brief A class for scoring a single quantity of interest in a Monte Carlo simulation. @@ -467,4 +467,4 @@ class EGS_EXPORT EGS_ScoringArray { }; -#endif +#endif \ No newline at end of file diff --git a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp index d08729c0d..d2d6b922d 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -284,12 +284,21 @@ extern "C" { anglesRadPtr->addDependency(anglesPtr, "", true); anglesPtr->addDependency(anglesRadPtr, "", true); geomBlockInput->addSingleInput("flag", false, "0 or 1 or 2. This input affects the region numbering algorithm; see the documentation for details.")->addDependency(typePtr, "EGS_ConeSet"); + auto mediaPtr = geomBlockInput->addBlockInput("media input"); + mediaPtr->addDependency(typePtr, "EGS_ConeSet"); + mediaPtr->addSingleInput("media", true, ""); + mediaPtr->addSingleInput("set medium", false, ""); // EGS_SimpleCone auto anglePtr = geomBlockInput->addSingleInput("opening angle", false, "The opening angle of the cone in degrees."); anglePtr->addDependency(typePtr, "EGS_SimpleCone"); anglePtr->addDependency(typePtr, "EGS_ParallelCones"); geomBlockInput->addSingleInput("height", false, "The height of the cone."); + auto mediaPtr2 = geomBlockInput->addBlockInput("media input"); + mediaPtr2->addDependency(typePtr, "EGS_SimpleCone"); + mediaPtr2->addDependency(typePtr, "EGS_ParallelCones"); + mediaPtr2->addSingleInput("media", true, ""); + mediaPtr2->addSingleInput("set medium", false, ""); // EGS_ParallelCones geomBlockInput->addSingleInput("apex distances", false, "A list of distances from the first apex."); @@ -604,4 +613,4 @@ extern "C" { return g; } -} +} \ No newline at end of file diff --git a/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp b/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp index 43ca3cfb9..6347e17a4 100644 --- a/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp @@ -1,3 +1,4 @@ + /* ############################################################################### # @@ -46,7 +47,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_Conez"}); diff --git a/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp b/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp index ffca4097b..baded5ddb 100644 --- a/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp @@ -264,7 +264,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_IPlanes"}); diff --git a/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp b/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp index 124e619cb..47e656f49 100644 --- a/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp @@ -95,7 +95,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_Planes"}); @@ -110,7 +110,7 @@ extern "C" { // EGS_PlaneCollection auto normsPtr = geomBlockInput->addSingleInput("normals", true, "3N number inputs For each plane's normal"); - normsPtr->addDependency(typePtr, "EGS_PlaneCollection"); + normsPtr->addDependency(typePtr, "EGS_PlaneCollection");; // Alternative definition of the plane position auto fpPtr = geomBlockInput->addSingleInput("first plane", false, "The position of the first plane."); @@ -254,4 +254,4 @@ extern "C" { return g; } -} +} \ No newline at end of file diff --git a/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp b/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp index 4b51868d3..a0b01ab2b 100644 --- a/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_roundrect_cylinders/egs_roundrect_cylinders.cpp @@ -58,7 +58,7 @@ extern "C" { geomBlockInput->addSingleInput("y-widths", true, "A list of cylinder half-widths in the y-direction, must be in increasing order"); geomBlockInput->addSingleInput("radii", true, "A list of fillet radii, must be in increasing order"); geomBlockInput->addSingleInput("midpoint", false, "The position of the midpoint (x, y, z)"); - + // EGS_RoundRectCylinders auto inpPtr = geomBlockInput->addSingleInput("x-axis", true, "x-axis of rounded rectangle (x, y, z)"); inpPtr->addDependency(typePtr, "EGS_RoundRectCylinders"); @@ -219,4 +219,4 @@ extern "C" { return g; } -} +} \ No newline at end of file diff --git a/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp b/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp index 6f79047eb..92d19b4fd 100644 --- a/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp @@ -231,7 +231,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_RZ"}); diff --git a/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp b/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp index 22a0f5edf..88b20682c 100644 --- a/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp @@ -48,7 +48,7 @@ extern "C" { static void setInputs() { inputSet = true; - setBaseGeometryInputs(false); + setBaseGeometryInputs(); geomBlockInput->getSingleInput("library")->setValues({"EGS_Space"}); } diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index e80170f80..52dfef164 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -1,3 +1,4 @@ + /* ############################################################################### # @@ -656,6 +657,8 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC } blockTitle = getBlockTitle(cursor); + QString parentTitle = getParentBlockTitle(cursor); + if (blockTitle.size() < 1) { return nullptr; } @@ -663,6 +666,14 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC bool foundTag; QString library = getInputValue("library", cursor.block(), foundTag); + // egsInformation("Printing parentBlockTitle: %s\n", parentTitle.toLatin1().data()); + // If the parent block is media definition, then just return pegsless + if (parentTitle.toStdString() == "media definition") { + shared_ptr inputBlock = inputStruct->getBlockInput("media definition")->getBlockInput("pegsless"); + egsInformation("Input Block title test: %s\n", inputBlock->getTitle().c_str()); + return inputBlock; + } + // If we couldn't find a library tag in the current block, // try searching the containing block (if there is one) if (library.size() < 1) { @@ -816,6 +827,61 @@ QString EGS_Editor::getBlockTitle(QTextCursor cursor) { return blockTitle; } +// There may be a cleaner way of implementing this in getBlockTitle instead +QString EGS_Editor::getParentBlockTitle(QTextCursor cursor) { + if (cursor == QTextCursor()) { + cursor = textCursor(); + } + + vector innerList; + QString blockTitle; + bool withinOtherBlock = false; + bool findingParent = false; + + // Starting at the current line, start iterating in reverse through + // the previous lines until we find two start blocks + for (QTextBlock block = cursor.block(); block.isValid(); block = block.previous()) { + QString line = block.text().simplified(); + + // Get block title + int pos = line.lastIndexOf(":start "); + if (pos >= 0) { + pos += 7; + int endPos = line.indexOf(":",pos); + if (endPos > 0) { + blockTitle = line.mid(pos, endPos-pos); + if (innerList.size() > 0 && blockTitle == innerList.back()) { + innerList.pop_back(); + blockTitle.clear(); + withinOtherBlock = false; + } + else { + if (findingParent) { + break; + } + findingParent = true; + } + } + } + + // Save a vector of blocks that have already been closed + // This means both a matching :start and :stop are above the cursor + // so we're not inside the block + pos = line.lastIndexOf(":stop "); + if (pos >= 0) { + pos += 6; + int endPos = line.indexOf(":", pos); + if (endPos > 0) { + QString stopTitle = line.mid(pos, endPos - pos); + innerList.push_back(stopTitle); + withinOtherBlock = true; + } + } + } + + return blockTitle; +} + QString EGS_Editor::getInputValue(QString inp, QTextBlock currentBlock, bool &foundTag) { QString value; vector innerList; @@ -1307,4 +1373,3 @@ bool EGS_Editor::eventFilter(QObject *obj, QEvent *event) { // return false; //} - diff --git a/HEN_HOUSE/egs++/view/egs_editor.h b/HEN_HOUSE/egs++/view/egs_editor.h index 960a222ac..ec5d391fd 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.h +++ b/HEN_HOUSE/egs++/view/egs_editor.h @@ -73,6 +73,7 @@ private slots: private: shared_ptr getBlockInput(QString &blockTitle, QTextCursor cursor = QTextCursor()); QString getBlockTitle(QTextCursor cursor = QTextCursor()); + QString getParentBlockTitle(QTextCursor cursor = QTextCursor()); QString getInputValue(QString inp, QTextBlock currentBlock, bool &foundTag); QTextBlock getBlockEnd(QTextBlock currentBlock); bool inputHasDependency(shared_ptr inp); @@ -107,4 +108,4 @@ class LineNumberArea : public QWidget { EGS_Editor *egsEditor; }; -#endif // EGS_EDITOR_H +#endif // EGS_EDITOR_H \ No newline at end of file diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index 1234f5921..f9d370945 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -78,9 +78,10 @@ typedef EGS_BaseGeometry *(*createGeomFunction)(); typedef EGS_BaseSource *(*createSourceFunction)(); typedef EGS_BaseShape *(*createShapeFunction)(); typedef EGS_AusgabObject *(*createAusgabObjectFunction)(); -typedef void (*getAppInputsFunction)(shared_ptr inpPtr); +typedef shared_ptr (*getAppInputsFunction)(); +typedef shared_ptr (*getAppSpecificInputsFunction)(); typedef shared_ptr (*getInputsFunction)(); -typedef string(*getExampleFunction)(); +typedef string (*getExampleFunction)(); #ifdef WIN32 #ifdef CYGWIN @@ -211,49 +212,48 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) editorLayout->addWidget(egsinpEdit); highlighter = new EGS_Highlighter(egsinpEdit->document()); -// TODO: This is an example of how to load an application for egs_editor inputs -// // Load an egs++ application to parse the input file -// string app_name; + + // Load the egs_application library + string app_name; int appc = 5; char *appv[] = { "egspp", "-a", "tutor7pp", "-i", "tracks1.egsinp", "-p", "tutor_data"}; -// -// // Appv: %s -a application [-p pegs_file] [-i input_file] [-o output_file] [-b] [-P number_of_parallel_jobs] [-j job_index] -// if (!EGS_Application::getArgument(appc,appv,"-a","--application",app_name)) { -// egsFatal("test fail\n\n"); -// } -// -// string lib_dir; -// EGS_Application::checkEnvironmentVar(appc,appv,"-e","--egs-home","EGS_HOME",lib_dir); -// lib_dir += "bin"; -// lib_dir += fs; -// lib_dir += CONFIG_NAME; -// lib_dir += fs; -// -// // Load the application library -// // We don't require the application to be compiled, just give a warning if it isn't. -// EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); -// bool app_loaded = true; -// if (!app_lib.load()) { -// egsWarning("\n%s: Failed to load the %s application library from %s\n\n", appv[0],app_name.c_str(),lib_dir.c_str()); -// app_loaded = false; -// } else { -// createAppFunction createApp = (createAppFunction) app_lib.resolve("createApplication"); -// if (!createApp) { -// egsWarning("\n%s: Failed to resolve the address of the 'createApplication' function in the application library %s\n\n",appv[0],app_lib.libraryFile()); -// app_loaded = false; -// } else { -// EGS_Application *app = createApp(appc,appv); -// if (!app) { -// egsWarning("\n%s: Failed to construct the application %s\n\n",appv[0],app_name.c_str()); -// app_loaded = false; -// } -// egsInformation("Testapp %f\n",app->getRM()); -// delete app; -// } -// } + if (!EGS_Application::getArgument(appc,appv,"-a","--application",app_name)) { + egsFatal("test fail\n\n"); + } + + EGS_Application::checkEnvironmentVar(appc,appv,"-e","--egs-home","EGS_HOME",lib_dir); + lib_dir += "bin"; + lib_dir += fs; + lib_dir += CONFIG_NAME; + lib_dir += fs; + // Load the application library + // We don't require the application to be compiled, just give a warning if it isn't. + EGS_Library app_lib(app_name.c_str(),lib_dir.c_str()); + bool app_loaded = true; + if (!app_lib.load()) { + egsWarning("\n%s: Failed to load the %s application library from %s\n\n", appv[0],app_name.c_str(),lib_dir.c_str()); + app_loaded = false; + } else { + createAppFunction createApp = (createAppFunction) app_lib.resolve("createApplication"); + if (!createApp) { + egsWarning("\n%s: Failed to resolve the address of the 'createApplication' function in the application library %s\n\n",appv[0],app_lib.libraryFile()); + app_loaded = false; + } else { + EGS_Application *app = createApp(appc,appv); + if (!app) { + egsWarning("\n%s: Failed to construct the application %s\n\n",appv[0],app_name.c_str()); + app_loaded = false; + } + egsInformation("Testapp %f\n",app->getRM()); + delete app; + } + } + // Get a list of all the libraries in the bin directory for applications + QDir binDirectory(lib_dir.c_str()); + QStringList binLibraries = binDirectory.entryList(QStringList() << (lib_prefix + "*" + lib_suffix).c_str(), QDir::Files); // Get a list of all the libraries in the dso directory string dso_dir; @@ -278,33 +278,116 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) QMenu *ausgabMenu = exampleMenu->addMenu("Ausgab/Output"); QMenu *mediaMenu = exampleMenu->addMenu("Media"); QMenu *runMenu = exampleMenu->addMenu("Run Control"); - QMenu *appMenu = exampleMenu->addMenu("Applications"); + + appMenu = exampleMenu->addMenu("Applications"); + + // Creates the example menu for different applications + QMenu *exampleMenu2 = new QMenu("Choose application"); + menuBar->addMenu(exampleMenu2); + + QAction *action = exampleMenu2->addAction("none"); + action->setData("none"); + connect(action, &QAction::triggered, this, [this] { setApplication(); }); + + for (const auto &lib : binLibraries) { + // Remove the extension + QString libName = lib.left(lib.lastIndexOf(".")); + + // Remove the prefix (EGS_Library adds it automatically) + libName = libName.right(libName.length() - lib_prefix.length()); + egsInformation("Trying %s\n", libName.toLatin1().data()); + + // Adds the button to the menu + QAction *action = exampleMenu2->addAction(libName); + action->setData(libName); + connect(action, &QAction::triggered, this, [this] { setApplication(); }); + } editorLayout->setMenuBar(menuBar); // The input template structure inputStruct = make_shared(); -// // Get the application level input blocks -// if(app_loaded) { -// getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); -// if(getAppInputs) { -// getAppInputs(inputStruct); -// if(inputStruct) { -// vector> inputBlocks = inputStruct->getBlockInputs(); -// for (auto &block : inputBlocks) { -// egsInformation(" block %s\n", block->getTitle().c_str()); -// vector> singleInputs = block->getSingleInputs(); + if(app_loaded) { + + getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppInputs"); + if(getAppInputs) { + + // before this was a BlockInput, now it is a InputStruct + shared_ptr app = getAppInputs(); + + if (app) { + inputStruct->addBlockInputs(app->getBlockInputs()); + +// vector> singleInputs = app->getSingleInputs(); // for (auto &inp : singleInputs) { // const vector vals = inp->getValues(); -// egsInformation(" single %s\n", inp->getTag().c_str()); -// for (auto&& val : vals) { -// egsInformation(" %s\n", val.c_str()); -// } +// // egsInformation(" single %s\n", inp->getTag().c_str()); +// // for (auto&& val : vals) { +// // egsInformation(" %s\n", val.c_str()); +// // } // } -// } -// } -// } -// } + + // vector> inputBlocks = app->getBlockInputs(); + // for (auto &block : inputBlocks) { + // egsInformation(" block %s\n", block->getTitle().c_str()); + // vector> singleInputs = block->getSingleInputs(); + // inputStruct->addBlockInput(block); + // for (auto &inp : singleInputs) { + // const vector vals = inp->getValues(); + // egsInformation(" single %s\n", inp->getTag().c_str()); + // for (auto&& val : vals) { + // egsInformation(" %s\n", val.c_str()); + // } + // } + // } + } + } + // getAppInputs(inputStruct); + // if(inputStruct) { + // vector> inputBlocks = inputStruct->getBlockInputs(); + // for (auto &block : inputBlocks) { + // egsInformation(" block %s\n", block->getTitle().c_str()); + // vector> singleInputs = block->getSingleInputs(); + // for (auto &inp : singleInputs) { + // const vector vals = inp->getValues(); + // egsInformation(" single %s\n", inp->getTag().c_str()); + // for (auto&& val : vals) { + // egsInformation(" %s\n", val.c_str()); + // } + // } + // } + // } + // } + + // Add the examples from the Application library + getExampleFunction getExample = (getExampleFunction) app_lib.resolve("getRunControlExample"); + if (getExample) { + QAction *action = runMenu->addAction("egs_run_control"); + action->setData(QString::fromStdString(getExample())); + connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); + } + + getExample = (getExampleFunction) app_lib.resolve("getmcExample"); + if (getExample) { + QAction *action = appMenu->addAction("egs_monte_carlo_parameters"); + action->setData(QString::fromStdString(getExample())); + connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); + } + + getExample = (getExampleFunction) app_lib.resolve("getRngDefinitionExample"); + if (getExample) { + QAction *action = appMenu->addAction("egs_rng_definition"); + action->setData(QString::fromStdString(getExample())); + connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); + } + + getExample = (getExampleFunction) app_lib.resolve("getMediaExample"); + if (getExample) { + QAction *action = mediaMenu->addAction("egs_example_media"); + action->setData(QString::fromStdString(getExample())); + connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); + } + } // Geometry definition block auto geomDefPtr = inputStruct->addBlockInput("geometry definition"); @@ -3415,4 +3498,56 @@ void GeometryViewControl::insertInputExample() { egsinpEdit->insertPlainText(pAction->data().toString()); } +void GeometryViewControl::setApplication() { + + // Gets the selected application from the menu + QAction *pAction = qobject_cast(sender()); + string newlySelectedApp = pAction->data().toString().toStdString(); + egsInformation("Selected application: %s\n", newlySelectedApp.c_str()); + + // Removes previous application inputs + if (selectedApplication != "None") { + inputStruct->removeBlockInputByApp(selectedApplication); + } + + // Load the new library + // Do not load if the default is selected + if (newlySelectedApp != "None") { + egsInformation("Loading library: %s\n", newlySelectedApp.c_str()); + EGS_Library app_lib(newlySelectedApp.c_str(),lib_dir.c_str()); + if (!app_lib.load()) { + egsWarning("Failed to load inputs and example for applications\n"); + } else { + getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppSpecificInputs"); + egsInformation("getAppInputs %s\n", getAppInputs ? "true" : "false"); + + if (getAppInputs) { + shared_ptr app = getAppInputs(); + if (app) { + inputStruct->addBlockInputs(app->getBlockInputs()); + } + } + + // Delete the previous application example + QList actions = appMenu->actions(); + for (QAction* action : actions) { + if (action->text() == "egs_current_app") { + appMenu->removeAction(action); + delete action; + break; + } + } + // Load the new application example + getExampleFunction getExample = (getExampleFunction) app_lib.resolve("getAppSpecificExample"); + if (getExample) { + QAction *action = appMenu->addAction("egs_current_app"); + action->setData(QString::fromStdString(getExample())); + connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); + } + } + } + + selectedApplication = newlySelectedApp; + egsinpEdit->setInputStruct(inputStruct); +} \ No newline at end of file diff --git a/HEN_HOUSE/egs++/view/viewcontrol.h b/HEN_HOUSE/egs++/view/viewcontrol.h index 762eaf9f2..4fea4c387 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -150,6 +150,7 @@ public slots: virtual void changeTrackMaxPo(int t); virtual void updateTracks(vector ntracks); virtual void insertInputExample(); + virtual void setApplication(); private: @@ -213,6 +214,9 @@ public slots: EGS_AdvancedApplication *egsApp; shared_ptr inputStruct; QMenu *exampleMenu; + string selectedApplication = "None"; + string lib_dir; + QMenu *appMenu; protected slots: @@ -222,4 +226,4 @@ protected slots: }; -#endif // GEOMETRYVIEWCONTROL_H +#endif // GEOMETRYVIEWCONTROL_H \ No newline at end of file diff --git a/HEN_HOUSE/user_codes/cavity/cavity.cpp b/HEN_HOUSE/user_codes/cavity/cavity.cpp index 08bb32db9..31c74b08e 100644 --- a/HEN_HOUSE/user_codes/cavity/cavity.cpp +++ b/HEN_HOUSE/user_codes/cavity/cavity.cpp @@ -186,6 +186,8 @@ #include "egs_transformations.h" // Interpolators #include "egs_interpolator.h" +// For autocomplete and examples +#include "egs_input_struct.h" #include #include @@ -3318,8 +3320,129 @@ void EGS_HVL::recursiveIteration(){ } +extern "C" { + APP_EXPORT shared_ptr getAppSpecificInputs() { + shared_ptr appInput = make_shared(); + + shared_ptr scoreBlock = appInput->addBlockInput("scoring options"); + scoreBlock->setAppName("cavity"); + shared_ptr scaleBlock = scoreBlock->addBlockInput("scale photon x-sections"); + scaleBlock->addSingleInput("factor", false, ""); + scaleBlock->addSingleInput("medium", false, ""); + scaleBlock->addSingleInput("cross section", false, "options are: all, Rayleigh, Compton, Pair, or Photo", {"all", "Rayleigh", "Compton", "Pair", "Photo"}); + + scoreBlock->addSingleInput("calculation type", false, "options are: Dose, Awall, Fano, HVL, FAC", {"Dose", "Awall", "Fano", "HVL", "FAC"}); + // not sure about inputs for scale xcc + scoreBlock->addSingleInput("scale xcc", false, ""); + + shared_ptr calcBlock = scoreBlock->addBlockInput("calculation geometry"); + calcBlock->addSingleInput("geometry name", false, ""); + calcBlock->addSingleInput("calculation name", true, ""); + calcBlock->addSingleInput("cavity regions", false, ""); + calcBlock->addSingleInput("aperture regions", false, ""); + calcBlock->addSingleInput("cavity mass", false, ""); + calcBlock->addSingleInput("charge regions", false, ""); + + scoreBlock->addSingleInput("correlated geometries", false, "only available with types Dose, HVL, and FAC"); + + shared_ptr fluenceBlock = scoreBlock->addBlockInput("fluence scoring"); + fluenceBlock->addSingleInput("minimum energy", false, ""); + fluenceBlock->addSingleInput("maximum energy", false, ""); + fluenceBlock->addSingleInput("number of bins", false, ""); + fluenceBlock->addSingleInput("scale", false, "options are: linear, logarithmic", {"linear", "logarithmic"}); + + shared_ptr hvlBlock = scoreBlock->addBlockInput("HVL scoring"); + hvlBlock->addSingleInput("scoring circle", false, ""); + hvlBlock->addSingleInput("scoring plane normal", false, ""); + hvlBlock->addSingleInput("muen file", false, ""); + hvlBlock->addSingleInput("absorber thicknesses", false, ""); + hvlBlock->addSingleInput("scatter", false, "yes or no", {"yes", "no"}); + + shared_ptr kermaBlock = scoreBlock->addBlockInput("kerma scoring"); + kermaBlock->addSingleInput("scoring circle", false, ""); + kermaBlock->addSingleInput("scoring plane normal", false, ""); + kermaBlock->addSingleInput("muen file", false, ""); + + shared_ptr varBlock = appInput->addBlockInput("variance reduction"); + varBlock->setAppName("cavity"); + varBlock->addSingleInput("photon splitting", false, ""); + shared_ptr rejBlock = varBlock->addBlockInput("range rejection"); + rejBlock->addSingleInput("rejection", false, ""); + rejBlock->addSingleInput("Esave", false, ""); + rejBlock->addSingleInput("cavity geometry", false, ""); + rejBlock->addSingleInput("rejection range medium", false, ""); + + return appInput; + } + + + + APP_EXPORT string getAppSpecificExample() { + string example; + example = { + R"( +:start scoring options: + :start scale photon x-sections: + factor = 1.5 + medium = ALL + cross section = all # Rayleigh, Compton, Pair, or Photo + :stop scale photon x-sections: + + calculation type = Dose # Dose, Awall, Fano, HVL, or FAC + scale xcc = 1.5 + + :start calculation geometry: + geometry name = fac_1 + cavity regions = 3184 + aperture regions = 490,1470,2450 + cavity mass = 0.009462477073 # cylinder defined by diaphragm and plates + :start transformation: + translation = 0 0 -99.55 + :stop transformation: + :stop calculation geometry: + + correlated geometries = fac_1 + + :start fluence scoring: + minimum energy = Emin + maximum energy = Emax + number of bins = N + scale = linear # linear or logarithmic + :stop fluence scoring: + + # if type is HVL + :start HVL scoring: + scoring circle = x y z R + scoring plane normal = u v w + muen file = E*muen file name + absorber thicknesses = t_1 t_2 ... t_ncg + scatter = yes or no + :stop HVL scoring: + + # if type is FAC + :start kerma scoring: + scoring circle = 0 0 0.45 0.5 + scoring plane normal = 0 0 1 + muen file = E*muen file name + :stop kerma scoring +:stop scoring options: + +:start variance reduction: + photon splitting = 50 + :start range rejection: + rejection = 100 + Esave = 1 + cavity geometry = cavity + rejection range medium = 170C521ICRU + :stop range rejection: +:stop variance reduction: +)"}; + return example; + } +} + #ifdef BUILD_APP_LIB APP_LIB(Cavity_Application); #else APP_MAIN(Cavity_Application); -#endif +#endif \ No newline at end of file diff --git a/HEN_HOUSE/user_codes/egs_cbct/egs_cbct.cpp b/HEN_HOUSE/user_codes/egs_cbct/egs_cbct.cpp index c727f73cf..adb4f4b87 100644 --- a/HEN_HOUSE/user_codes/egs_cbct/egs_cbct.cpp +++ b/HEN_HOUSE/user_codes/egs_cbct/egs_cbct.cpp @@ -67,6 +67,8 @@ #include "egs_timer.h" +#include "egs_input_struct.h" + const int __debug_case = -1; class EGS_RectangularBeam; @@ -4263,8 +4265,77 @@ void EGS_CBCT::doKleinNishina(EGS_CBCT_Photon &p) { EGS_Float sigt = w2/(Ko*Ko2); } +extern "C" { + APP_EXPORT shared_ptr getAppSpecificInputs() { + shared_ptr appInput = make_shared(); + shared_ptr scoreBlock = appInput->addBlockInput("scoring options"); + scoreBlock->setAppName("egs_cbct"); + + scoreBlock->addSingleInput("calculation type", false, "planar, volumetric, both, or ray-tracing", {"planar", "volumetric", "both", " ray-tracing"}); + scoreBlock->addSingleInput("angle", false, ""); + scoreBlock->addSingleInput("orbit", false, ""); + scoreBlock->addSingleInput("step", false, ""); + + shared_ptr planarBlock = scoreBlock->addBlockInput("planar scoring"); + planarBlock->addSingleInput("surrounding medium", false, "defaults to vaccum"); + planarBlock->addSingleInput("target uncertainty", false, "defaults to 1%"); + planarBlock->addSingleInput("maximum Aatt fraction", false, "defaults to 0.1"); + planarBlock->addSingleInput("screen resolution", false, ""); + planarBlock->addSingleInput("uncertainty estimation", false, ""); + planarBlock->addSingleInput("voxel size", false, ""); + planarBlock->addSingleInput("muen file", false, "get E*muen/rho values"); + + shared_ptr smoothingBlock = scoreBlock->addBlockInput("smoothing options"); + smoothingBlock->addSingleInput("nmax", false, ""); + smoothingBlock->addSingleInput("nmax2d", false, ""); + smoothingBlock->addSingleInput("chi2max", false, ""); + + return appInput; + } + + APP_EXPORT string getAppSpecificExample() { + string example; + example = { + R"( +# egs_cbct example input +:start scoring options: + calculation type = planar # planar, volumetric, both, or ray-tracing + angle = 0 + orbit = 0 + step = 0 + + # only available for planar calculation type + :start planar scoring: + surrounding medium = vacuum # defaults to vaccum + target uncertainty = 1% # defaults to 1% + maximum Aatt fraction = 0.1 # defaults to 0.1 + screen resolution = 64 64 + uncertainty estimation = 1 + voxel size = 1.25 + muen file = replace with your own + :stop planar scoring: + + ############################################# + # Smoothing of the scatter distribution. + # Shown to contribute about 50% of the + # large efficiency increase when estimating + # scatter. This part uses a 2D locally adaptive + # Savitzky-Golay filter. + ############################################# + start smoothing options: + nmax = 10 + nmax2d = 6 + chi2max = 2 + :stop smoothing options: + +:stop scoring options: +)"}; + return example; + } +} + #ifdef BUILD_APP_LIB APP_LIB(EGS_CBCT); #else APP_MAIN(EGS_CBCT); -#endif +#endif \ No newline at end of file diff --git a/HEN_HOUSE/user_codes/egs_chamber/egs_chamber.cpp b/HEN_HOUSE/user_codes/egs_chamber/egs_chamber.cpp index 472a437b8..eb962cfe5 100644 --- a/HEN_HOUSE/user_codes/egs_chamber/egs_chamber.cpp +++ b/HEN_HOUSE/user_codes/egs_chamber/egs_chamber.cpp @@ -80,6 +80,8 @@ // Interpolators #include "egs_interpolator.h" #include "egs_run_control.h" +// Autocomplete and examples +#include "egs_input_struct.h" #include "egs_rndm.h" #define getRNGPointers F77_OBJ_(egs_get_rng_pointers,EGS_GET_RNG_POINTERS) @@ -3027,8 +3029,158 @@ int EGS_ChamberApplication::startNewShower() { return 0; }; +extern "C" { + APP_EXPORT shared_ptr getAppSpecificInputs() { + shared_ptr appInput = make_shared(); + + shared_ptr varBlock = appInput->addBlockInput("variance reduction"); + varBlock->setAppName("egs_chamber"); + varBlock->addSingleInput("TmpPhsp", false, "i.e., score phase space and use it once in each specified sub-geometry"); + varBlock->addSingleInput("cs enhancement", false, "0 (XCSE off), >0 (XCSE on)"); + varBlock->addSingleInput("photon splitting", false, ""); + varBlock->addSingleInput("radiative splitting", false, ""); + + shared_ptr rrBlock = varBlock->addBlockInput("range rejection"); + rrBlock->addSingleInput("rejection", false, ""); + rrBlock->addSingleInput("Esave", false, ""); + rrBlock->addSingleInput("cavity geometry", false, ""); + rrBlock->addSingleInput("rejection range medium", false, ""); + + shared_ptr scoreBlock = appInput->addBlockInput("scoring options"); + scoreBlock->setAppName("egs_chamber"); + scoreBlock->addSingleInput("silent", false, ""); + scoreBlock->addSingleInput("onegeom", false, "when set to 1, only one geometry is used"); + scoreBlock->addSingleInput("scale xcc", false, "scale elastic scattering"); + + shared_ptr scaleBlock = scoreBlock->addBlockInput("scale photon x-sections"); + scaleBlock->addSingleInput("factor", false, ""); + scaleBlock->addSingleInput("medium", false, ""); + scaleBlock->addSingleInput("cross section", false, "options are: all, Rayleigh, Compton, Pair, or Photo", {"all", "Rayleigh", "Compton", "Pair", "Photo"}); + + shared_ptr calcBlock = scoreBlock->addBlockInput("calculation geometry"); + calcBlock->addSingleInput("geometry name", false, ""); + calcBlock->addSingleInput("cavity regions", false, ""); + calcBlock->addSingleInput("ECUT regions", false, ""); + calcBlock->addSingleInput("ECUT", false, ""); + calcBlock->addSingleInput("cavity geometry", false, ""); + calcBlock->addSingleInput("enhance regions", false, "only available when cs enhancement is on (1)"); + calcBlock->addSingleInput("enhancement", false, "only available when cs enhancement is on (1)"); + calcBlock->addSingleInput("cavity mass", false, ""); + // should also have a section for sub-geometries but I dont know how it should be implemented/formatted + + scoreBlock->addSingleInput("correlated geometries", false, "enter as many as needed to compute desired perturbation factors"); + + shared_ptr isoBlock = scoreBlock->addBlockInput("isocenter positioning uncertainty"); + isoBlock->addSingleInput("ncase per position", false, ""); + isoBlock->addSingleInput("positions per sample", false, ""); + shared_ptr transBlock = isoBlock->addBlockInput("translation"); + transBlock->addSingleInput("distribution", false, "gaussian or uniform"); + transBlock->addSingleInput("max shift", false, "3 values"); + transBlock->addSingleInput("sigma", false, "3 values"); + shared_ptr rotBlock = isoBlock->addBlockInput("rotation"); + rotBlock->addSingleInput("distribution", false, "gaussian or uniform"); + rotBlock->addSingleInput("max shift", false, "3 values"); + rotBlock->addSingleInput("sigma", false, "3 values"); + + shared_ptr cavBlock = scoreBlock->addBlockInput("cavity positioning uncertainty"); + cavBlock->addSingleInput("ncase per position", false, ""); + cavBlock->addSingleInput("positions per sample", false, ""); + shared_ptr transBlock2 = cavBlock->addBlockInput("translation"); + transBlock2->addSingleInput("distribution", false, "gaussian or uniform"); + transBlock2->addSingleInput("max shift", false, "3 values"); + transBlock2->addSingleInput("sigma", false, "only available with gaussian"); + + return appInput; + } + + APP_EXPORT string getAppSpecificExample() { + string example; + example = { + R"( +# egs_chamber example input +:start variance reduction: + TmpPhsp = 1 # i.e., score phase space and use it once in each specified sub-geometry + cs enhancement = 1 # 0 (XCSE off), >0 (XCSE on) + photon splitting = 10 + radiative splitting = 10 + + :start range rejection: + rejection = N_r + Esave = E_save # i.e. no range rejection but Russian Roulette + cavity geometry = cavity # since each geometry can have its own + # cavity geometry this is just a dummy + rejection range medium = = H2O521ICRU + :stop range rejection: +:stop variance reduction: + +:start scoring options: + silent = 0; + start scale photon x-sections: + factor = 1.0 + medium = 1 + cross section = all + stop scale photon x-sections: # all, Rayleigh, Compton, Pair, or Photo + onegeom = 0 # when set to 1, only one geometry is used + scale xcc = 5 + + # + # The simulation starts in the first calculation geometry + # If phase space scoring is set, which it is in our case, + # (see the variance reduction section below), + # then all particles entering the region specified as cavity are + # stored and then they are further transported in the additional + # calculation geometries specified + # + :start calculation geometry: + geometry name = phsp_scoring_geometry + cavity regions = 1 5 + ECUT regions = cavity + ECUT = 0.7 + cavity geometry = air_chamber_tube + enhance regions = 0 1 4 5 + enhancement = 128 128 128 128 + cavity mass = 1 + :stop calculation geometry: + + correlated geometries = geometry_i geometry_l # enter as many as needed to compute desired perturbation factors + + :start isocenter positioning uncertainty: + ncase per position = 1000000 + positions per sample = 10 + :start translation: + distribution = gaussian # gaussian or uniform + max shift = 0.1, 0.1, 0.1 # 3 values + sigma = 0.05, 0.05, 0.05 # 3 values + :stop translation: + :start rotation: + distribution = uniform # gaussian or uniform + max shift = 0, 0.1, 0 + :stop rotation: + :stop isocenter positioning uncertainty: + + :start cavity positioning uncertainty: + ncase per position = 1000000 + positions per sample = 10 + + :start translation: + distribution = gaussian # gaussian or uniform + max shift = 0, 0.1, 0 + sigma = 0.05, 0.05, 0.05 + :stop translation: + + :start rotation: + distribution = uniform # gaussian or uniform + max shift = 0, 0.1, 0 + :stop rotation: + :stop cavity positioning uncertainty: +:stop scoring options: +)"}; + return example; + } +} + #ifdef BUILD_APP_LIB APP_LIB(EGS_ChamberApplication); #else APP_MAIN(EGS_ChamberApplication); -#endif +#endif \ No newline at end of file diff --git a/HEN_HOUSE/user_codes/egs_fac/egs_fac.cpp b/HEN_HOUSE/user_codes/egs_fac/egs_fac.cpp index 954bd0d2e..e61717aa7 100644 --- a/HEN_HOUSE/user_codes/egs_fac/egs_fac.cpp +++ b/HEN_HOUSE/user_codes/egs_fac/egs_fac.cpp @@ -198,6 +198,7 @@ #include "egs_range_rejection.h" #include "egs_fac_simulation.h" #include "egs_math.h" +#include "egs_input_struct.h" #include using namespace std; @@ -1084,8 +1085,84 @@ void EGS_FACApplication::describeSimulation() { } } +extern "C" { + APP_EXPORT shared_ptr getAppSpecificInputs() { + shared_ptr appInput = make_shared(); + + shared_ptr scoreBlock = appInput->addBlockInput("scoring options"); + scoreBlock->setAppName("egs_fac"); + shared_ptr scaleBlock = scoreBlock->addBlockInput("scale photon x-sections"); + scaleBlock->addSingleInput("factor", false, ""); + scaleBlock->addSingleInput("medium", false, ""); + scaleBlock->addSingleInput("cross section", false, "options are: all, Rayleigh, Compton, Pair, or Photo", {"all", "Rayleigh", "Compton", "Pair", "Photo"}); + + scoreBlock->addSingleInput("scale xcc", false, "scale elastic scattering"); + shared_ptr calcBlock = scoreBlock->addBlockInput("calculation geometry"); + scoreBlock->addSingleInput("correlated geometries", false, ""); + scoreBlock->addSingleInput("Ax calculation", false, ""); + scoreBlock->addSingleInput("muen file", false, "get E*muen/rho values"); + + shared_ptr vrBlock = appInput->addBlockInput("variance reduction"); + vrBlock->setAppName("egs_fac"); + vrBlock->addSingleInput("photon splitting", false, ""); + vrBlock->addSingleInput("increase scatter", false, "yes or no", {"no", "yes"}); + + return appInput; + } + + APP_EXPORT string getAppSpecificExample() { + string example; + example = { + R"( +:start scoring options: + :start scale photon x-sections: + factor = 1.5 + medium = ALL + cross section = all + :stop scale photon x-sections: + scale xcc = 1.5 + + :start calculation geometry: + geometry name = fac_air_tube + cavity regions = 132 + aperture regions = 13 16 19 30 + front and back regions = 83 181 + cavity mass = 0.009462477073 # cylinder defined by diaphragm and plates + :start transformation: + translation = 0 0 -99.55 + :stop transformation: + POM = 0.45 0.5 + :stop calculation geometry: + + :start calculation geometry: + geometry name = fac_vacuum_tube + cavity regions = 132 + aperture regions = 13 16 19 30 + front and back regions = 83 181 + cavity mass = 0.009462477073 # cylinder defined by diaphragm and plates + :start transformation: + translation = 0 0 -99.55 + :stop transformation: + POM = 0.45 0.5 + :stop calculation geometry: + + correlated geometries = fac_air_tube fac_vacuum_tube + Ax calculation = fac_air_tube fac_vacuum_tube + muen file = # absolute or relative file path + +:stop scoring options: + +:start variance reduction: + photon splitting = 200 + increase scatter = no +:stop variance reduction: +)"}; + return example; + } +} + #ifdef BUILD_APP_LIB APP_LIB(EGS_FACApplication); #else APP_MAIN(EGS_FACApplication); -#endif +#endif \ No newline at end of file diff --git a/HEN_HOUSE/user_codes/egs_kerma/egs_kerma.cpp b/HEN_HOUSE/user_codes/egs_kerma/egs_kerma.cpp index 341eb8333..039102821 100644 --- a/HEN_HOUSE/user_codes/egs_kerma/egs_kerma.cpp +++ b/HEN_HOUSE/user_codes/egs_kerma/egs_kerma.cpp @@ -1,3 +1,4 @@ + /* ############################################################################### # @@ -85,6 +86,8 @@ #include "egs_transformations.h" // Interpolators #include "egs_interpolator.h" +// Get examples for autocomplete +#include #include #include @@ -1431,6 +1434,72 @@ void EGS_KermaApplication::describeSimulation() { } } +extern "C" { + APP_EXPORT shared_ptr getAppSpecificInputs() { + shared_ptr appInput = make_shared(); + + shared_ptr scoreBlock = appInput->addBlockInput("scoring options"); + scoreBlock->setAppName("egs_kerma"); + shared_ptr calcBlock = scoreBlock->addBlockInput("calculation geometry"); + scoreBlock->addSingleInput("correlated geometries", false, ""); + + shared_ptr fluBlock = scoreBlock->addBlockInput("fluence scoring"); + fluBlock->addSingleInput("minimum energy", false, ""); + fluBlock->addSingleInput("maximum energy", false, ""); + fluBlock->addSingleInput("number of bins", false, ""); + fluBlock->addSingleInput("scale", false, "linear or logarithmic", {"linear", "logarithmic"}); + + scoreBlock->addSingleInput("muen file", false, ""); + scoreBlock->addSingleInput("Default FD geometry", false, ""); + return appInput; + } + + APP_EXPORT string getAppSpecificExample() { + string example; + example = { + R"( +:start scoring options: + + ### use the same geometry under two different names, for easier bookeeping + :start calculation geometry: + geometry name = sphere_in_room_no_wall + scoring regions = 2 + excluded regions = 0 # exclude contribution from these regions + scoring region masses = 0.631 # mass in g for each scoring region + #scoring volume mass = 0.631 # alternatively: mass for whole scoring volume + :stop calculation geometry: + + :start calculation geometry: + geometry name = sphere_in_room_all + scoring regions = 2 + scoring region masses = 0.631 # mass in g for each region + #scoring volume mass = 0.631 # mass in g for whole scoring volume + :stop calculation geometry: + + ### ratio estimates wall contribution to air sphere + correlated geometries = sphere_in_room_all sphere_in_room_no_wall + + ### fluence scoring requested (common to all calculation geometries) + :start fluence scoring: + minimum energy = 0.001 + maximum energy = 0.040 + number of bins = 40 + scale = linear + :stop fluence scoring: + + ### E*muen file (could also be E*mutr): absolute or relative file path + ### Use absolute path when submitting parallel jobs!!! + emuen file = $EGS_HOME/egs_kerma/emuen_icru90_1.5MeV.data + + ### geometry for forced-detection (if omitted, score ONLY when reaching scoring region) + Default FD geometry = sphere + +:stop scoring options: +)"}; + return example; + } +} + #ifdef BUILD_APP_LIB APP_LIB(EGS_KermaApplication); #else diff --git a/HEN_HOUSE/user_codes/egs_phd/egs_phd.cpp b/HEN_HOUSE/user_codes/egs_phd/egs_phd.cpp index 2d4b92d28..97e361fdb 100644 --- a/HEN_HOUSE/user_codes/egs_phd/egs_phd.cpp +++ b/HEN_HOUSE/user_codes/egs_phd/egs_phd.cpp @@ -52,6 +52,7 @@ #include "egs_phd.h" +#include "egs_input_struct.h" // describeUserCode void phd_app::describeUserCode() const { @@ -340,6 +341,43 @@ int phd_app::startNewShower() { return 0; } +extern "C" { + APP_EXPORT shared_ptr getAppSpecificInputs() { + shared_ptr appInput = make_shared(); + + shared_ptr scoreBlock = appInput->addBlockInput("scoring options"); + scoreBlock->setAppName("egs_phd"); + + shared_ptr specBlock = scoreBlock->addBlockInput("spectrum"); + specBlock->addSingleInput("label", false, ""); + specBlock->addSingleInput("Emin", false, ""); + specBlock->addSingleInput("Emax", false, ""); + specBlock->addSingleInput("bins", false, ""); + specBlock->addSingleInput("spectrum file", false, ""); + + return appInput; + } + + APP_EXPORT string getAppSpecificExample() { + string example; + example = { + R"( +:start scoring options: + :start spectrum: + label = detector + Emin = 0.0 + Emax = 1.0 + bins = 100 + spectrum file = spectrum.dat + :stop spectrum: +:stop scoring options: +)"}; + return example; + } +} -// main application macro -APP_MAIN(phd_app); +#ifdef BUILD_APP_LIB + APP_LIB(phd_app); +#else + APP_MAIN(phd_app); +#endif \ No newline at end of file diff --git a/HEN_HOUSE/user_codes/mevegs/mevegs.cpp b/HEN_HOUSE/user_codes/mevegs/mevegs.cpp index db1dfb2cd..5aa7814f3 100644 --- a/HEN_HOUSE/user_codes/mevegs/mevegs.cpp +++ b/HEN_HOUSE/user_codes/mevegs/mevegs.cpp @@ -54,6 +54,8 @@ #include "egs_mesh.h" //! To handle EGS_Mesh in an EGS_EnvelopeGeometry #include "egs_envelope_geometry.h" +//! To handle input examples +#include "egs_input_struct.h" #include #include @@ -776,8 +778,41 @@ int Mevegs_Application::startNewShower() { return 0; } +extern "C" { + APP_EXPORT shared_ptr getAppSpecificInputs() { + shared_ptr appInput = make_shared(); + + shared_ptr scoreBlock = appInput->addBlockInput("scoring options"); + scoreBlock->setAppName("mevegs"); + scoreBlock->addSingleInput("scale xcc", false, ""); + scoreBlock->addSingleInput("scale bc", false, ""); + scoreBlock->addSingleInput("deflect electron after brems", false, "yes or no", {"yes", "no"}); + scoreBlock->addSingleInput("Russian Roulette", false, "survival probability is 1/input"); + scoreBlock->addSingleInput("pulse height regions", false, ""); + scoreBlock->addSingleInput("pulse height bins", false, ""); + + return appInput; + } + + APP_EXPORT string getAppSpecificExample() { + string example; + example = { + R"( +:start scoring options: + scale xcc = + scale bc = + deflect electron after brems = no # or yes + Russian Roulette = 5 # survival probability is 1/input + pulse height regions = 1 2 3 + pulse height bins = 1 2 3 +:stop scoring options: +)"}; + return example; + } +} + #ifdef BUILD_APP_LIB APP_LIB(Mevegs_Application); #else APP_MAIN(Mevegs_Application); -#endif +#endif \ No newline at end of file diff --git a/HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp b/HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp index 4abce121d..2d388d5f7 100644 --- a/HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp +++ b/HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp @@ -145,6 +145,7 @@ #include "egs_functions.h" //! We use the EGS_Input class #include "egs_input.h" +#include "egs_input_struct.h" //! To get the maximum source energy #include "egs_base_source.h" #include "egs_rndm.h" @@ -739,8 +740,50 @@ int Tutor7_Application::startNewShower() { return 0; } +extern "C" { + APP_EXPORT shared_ptr getAppSpecificInputs() { + shared_ptr tutor7Input = make_shared(); + shared_ptr scoreBlock = tutor7Input->addBlockInput("scoring options"); + scoreBlock->setAppName("tutor7pp"); + + // not sure about the inputs for scale xcc and scale bc + scoreBlock->addSingleInput("scale xcc", false, "2 values"); + scoreBlock->addSingleInput("scale bc", false, "2 values"); + scoreBlock->addSingleInput("deflect electron after brems", false, "yes or no", {"yes", "no"}); + scoreBlock->addSingleInput("Russian Roulette", false, "survival probability is 1/input"); + scoreBlock->addSingleInput("pulse height regions", false, "list of regions"); + scoreBlock->addSingleInput("pulse height bins", false, "list of bins"); + + return tutor7Input; + } + + APP_EXPORT string getAppSpecificExample() { + string example; + example = { + R"( +# tutor7pp example input +:start scoring options: + scale xcc = 1 + scale bc = 2 + deflect electron after brems = yes + Russian Roulette = 5 # survival probability is 1/5 + pulse height regions = 1 2 3 # a list of regions to score pulse height + # distributions + # how many bins to use for each pulse height + # distribution. This must be either a single + # input, in which case all pulse height + # distributions will use this number of bins, + # or the same number of inputs as pulse height + # regions. + pulse height bins = 100 +:stop scoring options: +)"}; + return example; + } +} + #ifdef BUILD_APP_LIB APP_LIB(Tutor7_Application); #else APP_MAIN(Tutor7_Application); -#endif +#endif \ No newline at end of file From a45213c221cd157e8e8fc5920137e5900e100c69 Mon Sep 17 00:00:00 2001 From: Xuan Zheng <91241583+Xuan-Zheng05@users.noreply.github.com> Date: Fri, 9 Aug 2024 23:39:28 -0400 Subject: [PATCH 34/40] Fixed hardcoded path to density correction files with system dependent path --- HEN_HOUSE/egs++/egs_application.h | 52 --------------------------- HEN_HOUSE/egs++/view/viewcontrol.cpp | 54 +++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index bdf874a91..8a79d84f9 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -65,54 +65,6 @@ class EGS_AusgabObject; class EGS_Interpolator; //template class EGS_SimpleContainer; -// Looks into \EGSnrc\HEN_HOUSE\pegs4\density_corrections\compounds for the density correction files -// returns a string vector of the file names -static vector findDensityCorrectionInputs() { - vector fileList; - #ifdef WIN32 - const char fs = '\\'; - #else - const char fs = '/'; - #endif - - string compound_dir = "C:"; - compound_dir += fs; - compound_dir += "EGSnrc"; - compound_dir += fs; - compound_dir += "HEN_HOUSE"; - compound_dir += fs; - compound_dir += "pegs4"; - compound_dir += fs; - compound_dir += "density_corrections"; - compound_dir += fs; - compound_dir += "compounds"; - - DIR *dir; - struct dirent *ent; - - if ((dir = opendir(compound_dir.c_str())) != NULL) { - while ((ent = readdir(dir)) != NULL) { - string filename = ent->d_name; - - // removes the .density at the end of the file - if (filename.find(".density") != string::npos) { - filename = filename.substr(0, filename.find(".density")); - fileList.push_back(filename); - } - } - closedir(dir); - } else { - egsInformation("Failed to open density correction files directory\n"); - } - - // egsInformation("Printing file titles \n"); - // for (const auto& file : fileList) { - // egsInformation("%s\n", file.c_str()); - // } - - return fileList; -} - static void addmcBlock(shared_ptr blockPtr) { shared_ptr mcBlock = blockPtr->addBlockInput("MC transport parameter"); mcBlock->addSingleInput("Global ECUT", false, "Global electron transport cutoff"); @@ -170,10 +122,6 @@ static void addMediaDefBlock(shared_ptr blockPtr) { mediumBlock->addSingleInput("stopping powers", false, "{restricted total, unrestricted collision, unrestricted collision and radiative, unrestricted collision and restricted radiative, restricted collision and unrestricted radiative, unrestricted radiative}"); mediumBlock->addSingleInput("bremsstrahlung correction", false, ""); mediumBlock->addSingleInput("gas pressure", false, ""); - - vector densityCorrectionFiles = findDensityCorrectionInputs(); - mediumBlock->addSingleInput("density correction file", false, "", densityCorrectionFiles); - mediumBlock->addSingleInput("e- stopping power output file", false, ""); } diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index f9d370945..d51720d61 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -67,6 +67,7 @@ #include #include #include +#include using namespace std; #ifndef M_PI @@ -110,6 +111,10 @@ static unsigned char standard_blue[] = { 0, 0, 191, 80, 127, 127, 192, 128 }; +// Looks into \EGSnrc\HEN_HOUSE\pegs4\density_corrections\compounds for the density correction files +// returns a string vector of the file names +vector findDensityCorrectionInputs(string compound_dir); + GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) : QMainWindow(parent) { setObjectName(name); @@ -314,7 +319,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // before this was a BlockInput, now it is a InputStruct shared_ptr app = getAppInputs(); - + if (app) { inputStruct->addBlockInputs(app->getBlockInputs()); @@ -387,6 +392,16 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) action->setData(QString::fromStdString(getExample())); connect(action, &QAction::triggered, this, [this] { insertInputExample(); }); } + + // Add the denstiy correction files + shared_ptr mediaBlockInput = inputStruct->getBlockInput("media definition"); + shared_ptr mediumBlock = mediaBlockInput->getBlockInput("pegsless"); + + string compound_dir; + EGS_Application::checkEnvironmentVar(appc,appv,"-H","--hen-house","HEN_HOUSE", compound_dir); + vector densityCorrectionFiles = findDensityCorrectionInputs(compound_dir); + + mediumBlock->addSingleInput("density correction file", false, "", densityCorrectionFiles); } // Geometry definition block @@ -3550,4 +3565,41 @@ void GeometryViewControl::setApplication() { selectedApplication = newlySelectedApp; egsinpEdit->setInputStruct(inputStruct); +} + +vector findDensityCorrectionInputs(string compound_dir) { + vector fileList; + + compound_dir += fs; + compound_dir += "pegs4"; + compound_dir += fs; + compound_dir += "density_corrections"; + compound_dir += fs; + compound_dir += "compounds"; + egsInformation("density file path: %s\n", compound_dir.c_str()); + + DIR *dir; + struct dirent *ent; + + if ((dir = opendir(compound_dir.c_str())) != NULL) { + while ((ent = readdir(dir)) != NULL) { + string filename = ent->d_name; + + // removes the .density at the end of the file + if (filename.find(".density") != string::npos) { + filename = filename.substr(0, filename.find(".density")); + fileList.push_back(filename); + } + } + closedir(dir); + } else { + egsInformation("Failed to open density correction files directory\n"); + } + + // egsInformation("Printing file titles \n"); + // for (const auto& file : fileList) { + // egsInformation("%s\n", file.c_str()); + // } + + return fileList; } \ No newline at end of file From 56e1cce0aa27091d33c7f724092ab30d4b1e0e08 Mon Sep 17 00:00:00 2001 From: Xuan Zheng <91241583+Xuan-Zheng05@users.noreply.github.com> Date: Tue, 13 Aug 2024 22:03:36 -0400 Subject: [PATCH 35/40] Fix pegless material autocompletion to work with any name --- HEN_HOUSE/egs++/egs_input_struct.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index 1cb8cee97..7d21b8bd2 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -200,7 +200,7 @@ vector> EGS_BlockInput::getSingleInputs() { } vector> EGS_BlockInput::getSingleInputs(string title) { - if (egsEquivStr(blockTitle, title) || + if (egsEquivStr(blockTitle, title) || (egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { return singleInputs; @@ -222,7 +222,7 @@ vector> EGS_BlockInput::getBlockInputs() { } vector> EGS_BlockInput::getBlockInputs(string title) { - if (egsEquivStr(this->getTitle(), title) || + if (egsEquivStr(blockTitle, title) || (egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { return blockInputs; @@ -259,7 +259,7 @@ shared_ptr EGS_BlockInput::getSingleInput(string inputTag) { shared_ptr EGS_BlockInput::getSingleInput(string inputTag, string title) { // First search the top-level input block - if (egsEquivStr(blockTitle, title) || + if (egsEquivStr(blockTitle, title) || (egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { for (auto &inp: singleInputs) { @@ -306,6 +306,10 @@ shared_ptr EGS_BlockInput::getBlockInput(string title) { } } + if(egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) { + return shared_from_this(); + } + return nullptr; } From d2b97b9565547653f9f2927d9ccb4a28e9f4ad04 Mon Sep 17 00:00:00 2001 From: Xuan Zheng <91241583+Xuan-Zheng05@users.noreply.github.com> Date: Thu, 22 Aug 2024 01:39:51 -0400 Subject: [PATCH 36/40] Fix incorrect example for media definition --- HEN_HOUSE/egs++/egs_application.h | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index 8a79d84f9..313de3f16 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -163,10 +163,11 @@ static string addMediaExample() { // Not completed yet, need to fill in numbers for example R"( :start media definition: - ae = 0.1 # lowest energy for electron production (kinetic+0.511) - ap = 0.1 # lowest energy for photon production (kinetic) - ue = 0.1 # maximum energy for electrons (kinetic+0.511) - up = 0.1 # maximum energy for photons (kinetic) + ae = 0.521 # lowest energy for electron production (kinetic+0.511) + ap = 0.01 # lowest energy for photon production (kinetic) + ue = 50.511 # maximum energy for electrons (kinetic+0.511) + up = 50 # maximum energy for photons (kinetic) # maximum energy for photons (kinetic) + :start pegsless: elements = number of atoms = @@ -179,19 +180,11 @@ static string addMediaExample() { density correction file = e- stopping power output file = :stop pegsless: -:stop media definition: - -# Here is an example for defining a material named water -:start media definition: - ae = 0.521 - ap = 0.01 - ue = 50.511 - up = 50 + # Here is an example for defining water :start water: density correction file = water_liquid.density :stop water: - :stop media definition: )"}; return example; From a509ab23db6bfbdda90031ac593b8cdfdc324533 Mon Sep 17 00:00:00 2001 From: Xuan Zheng <91241583+Xuan-Zheng05@users.noreply.github.com> Date: Fri, 30 Aug 2024 01:44:46 -0400 Subject: [PATCH 37/40] Fix autocomplete error from pegless material addition --- HEN_HOUSE/egs++/egs_input_struct.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index 7d21b8bd2..8457bbc5d 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -200,7 +200,7 @@ vector> EGS_BlockInput::getSingleInputs() { } vector> EGS_BlockInput::getSingleInputs(string title) { - if (egsEquivStr(blockTitle, title) || (egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || + if (egsEquivStr(blockTitle, title) || (parent != nullptr && egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { return singleInputs; @@ -222,7 +222,7 @@ vector> EGS_BlockInput::getBlockInputs() { } vector> EGS_BlockInput::getBlockInputs(string title) { - if (egsEquivStr(blockTitle, title) || (egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || + if (egsEquivStr(blockTitle, title) || (parent != nullptr && egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { return blockInputs; @@ -259,7 +259,7 @@ shared_ptr EGS_BlockInput::getSingleInput(string inputTag) { shared_ptr EGS_BlockInput::getSingleInput(string inputTag, string title) { // First search the top-level input block - if (egsEquivStr(blockTitle, title) || (egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || + if (egsEquivStr(blockTitle, title) || (parent != nullptr && egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { for (auto &inp: singleInputs) { @@ -306,9 +306,11 @@ shared_ptr EGS_BlockInput::getBlockInput(string title) { } } - if(egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) { - return shared_from_this(); + if(parent != nullptr && egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) { + return shared_from_this(); + } + return nullptr; } From efcfc4dacbb7415bb30c047cd50d3eeee261238f Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 8 Aug 2024 15:23:18 -0400 Subject: [PATCH 38/40] Fix egs_editor medium autocomplete --- HEN_HOUSE/egs++/egs_application.h | 61 ++++++++++++++++++++-- HEN_HOUSE/egs++/egs_input_struct.cpp | 16 ++++-- HEN_HOUSE/egs++/egs_rndm.h | 2 +- HEN_HOUSE/egs++/view/egs_editor.cpp | 13 ++--- HEN_HOUSE/egs++/view/viewcontrol.cpp | 38 +++++++------- HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp | 4 +- 6 files changed, 97 insertions(+), 37 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index 313de3f16..074df656f 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -65,6 +65,54 @@ class EGS_AusgabObject; class EGS_Interpolator; //template class EGS_SimpleContainer; +// Looks into \EGSnrc\HEN_HOUSE\pegs4\density_corrections\compounds for the density correction files +// returns a string vector of the file names +static vector findDensityCorrectionInputs() { + vector fileList; + #ifdef WIN32 + const char fs = '\\'; + #else + const char fs = '/'; + #endif + + string compound_dir = "C:"; + compound_dir += fs; + compound_dir += "EGSnrc"; + compound_dir += fs; + compound_dir += "HEN_HOUSE"; + compound_dir += fs; + compound_dir += "pegs4"; + compound_dir += fs; + compound_dir += "density_corrections"; + compound_dir += fs; + compound_dir += "compounds"; + + DIR *dir; + struct dirent *ent; + + if ((dir = opendir(compound_dir.c_str())) != NULL) { + while ((ent = readdir(dir)) != NULL) { + string filename = ent->d_name; + + // removes the .density at the end of the file + if (filename.find(".density") != string::npos) { + filename = filename.substr(0, filename.find(".density")); + fileList.push_back(filename); + } + } + closedir(dir); + } else { + egsInformation("Failed to open density correction files directory\n"); + } + + // egsInformation("Printing file titles \n"); + // for (const auto& file : fileList) { + // egsInformation("%s\n", file.c_str()); + // } + + return fileList; +} + static void addmcBlock(shared_ptr blockPtr) { shared_ptr mcBlock = blockPtr->addBlockInput("MC transport parameter"); mcBlock->addSingleInput("Global ECUT", false, "Global electron transport cutoff"); @@ -113,7 +161,7 @@ static void addMediaDefBlock(shared_ptr blockPtr) { mediaBlockInput->addSingleInput("ue", false, "maximum energy for electrons (kinetic+0.511)"); mediaBlockInput->addSingleInput("up", false, "maximum energy for photons (kinetic)"); - shared_ptr mediumBlock = mediaBlockInput->addBlockInput("pegsless"); + shared_ptr mediumBlock = mediaBlockInput->addBlockInput("myMediumName"); mediumBlock->addSingleInput("elements", false, ""); mediumBlock->addSingleInput("number of atoms", false, ""); mediumBlock->addSingleInput("mass fractions", false, ""); @@ -122,6 +170,10 @@ static void addMediaDefBlock(shared_ptr blockPtr) { mediumBlock->addSingleInput("stopping powers", false, "{restricted total, unrestricted collision, unrestricted collision and radiative, unrestricted collision and restricted radiative, restricted collision and unrestricted radiative, unrestricted radiative}"); mediumBlock->addSingleInput("bremsstrahlung correction", false, ""); mediumBlock->addSingleInput("gas pressure", false, ""); + + vector densityCorrectionFiles = findDensityCorrectionInputs(); + mediumBlock->addSingleInput("density correction file", false, "", densityCorrectionFiles); + mediumBlock->addSingleInput("e- stopping power output file", false, ""); } @@ -168,7 +220,7 @@ static string addMediaExample() { ue = 50.511 # maximum energy for electrons (kinetic+0.511) up = 50 # maximum energy for photons (kinetic) # maximum energy for photons (kinetic) - :start pegsless: + :start myMediumName: elements = number of atoms = mass fractions = @@ -179,12 +231,13 @@ static string addMediaExample() { gas pressure = density correction file = e- stopping power output file = - :stop pegsless: + :stop myMediumName: # Here is an example for defining water :start water: density correction file = water_liquid.density :stop water: + :stop media definition: )"}; return example; @@ -1378,4 +1431,4 @@ class EGS_EXPORT EGS_Application { }\ }\ -#endif \ No newline at end of file +#endif diff --git a/HEN_HOUSE/egs++/egs_input_struct.cpp b/HEN_HOUSE/egs++/egs_input_struct.cpp index 8457bbc5d..28cc2563b 100644 --- a/HEN_HOUSE/egs++/egs_input_struct.cpp +++ b/HEN_HOUSE/egs++/egs_input_struct.cpp @@ -62,7 +62,7 @@ void EGS_InputStruct::removeBlockInput(string title) { auto it = blockInputs.begin(); while (it != blockInputs.end()) { if ((*it)->getTitle() == title) { - it = blockInputs.erase(it); + it = blockInputs.erase(it); } else { ++it; } @@ -73,7 +73,7 @@ void EGS_InputStruct::removeBlockInputByApp(string appName) { auto it = blockInputs.begin(); while (it != blockInputs.end()) { if ((*it)->getAppName() == appName) { - it = blockInputs.erase(it); + it = blockInputs.erase(it); } else { ++it; } @@ -184,7 +184,7 @@ shared_ptr EGS_BlockInput::addSingleInput(string inputTag, bool shared_ptr EGS_BlockInput::addBlockInput(string blockTit, bool isReq) { blockInputs.push_back(make_shared(blockTit, isReq, shared_from_this())); - + return blockInputs.back(); } @@ -202,7 +202,10 @@ vector> EGS_BlockInput::getSingleInputs() { vector> EGS_BlockInput::getSingleInputs(string title) { if (egsEquivStr(blockTitle, title) || (parent != nullptr && egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". - (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { + (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape"))) || + // Handle the special case where material names match any block title + (egsEquivStr(blockTitle, "myMediumName")) + ) { return singleInputs; } else { @@ -261,7 +264,10 @@ shared_ptr EGS_BlockInput::getSingleInput(string inputTag, stri // First search the top-level input block if (egsEquivStr(blockTitle, title) || (parent != nullptr && egsEquivStr(parent->getTitle(), "media definition") && egsEquivStr(blockTitle, "pegsless")) || // Handle the special case where "target shape" and "source shape" for egs_collimated_source need to match just "shape". - (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape")))) { + (egsEquivStr(blockTitle, "shape") && (egsEquivStr(title, "target shape") || egsEquivStr(title, "source shape"))) || + // Handle the special case where material names match any block title + (egsEquivStr(blockTitle, "myMediumName")) + ) { for (auto &inp: singleInputs) { // TODO: this assumes unique inputTag if (inp && egsEquivStr(inp->getTag(), inputTag)) { diff --git a/HEN_HOUSE/egs++/egs_rndm.h b/HEN_HOUSE/egs++/egs_rndm.h index b8fe252ac..28b5f7df1 100644 --- a/HEN_HOUSE/egs++/egs_rndm.h +++ b/HEN_HOUSE/egs++/egs_rndm.h @@ -47,7 +47,7 @@ class EGS_Input; static void addRngDefinitionBlock(shared_ptr blockPtr) { shared_ptr rngBlock = blockPtr->addBlockInput("rng definition"); rngBlock->addSingleInput("type", true, "Generator type (Only ranmar)"); - rngBlock->addSingleInput("inital seeds", true, "Two integers that represent the inital seed"); + rngBlock->addSingleInput("initial seeds", true, "Two integers that represent the inital seed"); rngBlock->addSingleInput("high resolution", false, "Default is no", {"No", "Yes"}); } diff --git a/HEN_HOUSE/egs++/view/egs_editor.cpp b/HEN_HOUSE/egs++/view/egs_editor.cpp index 52dfef164..6f50ac386 100644 --- a/HEN_HOUSE/egs++/view/egs_editor.cpp +++ b/HEN_HOUSE/egs++/view/egs_editor.cpp @@ -570,7 +570,8 @@ void EGS_Editor::autoComplete() { format.setUnderlineStyle(QTextCharFormat::NoUnderline); auto inputPtr = inputBlockTemplate->getBlockInput(blockTit.toStdString()); - if (!inputPtr) { + // Don't do a red highlight if it's a material name, since they can be named anything + if (!inputPtr && !egsEquivStr(inputBlockTemplate->getTitle(), "myMediumName")) { // Red underline the input tag // Select the input tag selection.cursor.movePosition(QTextCursor::StartOfBlock); @@ -666,11 +667,11 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC bool foundTag; QString library = getInputValue("library", cursor.block(), foundTag); - // egsInformation("Printing parentBlockTitle: %s\n", parentTitle.toLatin1().data()); +// egsInformation("Printing parentBlockTitle: %s\n", parentTitle.toLatin1().data()); // If the parent block is media definition, then just return pegsless if (parentTitle.toStdString() == "media definition") { - shared_ptr inputBlock = inputStruct->getBlockInput("media definition")->getBlockInput("pegsless"); - egsInformation("Input Block title test: %s\n", inputBlock->getTitle().c_str()); + shared_ptr inputBlock = inputStruct->getBlockInput("media definition")->getBlockInput("myMediumName"); +// egsInformation("Input Block title test: %s\n", inputBlock->getTitle().c_str()); return inputBlock; } @@ -690,7 +691,7 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC while (blockEnd.text().contains(":start ")) { blockEnd = getBlockEnd(blockEnd.next()); if (++i > loopGuard) { - egsInformation("Warning: Encountered infinite loop while processing the input file. Contact the developers to report this bug.\n"); + egsInformation("Warning: Encountered infinite loop (i>%d) while processing the input file. Contact the developers to report this bug.\n", loopGuard); break; } if (blockEnd.isValid()) { @@ -718,7 +719,7 @@ shared_ptr EGS_Editor::getBlockInput(QString &blockTitle, QTextC while (blockEnd.text().contains(":start ")) { blockEnd = getBlockEnd(blockEnd.next()); if (++i > loopGuard) { - egsInformation("Warning: Encountered infinite loop while processing the input file. Contact the developers to report this bug.\n"); + egsInformation("Warning: Encountered infinite loop (i>%d) while processing the input file. Contact the developers to report this bug.\n", loopGuard); break; } if (blockEnd.isValid()) { diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index d51720d61..f91303c87 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -290,8 +290,8 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) QMenu *exampleMenu2 = new QMenu("Choose application"); menuBar->addMenu(exampleMenu2); - QAction *action = exampleMenu2->addAction("none"); - action->setData("none"); + QAction *action = exampleMenu2->addAction("None"); + action->setData("None"); connect(action, &QAction::triggered, this, [this] { setApplication(); }); for (const auto &lib : binLibraries) { @@ -319,7 +319,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // before this was a BlockInput, now it is a InputStruct shared_ptr app = getAppInputs(); - + if (app) { inputStruct->addBlockInputs(app->getBlockInputs()); @@ -332,19 +332,19 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // // } // } - // vector> inputBlocks = app->getBlockInputs(); - // for (auto &block : inputBlocks) { - // egsInformation(" block %s\n", block->getTitle().c_str()); - // vector> singleInputs = block->getSingleInputs(); - // inputStruct->addBlockInput(block); - // for (auto &inp : singleInputs) { - // const vector vals = inp->getValues(); - // egsInformation(" single %s\n", inp->getTag().c_str()); - // for (auto&& val : vals) { - // egsInformation(" %s\n", val.c_str()); - // } - // } - // } +// vector> inputBlocks = app->getBlockInputs(); +// for (auto &block : inputBlocks) { +// egsInformation(" block %s\n", block->getTitle().c_str()); +// vector> singleInputs = block->getSingleInputs(); +// inputStruct->addBlockInput(block); +// for (auto &inp : singleInputs) { +// const vector vals = inp->getValues(); +// egsInformation(" single %s\n", inp->getTag().c_str()); +// for (auto&& val : vals) { +// egsInformation(" %s\n", val.c_str()); +// } +// } +// } } } // getAppInputs(inputStruct); @@ -3535,11 +3535,11 @@ void GeometryViewControl::setApplication() { } else { getAppInputsFunction getAppInputs = (getAppInputsFunction) app_lib.resolve("getAppSpecificInputs"); egsInformation("getAppInputs %s\n", getAppInputs ? "true" : "false"); - + if (getAppInputs) { shared_ptr app = getAppInputs(); if (app) { - inputStruct->addBlockInputs(app->getBlockInputs()); + inputStruct->addBlockInputs(app->getBlockInputs()); } } @@ -3602,4 +3602,4 @@ vector findDensityCorrectionInputs(string compound_dir) { // } return fileList; -} \ No newline at end of file +} diff --git a/HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp b/HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp index 2d388d5f7..d010d5771 100644 --- a/HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp +++ b/HEN_HOUSE/user_codes/tutor7pp/tutor7pp.cpp @@ -765,7 +765,7 @@ extern "C" { :start scoring options: scale xcc = 1 scale bc = 2 - deflect electron after brems = yes + deflect electron after brems = yes Russian Roulette = 5 # survival probability is 1/5 pulse height regions = 1 2 3 # a list of regions to score pulse height # distributions @@ -786,4 +786,4 @@ extern "C" { APP_LIB(Tutor7_Application); #else APP_MAIN(Tutor7_Application); -#endif \ No newline at end of file +#endif From 59ea11248b9f11581c464982b4e3801e479e6b50 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 8 Aug 2024 15:29:46 -0400 Subject: [PATCH 39/40] Fix make clean of application library objects --- HEN_HOUSE/makefiles/cpp_makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HEN_HOUSE/makefiles/cpp_makefile b/HEN_HOUSE/makefiles/cpp_makefile index 322c06286..58419fb01 100644 --- a/HEN_HOUSE/makefiles/cpp_makefile +++ b/HEN_HOUSE/makefiles/cpp_makefile @@ -117,6 +117,6 @@ $(user_objects): clean: $(REMOVE) mortjob.mortran egsnrc_$(my_machine).F egsnrc_$(my_machine).mortlst - $(REMOVE) $(target) $(user_objects) $(egs_objects) + $(REMOVE) $(target) $(user_objects) $(user_lib_objects) $(egs_objects) $(egs_lib_objects) .PHONY: clean library From 99e2cbb9370d22a17deb2208b8c8eb292d7b1be3 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 17 Sep 2024 15:44:19 -0400 Subject: [PATCH 40/40] Tidy up merge with branch from Xuan --- HEN_HOUSE/egs++/egs_application.h | 52 ---------------------------- HEN_HOUSE/egs++/view/viewcontrol.cpp | 4 +-- 2 files changed, 2 insertions(+), 54 deletions(-) diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index 074df656f..10d087a90 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -65,54 +65,6 @@ class EGS_AusgabObject; class EGS_Interpolator; //template class EGS_SimpleContainer; -// Looks into \EGSnrc\HEN_HOUSE\pegs4\density_corrections\compounds for the density correction files -// returns a string vector of the file names -static vector findDensityCorrectionInputs() { - vector fileList; - #ifdef WIN32 - const char fs = '\\'; - #else - const char fs = '/'; - #endif - - string compound_dir = "C:"; - compound_dir += fs; - compound_dir += "EGSnrc"; - compound_dir += fs; - compound_dir += "HEN_HOUSE"; - compound_dir += fs; - compound_dir += "pegs4"; - compound_dir += fs; - compound_dir += "density_corrections"; - compound_dir += fs; - compound_dir += "compounds"; - - DIR *dir; - struct dirent *ent; - - if ((dir = opendir(compound_dir.c_str())) != NULL) { - while ((ent = readdir(dir)) != NULL) { - string filename = ent->d_name; - - // removes the .density at the end of the file - if (filename.find(".density") != string::npos) { - filename = filename.substr(0, filename.find(".density")); - fileList.push_back(filename); - } - } - closedir(dir); - } else { - egsInformation("Failed to open density correction files directory\n"); - } - - // egsInformation("Printing file titles \n"); - // for (const auto& file : fileList) { - // egsInformation("%s\n", file.c_str()); - // } - - return fileList; -} - static void addmcBlock(shared_ptr blockPtr) { shared_ptr mcBlock = blockPtr->addBlockInput("MC transport parameter"); mcBlock->addSingleInput("Global ECUT", false, "Global electron transport cutoff"); @@ -170,10 +122,6 @@ static void addMediaDefBlock(shared_ptr blockPtr) { mediumBlock->addSingleInput("stopping powers", false, "{restricted total, unrestricted collision, unrestricted collision and radiative, unrestricted collision and restricted radiative, restricted collision and unrestricted radiative, unrestricted radiative}"); mediumBlock->addSingleInput("bremsstrahlung correction", false, ""); mediumBlock->addSingleInput("gas pressure", false, ""); - - vector densityCorrectionFiles = findDensityCorrectionInputs(); - mediumBlock->addSingleInput("density correction file", false, "", densityCorrectionFiles); - mediumBlock->addSingleInput("e- stopping power output file", false, ""); } diff --git a/HEN_HOUSE/egs++/view/viewcontrol.cpp b/HEN_HOUSE/egs++/view/viewcontrol.cpp index f91303c87..e3b5789c9 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.cpp +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -395,7 +395,7 @@ GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) // Add the denstiy correction files shared_ptr mediaBlockInput = inputStruct->getBlockInput("media definition"); - shared_ptr mediumBlock = mediaBlockInput->getBlockInput("pegsless"); + shared_ptr mediumBlock = mediaBlockInput->getBlockInput("myMediumName"); string compound_dir; EGS_Application::checkEnvironmentVar(appc,appv,"-H","--hen-house","HEN_HOUSE", compound_dir); @@ -3580,7 +3580,7 @@ vector findDensityCorrectionInputs(string compound_dir) { DIR *dir; struct dirent *ent; - + if ((dir = opendir(compound_dir.c_str())) != NULL) { while ((ent = readdir(dir)) != NULL) { string filename = ent->d_name;