LCOV - code coverage report
Current view: top level - landmarks - LandmarkSelection.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 87 96 90.6 %
Date: 2025-12-04 11:19:34 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2015-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #include "core/ActionShortcut.h"
      23             : #include "core/ActionRegister.h"
      24             : #include "core/ActionWithValue.h"
      25             : #include "core/ActionPilot.h"
      26             : #include "core/PlumedMain.h"
      27             : #include "core/ActionSet.h"
      28             : 
      29             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_STRIDE
      30             : /*
      31             : Select every ith frame from the stored set of configurations
      32             : 
      33             : If you have collected a set of trajectory frames using [COLLECT_FRAMES](COLLECT_FRAMES.md) you can use this action to
      34             : select a subset you have collected.  This particular method for landmark selection reduces the number of frames by selecting taking every
      35             : $i$th frame. So, for example, if you use the input below every 10th frame of the stored trajectory is transferred to the `ll_data` Value
      36             : that is output which is output in the PDB file.  This happens because we are collecting 1000 trajectory frames in total but only taking
      37             : 100 landmarks from this data.
      38             : 
      39             : ```plumed
      40             : # This stores the positions of all the first 10 atoms in the system for later analysis
      41             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
      42             : 
      43             : # Select landmarks
      44             : ll: LANDMARK_SELECT_STRIDE ARG=cc NLANDMARKS=100
      45             : 
      46             : # Output the data to a file
      47             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
      48             : ```
      49             : 
      50             : If you expand the shortcuts in the input above you will notice that the LANDMARK_SELECT_STRIDE shortcut creates a [DISSIMILARITIES](DISSIMILARITIES.md) action
      51             : that calculates the distances between the input frames. We need to calculate these dissimilarities here because the LANDMARK_SELECT_STRIDE shortcut computes the
      52             : weights of the landmarks by doing a [VORONOI](VORONOI.md) analysis.  If you would like to turn this and the computing of dissimilarities off you can use the
      53             : NODISSIMILARITIES flag as shown below:
      54             : 
      55             : ```plumed
      56             : # This stores the positions of all the first 10 atoms in the system for later analysis
      57             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
      58             : 
      59             : # Select landmarks
      60             : ll: LANDMARK_SELECT_STRIDE ARG=cc NLANDMARKS=100 NODISSIMILARITIES
      61             : 
      62             : # Output the data to a file
      63             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
      64             : ```
      65             : 
      66             : If the NODISSIMILARITIES flag is __not__ present the weights of the landmark points are calculated by using VORONOI procedure as is illustrated in the expanded
      67             : version of the first example input above.  If you wish to turn this off you can use the NOVORONOI flag as shown below:
      68             : 
      69             : ```plumed
      70             : # This stores the positions of all the first 10 atoms in the system for later analysis
      71             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
      72             : 
      73             : # Select landmarks
      74             : ll: LANDMARK_SELECT_STRIDE ARG=cc NLANDMARKS=100 NOVORONOI
      75             : 
      76             : # Output the data to a file
      77             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
      78             : ```
      79             : 
      80             : Be aware, however, that dissimilarities are still computed if you only the the NOVORONOI flag.  If you use NODISSIMILARITIES the voronoi weights are not computed
      81             : and the dissimilarities are not computed.
      82             : 
      83             : If you have already computed the dissimilarities between the collected frames you can pass them in input to the LANDMARK_SELECT_STRIDE funtion as shown below:
      84             : 
      85             : ```plumed
      86             : # This stores the positions of all the first 10 atoms in the system for later analysis
      87             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
      88             : 
      89             : # This calculates the dissimilarities between the stored frames
      90             : cc_dataT: TRANSPOSE ARG=cc_data
      91             : dd: DISSIMILARITIES ARG=cc_data,cc_dataT
      92             : 
      93             : # Select landmarks
      94             : ll: LANDMARK_SELECT_STRIDE ARG=cc DISSIMILARITIES=dd NLANDMARKS=100
      95             : 
      96             : # Output the data to a file
      97             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
      98             : ```
      99             : 
     100             : Notice that you can also read in dissimilarities from a file using a [CONSTANT](CONSTANT.md) action and pass these directly to the LANDMARK_SELECT_STRIDE action and avoid using COLLECT_FRAMES.
     101             : 
     102             : You can learn how to use landmark selection for dimensionality reduction calculations by working through [this tutorial](https://www.plumed-tutorials.org/lessons/21/006/data/DIMENSIONALITY.html)
     103             : 
     104             : */
     105             : //+ENDPLUMEDOC
     106             : 
     107             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_RANDOM
     108             : /*
     109             : Select a random set of landmarks from a large set of configurations.
     110             : 
     111             : If you have collected a set of trajectory frames using [COLLECT_FRAMES](COLLECT_FRAMES.md) you can use this action to
     112             : select a subset of the configurations you have collected.  This particular method for landmark selection reduces the number of frames by
     113             : chooseing NLANDMARKS points from the data collected by COLLECT_FRAMES at random by using a quasi random number generator for which you may way to specify a seed using
     114             : the SEED keyword.  So, for example, if you use the input 100 randomly-selected
     115             : points from the 1000 trajectory frames that were by collected by the COLLECT_FRAMES action are transferred to the `ll_data` Value that is output which is output in the PDB file.
     116             : 
     117             : ```plumed
     118             : # This stores the positions of all the first 10 atoms in the system for later analysis
     119             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
     120             : 
     121             : # Select landmarks
     122             : ll: LANDMARK_SELECT_RANDOM ARG=cc SEED=23 NLANDMARKS=100
     123             : 
     124             : # Output the data to a file
     125             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
     126             : ```
     127             : 
     128             : If you expand the shortcuts in the input above you will notice that the LANDMARK_SELECT_RANDOM shortcut creates a [DISSIMILARITIES](DISSIMILARITIES.md) action
     129             : that calculates the distances between the input frames. We need to calculate these dissimilarities here because the LANDMARK_SELECT_RANDOM shortcut computes the
     130             : weights of the landmarks by doing a [VORONOI](VORONOI.md) analysis.  If you would like to turn this and the computing of dissimilarities off you can use the
     131             : NODISSIMILARITIES flag as shown below:
     132             : 
     133             : ```plumed
     134             : # This stores the positions of all the first 10 atoms in the system for later analysis
     135             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
     136             : 
     137             : # Select landmarks
     138             : ll: LANDMARK_SELECT_RANDOM ARG=cc NLANDMARKS=100 NODISSIMILARITIES
     139             : 
     140             : # Output the data to a file
     141             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
     142             : ```
     143             : 
     144             : If the NODISSIMILARITIES flag is __not__ present the weights of the landmark points are calculated by using VORONOI procedure as is illustrated in the expanded
     145             : version of the first example input above.  If you wish to turn this off you can use the NOVORONOI flag as shown below:
     146             : 
     147             : ```plumed
     148             : # This stores the positions of all the first 10 atoms in the system for later analysis
     149             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
     150             : 
     151             : # Select landmarks
     152             : ll: LANDMARK_SELECT_RANDOM ARG=cc NLANDMARKS=100 NOVORONOI
     153             : 
     154             : # Output the data to a file
     155             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
     156             : ```
     157             : 
     158             : Be aware, however, that dissimilarities are still computed if you only the the NOVORONOI flag.  If you use NODISSIMILARITIES the voronoi weights are not computed
     159             : and the dissimilarities are not computed.
     160             : 
     161             : If you have already computed the dissimilarities between the collected frames you can pass them in input to the LANDMARK_SELECT_RANDOM funtion as shown below:
     162             : 
     163             : ```plumed
     164             : # This stores the positions of all the first 10 atoms in the system for later analysis
     165             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
     166             : 
     167             : # This calculates the dissimilarities between the stored frames
     168             : cc_dataT: TRANSPOSE ARG=cc_data
     169             : dd: DISSIMILARITIES ARG=cc_data,cc_dataT
     170             : 
     171             : # Select landmarks
     172             : ll: LANDMARK_SELECT_RANDOM ARG=cc DISSIMILARITIES=dd NLANDMARKS=100
     173             : 
     174             : # Output the data to a file
     175             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
     176             : ```
     177             : 
     178             : Notice that you can also read in dissimilarities from a file using a [CONSTANT](CONSTANT.md) action and pass these directly to the LANDMARK_SELECT_RANDOM shortcut and avoid using COLLECT_FRAMES.
     179             : 
     180             : You can learn how to use landmark selection for dimensionality reduction calculations by working through [this tutorial](https://www.plumed-tutorials.org/lessons/21/006/data/DIMENSIONALITY.html)
     181             : 
     182             : */
     183             : //+ENDPLUMEDOC
     184             : 
     185             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_FPS
     186             : /*
     187             : Select a of landmarks from a large set of configurations using farthest point sampling.
     188             : 
     189             : If you have collected a set of trajectory frames using [COLLECT_FRAMES](COLLECT_FRAMES.md) you can use this action to
     190             : select a subset of the configurations you have collected. This shortcut does this using [FARTHEST_POINT_SAMPLING](FARTHEST_POINT_SAMPLING.md)
     191             : the first point is thus selected at random, which is why you may want to set a random SEED using the `SEED` keyword.  The remaining points are then selected by taking the unselected point in the input data set that is the furthest
     192             : from all the points that have been selected thus far.  The following input demonstrates how you can use this method:
     193             : 
     194             : ```plumed
     195             : # This stores the positions of all the first 10 atoms in the system for later analysis
     196             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
     197             : 
     198             : # Select landmarks
     199             : ll: LANDMARK_SELECT_FPS ARG=cc NLANDMARKS=100 SEED=23
     200             : 
     201             : # Output the data to a file
     202             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
     203             : ```
     204             : 
     205             : If you expand the shortcuts in the input above you will notice that the LANDMARK_SELECT_RANDOM shortcut creates a [DISSIMILARITIES](DISSIMILARITIES.md) action
     206             : that calculates the distances between the input frames. We have to compute these dissimilarities in order to perform the farthest point sampling here so you cannot use the
     207             : NODISSIMILARITIES flag with this action.  However, we also need the dissimilarities to compute the weights of the landmarks as this is done by performing a [VORONOI](VORONOI.md) analysis.
     208             : If you would like to turn off the computation of the VORONOI weights you can use the NOVORONOI flag as shown below:
     209             : 
     210             : ```plumed
     211             : # This stores the positions of all the first 10 atoms in the system for later analysis
     212             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
     213             : 
     214             : # Select landmarks
     215             : ll: LANDMARK_SELECT_FPS ARG=cc NLANDMARKS=100 NOVORONOI
     216             : 
     217             : # Output the data to a file
     218             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
     219             : ```
     220             : 
     221             : If you have already computed the dissimilarities between the collected frames you can pass them in input to the LANDMARK_SELECT_FPS funtion as shown below:
     222             : 
     223             : ```plumed
     224             : # This stores the positions of all the first 10 atoms in the system for later analysis
     225             : cc: COLLECT_FRAMES ATOMS=1,2,3,4,5,6,7,8,9,10 ALIGN=OPTIMAL STRIDE=1 CLEAR=1000
     226             : 
     227             : # This calculates the dissimilarities between the stored frames
     228             : cc_dataT: TRANSPOSE ARG=cc_data
     229             : dd: DISSIMILARITIES ARG=cc_data,cc_dataT
     230             : 
     231             : # Select landmarks
     232             : ll: LANDMARK_SELECT_FPS ARG=cc DISSIMILARITIES=dd NLANDMARKS=100
     233             : 
     234             : # Output the data to a file
     235             : DUMPPDB ATOMS=ll_data ATOM_INDICES=1,2,3,4,5,6,7,8,9,10 FILE=traj.pdb STRIDE=1000
     236             : ```
     237             : 
     238             : Notice that you can also read in dissimilarities from a file using a [CONSTANT](CONSTANT.md) action and pass these directly to the LANDMARK_SELECT_FPS shortcut and avoid using COLLECT_FRAMES.
     239             : 
     240             : You can learn how to use landmark selection for dimensionality reduction calculations by working through [this tutorial](https://www.plumed-tutorials.org/lessons/21/006/data/DIMENSIONALITY.html)
     241             : 
     242             : */
     243             : //+ENDPLUMEDOC
     244             : 
     245             : namespace PLMD {
     246             : namespace landmarks {
     247             : 
     248             : class LandmarkSelection : public ActionShortcut {
     249             : public:
     250             :   static void registerKeywords( Keywords& keys );
     251             :   explicit LandmarkSelection( const ActionOptions& ao );
     252             : };
     253             : 
     254             : PLUMED_REGISTER_ACTION(LandmarkSelection,"LANDMARK_SELECT_STRIDE")
     255             : PLUMED_REGISTER_ACTION(LandmarkSelection,"LANDMARK_SELECT_RANDOM")
     256             : PLUMED_REGISTER_ACTION(LandmarkSelection,"LANDMARK_SELECT_FPS")
     257             : 
     258          17 : void LandmarkSelection::registerKeywords( Keywords& keys ) {
     259          17 :   ActionShortcut::registerKeywords( keys );
     260          17 :   keys.add("optional","ARG","the COLLECT_FRAMES action that you used to get the data");
     261          17 :   keys.add("optional","DISSIMILARITIES","the matrix of dissimilarities if this is not provided the squared dissimilarities are calculated");
     262          17 :   keys.add("compulsory","NLANDMARKS","the numbe rof landmarks you would like to create");
     263          34 :   if( keys.getDisplayName()!="LANDMARK_SELECT_STRIDE" ) {
     264           7 :     keys.add("optional","SEED","a random number seed");
     265             :   }
     266          17 :   keys.addFlag("NOVORONOI",false,"do not do a Voronoi analysis of the data to determine weights of final points");
     267          34 :   if( keys.getDisplayName()!="LANDMARK_SELECT_FPS" ) {
     268          14 :     keys.addFlag("NODISSIMILARITIES",false,"do not calculate the dissimilarities");
     269             :   }
     270          34 :   keys.addOutputComponent("data","ARG","matrix","the data that is being collected by this action");
     271          34 :   keys.addOutputComponent("logweights","ARG","vector","the logarithms of the weights of the data points");
     272          34 :   keys.addOutputComponent("rectdissims","DISSIMILARITIES","matrix","a rectangular matrix containing the distances between the landmark points and the rest of the points");
     273          34 :   keys.addOutputComponent("sqrdissims","DISSIMILARITIES","matrix","a square matrix containing the distances between each pair of landmark points");
     274          17 :   keys.needsAction("LOGSUMEXP");
     275          17 :   keys.needsAction("TRANSPOSE");
     276          17 :   keys.needsAction("DISSIMILARITIES");
     277          17 :   keys.needsAction("ONES");
     278          17 :   keys.needsAction("CREATE_MASK");
     279          17 :   keys.needsAction("FARTHEST_POINT_SAMPLING");
     280          17 :   keys.needsAction("SELECT_WITH_MASK");
     281          17 :   keys.needsAction("COMBINE");
     282          17 :   keys.needsAction("VORONOI");
     283          17 :   keys.needsAction("MATRIX_PRODUCT");
     284          17 :   keys.needsAction("CUSTOM");
     285          17 : }
     286             : 
     287           8 : LandmarkSelection::LandmarkSelection( const ActionOptions& ao ):
     288             :   Action(ao),
     289           8 :   ActionShortcut(ao) {
     290             :   std::string nlandmarks;
     291           8 :   parse("NLANDMARKS",nlandmarks);
     292             :   bool novoronoi;
     293           8 :   parseFlag("NOVORONOI",novoronoi);
     294             : 
     295           8 :   bool nodissims=false;
     296           8 :   if( keywords.exists("NODISSIMILARITIES") ) {
     297          14 :     parseFlag("NODISSIMILARITIES",nodissims);
     298             :   }
     299             :   std::string argn, dissims;
     300           8 :   parse("ARG",argn);
     301          16 :   parse("DISSIMILARITIES",dissims);
     302           8 :   if( argn.length()>0 ) {
     303           7 :     ActionShortcut* as = plumed.getActionSet().getShortcutActionWithLabel( argn );
     304           7 :     if( !as || as->getName()!="COLLECT_FRAMES" ) {
     305           0 :       error("found no COLLECT_FRAMES action with label " + argn );
     306             :     }
     307             :     // Get the weights
     308          14 :     readInputLine( getShortcutLabel() + "_allweights: LOGSUMEXP ARG=" + argn + "_logweights");
     309             :   }
     310           8 :   if( dissims.length()>0 ) {
     311           4 :     ActionWithValue* ds = plumed.getActionSet().selectWithLabel<ActionWithValue*>( dissims );
     312           4 :     if( (ds->copyOutput(0))->getRank()!=2 ) {
     313           0 :       error("input for dissimilarities shoudl be a matrix");
     314             :     }
     315             :     // Calculate the dissimilarities if the user didn't specify them
     316           4 :   } else if( !nodissims ) {
     317           2 :     readInputLine( getShortcutLabel() + "_" + argn + "_dataT: TRANSPOSE ARG=" + argn + "_data");
     318           1 :     dissims = getShortcutLabel() + "_dissims";
     319           2 :     readInputLine( getShortcutLabel() + "_dissims: DISSIMILARITIES SQUARED ARG=" + argn + "_data," + getShortcutLabel() + "_" + argn + "_dataT");
     320             :   }
     321             :   // This deals with a corner case whereby users have a matrix of dissimilarities but no corresponding coordinates for these frames
     322           8 :   if( argn.length()==0 && dissims.size()>0 ) {
     323           1 :     ActionWithValue* ds = plumed.getActionSet().selectWithLabel<ActionWithValue*>( dissims );
     324           1 :     if( ds->getName()!="CONSTANT" || (ds->copyOutput(0))->getRank()!=2 ) {
     325           0 :       error("set ARG as well as DISSIMILARITIES");
     326             :     }
     327             :     std::string size;
     328           1 :     Tools::convert(  (ds->copyOutput(0))->getShape()[0], size );
     329           2 :     readInputLine( getShortcutLabel() + "_allweights: ONES SIZE=" + size );
     330             :   }
     331             : 
     332           8 :   if( getName()=="LANDMARK_SELECT_STRIDE" ) {
     333          12 :     readInputLine( getShortcutLabel() + "_mask: CREATE_MASK ARG=" + getShortcutLabel() + "_allweights TYPE=stride NZEROS=" + nlandmarks );
     334           2 :   } else if( getName()=="LANDMARK_SELECT_RANDOM" ) {
     335           1 :     if( argn.length()==0 ) {
     336           0 :       error("must set COLLECT_FRAMES object for landmark selection using ARG keyword");
     337             :     }
     338             :     std::string seed;
     339           2 :     parse("SEED",seed);
     340           1 :     if( seed.length()>0 ) {
     341           2 :       seed = " SEED=" + seed;
     342             :     }
     343           2 :     readInputLine( getShortcutLabel() + "_mask: CREATE_MASK ARG=" + getShortcutLabel() + "_allweights TYPE=random NZEROS=" + nlandmarks + seed );
     344           1 :   } else if( getName()=="LANDMARK_SELECT_FPS" ) {
     345           1 :     if( dissims.length()==0 ) {
     346           0 :       error("dissimiarities must be defined to use FPS sampling");
     347             :     }
     348             :     std::string seed;
     349           2 :     parse("SEED",seed);
     350           1 :     if( seed.length()>0 ) {
     351           0 :       seed = " SEED=" + seed;
     352             :     }
     353           2 :     readInputLine( getShortcutLabel() + "_mask: FARTHEST_POINT_SAMPLING ARG=" + dissims + " NZEROS=" + nlandmarks + seed );
     354             :   }
     355             : 
     356           8 :   if( argn.length()>0 ) {
     357          14 :     readInputLine( getShortcutLabel() + "_data: SELECT_WITH_MASK ARG=" + argn + "_data ROW_MASK=" + getShortcutLabel() + "_mask");
     358             :   }
     359             : 
     360             :   unsigned nland;
     361           8 :   Tools::convert( nlandmarks, nland );
     362           8 :   if( dissims.length()>0 ) {
     363           5 :     ActionWithValue* ds = plumed.getActionSet().selectWithLabel<ActionWithValue*>( dissims );
     364           5 :     if( (ds->copyOutput(0))->getShape()[0]==nland ) {
     365           1 :       if( !novoronoi ) {
     366           0 :         warning("cannot use voronoi procedure to give weights as not all distances between points are known");
     367           0 :         novoronoi=true;
     368             :       }
     369           2 :       readInputLine( getShortcutLabel() + "_sqrdissims: COMBINE ARG=" + dissims + " PERIODIC=NO");
     370             :     } else {
     371           8 :       readInputLine( getShortcutLabel() + "_rmask: CREATE_MASK ARG=" + getShortcutLabel() + "_allweights TYPE=nomask");
     372           8 :       readInputLine( getShortcutLabel() + "_rectdissims: SELECT_WITH_MASK ARG=" + dissims + " COLUMN_MASK=" + getShortcutLabel() + "_mask ROW_MASK=" + getShortcutLabel() + "_rmask");
     373           8 :       readInputLine( getShortcutLabel() + "_sqrdissims: SELECT_WITH_MASK ARG=" + dissims + " ROW_MASK=" + getShortcutLabel() + "_mask COLUMN_MASK=" + getShortcutLabel() + "_mask");
     374             :     }
     375             :   }
     376             : 
     377           8 :   if( !novoronoi && argn.length()>0 && dissims.length()>0 ) {
     378           6 :     readInputLine( getShortcutLabel() + "_voronoi: VORONOI ARG=" + getShortcutLabel() + "_rectdissims");
     379           6 :     readInputLine( getShortcutLabel() + "_allweightsT: TRANSPOSE ARG=" + getShortcutLabel() + "_allweights");
     380           6 :     readInputLine( getShortcutLabel() + "_weightsT: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_allweightsT," + getShortcutLabel() + "_voronoi");
     381           6 :     readInputLine( getShortcutLabel() + "_weights: TRANSPOSE ARG=" + getShortcutLabel() + "_weightsT");
     382           6 :     readInputLine( getShortcutLabel() + "_logweights: CUSTOM ARG=" + getShortcutLabel() + "_weights FUNC=log(x) PERIODIC=NO");
     383           5 :   } else if( argn.length()>0 ) {
     384           4 :     if( !novoronoi ) {
     385           0 :       warning("cannot use voronoi procedure to give weights to landmark points as DISSIMILARITIES was not set");
     386             :     }
     387           8 :     readInputLine( getShortcutLabel() + "_logweights: SELECT_WITH_MASK ARG=" + argn + "_logweights MASK=" + getShortcutLabel() + "_mask");
     388             :   }
     389             :   // Create the vector of ones that is needed by Classical MDS
     390           8 :   if( argn.length()>0 ) {
     391          14 :     readInputLine( getShortcutLabel() + "_ones: SELECT_WITH_MASK ARG=" + argn + "_ones MASK=" + getShortcutLabel() + "_mask");
     392             :   }
     393           8 : }
     394             : 
     395             : }
     396             : }

Generated by: LCOV version 1.16