Extract IOptionsContainer from Options
[alexxy/gromacs.git] / src / gromacs / trajectoryanalysis / modules / angle.cpp
index e63cb502d644bf4cb953b9500bddde905be5570b..c9826aed25a157337da46610b4132cdc1c67c75b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014,2015, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -55,6 +55,7 @@
 #include "gromacs/math/vec.h"
 #include "gromacs/options/basicoptions.h"
 #include "gromacs/options/filenameoption.h"
+#include "gromacs/options/ioptionscontainer.h"
 #include "gromacs/options/options.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/selection/selection.h"
@@ -244,9 +245,8 @@ class Angle : public TrajectoryAnalysisModule
 {
     public:
         Angle();
-        virtual ~Angle();
 
-        virtual void initOptions(Options                    *options,
+        virtual void initOptions(IOptionsContainer          *options,
                                  TrajectoryAnalysisSettings *settings);
         virtual void optionsFinished(Options                    *options,
                                      TrajectoryAnalysisSettings *settings);
@@ -284,8 +284,7 @@ class Angle : public TrajectoryAnalysisModule
         std::vector<int>                         angleCount_;
         int                                      natoms1_;
         int                                      natoms2_;
-        // TODO: It is not possible to put rvec into a container.
-        std::vector<rvec *>                      vt0_;
+        std::vector<std::vector<RVec> >          vt0_;
 
         // Copy and assign disallowed by base.
 };
@@ -305,17 +304,8 @@ Angle::Angle()
 }
 
 
-Angle::~Angle()
-{
-    for (size_t g = 0; g < vt0_.size(); ++g)
-    {
-        delete [] vt0_[g];
-    }
-}
-
-
 void
-Angle::initOptions(Options *options, TrajectoryAnalysisSettings * /*settings*/)
+Angle::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings)
 {
     static const char *const desc[] = {
         "[THISMODULE] computes different types of angles between vectors.",
@@ -370,7 +360,7 @@ Angle::initOptions(Options *options, TrajectoryAnalysisSettings * /*settings*/)
     static const char *const cGroup2TypeEnum[] =
     { "none", "vector", "plane", "t0", "z", "sphnorm" };
 
-    options->setDescription(desc);
+    settings->setHelpText(desc);
 
     options->addOption(FileNameOption("oav").filetype(eftPlot).outputFile()
                            .store(&fnAverage_).defaultBasename("angaver")
@@ -584,7 +574,7 @@ Angle::initAnalysis(const TrajectoryAnalysisSettings &settings,
         vt0_.resize(sel1_.size());
         for (size_t g = 0; g < sel1_.size(); ++g)
         {
-            vt0_[g] = new rvec[sel1_[g].posCount() / natoms1_];
+            vt0_[g].resize(sel1_[g].posCount() / natoms1_);
         }
     }
 
@@ -697,21 +687,38 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
     {
         rvec  v1, v2;
         rvec  c1, c2;
+
+        // v2 & c2 are conditionally set in the switch statement below, and conditionally
+        // used in a different switch statement later. Apparently the clang static analyzer
+        // thinks there are cases where they can be used uninitialzed (which I cannot find),
+        // but to avoid trouble if we ever change just one of the switch statements it
+        // makes sense to clear them outside the first switch.
+
+        clear_rvec(v2);
+        clear_rvec(c2);
+
         switch (g2type_[0])
         {
             case 'z':
-                clear_rvec(v2);
                 v2[ZZ] = 1.0;
-                clear_rvec(c2);
                 break;
             case 's':
                 copy_rvec(sel2_[g].position(0).x(), c2);
                 break;
+            default:
+                // do nothing
+                break;
         }
+
         dh.selectDataSet(g);
         for (int n = 0; n < angleCount_[g]; ++n, iter1.nextValue(), iter2.nextValue())
         {
             rvec x[4];
+            // x[] will be assigned below based on the number of atoms used to initialize iter1,
+            // which in turn should correspond perfectly to g1type_[0] (which determines how many we read),
+            // but unsurprisingly the static analyzer chokes a bit on that.
+            clear_rvecs(4, x);
+
             real angle;
             // checkSelections() ensures that this reflects all the involved
             // positions.