Ejemplo n.º 1
0
void HelpManager::enterTopic(const char *name)
{
    const HelpTopicInterface &topic = impl_->currentTopic();
    if (!topic.hasSubTopics())
    {
        GMX_THROW(InvalidInputError(
                    formatString("Help topic '%s' has no subtopics",
                                 impl_->currentTopicAsString().c_str())));
    }
    const HelpTopicInterface *newTopic = topic.findSubTopic(name);
    if (newTopic == NULL)
    {
        if (impl_->isAtRootTopic())
        {
            GMX_THROW(InvalidInputError(
                        formatString("No help available for '%s'", name)));
        }
        else
        {
            GMX_THROW(InvalidInputError(
                        formatString("Help topic '%s' has no subtopic '%s'",
                                     impl_->currentTopicAsString().c_str(), name)));
        }
    }
    impl_->topicStack_.push_back(newTopic);
}
Ejemplo n.º 2
0
std::string FileNameOptionManager::completeDefaultFileName(
        const std::string &prefix, const FileNameOptionInfo &option)
{
    if (option.isDirectoryOption())
    {
        return std::string();
    }
    const bool        bInput = option.isInputFile() || option.isInputOutputFile();
    const std::string realPrefix
        = !impl_->defaultFileName_.empty() ? impl_->defaultFileName_ : prefix;
    if (bInput && !impl_->bInputCheckingDisabled_)
    {
        const std::string completedName
            = findExistingExtension(realPrefix, option, impl_->redirector_);
        if (!completedName.empty())
        {
            return completedName;
        }
        if (option.allowMissing())
        {
            return realPrefix + option.defaultExtension();
        }
        else if (option.isLibraryFile())
        {
            // TODO: Treat also library files here.
            return realPrefix + option.defaultExtension();
        }
        else if (option.isSet())
        {
            std::string message
                = formatString("No file name was provided, and the default file "
                               "'%s' does not exist or is not accessible.\n"
                               "The following extensions were tried to complete the file name:\n  %s",
                               prefix.c_str(), joinStrings(option.extensions(), ", ").c_str());
            GMX_THROW(InvalidInputError(message));
        }
        else if (option.isRequired())
        {
            std::string message
                = formatString("Required option was not provided, and the default file "
                               "'%s' does not exist or is not accessible.\n"
                               "The following extensions were tried to complete the file name:\n  %s",
                               prefix.c_str(), joinStrings(option.extensions(), ", ").c_str());
            GMX_THROW(InvalidInputError(message));
        }
        // We get here with the legacy optional behavior.
    }
    return realPrefix + option.defaultExtension();
}
Ejemplo n.º 3
0
void OptionsAssigner::finishOption()
{
    AbstractOptionStorage *option = _impl->_currentOption;
    GMX_RELEASE_ASSERT(option != NULL, "startOption() not called");
    bool bBoolReverseValue = false;
    if (option->isBoolean())
    {
        if (_impl->_currentValueCount == 0)
        {
            // Should not throw, otherwise something is wrong.
            // TODO: Get rid of the hard-coded values.
            option->appendValue(_impl->_reverseBoolean ? "0" : "1");
        }
        else if (_impl->_reverseBoolean)
        {
            bBoolReverseValue = true;
        }
    }
    _impl->_currentOption = NULL;
    _impl->_reverseBoolean = false;
    option->finishSet();
    if (bBoolReverseValue)
    {
        GMX_THROW(InvalidInputError("Cannot specify a value together with 'no' prefix"));
    }
}
Ejemplo n.º 4
0
void OptionsAssigner::startOption(const char *name)
{
    if (!tryStartOption(name))
    {
        GMX_THROW(InvalidInputError("Unknown option " + std::string(name)));
    }
}
Ejemplo n.º 5
0
void OptionsAssigner::finishOption()
{
    AbstractOptionStorage *option = impl_->currentOption_;
    GMX_RELEASE_ASSERT(option != nullptr, "startOption() not called");
    bool                   bBoolReverseValue = false;
    if (option->isBoolean())
    {
        if (impl_->currentValueCount_ == 0)
        {
            // Should not throw, otherwise something is wrong.
            option->appendValue(Variant::create<bool>(!impl_->reverseBoolean_));
        }
        else if (impl_->reverseBoolean_)
        {
            bBoolReverseValue = true;
        }
    }
    impl_->currentOption_  = nullptr;
    impl_->reverseBoolean_ = false;
    option->finishSet();
    if (bBoolReverseValue)
    {
        GMX_THROW(InvalidInputError("Cannot specify a value together with 'no' prefix"));
    }
}
Ejemplo n.º 6
0
void File::throwOnNotFound(const NotFoundInfo &info)
{
    throwOnError(info);
    const std::string message
        = formatString("File '%s' does not exist or is not accessible.\n%s",
                       info.filename, info.message);
    GMX_THROW_WITH_ERRNO(InvalidInputError(message), info.call, info.err);
}
Ejemplo n.º 7
0
 inline
 Mutation::Mutation(MutationType type, int start, int end, std::string newBases)
     : type_(type),
       start_(start),
       end_(end),
       newBases_(newBases)
 {
     if (!CheckInvariants()) throw InvalidInputError();
 }
