From 3c4b0216979812b8ee1cfd3e4bfa98f19b2ea944 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Sat, 3 Aug 2019 09:01:04 -0400 Subject: [PATCH 01/32] 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 619662264..ff38cc36a 100644 --- a/HEN_HOUSE/egs++/Makefile +++ b/HEN_HOUSE/egs++/Makefile @@ -43,7 +43,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 @@ -74,7 +74,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) @@ -86,6 +86,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) @@ -132,6 +135,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 e638e843f..302bed01b 100644 --- a/HEN_HOUSE/egs++/egs_application.cpp +++ b/HEN_HOUSE/egs++/egs_application.cpp @@ -100,6 +100,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 c7842f38b..c4fdacf22 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; @@ -1190,6 +1192,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 9bfed973b..6a37232e0 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -43,10 +43,12 @@ #define EGS_BASE_GEOMETRY_ #include "egs_vector.h" +#include "egs_input_struct.h" #include #include #include +#include using std::string; using std::vector; @@ -71,6 +73,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 32b9a6390..7324503a6 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -36,6 +36,7 @@ #include "egs_box.h" #include "egs_input.h" +#include "egs_base_geometry.h" void EGS_Box::printInfo() const { EGS_BaseGeometry::printInfo(); @@ -43,7 +44,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?"; @@ -52,19 +54,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) { @@ -89,5 +128,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 5170608d4..1347f5e3b 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 af1a8c9ce..9108ee965 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -37,11 +37,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 @@ -50,7 +54,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 } @@ -58,7 +62,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 { @@ -66,13 +70,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 13c7d0e76..330dc11c0 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -38,6 +38,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 @@ -84,6 +87,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); @@ -143,6 +147,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: @@ -199,7 +205,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 bec3933d2..426afb660 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui +++ b/HEN_HOUSE/egs++/view/viewcontrol.ui @@ -65,7 +65,7 @@ 0 - + 0 @@ -91,7 +91,7 @@ 0 0 671 - 563 + 567 @@ -116,7 +116,7 @@ - 0 + 4 @@ -155,7 +155,7 @@ - Simulation geometry + View geometry @@ -431,6 +431,14 @@ true + + + 0 + 0 + 297 + 189 + + @@ -1638,15 +1646,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> @@ -1657,6 +1665,61 @@ p, li { white-space: pre-wrap; } + + + + 0 + 0 + + + + Editor + + + + + + + + QLayout::SetMaximumSize + + + + + + 0 + 0 + + + + Insert template: + + + + + + + + Geometry + + + + + + + + + Simulation + + + + + + + + + + @@ -1673,7 +1736,7 @@ p, li { white-space: pre-wrap; } 0 0 675 - 25 + 21 @@ -1685,6 +1748,7 @@ p, li { white-space: pre-wrap; } + @@ -1704,7 +1768,7 @@ p, li { white-space: pre-wrap; } - &Open... + &Open egsinp... Ctrl+O @@ -1720,7 +1784,7 @@ p, li { white-space: pre-wrap; } - Save &image... + Save &image Ctrl+I @@ -1728,10 +1792,10 @@ p, li { white-space: pre-wrap; } - &Save settings... + Save settin&gs - Ctrl+S + Ctrl+G @@ -1768,7 +1832,7 @@ p, li { white-space: pre-wrap; } - Open &dose... + Open 3d&dose... Ctrl+D @@ -1776,12 +1840,20 @@ p, li { white-space: pre-wrap; } - Open trac&ks... + Open ptrac&ks... Ctrl+K + + + &Save egsinp + + + Ctrl+S + + @@ -2174,6 +2246,22 @@ p, li { white-space: pre-wrap; } + + actionSave_egsinp + triggered() + GeometryViewControl + saveEgsinp() + + + -1 + -1 + + + 20 + 20 + + + showPhotonsCheckbox toggled(bool) @@ -2398,6 +2486,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 b078a07627b96fa41f7038f4eacc356158e23c2d Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 13 Dec 2019 11:30:39 -0500 Subject: [PATCH 02/32] 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 330dc11c0..889af457c 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -210,6 +210,7 @@ public slots: EGS_Editor *egsinpEdit; EGS_Highlighter *highlighter; EGS_AdvancedApplication *egsApp; + shared_ptr inputStruct; protected slots: From 94ef2bda9ac531a29ce5bd745c6719effaba8327 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Sat, 3 Aug 2019 09:01:04 -0400 Subject: [PATCH 03/32] 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 889af457c..330dc11c0 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -210,7 +210,6 @@ public slots: EGS_Editor *egsinpEdit; EGS_Highlighter *highlighter; EGS_AdvancedApplication *egsApp; - shared_ptr inputStruct; protected slots: From b026cbff974cf50f5c6f5785370eca1673c48b01 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 13 Dec 2019 11:30:39 -0500 Subject: [PATCH 04/32] 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 a9dfcc3399789b0b303af38cd10a406083300a21 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 4 Feb 2020 12:22:03 -0500 Subject: [PATCH 05/32] 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 6a37232e0..53cfdbcaa 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -75,9 +75,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 7324503a6..cef832491 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -54,17 +54,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; } @@ -79,8 +79,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() { @@ -96,8 +112,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 718853b39..97b46ec5a 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 @@ -46,7 +46,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" @@ -110,6 +129,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"); @@ -120,16 +172,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 330dc11c0..248ec4cd0 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -205,6 +205,7 @@ public slots: energyScaling; vector> scoreArrays; vector geometryNames; + vector geomExamples; vector> geomTemplates; EGS_BaseGeometry *origSimGeom; EGS_Editor *egsinpEdit; From 426dadfc86f1275877ef863d142105d40742e3b3 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Sat, 22 Feb 2020 09:27:19 -0500 Subject: [PATCH 06/32] 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 53cfdbcaa..c44c0e7df 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -74,11 +74,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 cef832491..8f9a314f7 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Frederic Tessier +# 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 97b46ec5a..619415b0d 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 @@ -25,6 +25,7 @@ # # Contributors: Frederic Tessier # Ernesto Mainegra-Hing +# Reid Townson # ############################################################################### */ @@ -51,22 +52,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"); @@ -132,11 +117,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() { @@ -173,20 +161,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 b58ec5d8c..446aef559 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Frederic Tessier +# Reid Townson # ############################################################################### */ @@ -49,6 +50,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) { @@ -244,6 +247,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 20d2a2ee811b3be2d99b43e6709cc9b0f9cd3359 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 13 Mar 2020 15:24:49 -0400 Subject: [PATCH 07/32] 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 8f9a314f7..272a4a9f1 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -81,8 +81,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 619415b0d..678788034 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,11 +120,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 446aef559..72c747817 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -253,42 +253,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; @@ -364,7 +443,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 7dd58d2cbdeee1e94a641cb74ab29ee0a68a653a Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 13 Mar 2020 16:28:52 -0400 Subject: [PATCH 08/32] 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 c44c0e7df..512fb2a8f 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -75,6 +75,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 272a4a9f1..d4be23062 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -80,8 +80,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 678788034..6f9785079 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 @@ -119,9 +119,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 72c747817..765c77a69 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -252,8 +252,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 115d583e79f08d2ca4b03a88f0b2733478e5fcc0 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 31 Mar 2020 11:32:26 -0400 Subject: [PATCH 09/32] 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 ff38cc36a..d8711d8df 100644 --- a/HEN_HOUSE/egs++/Makefile +++ b/HEN_HOUSE/egs++/Makefile @@ -74,7 +74,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) @@ -86,8 +87,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) @@ -133,7 +134,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 512fb2a8f..c1c09fee6 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -73,13 +73,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 392eed3d8..ecb085131 100644 --- a/HEN_HOUSE/egs++/egs_base_source.h +++ b/HEN_HOUSE/egs++/egs_base_source.h @@ -43,6 +43,7 @@ #include "egs_vector.h" #include "egs_object_factory.h" #include "egs_functions.h" +#include "egs_input_struct.h" #include #include @@ -53,6 +54,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 dbefb21b0..4b962a2e8 100644 --- a/HEN_HOUSE/egs++/egs_shapes.h +++ b/HEN_HOUSE/egs++/egs_shapes.h @@ -41,12 +41,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 4b92109a5..462647051 100644 --- a/HEN_HOUSE/egs++/egs_spectra.cpp +++ b/HEN_HOUSE/egs++/egs_spectra.cpp @@ -374,10 +374,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 d4be23062..99a22e821 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -65,7 +65,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; } @@ -80,10 +80,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() { @@ -105,7 +105,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 6f9785079..edb94f59f 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 @@ -119,12 +119,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() { @@ -147,7 +147,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 765c77a69..562886ab8 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -252,20 +252,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."); @@ -273,23 +273,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) { @@ -378,7 +378,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 97cd94cbd..2e9f9baa8 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 @@ -25,6 +25,7 @@ # # Contributors: Long Zhang # Hubert Ho +# Reid Townson # ############################################################################### */ @@ -39,6 +40,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), @@ -149,6 +153,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 248ec4cd0..76d9664ea 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -206,7 +206,7 @@ public slots: vector> scoreArrays; vector geometryNames; vector geomExamples; - vector> geomTemplates; + vector sourceExamples; EGS_BaseGeometry *origSimGeom; EGS_Editor *egsinpEdit; EGS_Highlighter *highlighter; From 635712930e13c2845d063b6472dc99417483e587 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Fri, 3 Apr 2020 14:42:24 -0400 Subject: [PATCH 10/32] 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 76d9664ea..5ac509fcc 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -147,8 +147,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: @@ -205,12 +204,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 426afb660..a9bc7297b 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui +++ b/HEN_HOUSE/egs++/view/viewcontrol.ui @@ -1675,50 +1675,7 @@ p, li { white-space: pre-wrap; } Editor - - - - - - - QLayout::SetMaximumSize - - - - - - 0 - 0 - - - - Insert template: - - - - - - - - Geometry - - - - - - - - - Simulation - - - - - - - - - + @@ -2486,38 +2443,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 8e6da9a72fbcb297536afa79b31c0a7edaed8a11 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Wed, 13 May 2020 16:11:12 -0400 Subject: [PATCH 11/32] 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 4b962a2e8..8f870cce6 100644 --- a/HEN_HOUSE/egs++/egs_shapes.h +++ b/HEN_HOUSE/egs++/egs_shapes.h @@ -49,7 +49,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 2e9f9baa8..00c427bbd 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 @@ -163,7 +163,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 aac039ee3541a060f8356c8ed867178c6f7bac23 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 7 Jul 2020 12:06:15 -0400 Subject: [PATCH 12/32] 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 8f870cce6..64bf75805 100644 --- a/HEN_HOUSE/egs++/egs_shapes.h +++ b/HEN_HOUSE/egs++/egs_shapes.h @@ -74,6 +74,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 dac540615..aeb49e167 100644 --- a/HEN_HOUSE/egs++/egs_transformations.h +++ b/HEN_HOUSE/egs++/egs_transformations.h @@ -43,6 +43,7 @@ #include "egs_libconfig.h" #include "egs_math.h" #include "egs_functions.h" +#include "egs_input_struct.h" #include @@ -50,6 +51,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 23ff8239c07c622aad981ff4c4cd88bfbb77c41f Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Mon, 20 Jul 2020 10:21:15 -0400 Subject: [PATCH 13/32] 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 302bed01b..d340ae448 100644 --- a/HEN_HOUSE/egs++/egs_application.cpp +++ b/HEN_HOUSE/egs++/egs_application.cpp @@ -43,7 +43,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 c4fdacf22..867175eb9 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 @@ -1220,6 +1221,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 c1c09fee6..c27170d0d 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -81,7 +81,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 b27d66c49..a0fad9ed4 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -40,6 +40,7 @@ #include "egs_libconfig.h" #include "egs_timer.h" +#include "egs_input_struct.h" #include using namespace std; @@ -47,6 +48,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 64bf75805..4a1d0f06e 100644 --- a/HEN_HOUSE/egs++/egs_shapes.h +++ b/HEN_HOUSE/egs++/egs_shapes.h @@ -57,13 +57,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"); @@ -71,9 +71,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 9108ee965..4d6f56b9a 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -54,7 +54,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 } @@ -62,7 +62,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 { @@ -70,13 +70,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 797b6f47c14cb8dd2701f5b18d2c19f17d221bb8 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 23 Jul 2020 11:15:55 -0400 Subject: [PATCH 14/32] 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 867175eb9..b1c97ee16 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -1221,12 +1221,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 a0fad9ed4..4b6ea6e69 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -48,7 +48,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 0213a4e7992393ab8678cb5b8dbb790af5408a6b Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 30 Jul 2020 09:42:46 -0400 Subject: [PATCH 15/32] 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 7e30d5af27b764a3ab481730956d6e6e239b283c Mon Sep 17 00:00:00 2001 From: Gallop Date: Tue, 2 Feb 2021 13:52:41 -0500 Subject: [PATCH 16/32] 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 | 29 +- .../geometry/egs_cylinders/egs_cylinders.cpp | 64 ++ .../egs_elliptic_cylinders.cpp | 34 +- .../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 | 913 ++++++++++-------- .../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, 1350 insertions(+), 402 deletions(-) diff --git a/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp b/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp index c46d9d501..575472472 100644 --- a/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp @@ -70,6 +70,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) : @@ -803,7 +804,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) { @@ -933,6 +934,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 8832242b1..8167c8f11 100644 --- a/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -37,8 +37,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 77095519a..1dd8d6490 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Frederic Tessier +# Hannah Gallop # ############################################################################### */ @@ -37,8 +38,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 f98b537e0..8140120e2 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 @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2006 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### # @@ -44,10 +44,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 f94a7f468..87aa01264 100644 --- a/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp @@ -25,6 +25,7 @@ # # Contributors: Frederic Tessier # Ernesto Mainegra-Hing +# Hannah Gallop # ############################################################################### */ @@ -46,6 +47,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"); @@ -358,6 +361,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 ef48af04a..e7505aa9f 100644 --- a/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Marc Chamberland # Ernesto Mainegra-Hing +# Hannah Gallop # ############################################################################### */ @@ -43,6 +44,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: " @@ -122,6 +125,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 f22ba9055..d7de5c544 100644 --- a/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Ernesto Mainegra-Hing # Hubert Ho +# Hannah Gallop # ############################################################################### */ @@ -41,6 +42,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"); @@ -68,6 +71,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 523028c22..6f5e72828 100644 --- a/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Frederic Tessier +# Hannah Gallop # ############################################################################### */ @@ -47,6 +48,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) { @@ -257,6 +260,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 8daf2ca5a..22a2a934a 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 @@ -28,6 +28,7 @@ # Ernesto Mainegra-Hing # Hubert Ho # Randle Taylor +# Hannah Gallop # ############################################################################### */ @@ -1076,494 +1077,634 @@ 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 const static char *func = "createGeometry(XYZ)"; - string type; - int is_xyz = input->getInput("type",type); - if (!is_xyz && input->compare("EGS_XYZRepeater",type)) { - string base,medium; - vector xr, yr, zr; - int err1 = input->getInput("repeated geometry",base); - int err2 = input->getInput("repeat x",xr); - int err3 = input->getInput("repeat y",yr); - int err4 = input->getInput("repeat z",zr); - int err5 = input->getInput("medium",medium); - EGS_BaseGeometry *g = 0; - if (err1) { - egsWarning("%s: missing 'repeated geometry' input\n",err_msg1); - } - else { - g = EGS_BaseGeometry::getGeometry(base); - if (!g) { - egsWarning("%s: no geometry named %s exists\n",err_msg1, - base.c_str()); + string type; + int is_xyz = input->getInput("type",type); + if (!is_xyz && input->compare("EGS_XYZRepeater",type)) { + string base,medium; + vector xr, yr, zr; + int err1 = input->getInput("repeated geometry",base); + int err2 = input->getInput("repeat x",xr); + int err3 = input->getInput("repeat y",yr); + int err4 = input->getInput("repeat z",zr); + int err5 = input->getInput("medium",medium); + EGS_BaseGeometry *g = 0; + if (err1) { + egsWarning("%s: missing 'repeated geometry' input\n",err_msg1); + } + else { + g = EGS_BaseGeometry::getGeometry(base); + if (!g) { + egsWarning("%s: no geometry named %s exists\n",err_msg1, + base.c_str()); + err1 = 1; + } + } + if (err2 || xr.size() != 3) { err1 = 1; + egsWarning("%s: wrong/missing 'repeat x' input\n",err_msg1); } - } - if (err2 || xr.size() != 3) { - err1 = 1; - egsWarning("%s: wrong/missing 'repeat x' input\n",err_msg1); - } - if (err3 || yr.size() != 3) { - err1 = 1; - egsWarning("%s: wrong/missing 'repeat y' input\n",err_msg1); - } - if (err4 || zr.size() != 3) { - err1 = 1; - egsWarning("%s: wrong/missing 'repeat z' input\n",err_msg1); - } - if (err1) { - return 0; - } - EGS_Float xmin = xr[0], xmax = xr[1]; - int nx = (int)(xr[2]+0.1); - if (xmin >= xmax || nx < 1) { - egsWarning("%s: wrong 'repeat x' input xmin=%g xmax=%g nx=%d\n", - xmin,xmax,nx); - err1 = 1; - } - EGS_Float ymin = yr[0], ymax = yr[1]; - int ny = (int)(yr[2]+0.1); - if (ymin >= ymax || ny < 1) { - egsWarning("%s: wrong 'repeat y' input ymin=%g ymax=%g ny=%d\n", - ymin,ymax,ny); - err1 = 1; - } - EGS_Float zmin = zr[0], zmax = zr[1]; - int nz = (int)(zr[2]+0.1); - if (zmin >= zmax || nz < 1) { - egsWarning("%s: wrong 'repeat z' input zmin=%g zmax=%g nz=%d\n", - zmin,zmax,nz); - err1 = 1; - } - if (err1) { - return 0; - } - - EGS_XYZRepeater *result = - new EGS_XYZRepeater(xmin,xmax,ymin,ymax,zmin,zmax,nx,ny,nz,g); - result->setName(input); - result->setBoundaryTolerance(input); - if (!err5) { - result->setMedium(medium); - } - result->setXYZLabels(input); - result->setLabels(input); - return result; - } - else if (!is_xyz && input->compare("EGS_XYZGeometry",type)) { - string dens_file, ramp_file, egsphant_file, interfile_file; - int ierr1 = input->getInput("density matrix",dens_file); - int ierr2 = input->getInput("ct ramp",ramp_file); - int ierr3 = input->getInput("egsphant file",egsphant_file); - int ierr4 = input->getInput("interfile header",interfile_file); - int dens_or_egsphant_or_interfile = -1; - if (!ierr1) { - dens_or_egsphant_or_interfile = 0; - } - else if (!ierr3) { - dens_or_egsphant_or_interfile = 1; - dens_file = egsphant_file; - } - else if (!ierr4) { - dens_or_egsphant_or_interfile = 2; - dens_file = interfile_file; - } - if (dens_or_egsphant_or_interfile >= 0 || !ierr2) { - if (dens_or_egsphant_or_interfile < 0) { - egsWarning("%s: no 'density matrix', 'egsphant file' or 'interfile header' input\n",func); + if (err3 || yr.size() != 3) { + err1 = 1; + egsWarning("%s: wrong/missing 'repeat y' input\n",err_msg1); + } + if (err4 || zr.size() != 3) { + err1 = 1; + egsWarning("%s: wrong/missing 'repeat z' input\n",err_msg1); + } + if (err1) { return 0; } - if (ierr2) { - egsWarning("%s: no 'ct ramp' input\n",func); + EGS_Float xmin = xr[0], xmax = xr[1]; + int nx = (int)(xr[2]+0.1); + if (xmin >= xmax || nx < 1) { + egsWarning("%s: wrong 'repeat x' input xmin=%g xmax=%g nx=%d\n", + xmin,xmax,nx); + err1 = 1; + } + EGS_Float ymin = yr[0], ymax = yr[1]; + int ny = (int)(yr[2]+0.1); + if (ymin >= ymax || ny < 1) { + egsWarning("%s: wrong 'repeat y' input ymin=%g ymax=%g ny=%d\n", + ymin,ymax,ny); + err1 = 1; + } + EGS_Float zmin = zr[0], zmax = zr[1]; + int nz = (int)(zr[2]+0.1); + if (zmin >= zmax || nz < 1) { + egsWarning("%s: wrong 'repeat z' input zmin=%g zmax=%g nz=%d\n", + zmin,zmax,nz); + err1 = 1; + } + if (err1) { return 0; } - EGS_XYZGeometry *result = - EGS_XYZGeometry::constructGeometry(dens_file.c_str(),ramp_file.c_str(),dens_or_egsphant_or_interfile); - if (result) { - result->setName(input); - result->setBoundaryTolerance(input); - result->setBScaling(input); + EGS_XYZRepeater *result = + new EGS_XYZRepeater(xmin,xmax,ymin,ymax,zmin,zmax,nx,ny,nz,g); + result->setName(input); + result->setBoundaryTolerance(input); + if (!err5) { + result->setMedium(medium); } - + result->setXYZLabels(input); + result->setLabels(input); return result; } - vector xpos, ypos, zpos, xslab, yslab, zslab; - int ix = input->getInput("x-planes",xpos); - int iy = input->getInput("y-planes",ypos); - int iz = input->getInput("z-planes",zpos); - int ix1 = input->getInput("x-slabs",xslab); - int iy1 = input->getInput("y-slabs",yslab); - int iz1 = input->getInput("z-slabs",zslab); - int nx=0, ny=0, nz=0; - if (!ix1) { - if (xslab.size() != 3) { - egsWarning("createGeometry(XYZ): exactly 3 inputs are required" - " when using 'x-slabs' input method\n"); - ix1 = 1; + else if (!is_xyz && input->compare("EGS_XYZGeometry",type)) { + string dens_file, ramp_file, egsphant_file, interfile_file; + int ierr1 = input->getInput("density matrix",dens_file); + int ierr2 = input->getInput("ct ramp",ramp_file); + int ierr3 = input->getInput("egsphant file",egsphant_file); + int ierr4 = input->getInput("interfile header",interfile_file); + int dens_or_egsphant_or_interfile = -1; + if (!ierr1) { + dens_or_egsphant_or_interfile = 0; } - else { - nx = (int)(xslab[2]+0.1); - if (nx < 1) { - egsWarning("createGeometry(XYZ): number of slabs must be" - " positive!\n"); - ix1 = 1; + else if (!ierr3) { + dens_or_egsphant_or_interfile = 1; + dens_file = egsphant_file; + } + else if (!ierr4) { + dens_or_egsphant_or_interfile = 2; + dens_file = interfile_file; + } + if (dens_or_egsphant_or_interfile >= 0 || !ierr2) { + if (dens_or_egsphant_or_interfile < 0) { + egsWarning("%s: no 'density matrix', 'egsphant file' or 'interfile header' input\n",func); + return 0; } - if (xslab[1] <= 0) { - egsWarning("createGeometry(XYZ): slab thickness must be" - " positive!\n"); + if (ierr2) { + egsWarning("%s: no 'ct ramp' input\n",func); + return 0; + } + EGS_XYZGeometry *result = + EGS_XYZGeometry::constructGeometry(dens_file.c_str(),ramp_file.c_str(),dens_or_egsphant_or_interfile); + + if (result) { + result->setName(input); + result->setBoundaryTolerance(input); + result->setBScaling(input); + } + + return result; + } + vector xpos, ypos, zpos, xslab, yslab, zslab; + int ix = input->getInput("x-planes",xpos); + int iy = input->getInput("y-planes",ypos); + int iz = input->getInput("z-planes",zpos); + int ix1 = input->getInput("x-slabs",xslab); + int iy1 = input->getInput("y-slabs",yslab); + int iz1 = input->getInput("z-slabs",zslab); + int nx=0, ny=0, nz=0; + if (!ix1) { + if (xslab.size() != 3) { + egsWarning("createGeometry(XYZ): exactly 3 inputs are required" + " when using 'x-slabs' input method\n"); ix1 = 1; } + else { + nx = (int)(xslab[2]+0.1); + if (nx < 1) { + egsWarning("createGeometry(XYZ): number of slabs must be" + " positive!\n"); + ix1 = 1; + } + if (xslab[1] <= 0) { + egsWarning("createGeometry(XYZ): slab thickness must be" + " positive!\n"); + ix1 = 1; + } + } } - } - if (ix && ix1) { - egsWarning("createGeometry(XYZ): wrong/missing 'x-planes' " - "and 'x-slabs' input\n"); - return 0; - } - if (!iy1) { - if (yslab.size() != 3) { - egsWarning("createGeometry(XYZ): exactly 3 inputs are required" - " when using 'y-slabs' input method\n"); - iy1 = 1; + if (ix && ix1) { + egsWarning("createGeometry(XYZ): wrong/missing 'x-planes' " + "and 'x-slabs' input\n"); + return 0; } - else { - ny = (int)(yslab[2]+0.1); - if (ny < 1) { - egsWarning("createGeometry(XYZ): number of slabs must be" - " positive!\n"); + if (!iy1) { + if (yslab.size() != 3) { + egsWarning("createGeometry(XYZ): exactly 3 inputs are required" + " when using 'y-slabs' input method\n"); iy1 = 1; } - if (yslab[1] <= 0) { - egsWarning("createGeometry(XYZ): slab thickness must be" - " positive!\n"); - iy1 = 1; + else { + ny = (int)(yslab[2]+0.1); + if (ny < 1) { + egsWarning("createGeometry(XYZ): number of slabs must be" + " positive!\n"); + iy1 = 1; + } + if (yslab[1] <= 0) { + egsWarning("createGeometry(XYZ): slab thickness must be" + " positive!\n"); + iy1 = 1; + } } } - } - if (iy && iy1) { - egsWarning("createGeometry(XYZ): wrong/missing 'y-planes' " - "and 'y-slabs' input\n"); - return 0; - } - if (!iz1) { - if (zslab.size() != 3) { - egsWarning("createGeometry(XYZ): exactly 3 inputs are required" - " when using 'z-slabs' input method\n"); - iz1 = 1; + if (iy && iy1) { + egsWarning("createGeometry(XYZ): wrong/missing 'y-planes' " + "and 'y-slabs' input\n"); + return 0; } - else { - nz = (int)(zslab[2]+0.1); - if (nz < 1) { - egsWarning("createGeometry(XYZ): number of slabs must be" - " positive!\n"); + if (!iz1) { + if (zslab.size() != 3) { + egsWarning("createGeometry(XYZ): exactly 3 inputs are required" + " when using 'z-slabs' input method\n"); iz1 = 1; } - if (zslab[1] <= 0) { - egsWarning("createGeometry(XYZ): slab thickness must be" - " positive!\n"); - iz1 = 1; + else { + nz = (int)(zslab[2]+0.1); + if (nz < 1) { + egsWarning("createGeometry(XYZ): number of slabs must be" + " positive!\n"); + iz1 = 1; + } + if (zslab[1] <= 0) { + egsWarning("createGeometry(XYZ): slab thickness must be" + " positive!\n"); + iz1 = 1; + } } } - } - if (iz && iz1) { - egsWarning("createGeometry(XYZ): wrong/missing 'z-planes' " - "and 'z-slabs' input\n"); - return 0; - } - EGS_PlanesX *xp = !ix1 ? - new EGS_PlanesX(xslab[0],xslab[1],nx,"",EGS_XProjector("x-planes")) : - new EGS_PlanesX(xpos,"",EGS_XProjector("x-planes")); - EGS_PlanesY *yp = !iy1 ? - new EGS_PlanesY(yslab[0],yslab[1],ny,"",EGS_YProjector("y-planes")) : - new EGS_PlanesY(ypos,"",EGS_YProjector("y-planes")); - EGS_PlanesZ *zp = !iz1 ? - new EGS_PlanesZ(zslab[0],zslab[1],nz,"",EGS_ZProjector("z-planes")) : - new EGS_PlanesZ(zpos,"",EGS_ZProjector("z-planes")); - EGS_XYZGeometry *result = new EGS_XYZGeometry(xp,yp,zp); - - if (result) { - egsWarning("**********************************************\n"); - EGS_BaseGeometry *g = result; - result->setName(input); - result->setBoundaryTolerance(input); - g->setMedia(input); - result->voxelizeGeometry(input); + if (iz && iz1) { + egsWarning("createGeometry(XYZ): wrong/missing 'z-planes' " + "and 'z-slabs' input\n"); + return 0; + } + EGS_PlanesX *xp = !ix1 ? + new EGS_PlanesX(xslab[0],xslab[1],nx,"",EGS_XProjector("x-planes")) : + new EGS_PlanesX(xpos,"",EGS_XProjector("x-planes")); + EGS_PlanesY *yp = !iy1 ? + new EGS_PlanesY(yslab[0],yslab[1],ny,"",EGS_YProjector("y-planes")) : + new EGS_PlanesY(ypos,"",EGS_YProjector("y-planes")); + EGS_PlanesZ *zp = !iz1 ? + new EGS_PlanesZ(zslab[0],zslab[1],nz,"",EGS_ZProjector("z-planes")) : + new EGS_PlanesZ(zpos,"",EGS_ZProjector("z-planes")); + EGS_XYZGeometry *result = new EGS_XYZGeometry(xp,yp,zp); - // labels - result->setXYZLabels(input); - g->setLabels(input); + if (result) { + egsWarning("**********************************************\n"); + EGS_BaseGeometry *g = result; + result->setName(input); + result->setBoundaryTolerance(input); + g->setMedia(input); + result->voxelizeGeometry(input); + + // labels + result->setXYZLabels(input); + g->setLabels(input); + } + return result; } - return result; - } #endif - vector dims; - EGS_Input *ij; - int error = 0; - while ((ij = input->takeInputItem("geometry",false)) != 0) { - EGS_BaseGeometry *g = EGS_BaseGeometry::createSingleGeometry(ij); - if (g) { - dims.push_back(g); - g->ref(); - } - else { - error++; - } - delete ij; - } - vector gnames; - int err1 = input->getInput("dimensions",gnames); - if (!err1) { - for (unsigned int j=0; j dims; + EGS_Input *ij; + int error = 0; + while ((ij = input->takeInputItem("geometry",false)) != 0) { + EGS_BaseGeometry *g = EGS_BaseGeometry::createSingleGeometry(ij); if (g) { dims.push_back(g); g->ref(); } else { - egsWarning("Geometry %s does not exist\n",gnames[j].c_str()); error++; } + delete ij; + } + vector gnames; + int err1 = input->getInput("dimensions",gnames); + if (!err1) { + for (unsigned int j=0; jref(); + } + else { + egsWarning("Geometry %s does not exist\n",gnames[j].c_str()); + error++; + } + } } - } - if (error) { - egsWarning("createGeometry(ND_Geometry): %d errors while " - "creating/geting geometries defining individual dimensions\n",error); - return 0; - } - if (dims.size() < 2) { - egsWarning("createGeometry(ND_Geometry): why do you want to " - "construct a ND geometry with a single dimension?\n"); - input->print(0,cerr); - for (int j=0; jisConvex()) { - n_concav++; - } - bool is_ok = true; - if (n_concav > 1) { - egsWarning("createGeometry(ND_Geometry): a ND geometry can not have " - " more than one non-convex dimension, yours has %d\n",n_concav); - is_ok = false; - } - else if (n_concav == 1) { - if (dims[dims.size()-1]->isConvex()) { - egsWarning("createGeometry(ND_Geometry): the non-convex " - "dimension must be the last dimension\n"); + if (error) { + egsWarning("createGeometry(ND_Geometry): %d errors while " + "creating/geting geometries defining individual dimensions\n",error); + return 0; + } + if (dims.size() < 2) { + egsWarning("createGeometry(ND_Geometry): why do you want to " + "construct a ND geometry with a single dimension?\n"); + input->print(0,cerr); + for (int j=0; jisConvex()) { + n_concav++; + } + bool is_ok = true; + if (n_concav > 1) { + egsWarning("createGeometry(ND_Geometry): a ND geometry can not have " + " more than one non-convex dimension, yours has %d\n",n_concav); is_ok = false; } - } - if (!is_ok) { - for (int j=0; jderef()) { - delete dims[j]; + else if (n_concav == 1) { + if (dims[dims.size()-1]->isConvex()) { + egsWarning("createGeometry(ND_Geometry): the non-convex " + "dimension must be the last dimension\n"); + is_ok = false; } - return 0; - } - int hn_method=0; - err1 = input->getInput("hownear method",hn_method); - EGS_BaseGeometry *result; - if (!err1 && hn_method == 1) { - result = new EGS_NDGeometry(dims,"",false); - } - else { - result = new EGS_NDGeometry(dims); + } + if (!is_ok) { + for (int j=0; jderef()) { + delete dims[j]; + } + return 0; + } + int hn_method=0; + err1 = input->getInput("hownear method",hn_method); + EGS_BaseGeometry *result; + if (!err1 && hn_method == 1) { + result = new EGS_NDGeometry(dims,"",false); + } + else { + result = new EGS_NDGeometry(dims); + } + result->setName(input); + result->setBoundaryTolerance(input); + result->setMedia(input); + result->setLabels(input); + return result; } - result->setName(input); - result->setBoundaryTolerance(input); - result->setMedia(input); - result->setLabels(input); - return result; - } - void EGS_XYZGeometry::setXYZLabels(EGS_Input *input) { + void EGS_XYZGeometry::setXYZLabels(EGS_Input *input) { - // x,y,z labels - string inp; - int err; + // x,y,z labels + string inp; + int err; - err = input->getInput("set x label", inp); - if (!err) { - xp->setLabels(inp); - } + err = input->getInput("set x label", inp); + if (!err) { + xp->setLabels(inp); + } - err = input->getInput("set y label", inp); - if (!err) { - yp->setLabels(inp); - } + err = input->getInput("set y label", inp); + if (!err) { + yp->setLabels(inp); + } - err = input->getInput("set z label", inp); - if (!err) { - zp->setLabels(inp); + err = input->getInput("set z label", inp); + if (!err) { + zp->setLabels(inp); + } } - } - void EGS_NDGeometry::ndRegions(int r, int dim, int dimk, int k, vector ®s) { + void EGS_NDGeometry::ndRegions(int r, int dim, int dimk, int k, vector ®s) { - // skip looping over selected dimension - if (dim == dimk) { - r += k*n[dimk]; - if (dim == N-1) { - regs.push_back(r); - } - else { - ndRegions(r, dim+1, dimk, k, regs); + // skip looping over selected dimension + if (dim == dimk) { + r += k*n[dimk]; + if (dim == N-1) { + regs.push_back(r); + } + else { + ndRegions(r, dim+1, dimk, k, regs); + } } - } - // last dimension: end recursion and record global region number - else if (dim == N-1) { - for (int j=0; jregions(); j++) { - regs.push_back(r+j*n[dim]); + // last dimension: end recursion and record global region number + else if (dim == N-1) { + for (int j=0; jregions(); j++) { + regs.push_back(r+j*n[dim]); + } } - } - // keep collecting by recursion - else { - for (int j=0; jregions(); j++) { - ndRegions(r + j*n[dim], dim+1, dimk, k, regs); + // keep collecting by recursion + else { + for (int j=0; jregions(); j++) { + ndRegions(r + j*n[dim], dim+1, dimk, k, regs); + } } } - } - void EGS_NDGeometry::getLabelRegions(const string &str, vector ®s) { + void EGS_NDGeometry::getLabelRegions(const string &str, vector ®s) { - // label defined in the sub-geometries - vector local_regs; - for (int i=0; igetLabelRegions(str, local_regs); - } - if (local_regs.size() == 0) { - continue; - } + // label defined in the sub-geometries + vector local_regs; + for (int i=0; igetLabelRegions(str, local_regs); + } + if (local_regs.size() == 0) { + continue; + } - // recurse to collect all global regions comprised in each local region - for (int j=0; j ®s) { + void EGS_XYZGeometry::getLabelRegions(const string &str, vector ®s) { - vector local_regs; + vector local_regs; - // x plane labels - local_regs.clear(); - xp->getLabelRegions(str, local_regs); - for (int i=0; igetLabelRegions(str, local_regs); + for (int i=0; igetLabelRegions(str, local_regs); - for (int j=0; jgetLabelRegions(str, local_regs); + for (int j=0; jgetLabelRegions(str, local_regs); - for (int k=0; kgetLabelRegions(str, local_regs); + for (int k=0; k ®s) { + void EGS_XYZRepeater::getLabelRegions(const string &str, vector ®s) { - vector local_regs; + vector local_regs; - // label in repeated geometry - local_regs.clear(); - g->getLabelRegions(str, local_regs); - for (int i=0; igetLabelRegions(str, local_regs); + for (int i=0; igetXLabelRegions(str, local_regs); - for (int i=0; igetXLabelRegions(str, local_regs); + for (int i=0; igetYLabelRegions(str, local_regs); - for (int j=0; jgetYLabelRegions(str, local_regs); + for (int j=0; jgetZLabelRegions(str, local_regs); - for (int k=0; kgetZLabelRegions(str, local_regs); + for (int k=0; kgetSingleInput("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 24e4ed8d0..77824581d 100644 --- a/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Frederic Tessier +# Hannah Gallop # ############################################################################### */ @@ -47,6 +48,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, @@ -87,6 +90,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 8dbe78806..5b676bb64 100644 --- a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Frederic Tessier +# Hannah Gallop # ############################################################################### */ @@ -45,8 +46,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 3b9ef20f6..9f736ae57 100644 --- a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Frederic Tessier +# Hannah Gallop # ############################################################################### */ @@ -46,6 +47,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), @@ -94,6 +97,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 ee02472c0..ffb4937a9 100644 --- a/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_rz/egs_rz.cpp @@ -27,6 +27,7 @@ # Contributors: Marc Chamberland # Rowan Thomson # Dave Rogers +# Hannah Gallop # ############################################################################### # @@ -47,6 +48,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"; @@ -225,6 +227,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 b0e72b53f..b6192c1a4 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 @@ -65,6 +65,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"); @@ -254,6 +256,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 89678dfb1..afebf785f 100644 --- a/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Frederic Tessier +# Hannah Gallop # ############################################################################### */ @@ -39,8 +40,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 faa2b6d24..2e1e7fd42 100644 --- a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp @@ -27,6 +27,7 @@ # Frederic Tessier # Reid Townson # Randle Taylor +# Hannah Gallop # ############################################################################### */ @@ -46,6 +47,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) : @@ -679,6 +682,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 ed6d7f7d1..39ac380fa 100644 --- a/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp @@ -26,6 +26,7 @@ # Contributors: Frederic Tessier # Ernesto Mainegra-Hing # Hubert Ho +# Hannah Gallop # ############################################################################### */ @@ -44,6 +45,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"); @@ -167,6 +170,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) { @@ -203,8 +238,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 1be4948e8768c39ba665008694091a6860bf52f1 Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Wed, 10 Feb 2021 14:57:48 -0500 Subject: [PATCH 17/32] Add sources, ausgab, other egs_view editor support --- .../egs_dose_scoring/egs_dose_scoring.cpp | 36 ++++++++ .../egs_phsp_scoring/egs_phsp_scoring.cpp | 84 ++++++++++++++++++- .../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 | 31 ++++++- .../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 | 53 +++++++++++- .../egs_parallel_beam/egs_parallel_beam.cpp | 52 +++++++++++- .../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(+), 20 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 39387525f..3540f5627 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 @@ -27,6 +27,7 @@ # Reid Townson # Hubert Ho # Blake Walters +# Hannah Gallop # ############################################################################### # @@ -96,6 +97,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), @@ -589,6 +592,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 958a8b71c..adf7f546a 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 @@ -23,7 +23,7 @@ # # Author: Blake Walters, 2018 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -44,6 +44,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(0), @@ -510,6 +512,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 fbcd05b52..3d111f51e 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) { @@ -95,6 +97,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 ceeda3275..502c4c2a1 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 ecb085131..fb8a16e4d 100644 --- a/HEN_HOUSE/egs++/egs_base_source.h +++ b/HEN_HOUSE/egs++/egs_base_source.h @@ -61,7 +61,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 575472472..688103a24 100644 --- a/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_autoenvelope/egs_autoenvelope.cpp @@ -27,6 +27,7 @@ # Contributors: Marc Chamberland # Rowan Thomson # Dave Rogers +# 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 1dd8d6490..48b72507f 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.cpp @@ -45,7 +45,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 8140120e2..90f14469d 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 @@ -51,7 +51,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 22a2a934a..bcc86eb32 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 @@ -1086,7 +1086,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 5b676bb64..c7cee169c 100644 --- a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp @@ -53,7 +53,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 9f736ae57..aef090eb7 100644 --- a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp @@ -100,7 +100,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 b6192c1a4..be929c694 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 @@ -25,6 +25,7 @@ # # Contributors: Frederic Tessier # Ernesto Mainegra-Hing +# 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 2e1e7fd42..3ef5663d7 100644 --- a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp @@ -685,7 +685,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 45ba79e9b..ac276bfbf 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 @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -40,6 +40,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]; @@ -140,6 +143,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 e4c7e1e1d..a9ff3c5a3 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 @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Hubert Ho +# Hannah Gallop # ############################################################################### */ @@ -37,6 +38,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) { @@ -120,6 +123,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 db4475f62..fcb3387e8 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 @@ -24,7 +24,7 @@ # Authors: Ernesto Mainegra-Hing, 2016 # Hugo Bouchard, 2016 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -41,6 +41,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 +146,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 09009c9bf..1eec20a4f 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 @@ -23,7 +23,7 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Hannah Gallop # ############################################################################### */ @@ -37,6 +37,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 +111,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 26f9904d0..e99ea758d 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(); @@ -503,6 +506,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 b56c0a738..ff36f8c03 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 @@ -24,6 +24,7 @@ # Author: Reid Townson, 2016 # # Contributors: Martin Martinov +# Hannah Gallop # ############################################################################### */ @@ -39,6 +40,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) { @@ -353,6 +356,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 bc62e07f8..eec10b819 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 @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Marc Chamberland +# Hannah Gallop # ############################################################################### */ @@ -37,6 +38,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; @@ -132,6 +135,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 b651660378cdeb85e91eefb83be1315346b26b8f Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Mon, 15 Feb 2021 09:15:04 -0500 Subject: [PATCH 18/32] 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 a029f9403..cd5772269 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 @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Marc Chamberland +# Hannah Gallop # ############################################################################### */ @@ -38,6 +39,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) { @@ -60,6 +64,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 fe091b736..071fee02f 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 @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2009 # # Contributors: Frederic Tessier +# Hannah Gallop # ############################################################################### */ @@ -41,6 +42,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; @@ -368,6 +372,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 8137b50f8a02bde247b065fe562efa676e67d607 Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Fri, 26 Feb 2021 11:20:58 -0500 Subject: [PATCH 19/32] 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 0c1b4d9d10822b2a489cb7515d7f5ad0c2948cb2 Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Mon, 26 Apr 2021 12:33:00 -0400 Subject: [PATCH 20/32] 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 b1c97ee16..e2967015f 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 */ @@ -1194,9 +1237,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); \ @@ -1223,9 +1264,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 4b6ea6e69..c28dccff5 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -64,7 +64,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 c526131c1..d9704b01f 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 5ac509fcc..f0a1c3888 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -109,6 +109,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 2e6d1fc607f5065e73b86d7692d528c7cc712c3b Mon Sep 17 00:00:00 2001 From: Hannah Gallop Date: Fri, 30 Apr 2021 14:10:15 -0400 Subject: [PATCH 21/32] 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 d7e2e746d7660cdbb3226a6f8dcbdd34cd52ed8b Mon Sep 17 00:00:00 2001 From: Townson Date: Wed, 19 May 2021 14:15:50 -0400 Subject: [PATCH 22/32] 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 a9bc7297b..edc4ab591 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui +++ b/HEN_HOUSE/egs++/view/viewcontrol.ui @@ -116,7 +116,7 @@ - 4 + 0 @@ -184,123 +184,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 - - - - - - @@ -380,6 +263,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 + + + + + + @@ -408,16 +440,31 @@ 6 - - - 100 - - - 50 - - - Qt::Horizontal + + + Opacity + + + + + 100 + + + 50 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 10 + + + + @@ -425,7 +472,7 @@ - QFrame::Box + QFrame::NoFrame true @@ -435,8 +482,8 @@ 0 0 - 297 - 189 + 301 + 155 @@ -448,7 +495,7 @@ - No ausgab objects found + No dose files found Qt::AlignCenter @@ -551,7 +598,7 @@ - Transparency + Opacity @@ -576,6 +623,34 @@ + + + + Global Opacity + + + + + + 255 + + + 255 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 25 + + + + + + @@ -707,6 +782,16 @@ + + + + No particle tracks found + + + Qt::AlignCenter + + + From 99f96062918ec45cc1d09b7cf3d701cf56610184 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 20 May 2021 16:35:01 -0400 Subject: [PATCH 23/32] 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 4d6f56b9a..026508d32 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -76,7 +76,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 1034f44e2efac8c2af571427d308c0e79097b09c Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Wed, 6 Apr 2022 12:24:14 -0400 Subject: [PATCH 24/32] 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/view.pro | 2 - HEN_HOUSE/egs++/view/viewcontrol.cpp | 5 +++ 4 files changed, 50 insertions(+), 3 deletions(-) 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 e99ea758d..53268fe81 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 @@ -516,7 +516,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 b691b15e6..edd3f84d6 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(); @@ -525,6 +527,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 @@ -532,3 +575,4 @@ extern "C" { } } + diff --git a/HEN_HOUSE/egs++/view/view.pro b/HEN_HOUSE/egs++/view/view.pro index 026508d32..074f8d05b 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -107,5 +107,3 @@ greaterThan(QMAKE_GCC_MAJOR_VERSION, 4) { UI_DIR = .ui/$$my_machine MOC_DIR = .moc/$$my_machine OBJECTS_DIR = .obj/$$my_machine - - 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 9b436062b40053db2791cb577d1724ebc3b90909 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 7 Apr 2022 11:15:14 -0400 Subject: [PATCH 25/32] 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 074f8d05b..f899d73f5 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -92,7 +92,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 edc4ab591..a283f8258 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui +++ b/HEN_HOUSE/egs++/view/viewcontrol.ui @@ -1758,7 +1758,7 @@ p, li { white-space: pre-wrap; } - Editor + Editor (experimental) From 63747c1025dd70c06ab8227effd2e833babdfe1d Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Mon, 2 May 2022 08:21:49 -0400 Subject: [PATCH 26/32] 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 ac276bfbf..b8f4a3cee 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 @@ -147,6 +147,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 071fee02f..9a01bd54d 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 @@ -377,6 +377,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 f899d73f5..ac6d78570 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -92,7 +92,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 bc104aa00d6bbc35526ff55b062ab1afce0ffb1f Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 10 May 2022 16:17:53 -0400 Subject: [PATCH 27/32] 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 3540f5627..e874b9484 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 @@ -619,7 +619,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 adf7f546a..d75b5e3dc 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 @@ -558,8 +558,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 @@ -595,187 +595,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 3d111f51e..e00f35b58 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 @@ -109,7 +109,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 c27170d0d..ee40a5477 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -78,7 +78,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 fb8a16e4d..0bcb8007a 100644 --- a/HEN_HOUSE/egs++/egs_base_source.h +++ b/HEN_HOUSE/egs++/egs_base_source.h @@ -59,11 +59,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"}); @@ -92,7 +92,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 99a22e821..bef8d9c74 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -65,7 +65,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; } @@ -87,8 +87,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 edb94f59f..af6835cfb 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 @@ -128,8 +128,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 562886ab8..20a2939a9 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -294,8 +294,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 b8f4a3cee..cc81cf839 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 @@ -152,8 +152,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 cd5772269..d2cbf90a6 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 @@ -75,8 +75,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 @@ -147,7 +147,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 a9ff3c5a3..f5eca51d1 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 @@ -142,8 +142,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 fcb3387e8..2db0c048d 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 @@ -163,8 +163,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 00c427bbd..05f69ab57 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 @@ -182,8 +182,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 1eec20a4f..4207b3e1c 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 @@ -128,8 +128,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 53268fe81..572290dd7 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 @@ -524,8 +524,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 ff36f8c03..865f9d979 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 @@ -399,8 +399,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 eec10b819..55f31bcc5 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 @@ -149,8 +149,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 edd3f84d6..edb6fc4ed 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 @@ -545,8 +545,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 9af480076b60bb8b75edc79f13b9c1ff3c472f2c Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 28 Jun 2022 16:06:45 -0400 Subject: [PATCH 28/32] 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 c28dccff5..4b6ea6e69 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -64,7 +64,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 d2cbf90a6..0e7f72902 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 @@ -79,7 +79,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 ac6d78570..f899d73f5 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -92,7 +92,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 7494d3cc7bdd3a80b5911cfd0e9d3d4d96c1353c Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Mon, 4 Jul 2022 16:00:47 -0400 Subject: [PATCH 29/32] 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 1347f5e3b..5170608d4 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 4121af24b7b71a9ab7e1324c7de55e559266833d Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Tue, 5 Jul 2022 09:45:24 -0400 Subject: [PATCH 30/32] 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 dbe2985fb05e0585ab350e5c645572fc9f927e41 Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 9 Nov 2023 14:08:57 -0500 Subject: [PATCH 31/32] 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 1546410d50ed673ed22c1c56e9a577755bfbff2e Mon Sep 17 00:00:00 2001 From: Reid Townson Date: Thu, 9 Nov 2023 14:38:26 -0500 Subject: [PATCH 32/32] 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;