void
TrajectoryAnalysisRunnerCommon::optionsFinished()
{
    if (impl_->trjfile_.empty() && impl_->topfile_.empty())
    {
        GMX_THROW(InconsistentInputError("No trajectory or topology provided, nothing to do!"));
    }

    if (impl_->trajectoryGroup_.isValid() && impl_->trjfile_.empty())
    {
        GMX_THROW(InconsistentInputError("-fgroup only makes sense together with a trajectory (-f)"));
    }

    impl_->settings_.impl_->plotSettings.setTimeUnit(impl_->settings_.timeUnit());

    if (impl_->bStartTimeSet_)
    {
        setTimeValue(TBEGIN, impl_->startTime_);
    }
    if (impl_->bEndTimeSet_)
    {
        setTimeValue(TEND, impl_->endTime_);
    }
    if (impl_->bDeltaTimeSet_)
    {
        setTimeValue(TDELTA, impl_->deltaTime_);
    }
}
Exemple #2
0
void SelectionTreeElement::resolveIndexGroupReference(
    gmx_ana_indexgrps_t *grps, int natoms)
{
    GMX_RELEASE_ASSERT(type == SEL_GROUPREF,
                       "Should only be called for index group reference elements");
    if (grps == NULL)
    {
        std::string message = formatString(
                                  "Cannot match '%s', because index groups are not available.",
                                  name().c_str());
        GMX_THROW(InconsistentInputError(message));
    }

    gmx_ana_index_t foundGroup;
    std::string     foundName;
    if (u.gref.name != NULL)
    {
        if (!gmx_ana_indexgrps_find(&foundGroup, &foundName, grps, u.gref.name))
        {
            std::string message = formatString(
                                      "Cannot match '%s', because no such index group can be found.",
                                      name().c_str());
            GMX_THROW(InconsistentInputError(message));
        }
    }
    else
    {
        if (!gmx_ana_indexgrps_extract(&foundGroup, &foundName, grps, u.gref.id))
        {
            std::string message = formatString(
                                      "Cannot match '%s', because no such index group can be found.",
                                      name().c_str());
            GMX_THROW(InconsistentInputError(message));
        }
    }

    if (!gmx_ana_index_check_sorted(&foundGroup))
    {
        flags |= SEL_UNSORTED;
    }

    sfree(u.gref.name);
    type = SEL_CONST;
    gmx_ana_index_set(&u.cgrp, foundGroup.isize, foundGroup.index,
                      foundGroup.nalloc_index);
    setName(foundName);

    if (natoms > 0)
    {
        checkIndexGroup(natoms);
    }
}
Exemple #3
0
void
SelectionCollection::setTopology(t_topology *top, int natoms)
{
    GMX_RELEASE_ASSERT(natoms > 0 || top != NULL,
                       "The number of atoms must be given if there is no topology");
    // Get the number of atoms from the topology if it is not given.
    if (natoms <= 0)
    {
        natoms = top->atoms.nr;
    }
    if (impl_->bExternalGroupsSet_)
    {
        ExceptionInitializer        errors("Invalid index group references encountered");
        SelectionTreeElementPointer root = impl_->sc_.root;
        while (root)
        {
            checkExternalGroups(root, natoms, &errors);
            root = root->next;
        }
        if (errors.hasNestedExceptions())
        {
            GMX_THROW(InconsistentInputError(errors));
        }
    }
    gmx_ana_selcollection_t *sc = &impl_->sc_;
    // Do this first, as it allocates memory, while the others don't throw.
    gmx_ana_index_init_simple(&sc->gall, natoms);
    sc->pcc.setTopology(top);
    sc->top = top;
}
void
TrajectoryAnalysisRunnerCommon::Impl::initTopology(bool required)
{
    // Return immediately if the topology has already been loaded.
    if (topInfo_.hasTopology())
    {
        return;
    }

    if (required && topfile_.empty())
    {
        GMX_THROW(InconsistentInputError("No topology provided, but one is required for analysis"));
    }

    // Load the topology if requested.
    if (!topfile_.empty())
    {
        snew(topInfo_.top_, 1);
        topInfo_.bTop_ = read_tps_conf(topfile_.c_str(), topInfo_.top_, &topInfo_.ePBC_,
                                       &topInfo_.xtop_, NULL, topInfo_.boxtop_, TRUE);
        if (hasTrajectory()
            && !settings_.hasFlag(TrajectoryAnalysisSettings::efUseTopX))
        {
            sfree(topInfo_.xtop_);
            topInfo_.xtop_ = NULL;
        }
    }
}
bool
TrajectoryAnalysisRunnerCommon::optionsFinished(Options *options)
{
    if (impl_->bHelp_)
    {
        return false;
    }

    impl_->settings_.impl_->plotSettings.setTimeUnit(
            impl_->settings_.impl_->timeUnitManager.timeUnit());

    if (impl_->trjfile_.empty() && impl_->topfile_.empty())
    {
        GMX_THROW(InconsistentInputError("No trajectory or topology provided, nothing to do!"));
    }

    if (options->isSet("b"))
    {
        setTimeValue(TBEGIN, impl_->startTime_);
    }
    if (options->isSet("e"))
    {
        setTimeValue(TEND, impl_->endTime_);
    }
    if (options->isSet("dt"))
    {
        setTimeValue(TDELTA, impl_->deltaTime_);
    }

    return true;
}
Exemple #6
0
void
SelectionCollection::setIndexGroups(gmx_ana_indexgrps_t *grps)
{
    GMX_RELEASE_ASSERT(grps == NULL || !impl_->bExternalGroupsSet_,
                       "Can only set external groups once or clear them afterwards");
    impl_->grps_               = grps;
    impl_->bExternalGroupsSet_ = true;

    ExceptionInitializer        errors("Invalid index group reference(s)");
    SelectionTreeElementPointer root = impl_->sc_.root;
    while (root)
    {
        impl_->resolveExternalGroups(root, &errors);
        root->checkUnsortedAtoms(true, &errors);
        root = root->next;
    }
    if (errors.hasNestedExceptions())
    {
        GMX_THROW(InconsistentInputError(errors));
    }
    for (size_t i = 0; i < impl_->sc_.sel.size(); ++i)
    {
        impl_->sc_.sel[i]->refreshName();
    }
}
Exemple #7
0
void
Angle::optionsFinished(Options *options, TrajectoryAnalysisSettings *settings)
{
    bool bSingle = (g1type_[0] == 'a' || g1type_[0] == 'd');

    if (bSingle && g2type_[0] != 'n')
    {
        GMX_THROW(InconsistentInputError("Cannot use a second group (-g2) with "
                                         "-g1 angle or dihedral"));
    }
    if (bSingle && options->isSet("group2"))
    {
        GMX_THROW(InconsistentInputError("Cannot provide a second selection "
                                         "(-group2) with -g1 angle or dihedral"));
    }
    if (!bSingle && g2type_[0] == 'n')
    {
        GMX_THROW(InconsistentInputError("Should specify a second group (-g2) "
                                         "if the first group is not an angle or a dihedral"));
    }

    // Set up the number of positions per angle.
    switch (g1type_[0])
    {
        case 'a': natoms1_ = 3; break;
        case 'd': natoms1_ = 4; break;
        case 'v': natoms1_ = 2; break;
        case 'p': natoms1_ = 3; break;
        default:
            GMX_THROW(InternalError("invalid -g1 value"));
    }
    switch (g2type_[0])
    {
        case 'n': natoms2_ = 0; break;
        case 'v': natoms2_ = 2; break;
        case 'p': natoms2_ = 3; break;
        case 't': natoms2_ = 0; break;
        case 'z': natoms2_ = 0; break;
        case 's': natoms2_ = 1; break;
        default:
            GMX_THROW(InternalError("invalid -g2 value"));
    }
    if (natoms2_ == 0 && options->isSet("group2"))
    {
        GMX_THROW(InconsistentInputError("Cannot provide a second selection (-group2) with -g2 t0 or z"));
    }
}
Exemple #8
0
void
TrajectoryAnalysisRunnerCommon::initTopology(SelectionCollection *selections)
{
    // Return immediately if the topology has already been loaded.
    if (impl_->topInfo_.hasTopology())
    {
        return;
    }

    const TrajectoryAnalysisSettings &settings = impl_->settings_;
    const bool bRequireTop
        = settings.hasFlag(TrajectoryAnalysisSettings::efRequireTop)
            || selections->requiresTopology();
    if (bRequireTop && impl_->topfile_.empty())
    {
        GMX_THROW(InconsistentInputError("No topology provided, but one is required for analysis"));
    }

    // Load the topology if requested.
    if (!impl_->topfile_.empty())
    {
        char  title[STRLEN];

        snew(impl_->topInfo_.top_, 1);
        impl_->topInfo_.bTop_ = read_tps_conf(impl_->topfile_.c_str(), title,
                                              impl_->topInfo_.top_, &impl_->topInfo_.ePBC_,
                                              &impl_->topInfo_.xtop_, NULL, impl_->topInfo_.boxtop_, TRUE);
        if (hasTrajectory()
            && !settings.hasFlag(TrajectoryAnalysisSettings::efUseTopX))
        {
            sfree(impl_->topInfo_.xtop_);
            impl_->topInfo_.xtop_ = NULL;
        }
    }

    // Read the first frame if we don't know the maximum number of atoms
    // otherwise.
    int  natoms = -1;
    if (!impl_->topInfo_.hasTopology())
    {
        initFirstFrame();
        natoms = impl_->fr->natoms;
    }
    selections->setTopology(impl_->topInfo_.topology(), natoms);

    /*
       if (impl_->bSelDump)
       {
        gmx_ana_poscalc_coll_print_tree(stderr, impl_->pcc);
        fprintf(stderr, "\n");
       }
     */
}
Exemple #9
0
void
Angle::checkSelections(const SelectionList &sel1,
                       const SelectionList &sel2) const
{
    if (natoms2_ > 0 && sel1.size() != sel2.size())
    {
        GMX_THROW(InconsistentInputError(
                          "-group1 and -group2 should specify the same number of selections"));
    }

    for (size_t g = 0; g < sel1.size(); ++g)
    {
        int na1 = sel1[g].posCount();
        int na2 = (natoms2_ > 0) ? sel2[g].posCount() : 0;
        if (natoms1_ > 1 && na1 % natoms1_ != 0)
        {
            GMX_THROW(InconsistentInputError(formatString(
                                                     "Number of positions in selection %d in the first group not divisible by %d",
                                                     static_cast<int>(g + 1), natoms1_)));
        }
        if (natoms2_ > 1 && na2 % natoms2_ != 0)
        {
            GMX_THROW(InconsistentInputError(formatString(
                                                     "Number of positions in selection %d in the second group not divisible by %d",
                                                     static_cast<int>(g + 1), natoms2_)));
        }
        if (natoms1_ > 0 && natoms2_ > 1 && na1 / natoms1_ != na2 / natoms2_)
        {
            GMX_THROW(InconsistentInputError(
                              "Number of vectors defined by the two groups are not the same"));
        }
        if (g2type_[0] == 's' && sel2[g].posCount() != 1)
        {
            GMX_THROW(InconsistentInputError(
                              "The second group should contain a single position with -g2 sphnorm"));
        }
    }
}
Exemple #10
0
void SelectionTreeElement::checkIndexGroup(int natoms)
{
    GMX_RELEASE_ASSERT(type == SEL_CONST && v.type == GROUP_VALUE,
                       "Should only be called for index group elements");
    if (!gmx_ana_index_check_range(&u.cgrp, natoms))
    {
        std::string message = formatString(
                                  "Group '%s' cannot be used in selections, because it "
                                  "contains negative atom indices and/or references atoms "
                                  "not present (largest allowed atom index is %d).",
                                  name().c_str(), natoms);
        GMX_THROW(InconsistentInputError(message));
    }
}
Exemple #11
0
 virtual int getAtomCount()
 {
     if (!topInfo_.hasTopology())
     {
         if (trajectoryGroup_.isValid())
         {
             GMX_THROW(InconsistentInputError("-fgroup is only supported when -s is also specified"));
         }
         // Read the first frame if we don't know the maximum number of
         // atoms otherwise.
         initFirstFrame();
         return fr->natoms;
     }
     return -1;
 }