Ejemplo n.º 8
0
void AbstractOptionStorage::finish()
{
    GMX_RELEASE_ASSERT(!bInSet_, "finishSet() not called");
    processAll();
    if (isRequired() && !(isSet() || hasFlag(efOption_ExplicitDefaultValue)))
    {
        GMX_THROW(InvalidInputError("Option is required, but not set"));
    }
}
Ejemplo n.º 9
0
void OptionsAssigner::startSubSection(const char *name)
{
    Options *section = _impl->currentSection()._impl->findSubSection(name);
    if (section == NULL)
    {
        GMX_THROW(InvalidInputError("Unknown subsection"));
    }
    _impl->_sectionStack.push_back(section);
}
Ejemplo n.º 10
0
std::vector<int>
parseUserGpuIds(const std::string &gpuIdString)
{
    // An optional comma is used to separate GPU IDs assigned to the
    // same type of task, which will be useful for any nodes that have
    // more than ten GPUs.

    std::vector<int> digits;
    auto             foundCommaDelimiters = gpuIdString.find(',') != std::string::npos;
    if (!foundCommaDelimiters)
    {
        for (const auto &c : gpuIdString)
        {
            if (std::isdigit(c) == 0)
            {
                GMX_THROW(InvalidInputError(formatString("Invalid character in GPU ID string: \"%c\"\n", c)));
            }
            // Convert each character in the token to an integer
            digits.push_back(c - '0');
        }
    }
    else
    {
        if (gpuIdString[0] == ',')
        {
            GMX_THROW(InvalidInputError("Invalid use of leading comma in GPU ID string"));
        }
        std::istringstream ss(gpuIdString);
        std::string        token;
        digits.reserve(gpuIdString.length());
        token.reserve(gpuIdString.length());
        while (std::getline(ss, token, ','))
        {
            // Convert the whole token to an integer
            if (token.empty())
            {
                GMX_THROW(InvalidInputError("Invalid use of comma in GPU ID string"));
            }
            digits.push_back(std::stoi(token));
        }
    }
    return digits;
}
Ejemplo n.º 11
0
 explicit Impl(const std::string &value)
 try : regex_(value, std::regex::nosubs | std::regex::extended)
 {
 }
 catch (const std::regex_error &)
 {
     // TODO: Better error messages.
     GMX_THROW(InvalidInputError(formatString(
                                         "Error in regular expression \"%s\"", value)));
 }
Ejemplo n.º 12
0
void OptionsAssigner::startSection(const char *name)
{
    Impl::Section *section = impl_->currentSection().findSection(name);
    if (section == nullptr)
    {
        GMX_THROW(InvalidInputError("Unknown subsection"));
    }
    impl_->sectionStack_.push_back(section);
    section->start();
}
Ejemplo n.º 13
0
 void compile(const char *value)
 {
     std::string buf(formatString("^%s$", value));
     int         rc = regcomp(&regex_, buf.c_str(), REG_EXTENDED | REG_NOSUB);
     if (rc != 0)
     {
         // TODO: Better error messages.
         GMX_THROW(InvalidInputError(formatString(
                                             "Error in regular expression \"%s\"", value)));
     }
 }
Ejemplo n.º 14
0
void AbstractOptionStorage::setMaxValueCount(int count)
{
    GMX_RELEASE_ASSERT(!hasFlag(efOption_MultipleTimes),
                       "setMaxValueCount() not supported with efOption_MultipleTimes");
    GMX_RELEASE_ASSERT(count >= -1, "Invalid value count");
    maxValueCount_ = count;
    if (isSet() && maxValueCount_ >= 0 && valueCount() > maxValueCount_)
    {
        GMX_THROW(InvalidInputError("Too many values"));
    }
}
inline Mutation::Mutation(MutationType type, int position, char base)
    : type_(type), start_(position)
{
    if (type == INSERTION) {
        end_ = position;
    } else {
        end_ = position + 1;
    }
    newBases_ = (type == DELETION ? "" : std::string(1, base));
    if (!CheckInvariants()) throw InvalidInputError();
}
Ejemplo n.º 16
0
void OptionsAssigner::startOption(const char *name)
{
    GMX_RELEASE_ASSERT(_impl->_currentOption == NULL, "finishOption() not called");
    AbstractOptionStorage *option = _impl->findOption(name);
    if (option == NULL)
    {
        GMX_THROW(InvalidInputError("Unknown option"));
    }
    option->startSet();
    _impl->_currentOption = option;
    _impl->_currentValueCount = 0;
}
Ejemplo n.º 17
0
void AbstractOptionStorage::setMinValueCount(int count)
{
    GMX_RELEASE_ASSERT(!hasFlag(efOption_MultipleTimes),
                       "setMinValueCount() not supported with efOption_MultipleTimes");
    GMX_RELEASE_ASSERT(count >= 0, "Invalid value count");
    minValueCount_ = count;
    if (isSet() && !hasFlag(efOption_DontCheckMinimumCount)
        && valueCount() < minValueCount_)
    {
        GMX_THROW(InvalidInputError("Too few values"));
    }
}
Ejemplo n.º 18
0
void
Distance::initAnalysis(const TrajectoryAnalysisSettings &settings,
                       const TopologyInformation         & /*top*/)
{
    if (sel_[0].posCount() != 1)
    {
        GMX_THROW(InvalidInputError("The first selection does not define a single position"));
    }
    if (sel_[1].posCount() != 1)
    {
        GMX_THROW(InvalidInputError("The second selection does not define a single position"));
    }

    data_.addModule(avem_);
    AnalysisDataPlotModulePointer plotm_(new AnalysisDataPlotModule());
    plotm_->setSettings(settings.plotSettings());
    plotm_->setFileName(fnDist_);
    plotm_->setTitle("Distance");
    plotm_->setXAxisIsTime();
    plotm_->setYLabel("Distance (nm)");
    data_.addModule(plotm_);
}
Ejemplo n.º 19
0
void
SelectionCollection::parseRequestedFromString(const std::string &str)
{
    Impl::RequestsClearer clearRequestsOnExit(&_impl->_requests);

    std::vector<Selection *> selections;
    parseFromString(str, &selections);

    std::vector<Selection *>::const_iterator first = selections.begin();
    std::vector<Selection *>::const_iterator last = first;
    Impl::RequestList::const_iterator i;
    for (i = _impl->_requests.begin(); i != _impl->_requests.end(); ++i)
    {
        const Impl::SelectionRequest &request = *i;
        if (request.count() > 0)
        {
            if (selections.end() - first < request.count())
            {
                GMX_THROW(InvalidInputError("Too few selections provided"));
            }
            last = first + request.count();
        }
        else
        {
            if (i != _impl->_requests.end() - 1)
            {
                GMX_THROW(APIError("Request for all selections not the last option"));
            }
            last = selections.end();
        }
        std::vector<Selection *> curr(first, last);
        request.storage->addSelections(curr, true);
        first = last;
    }
    if (last != selections.end())
    {
        GMX_THROW(InvalidInputError("Too many selections provided"));
    }
}
Ejemplo n.º 20
0
void AbstractOptionStorage::startSet()
{
    GMX_RELEASE_ASSERT(!bInSet_, "finishSet() not called");
    // The last condition takes care of the situation where multiple
    // sources are used, and a later source should be able to reassign
    // the value even though the option is already set.
    if (isSet() && !hasFlag(efOption_MultipleTimes)
        && !hasFlag(efOption_ClearOnNextSet))
    {
        GMX_THROW(InvalidInputError("Option specified multiple times"));
    }
    clearSet();
    bInSet_              = true;
    bSetValuesHadErrors_ = false;
}
Ejemplo n.º 21
0
    const ArrowConfig& ArrowConfigTable::At(const std::string& name) const
        throw(InvalidInputError)
    {
        const_iterator it;

        // If we find a direct match for the chemistry, use it
        for (it = table.begin(); it != table.end(); it++)
            if (it->first.compare(name) == 0)
                return it->second;

        // Fallback is "*"
        for (it = table.begin(); it != table.end(); it++)
            if (it->first.compare("*") == 0)
                return it->second;

        throw InvalidInputError("Chemistry not found in ArrowConfigTable");
    }