Exemple #12
0
void
SelectionCollection::evaluate(t_trxframe *fr, t_pbc *pbc)
{
    if (fr->natoms <= impl_->maxAtomIndex_)
    {
        std::string message = formatString(
                    "Trajectory has less atoms (%d) than what is required for "
                    "evaluating the provided selections (atoms up to index %d "
                    "are required).", fr->natoms, impl_->maxAtomIndex_ + 1);
        GMX_THROW(InconsistentInputError(message));
    }
    impl_->sc_.pcc.initFrame();

    SelectionEvaluator evaluator;
    evaluator.evaluate(this, fr, pbc);

    if (impl_->debugLevel_ >= 3)
    {
        std::fprintf(stderr, "\n");
        printTree(stderr, true);
    }
}
Exemple #13
0
void checkUserGpuIds(const gmx_gpu_info_t   &gpu_info,
                     const std::vector<int> &compatibleGpus,
                     const std::vector<int> &gpuIds)
{
    bool        foundIncompatibleGpuIds = false;
    std::string message
        = "Some of the requested GPUs do not exist, behave strangely, or are not compatible:\n";

    for (const auto &gpuId : gpuIds)
    {
        if (std::find(compatibleGpus.begin(), compatibleGpus.end(), gpuId) == compatibleGpus.end())
        {
            foundIncompatibleGpuIds = true;
            message                += gmx::formatString("    GPU #%d: %s\n",
                                                        gpuId,
                                                        getGpuCompatibilityDescription(gpu_info, gpuId));
        }
    }
    if (foundIncompatibleGpuIds)
    {
        GMX_THROW(InconsistentInputError(message));
    }
}
Exemple #14
0
void
TrajectoryAnalysisRunnerCommon::Impl::initFrameIndexGroup()
{
    if (!trajectoryGroup_.isValid())
    {
        return;
    }
    GMX_RELEASE_ASSERT(bTrajOpen_,
                       "Trajectory index only makes sense with a real trajectory");
    if (trajectoryGroup_.atomCount() != fr->natoms)
    {
        const std::string message = formatString(
                    "Selection specified with -fgroup has %d atoms, but "
                    "the trajectory (-f) has %d atoms.",
                    trajectoryGroup_.atomCount(), fr->natoms);
        GMX_THROW(InconsistentInputError(message));
    }
    fr->bIndex = TRUE;
    snew(fr->index, trajectoryGroup_.atomCount());
    std::copy(trajectoryGroup_.atomIndices().begin(),
              trajectoryGroup_.atomIndices().end(),
              fr->index);
}
void
SelectionCollection::compile()
{
    if (_impl->_sc.top == NULL && requiresTopology())
    {
        GMX_THROW(InconsistentInputError("Selection requires topology information, but none provided"));
    }
    if (!_impl->hasFlag(Impl::efExternalGroupsSet))
    {
        setIndexGroups(NULL);
    }
    if (_impl->_debugLevel >= 1)
    {
        printTree(stderr, false);
    }

    SelectionCompiler compiler;
    compiler.compile(this);

    if (_impl->hasFlag(Impl::efOwnPositionCollection))
    {
        if (_impl->_debugLevel >= 1)
        {
            std::fprintf(stderr, "\n");
            printTree(stderr, false);
            std::fprintf(stderr, "\n");
            gmx_ana_poscalc_coll_print_tree(stderr, _impl->_sc.pcc);
            std::fprintf(stderr, "\n");
        }
        gmx_ana_poscalc_init_eval(_impl->_sc.pcc);
        if (_impl->_debugLevel >= 1)
        {
            gmx_ana_poscalc_coll_print_tree(stderr, _impl->_sc.pcc);
            std::fprintf(stderr, "\n");
        }
    }
}
Exemple #16
0
void SelectionTreeElement::checkUnsortedAtoms(
    bool bUnsortedAllowed, ExceptionInitializer *errors) const
{
    const bool bUnsortedSupported
        = (type == SEL_CONST && v.type == GROUP_VALUE)
          || type == SEL_ROOT || type == SEL_SUBEXPR || type == SEL_SUBEXPRREF
          // TODO: Consolidate.
          || type == SEL_MODIFIER
          || (type == SEL_EXPRESSION && (u.expr.method->flags & SMETH_ALLOW_UNSORTED));

    // TODO: For some complicated selections, this may result in the same
    // index group reference being flagged as an error multiple times for the
    // same selection.
    SelectionTreeElementPointer child = this->child;
    while (child)
    {
        child->checkUnsortedAtoms(bUnsortedAllowed && bUnsortedSupported,
                                  errors);
        child = child->next;
    }

    // The logic here is simplified by the fact that only constant groups can
    // currently be the root cause of SEL_UNSORTED being set, so only those
    // need to be considered in triggering the error.
    if (!bUnsortedAllowed && (flags & SEL_UNSORTED)
            && type == SEL_CONST && v.type == GROUP_VALUE)
    {
        std::string message = formatString(
                                  "Group '%s' cannot be used in selections except "
                                  "as a full value of the selection, "
                                  "because atom indices in it are not sorted and/or "
                                  "it contains duplicate atoms.",
                                  name().c_str());
        errors->addNested(InconsistentInputError(message));
    }
}
Exemple #17
0
void
TrajectoryAnalysisRunnerCommon::optionsFinished()
{
    impl_->settings_.impl_->plotSettings.setTimeUnit(
            impl_->settings_.impl_->timeUnitManager.timeUnit());

    if (impl_->trjfile_.empty() && impl_->topfile_.empty())
    {
        GMX_THROW(InconsistentInputError("No trajectory or topology provided, nothing to do!"));
    }

    if (impl_->bStartTimeSet_)
    {
        setTimeValue(TBEGIN, impl_->startTime_);
    }
    if (impl_->bEndTimeSet_)
    {
        setTimeValue(TEND, impl_->endTime_);
    }
    if (impl_->bDeltaTimeSet_)
    {
        setTimeValue(TDELTA, impl_->deltaTime_);
    }
}
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);
    }
}
Exemple #19
0
void
Angle::initOptionsDone(TrajectoryAnalysisSettings *settings)
{
    // Validity checks.
    bool bSingle = (_g1type[0] == 'a' || _g1type[0] == 'd');

    if (bSingle && _g2type[0] != 'n')
    {
        GMX_THROW(InconsistentInputError("Cannot use a second group (-g2) with "
                                         "-g1 angle or dihedral"));
    }
    if (bSingle && _options.isSet("group2"))
    {
        GMX_THROW(InconsistentInputError("Cannot provide a second selection "
                                         "(-group2) with -g1 angle or dihedral"));
    }
    if (!bSingle && _g2type[0] == 'n')
    {
        GMX_THROW(InconsistentInputError("Should specify a second group (-g2) "
                                         "if the first group is not an angle or a dihedral"));
    }
    if (bSingle && _bDumpDist)
    {
        GMX_THROW(InconsistentInputError("Cannot calculate distances with -g1 angle or dihedral"));
        // _bDumpDist = false;
    }
    if (_bMulti && !bSingle)
    {
        GMX_THROW(InconsistentInputError("-mult can only be combined with -g1 angle or dihedral"));
    }
    if (_bMulti && _bSplit1)
    {
        GMX_THROW(InconsistentInputError("-mult can not be combined with -split1"));
    }
    if (_bMulti && _bAll)
    {
        GMX_THROW(InconsistentInputError("-mult and -all are mutually exclusive options"));
    }

    if (_bAll)
    {
        _sel1Adj->setOnlyStatic(true);
    }

    // Set up the number of positions per angle.
    switch (_g1type[0])
    {
        case 'a': _natoms1 = 3; break;
        case 'd': _natoms1 = 4; break;
        case 'v': _natoms1 = 2; break;
        case 'p': _natoms1 = 3; break;
        default:
            GMX_THROW(InternalError("invalid -g1 value"));
    }
    switch (_g2type[0])
    {
        case 'n': _natoms2 = 0; break;
        case 'v': _natoms2 = 2; break;
        case 'p': _natoms2 = 3; break;
        case 't': _natoms2 = 0; break;
        case 'z': _natoms2 = 0; break;
        case 's': _natoms2 = 1; break;
        default:
            GMX_THROW(InternalError("invalid -g2 value"));
    }
    if (_natoms2 == 0 && _options.isSet("group2"))
    {
        GMX_THROW(InconsistentInputError("Cannot provide a second selection (-group2) with -g2 t0 or z"));
    }

    if (!_bMulti)
    {
        _sel1Adj->setValueCount(_bSplit1 ? _natoms1 : 1);
    }
    if (_natoms2 > 0)
    {
        _sel2Adj->setValueCount(_bSplit2 ? _natoms2 : 1);
    }
}
Exemple #20
0
void
Angle::checkSelections(const std::vector<Selection *> &sel1,
                       const std::vector<Selection *> &sel2) const
{
    if (_bMulti)
    {
        for (size_t g = 0; g < sel1.size(); ++g)
        {
            if (sel1[g]->posCount() % _natoms1 != 0)
            {
                GMX_THROW(InconsistentInputError(formatString(
                    "Number of positions in selection %d not divisible by %d",
                    static_cast<int>(g + 1), _natoms1)));
            }
        }
        return;
    }

    int na1 = sel1[0]->posCount();
    int na2 = (_natoms2 > 0) ? sel2[0]->posCount() : 0;

    if (!_bSplit1 && _natoms1 > 1 && na1 % _natoms1 != 0)
    {
        GMX_THROW(InconsistentInputError(formatString(
            "Number of positions in the first group not divisible by %d",
            _natoms1)));
    }
    if (!_bSplit2 && _natoms2 > 1 && na2 % _natoms2 != 0)
    {
        GMX_THROW(InconsistentInputError(formatString(
            "Number of positions in the second group not divisible by %d",
            _natoms2)));
    }

    if (_bSplit1)
    {
        for (int g = 1; g < _natoms1; ++g)
        {
            if (sel1[g]->posCount() != na1)
            {
                GMX_THROW(InconsistentInputError(
                          "All selections in the first group should contain "
                          "the same number of positions"));
            }
        }
    }
    else
    {
        na1 /= _natoms1;
    }
    if (_natoms2 > 1)
    {
        if (_bSplit2)
        {
            for (int g = 1; g < _natoms2; ++g)
            {
                if (sel2[g]->posCount() != na2)
                {
                    GMX_THROW(InconsistentInputError(
                              "All selections in the second group should contain "
                              "the same number of positions"));
                }
            }
        }
        else
        {
            na2 /= _natoms2;
        }
    }
    if (_natoms1 > 0 && _natoms2 > 1 && na1 != na2)
    {
        GMX_THROW(InconsistentInputError(
                  "Number of vectors defined by the two groups are not the same"));
    }
    if (_g2type[0] == 's' && sel2[0]->posCount() != 1)
    {
        GMX_THROW(InconsistentInputError(
                  "The second group should contain a single position with -g2 sphnorm"));
    }
}
Exemple #21
0
void
SelectionCollection::compile()
{
    if (impl_->sc_.top == NULL && requiresTopology())
    {
        GMX_THROW(InconsistentInputError("Selection requires topology information, but none provided"));
    }
    if (!impl_->bExternalGroupsSet_)
    {
        setIndexGroups(NULL);
    }
    if (impl_->debugLevel_ >= 1)
    {
        printTree(stderr, false);
    }

    SelectionCompiler compiler;
    compiler.compile(this);

    if (impl_->debugLevel_ >= 1)
    {
        std::fprintf(stderr, "\n");
        printTree(stderr, false);
        std::fprintf(stderr, "\n");
        impl_->sc_.pcc.printTree(stderr);
        std::fprintf(stderr, "\n");
    }
    impl_->sc_.pcc.initEvaluation();
    if (impl_->debugLevel_ >= 1)
    {
        impl_->sc_.pcc.printTree(stderr);
        std::fprintf(stderr, "\n");
    }

    // TODO: It would be nicer to associate the name of the selection option
    // (if available) to the error message.
    SelectionDataList::const_iterator iter;
    for (iter = impl_->sc_.sel.begin(); iter != impl_->sc_.sel.end(); ++iter)
    {
        const internal::SelectionData &sel = **iter;
        if (sel.hasFlag(efSelection_OnlyAtoms))
        {
            if (!sel.hasOnlyAtoms())
            {
                std::string message = formatString(
                            "Selection '%s' does not evaluate to individual atoms. "
                            "This is not allowed in this context.",
                            sel.selectionText());
                GMX_THROW(InvalidInputError(message));
            }
        }
        if (sel.hasFlag(efSelection_DisallowEmpty))
        {
            if (sel.posCount() == 0)
            {
                std::string message = formatString(
                            "Selection '%s' never matches any atoms.",
                            sel.selectionText());
                GMX_THROW(InvalidInputError(message));
            }
        }
    }
}
Exemple #22
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);
    }
}