Ejemplo n.º 22
0
void
SelectionCollection::setIndexGroups(gmx_ana_indexgrps_t *grps)
{
    GMX_RELEASE_ASSERT(grps == NULL || !_impl->hasFlag(Impl::efExternalGroupsSet),
                       "Can only set external groups once or clear them afterwards");
    _impl->_grps = grps;
    _impl->_flags.set(Impl::efExternalGroupsSet);

    MessageStringCollector errors;
    t_selelem *root = _impl->_sc.root;
    while (root != NULL)
    {
        _impl->resolveExternalGroups(root, &errors);
        root = root->next;
    }
    if (!errors.isEmpty())
    {
        GMX_THROW(InvalidInputError(errors.toString()));
    }
}
Ejemplo n.º 23
0
void TimeUnitBehavior::setTimeUnitFromEnvironment()
{
    const char *const value = std::getenv("GMXTIMEUNIT");
    if (value != NULL)
    {
        ConstArrayRef<const char *>                 timeUnits(g_timeUnits);
        ConstArrayRef<const char *>::const_iterator i =
            std::find(timeUnits.begin(), timeUnits.end(), std::string(value));
        if (i == timeUnits.end())
        {
            std::string message = formatString(
                        "Time unit provided with environment variable GMXTIMEUNIT=%s "
                        "is not recognized as a valid time unit.\n"
                        "Possible values are: %s",
                        value, joinStrings(timeUnits, ", ").c_str());
            GMX_THROW(InvalidInputError(message));
        }
        setTimeUnit(static_cast<TimeUnit>(i - timeUnits.begin()));
    }
}
Ejemplo n.º 24
0
void Options::finish()
{
    // TODO: Consider how to customize these error messages based on context.
    ExceptionInitializer             errors("Invalid input values");
    Impl::OptionList::const_iterator i;
    for (i = impl_->options_.begin(); i != impl_->options_.end(); ++i)
    {
        AbstractOptionStorage &option = **i;
        try
        {
            option.finish();
        }
        catch (UserInputError &ex)
        {
            ex.prependContext("In option " + option.name());
            errors.addCurrentExceptionAsNested();
        }
    }
    Impl::SubSectionList::const_iterator j;
    for (j = impl_->subSections_.begin(); j != impl_->subSections_.end(); ++j)
    {
        Options &section = **j;
        try
        {
            section.finish();
        }
        catch (const UserInputError &)
        {
            errors.addCurrentExceptionAsNested();
        }
    }
    if (errors.hasNestedExceptions())
    {
        // TODO: This exception type may not always be appropriate.
        GMX_THROW(InvalidInputError(errors));
    }
}
Ejemplo n.º 25
0
void
SelectionCollection::Impl::runParser(yyscan_t scanner, int maxnr,
                                     std::vector<Selection *> *output)
{
    gmx_ana_selcollection_t *sc = &_sc;
    GMX_ASSERT(sc == _gmx_sel_lexer_selcollection(scanner),
               "Incorrectly initialized lexer");

    MessageStringCollector errors;
    _gmx_sel_set_lexer_error_reporter(scanner, &errors);

    int oldCount = sc->sel.size();
    int bOk = !_gmx_sel_yybparse(scanner);
    _gmx_sel_free_lexer(scanner);
    int nr = sc->sel.size() - oldCount;
    if (maxnr > 0 && nr != maxnr)
    {
        bOk = false;
        errors.append("Too few selections provided");
    }

    if (bOk)
    {
        SelectionList::const_iterator i;
        for (i = _sc.sel.begin() + oldCount; i != _sc.sel.end(); ++i)
        {
            output->push_back(*i);
        }
    }

    if (!bOk || !errors.isEmpty())
    {
        GMX_ASSERT(!bOk && !errors.isEmpty(), "Inconsistent error reporting");
        GMX_THROW(InvalidInputError(errors.toString()));
    }
}
Ejemplo n.º 26
0
void mapGridToDataGrid(std::vector<int>    *gridpointToDatapoint,
                       const double* const *data,
                       int                  numDataPoints,
                       const std::string   &dataFilename,
                       const Grid          &grid,
                       const std::string   &correctFormatMessage)
{
    /* Transform the data into a grid in order to map each grid point to a data point
       using the grid functions. */
    std::vector<GridAxis> axis_;

    /* Count the number of points for each dimension. Each dimension
       has its own stride. */
    int              stride           = 1;
    int              numPointsCounted = 0;
    std::vector<int> numPoints(grid.numDimensions());
    for (int d = grid.numDimensions() - 1; d >= 0; d--)
    {
        int    numPointsInDim = 0;
        int    pointIndex     = 0;
        double firstValue     = data[d][pointIndex];
        do
        {
            numPointsInDim++;
            pointIndex       += stride;
        }
        while (pointIndex < numDataPoints &&
               !gmx_within_tol(firstValue, data[d][pointIndex], GMX_REAL_EPS));

        /* The stride in dimension dimension d - 1 equals the number of points
           dimension d. */
        stride = numPointsInDim;

        numPointsCounted = (numPointsCounted == 0) ? numPointsInDim : numPointsCounted*numPointsInDim;

        numPoints[d]     = numPointsInDim;
    }

    if (numPointsCounted != numDataPoints)
    {
        std::string mesg = gmx::formatString("Could not extract data properly from %s. Wrong data format?"
                                             "\n\n%s",
                                             dataFilename.c_str(), correctFormatMessage.c_str());
        GMX_THROW(InvalidInputError(mesg));
    }

    /* The data grid has the data that was read and the properties of the AWH grid */
    for (int d = 0; d < grid.numDimensions(); d++)
    {
        axis_.push_back(GridAxis(data[d][0], data[d][numDataPoints - 1],
                                 grid.axis(d).period(), numPoints[d]));
    }

    /* Map each grid point to a data point. No interpolation, just pick the nearest one.
     * It is assumed that the given data is uniformly spaced for each dimension.
     */
    for (size_t m = 0; m < grid.numPoints(); m++)
    {
        /* We only define what we need for the datagrid since it's not needed here which is a bit ugly */

        if (!valueIsInGrid(grid.point(m).coordValue, axis_))
        {
            std::string mesg =
                gmx::formatString("%s does not contain data for all coordinate values. "
                                  "Make sure your input data covers the whole sampling domain "
                                  "and is correctly formatted. \n\n%s",
                                  dataFilename.c_str(), correctFormatMessage.c_str());
            GMX_THROW(InvalidInputError(mesg));
        }
        (*gridpointToDatapoint)[m] = getNearestIndexInGrid(grid.point(m).coordValue, axis_);
    }
}
Ejemplo n.º 27
0
void
TrajectoryAnalysisRunnerCommon::initFirstFrame()
{
    // Return if we have already initialized the trajectory.
    if (impl_->fr)
    {
        return;
    }
    time_unit_t time_unit
        = static_cast<time_unit_t>(impl_->settings_.timeUnit() + 1);
    output_env_init(&impl_->oenv_, 0, NULL, time_unit, FALSE, exvgNONE, 0, 0);

    int frflags = impl_->settings_.frflags();
    frflags |= TRX_NEED_X;

    snew(impl_->fr, 1);

    const TopologyInformation &top = impl_->topInfo_;
    if (hasTrajectory())
    {
        if (!read_first_frame(impl_->oenv_, &impl_->status_,
                              impl_->trjfile_.c_str(), impl_->fr, frflags))
        {
            GMX_THROW(FileIOError("Could not read coordinates from trajectory"));
        }
        impl_->bTrajOpen_ = true;

        if (top.hasTopology() && impl_->fr->natoms > top.topology()->atoms.nr)
        {
            GMX_THROW(InconsistentInputError(formatString(
                                                     "Trajectory (%d atoms) does not match topology (%d atoms)",
                                                     impl_->fr->natoms, top.topology()->atoms.nr)));
        }
        // Check index groups if they have been initialized based on the topology.
        /*
           if (top)
           {
            for (int i = 0; i < impl_->sel->nr(); ++i)
            {
                gmx_ana_index_check(impl_->sel->sel(i)->indexGroup(),
                                    impl_->fr->natoms);
            }
           }
         */
    }
    else
    {
        // Prepare a frame from topology information.
        // TODO: Initialize more of the fields.
        if (frflags & (TRX_NEED_V))
        {
            GMX_THROW(NotImplementedError("Velocity reading from a topology not implemented"));
        }
        if (frflags & (TRX_NEED_F))
        {
            GMX_THROW(InvalidInputError("Forces cannot be read from a topology"));
        }
        impl_->fr->flags  = frflags;
        impl_->fr->natoms = top.topology()->atoms.nr;
        impl_->fr->bX     = TRUE;
        snew(impl_->fr->x, impl_->fr->natoms);
        memcpy(impl_->fr->x, top.xtop_,
               sizeof(*impl_->fr->x) * impl_->fr->natoms);
        impl_->fr->bBox   = TRUE;
        copy_mat(const_cast<rvec *>(top.boxtop_), impl_->fr->box);
    }

    set_trxframe_ePBC(impl_->fr, top.ePBC());
    if (top.hasTopology() && impl_->settings_.hasRmPBC())
    {
        impl_->gpbc_ = gmx_rmpbc_init(&top.topology()->idef, top.ePBC(),
                                      impl_->fr->natoms, impl_->fr->box);
    }
}
Ejemplo n.º 28
0
CommandLineModuleInterface *
CommandLineModuleManager::Impl::processCommonOptions(
        CommandLineCommonOptionsHolder *optionsHolder, int *argc, char ***argv)
{
    // Check if we are directly invoking a certain module.
    CommandLineModuleInterface *module = singleModule_;

    // TODO: It would be nice to propagate at least the -quiet option to
    // the modules so that they can also be quiet in response to this.

    if (module == NULL)
    {
        // If not in single-module mode, process options to the wrapper binary.
        // TODO: Ideally, this could be done by CommandLineParser.
        int argcForWrapper = 1;
        while (argcForWrapper < *argc && (*argv)[argcForWrapper][0] == '-')
        {
            ++argcForWrapper;
        }
        if (argcForWrapper > 1)
        {
            CommandLineParser(optionsHolder->options())
                .parse(&argcForWrapper, *argv);
        }
        // If no action requested and there is a module specified, process it.
        if (argcForWrapper < *argc && !optionsHolder->shouldIgnoreActualModule())
        {
            const char *moduleName = (*argv)[argcForWrapper];
            CommandLineModuleMap::const_iterator moduleIter
                = findModuleByName(moduleName);
            if (moduleIter == modules_.end())
            {
                std::string message =
                    formatString("'%s' is not a GROMACS command.", moduleName);
                GMX_THROW(InvalidInputError(message));
            }
            module = moduleIter->second.get();
            *argc -= argcForWrapper;
            *argv += argcForWrapper;
            // After this point, argc and argv are the same independent of
            // which path is taken: (*argv)[0] is the module name.
        }
    }
    if (module != NULL)
    {
        if (singleModule_ == NULL)
        {
            programContext_.setDisplayName(binaryName_ + " " + module->name());
        }
        // Recognize the common options also after the module name.
        // TODO: It could be nicer to only recognize -h/-hidden if module is not
        // null.
        CommandLineParser(optionsHolder->options())
            .skipUnknown(true).parse(argc, *argv);
    }
    if (!optionsHolder->finishOptions())
    {
        return NULL;
    }
    // If no module specified and no other action, show the help.
    // Also explicitly specifying -h for the wrapper binary goes here.
    if (module == NULL || optionsHolder->shouldShowHelp())
    {
        ensureHelpModuleExists();
        if (module != NULL)
        {
            helpModule_->setModuleOverride(*module);
        }
        *argc  = 1;
        module = helpModule_;
    }
    if (module == helpModule_)
    {
        helpModule_->setShowHidden(optionsHolder->shouldShowHidden());
    }
    return module;
}
Ejemplo n.º 29
0
void CommandLineParser::parse(int *argc, char *argv[])
{
    ExceptionInitializer errors("Invalid command-line options");
    std::string          currentContext;
    bool                 bInOption = false;

    impl_->assigner_.start();
    int newi = 1;
    for (int i = 1; i != *argc; ++i)
    {
        const char *const arg        = argv[i];
        const char *const optionName = impl_->toOptionName(arg);
        if (optionName != NULL)
        {
            if (bInOption)
            {
                try
                {
                    impl_->assigner_.finishOption();
                }
                catch (UserInputError &ex)
                {
                    ex.prependContext(currentContext);
                    errors.addCurrentExceptionAsNested();
                }
            }
            currentContext = "In command-line option " + std::string(arg);
            try
            {
                bInOption = impl_->assigner_.tryStartOption(optionName);
                if (!bInOption)
                {
                    currentContext.clear();
                    if (!impl_->bSkipUnknown_)
                    {
                        std::string message =
                            "Unknown command-line option " + std::string(arg);
                        GMX_THROW(InvalidInputError(message));
                    }
                }
            }
            catch (UserInputError &ex)
            {
                // If tryStartOption() throws, make sure that the rest gets
                // ignored.
                // TODO: Consider whether we should remove the option from the
                // command line nonetheless, as it is recognized, but just
                // invalid.
                bInOption = false;
                ex.prependContext(currentContext);
                errors.addCurrentExceptionAsNested();
                currentContext.clear();
            }
        }
        else if (bInOption)
        {
            try
            {
                impl_->assigner_.appendValue(arg);
            }
            // TODO: Consider if some types of exceptions would be better left
            // unhandled.
            catch (GromacsException &ex)
            {
                ex.prependContext(currentContext);
                errors.addCurrentExceptionAsNested();
            }
        }
        // Remove recognized options if applicable.
        if (!bInOption && impl_->bSkipUnknown_)
        {
            argv[newi] = argv[i];
            ++newi;
        }
    }
    // Update the argc count if argv was modified.
    if (impl_->bSkipUnknown_)
    {
        *argc      = newi;
        argv[newi] = NULL;
    }
    // Finish the last option.
    if (bInOption)
    {
        try
        {
            impl_->assigner_.finishOption();
        }
        catch (UserInputError &ex)
        {
            ex.prependContext(currentContext);
            errors.addCurrentExceptionAsNested();
        }
    }
    impl_->assigner_.finish();
    if (errors.hasNestedExceptions())
    {
        // TODO: This exception type may not always be appropriate.
        GMX_THROW(InvalidInputError(errors));
    }
}
Ejemplo n.º 30
0
void
TrajectoryAnalysisRunnerCommon::Impl::initFirstFrame()
{
    // Return if we have already initialized the trajectory.
    if (fr != NULL)
    {
        return;
    }
    time_unit_t time_unit
        = static_cast<time_unit_t>(settings_.timeUnit() + 1);
    output_env_init(&oenv_, getProgramContext(), time_unit, FALSE, exvgNONE, 0);

    int frflags = settings_.frflags();
    frflags |= TRX_NEED_X;

    snew(fr, 1);

    if (hasTrajectory())
    {
        if (!read_first_frame(oenv_, &status_, trjfile_.c_str(), fr, frflags))
        {
            GMX_THROW(FileIOError("Could not read coordinates from trajectory"));
        }
        bTrajOpen_ = true;

        if (topInfo_.hasTopology())
        {
            const int topologyAtomCount = topInfo_.topology()->atoms.nr;
            if (fr->natoms > topologyAtomCount)
            {
                const std::string message
                    = formatString("Trajectory (%d atoms) does not match topology (%d atoms)",
                                   fr->natoms, topologyAtomCount);
                GMX_THROW(InconsistentInputError(message));
            }
        }
    }
    else
    {
        // Prepare a frame from topology information.
        // TODO: Initialize more of the fields.
        if (frflags & (TRX_NEED_V))
        {
            GMX_THROW(NotImplementedError("Velocity reading from a topology not implemented"));
        }
        if (frflags & (TRX_NEED_F))
        {
            GMX_THROW(InvalidInputError("Forces cannot be read from a topology"));
        }
        fr->natoms = topInfo_.topology()->atoms.nr;
        fr->bX     = TRUE;
        snew(fr->x, fr->natoms);
        memcpy(fr->x, topInfo_.xtop_,
               sizeof(*fr->x) * fr->natoms);
        fr->bBox   = TRUE;
        copy_mat(topInfo_.boxtop_, fr->box);
    }

    set_trxframe_ePBC(fr, topInfo_.ePBC());
    if (topInfo_.hasTopology() && settings_.hasRmPBC())
    {
        gpbc_ = gmx_rmpbc_init(&topInfo_.topology()->idef, topInfo_.ePBC(),
                               fr->natoms);
    }
}