LCOV - code coverage report
Current view: top level - secondarystructure - ParabetaRMSD.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 194 201 96.5 %
Date: 2025-12-04 11:19:34 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-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 "SecondaryStructureBase.h"
      23             : #include "core/ActionShortcut.h"
      24             : #include "core/ActionRegister.h"
      25             : 
      26             : namespace PLMD {
      27             : namespace secondarystructure {
      28             : 
      29             : //+PLUMEDOC COLVAR PARABETARMSD
      30             : /*
      31             : Probe the parallel beta sheet content of your protein structure.
      32             : 
      33             : Two protein segments containing three contiguous residues can form a parallel beta sheet.
      34             : Although if the two segments are part of the same protein chain they must be separated by
      35             : a minimum of 3 residues to make room for the turn. This colvar thus generates the set of
      36             : all possible six residue sections that could conceivably form a parallel beta sheet
      37             : and calculates the [DRMSD](DRMSD.md) or [RMSD](RMSD.md) distance between the configuration in which the residues find themselves
      38             : and an idealized parallel beta sheet structure. These distances can be calculated by either
      39             : aligning the instantaneous structure with the reference structure and measuring each
      40             : atomic displacement or by calculating differences between the set of inter-atomic
      41             : distances in the reference and instantaneous structures.
      42             : 
      43             : This colvar is based on the reference in the bibliography below.  The authors of
      44             : this paper use the set of distances from the parallel beta sheet configurations to measure
      45             : the number of segments whose configuration resembles a parallel beta sheet. This is done by calculating
      46             : the following sum of functions of the rmsd distances:
      47             : 
      48             : $$
      49             : s = \sum_i \frac{ 1 - \left(\frac{r_i-d_0}{r_0}\right)^n } { 1 - \left(\frac{r_i-d_0}{r_0}\right)^m }
      50             : $$
      51             : 
      52             : where the sum runs over all possible segments of parallel beta sheet.  By default the
      53             : NN, MM and D_0 parameters are set equal to those used in the paper cited below.  The R_0
      54             : parameter must be set by the user - the value used in the paper cited below was 0.08 nm.
      55             : 
      56             : If you change the function in the above sum you can calculate quantities such as the average
      57             : distance from a structure composed of only parallel beta sheets or the distance between the set of
      58             : residues that is closest to a parallel beta sheet and the reference configuration. To do these sorts of
      59             : calculations you can use the AVERAGE and MIN keywords. In addition you can use the LESS_THAN
      60             : keyword if you would like to change the form of the switching function. If you use any of these
      61             : options you no longer need to specify NN, R_0, MM and D_0.
      62             : 
      63             : The following input calculates the number of six residue segments of
      64             : protein that are in an parallel beta sheet configuration.
      65             : 
      66             : ```plumed
      67             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
      68             : MOLINFO STRUCTURE=regtest/basic/rt32/helix.pdb
      69             : pb: PARABETARMSD RESIDUES=all STRANDS_CUTOFF=1 R_0=0.1
      70             : PRINT ARG=pb FILE=colvar
      71             : ```
      72             : 
      73             : Here the same is done use [RMSD](RMSD.md) instead of [DRMSD](DRMSD.md), which is normally faster.
      74             : 
      75             : ```plumed
      76             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
      77             : MOLINFO STRUCTURE=regtest/basic/rt32/helix.pdb
      78             : WHOLEMOLECULES ENTITY0=1-100
      79             : hh: PARABETARMSD RESIDUES=all TYPE=OPTIMAL LESS_THAN={RATIONAL R_0=0.1 NN=8 MM=12}  STRANDS_CUTOFF=1
      80             : PRINT ARG=hh.lessthan FILE=colvar
      81             : ```
      82             : 
      83             : __YOUR CALCULATION WILL BE MUCH FASTER IF YOU USE THE `STRANDS_CUTOFF` KEYWORD.__  As you can see from the
      84             : expanded version of the inputs above this keyword reduces the computational cost of the calculation by
      85             : avoiding calculations of the RMSD values for segments that have the two strands of the beta sheet further apart
      86             : than a cutoff.
      87             : 
      88             : ## Periodic boundary conditions
      89             : 
      90             : You can turn off periodic boundary conditions by using the NOPBC flag as shown below:
      91             : 
      92             : ```plumed
      93             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
      94             : MOLINFO STRUCTURE=regtest/basic/rt32/helix.pdb
      95             : pb: PARABETARMSD RESIDUES=all STRANDS_CUTOFF=1 R_0=0.1 NOPBC
      96             : PRINT ARG=pb FILE=colvar
      97             : ```
      98             : 
      99             : If you are using [DRMSD](DRMSD.md) to measure distances and you __don't__ use the NOPBC flag then
     100             : all distances in the instaneous structure are evaluated in a way that takes the periodic boundary conditions
     101             : into account. Using the NOPBC flag turns off this treatment.
     102             : 
     103             : If you are using [RMSD](RMSD.md) to measure distances and you __don't__ use the NOPBC flag the the instaneous positions of
     104             : each segment for which the RMSD is computed is reconstructed using the procedure outlined in the documentation for [WHOLEMOLECULES](WHOLEMOLECULES.md)
     105             : before the RMSD is computed. Using the NOPBC flag turns off this treatment.
     106             : 
     107             : */
     108             : //+ENDPLUMEDOC
     109             : 
     110             : class ParabetaRMSD : public ActionShortcut {
     111             : public:
     112             :   static void registerKeywords( Keywords& keys );
     113             :   explicit ParabetaRMSD(const ActionOptions&);
     114             : };
     115             : 
     116             : PLUMED_REGISTER_ACTION(ParabetaRMSD,"PARABETARMSD")
     117             : 
     118         100 : void ParabetaRMSD::registerKeywords( Keywords& keys ) {
     119         100 :   SecondaryStructureBase<Vector>::registerKeywords( keys );
     120         100 :   keys.remove("ATOMS");
     121         100 :   keys.remove("SEGMENT");
     122         100 :   keys.remove("STRUCTURE");
     123         100 :   keys.remove("MASK");
     124         100 :   keys.remove("ALIGN_STRANDS");
     125         200 :   keys.setValueDescription("scalar/vector","if LESS_THAN is present the RMSD distance between each residue and the ideal parallel beta sheet.  If LESS_THAN is not present the number of residue segments where the structure is similar to a parallel beta sheet");
     126         100 :   keys.add("compulsory","STYLE","all","Parallel beta sheets can either form in a single chain or from a pair of chains. If STYLE=all all "
     127             :            "chain configuration with the appropriate geometry are counted.  If STYLE=inter "
     128             :            "only sheet-like configurations involving two chains are counted, while if STYLE=intra "
     129             :            "only sheet-like configurations involving a single chain are counted");
     130         100 :   keys.add("optional","STRANDS_CUTOFF","If in a segment of protein the two strands are further apart then the calculation "
     131             :            "of the actual RMSD is skipped as the structure is very far from being beta-sheet like. "
     132             :            "This keyword speeds up the calculation enormously when you are using the LESS_THAN option. "
     133             :            "However, if you are using some other option, then this cannot be used");
     134         100 :   keys.needsAction("LOWEST");
     135         100 :   keys.needsAction("DISTANCE");
     136         100 :   keys.needsAction("CUSTOM");
     137         100 : }
     138             : 
     139          18 : ParabetaRMSD::ParabetaRMSD(const ActionOptions&ao):
     140             :   Action(ao),
     141          18 :   ActionShortcut(ao) {
     142             :   // Read in the input and create a string that describes how to compute the less than
     143             :   std::string ltmap;
     144          18 :   bool uselessthan=SecondaryStructureBase<Vector>::readShortcutWords( ltmap, this );
     145             :   // read in the backbone atoms
     146             :   std::vector<unsigned> chains;
     147             :   std::vector<std::string> all_atoms;
     148          36 :   SecondaryStructureBase<Vector>::readBackboneAtoms( this, plumed, "protein", chains, all_atoms );
     149             : 
     150             :   bool intra_chain(false), inter_chain(false);
     151             :   std::string style;
     152          36 :   parse("STYLE",style);
     153          18 :   if( Tools::caseInSensStringCompare(style, "all") ) {
     154             :     intra_chain=true;
     155             :     inter_chain=true;
     156           1 :   } else if( Tools::caseInSensStringCompare(style, "inter") ) {
     157             :     intra_chain=false;
     158             :     inter_chain=true;
     159           0 :   } else if( Tools::caseInSensStringCompare(style, "intra") ) {
     160             :     intra_chain=true;
     161             :     inter_chain=false;
     162             :   } else {
     163           0 :     error( style + " is not a valid directive for the STYLE keyword");
     164             :   }
     165             : 
     166          18 :   double strands_cutoff=-1.0;
     167          36 :   parse("STRANDS_CUTOFF",strands_cutoff);
     168             :   std::string scutoff_action;
     169          18 :   if( strands_cutoff>0 ) {
     170          32 :     scutoff_action=getShortcutLabel() + "_cut_dists: DISTANCE ";
     171             :   }
     172             : 
     173             :   // This constructs all conceivable sections of antibeta sheet in the backbone of the chains
     174             :   std::string seglist;
     175          18 :   unsigned jjkk=1;
     176          18 :   if( intra_chain ) {
     177             :     unsigned nprevious=0;
     178          17 :     std::vector<unsigned> nlist(30);
     179         272 :     for(unsigned i=0; i<chains.size(); ++i) {
     180         255 :       if( chains[i]<40 ) {
     181           0 :         error("segment of backbone is not long enough to form an antiparallel beta hairpin. Each backbone fragment must contain a minimum of 8 residues");
     182             :       }
     183             :       // Loop over all possible triples in each 8 residue segment of protein
     184         255 :       unsigned nres=chains[i]/5;
     185         255 :       if( chains[i]%5!=0 ) {
     186           0 :         error("backbone segment received does not contain a multiple of five residues");
     187             :       }
     188         267 :       for(unsigned ires=0; ires<nres-8; ires++) {
     189          42 :         for(unsigned jres=ires+6; jres<nres-2; jres++) {
     190         480 :           for(unsigned k=0; k<15; ++k) {
     191         450 :             nlist[k]=nprevious + ires*5+k;
     192         450 :             nlist[k+15]=nprevious + jres*5+k;
     193             :           }
     194             :           std::string nlstr, num;
     195          30 :           Tools::convert( nlist[0], nlstr );
     196          30 :           Tools::convert(jjkk, num);
     197          30 :           jjkk++;
     198          60 :           seglist += " SEGMENT" + num + "=" + nlstr;
     199         900 :           for(unsigned kk=1; kk<nlist.size(); ++kk ) {
     200         870 :             Tools::convert( nlist[kk], nlstr );
     201        1740 :             seglist += "," + nlstr;
     202             :           }
     203          30 :           if( strands_cutoff>0 ) {
     204          20 :             scutoff_action += " ATOMS" + num + "=" + all_atoms[nlist[6]] + "," + all_atoms[nlist[21]];
     205             :           }
     206             :         }
     207             :       }
     208         255 :       nprevious+=chains[i];
     209             :     }
     210             :   }
     211             :   // This constructs all conceivable sections of antibeta sheet that form between chains
     212          18 :   if( inter_chain ) {
     213          18 :     if( chains.size()==1 && !Tools::caseInSensStringCompare(style, "all") ) {
     214           0 :       error("there is only one chain defined so cannot use inter_chain option");
     215             :     }
     216          18 :     std::vector<unsigned> nlist(30);
     217         273 :     for(unsigned ichain=1; ichain<chains.size(); ++ichain) {
     218             :       unsigned iprev=0;
     219        2550 :       for(unsigned i=0; i<ichain; ++i) {
     220        2295 :         iprev+=chains[i];
     221             :       }
     222         255 :       unsigned inres=chains[ichain]/5;
     223         255 :       if( chains[ichain]%5!=0 ) {
     224           0 :         error("backbone segment received does not contain a multiple of five residues");
     225             :       }
     226        1785 :       for(unsigned ires=0; ires<inres-2; ++ires) {
     227       15300 :         for(unsigned jchain=0; jchain<ichain; ++jchain) {
     228             :           unsigned jprev=0;
     229       87210 :           for(unsigned i=0; i<jchain; ++i) {
     230       73440 :             jprev+=chains[i];
     231             :           }
     232       13770 :           unsigned jnres=chains[jchain]/5;
     233       13770 :           if( chains[jchain]%5!=0 ) {
     234           0 :             error("backbone segment received does not contain a multiple of five residues");
     235             :           }
     236       96390 :           for(unsigned jres=0; jres<jnres-2; ++jres) {
     237     1321920 :             for(unsigned k=0; k<15; ++k) {
     238     1239300 :               nlist[k]=iprev + ires*5+k;
     239     1239300 :               nlist[k+15]=jprev + jres*5+k;
     240             :             }
     241             :             std::string nlstr, num;
     242       82620 :             Tools::convert( nlist[0], nlstr );
     243       82620 :             Tools::convert(jjkk, num);
     244       82620 :             jjkk++;
     245      165240 :             seglist += " SEGMENT" + num + "=" + nlstr;
     246     2478600 :             for(unsigned kk=1; kk<nlist.size(); ++kk ) {
     247     2395980 :               Tools::convert( nlist[kk], nlstr );
     248     4791960 :               seglist += "," + nlstr;
     249             :             }
     250       82620 :             if( strands_cutoff>0 ) {
     251      165240 :               scutoff_action += " ATOMS" + num + "=" + all_atoms[nlist[6]] + "," + all_atoms[nlist[21]];
     252             :             }
     253             :           }
     254             :         }
     255             :       }
     256             :     }
     257             :   }
     258             : 
     259             :   // Build the reference structure ( in angstroms )
     260          18 :   std::vector<Vector> reference(30);
     261          18 :   reference[0]=Vector( 1.244, -4.620, -2.127); // N    i
     262          18 :   reference[1]=Vector(-0.016, -4.500, -1.395); // CA
     263          18 :   reference[2]=Vector( 0.105, -5.089,  0.024); // CB
     264          18 :   reference[3]=Vector(-0.287, -3.000, -1.301); // C
     265          18 :   reference[4]=Vector( 0.550, -2.245, -0.822); // O
     266          18 :   reference[5]=Vector(-1.445, -2.551, -1.779); // N    i+1
     267          18 :   reference[6]=Vector(-1.752, -1.130, -1.677); // CA
     268          18 :   reference[7]=Vector(-2.113, -0.550, -3.059); // CB
     269          18 :   reference[8]=Vector(-2.906, -0.961, -0.689); // C
     270          18 :   reference[9]=Vector(-3.867, -1.738, -0.695); // O
     271          18 :   reference[10]=Vector(-2.774,  0.034,  0.190); // N    i+2
     272          18 :   reference[11]=Vector(-3.788,  0.331,  1.201); // CA
     273          18 :   reference[12]=Vector(-3.188,  0.300,  2.624); // CB
     274          18 :   reference[13]=Vector(-4.294,  1.743,  0.937); // C
     275          18 :   reference[14]=Vector(-3.503,  2.671,  0.821); // O
     276          18 :   reference[15]=Vector( 4.746, -2.363,  0.188); // N    j
     277          18 :   reference[16]=Vector( 3.427, -1.839,  0.545); // CA
     278          18 :   reference[17]=Vector( 3.135, -1.958,  2.074); // CB
     279          18 :   reference[18]=Vector( 3.346, -0.365,  0.181); // C
     280          18 :   reference[19]=Vector( 4.237,  0.412,  0.521); // O
     281          18 :   reference[20]=Vector( 2.261,  0.013, -0.487); // N    j+1
     282          18 :   reference[21]=Vector( 2.024,  1.401, -0.875); // CA
     283          18 :   reference[22]=Vector( 1.489,  1.514, -2.313); // CB
     284          18 :   reference[23]=Vector( 0.914,  1.902,  0.044); // C
     285          18 :   reference[24]=Vector(-0.173,  1.330,  0.052); // O
     286          18 :   reference[25]=Vector( 1.202,  2.940,  0.828); // N    j+2
     287          18 :   reference[26]=Vector( 0.190,  3.507,  1.718); // CA
     288          18 :   reference[27]=Vector( 0.772,  3.801,  3.104); // CB
     289          18 :   reference[28]=Vector(-0.229,  4.791,  1.038); // C
     290          18 :   reference[29]=Vector( 0.523,  5.771,  0.996); // O
     291             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
     292             :   std::string ref0, ref1, ref2;
     293          18 :   Tools::convert(  reference[0][0], ref0 );
     294          18 :   Tools::convert(  reference[0][1], ref1 );
     295          18 :   Tools::convert(  reference[0][2], ref2 );
     296          36 :   std::string structure=" STRUCTURE1=" + ref0 + "," + ref1 + "," + ref2;
     297         540 :   for(unsigned i=1; i<30; ++i) {
     298        2088 :     for(unsigned k=0; k<3; ++k) {
     299        1566 :       Tools::convert( reference[i][k], ref0 );
     300        3132 :       structure += "," + ref0;
     301             :     }
     302             :   }
     303             : 
     304          18 :   reference[0]=Vector(-1.439, -5.122, -1.144); // N    i
     305          18 :   reference[1]=Vector(-0.816, -3.803, -1.013); // CA
     306          18 :   reference[2]=Vector( 0.099, -3.509, -2.206); // CB
     307          18 :   reference[3]=Vector(-1.928, -2.770, -0.952); // C
     308          18 :   reference[4]=Vector(-2.991, -2.970, -1.551); // O
     309          18 :   reference[5]=Vector(-1.698, -1.687, -0.215); // N    i+1
     310          18 :   reference[6]=Vector(-2.681, -0.613, -0.143); // CA
     311          18 :   reference[7]=Vector(-3.323, -0.477,  1.267); // CB
     312          18 :   reference[8]=Vector(-1.984,  0.681, -0.574); // C
     313          18 :   reference[9]=Vector(-0.807,  0.921, -0.273); // O
     314          18 :   reference[10]=Vector(-2.716,  1.492, -1.329); // N    i+2
     315          18 :   reference[11]=Vector(-2.196,  2.731, -1.883); // CA
     316          18 :   reference[12]=Vector(-2.263,  2.692, -3.418); // CB
     317          18 :   reference[13]=Vector(-2.989,  3.949, -1.433); // C
     318          18 :   reference[14]=Vector(-4.214,  3.989, -1.583); // O
     319          18 :   reference[15]=Vector( 2.464, -4.352,  2.149); // N    j
     320          18 :   reference[16]=Vector( 3.078, -3.170,  1.541); // CA
     321          18 :   reference[17]=Vector( 3.398, -3.415,  0.060); // CB
     322          18 :   reference[18]=Vector( 2.080, -2.021,  1.639); // C
     323          18 :   reference[19]=Vector( 0.938, -2.178,  1.225); // O
     324          18 :   reference[20]=Vector( 2.525, -0.886,  2.183); // N    j+1
     325          18 :   reference[21]=Vector( 1.692,  0.303,  2.346); // CA
     326          18 :   reference[22]=Vector( 1.541,  0.665,  3.842); // CB
     327          18 :   reference[23]=Vector( 2.420,  1.410,  1.608); // C
     328          18 :   reference[24]=Vector( 3.567,  1.733,  1.937); // O
     329          18 :   reference[25]=Vector( 1.758,  1.976,  0.600); // N    j+2
     330          18 :   reference[26]=Vector( 2.373,  2.987, -0.238); // CA
     331          18 :   reference[27]=Vector( 2.367,  2.527, -1.720); // CB
     332          18 :   reference[28]=Vector( 1.684,  4.331, -0.148); // C
     333          18 :   reference[29]=Vector( 0.486,  4.430, -0.415); // O
     334             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
     335          18 :   Tools::convert(  reference[0][0], ref0 );
     336          18 :   Tools::convert(  reference[0][1], ref1 );
     337          18 :   Tools::convert(  reference[0][2], ref2 );
     338          36 :   structure +=" STRUCTURE2=" + ref0 + "," + ref1 + "," + ref2;
     339         540 :   for(unsigned i=1; i<30; ++i) {
     340        2088 :     for(unsigned k=0; k<3; ++k) {
     341        1566 :       Tools::convert( reference[i][k], ref0 );
     342        3132 :       structure += "," + ref0;
     343             :     }
     344             :   }
     345             : 
     346          18 :   std::string nopbcstr="";
     347             :   bool nopbc;
     348          18 :   parseFlag("NOPBC",nopbc);
     349          18 :   if( nopbc ) {
     350             :     nopbcstr = " NOPBC";
     351             :   }
     352          18 :   std::string usegpustr="";
     353             :   {
     354             :     bool usegpu;
     355          18 :     parseFlag("USEGPU",usegpu);
     356          18 :     if( usegpu ) {
     357             :       usegpustr = " USEGPU";
     358             :     }
     359             :   }
     360             :   std::string type;
     361          18 :   parse("TYPE",type);
     362          18 :   std::string lab = getShortcutLabel() + "_low";
     363          18 :   if( uselessthan ) {
     364          17 :     lab = getShortcutLabel();
     365             :   }
     366          18 :   std::string atoms="ATOMS=" + all_atoms[0];
     367       10980 :   for(unsigned i=1; i<all_atoms.size(); ++i) {
     368       21924 :     atoms += "," + all_atoms[i];
     369             :   }
     370          18 :   std::string inputLine =  getShortcutLabel() + "_both:";
     371          18 :   if( type=="DRMSD" ) {
     372             :     inputLine+=" SECONDARY_STRUCTURE_DRMSD BONDLENGTH=0.17";
     373             :   } else {
     374          20 :     inputLine+=" SECONDARY_STRUCTURE_RMSD TYPE=" +type;
     375             :   }
     376          36 :   inputLine+=" ALIGN_STRANDS " + seglist + structure
     377          36 :              + " " + atoms + nopbcstr + usegpustr;
     378             : 
     379          18 :   if( strands_cutoff>0 ) {
     380          16 :     readInputLine( scutoff_action );
     381             :     std::string str_cut;
     382          16 :     Tools::convert( strands_cutoff, str_cut );
     383          48 :     readInputLine( getShortcutLabel() + "_cut: CUSTOM ARG=" + getShortcutLabel()
     384          32 :                    + "_cut_dists FUNC=step(" + str_cut + "-x) PERIODIC=NO");
     385          32 :     inputLine+=" MASK=" + getShortcutLabel() + "_cut";
     386          16 :     readInputLine(inputLine);
     387          16 :     if( ltmap.length()>0 ) {
     388             :       // Create the lowest line
     389          48 :       readInputLine( lab + ": LOWEST ARG=" + getShortcutLabel() + "_both.struct-1,"
     390          48 :                      + getShortcutLabel() + "_both.struct-2 MASK=" + getShortcutLabel() + "_cut");
     391             :       // Create the less than object
     392          48 :       readInputLine( getShortcutLabel() + "_ltu: LESS_THAN ARG=" + lab
     393          48 :                      + " SWITCH={" + ltmap  +"} MASK=" + getShortcutLabel() + "_cut");
     394             :       // Multiply by the strands cutoff
     395          32 :       readInputLine( getShortcutLabel()
     396          48 :                      + "_lt: CUSTOM ARG=" + getShortcutLabel() + "_ltu,"
     397          48 :                      + getShortcutLabel() + "_cut"
     398             :                      " FUNC=x*y PERIODIC=NO");
     399             :     }
     400             :   } else {
     401           2 :     readInputLine(inputLine);
     402           2 :     if( ltmap.length()>0 ) {
     403             :       // Create the lowest line
     404           6 :       readInputLine( lab + ": LOWEST ARG=" + getShortcutLabel() + "_both.struct-1,"
     405           6 :                      + getShortcutLabel() + "_both.struct-2" );
     406             :       // Create the less than object
     407           4 :       readInputLine( getShortcutLabel() + "_lt: LESS_THAN ARG=" + lab + " SWITCH={" + ltmap  +"}");
     408             :     }
     409             :   }
     410             :   // Create the less than object
     411          18 :   if( ltmap.length()>0 ) {
     412          18 :     if( uselessthan ) {
     413          34 :       readInputLine( getShortcutLabel() + "_lessthan: SUM ARG=" + getShortcutLabel() + "_lt PERIODIC=NO");
     414             :     } else {
     415           2 :       readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_lt PERIODIC=NO");
     416             :     }
     417             :   }
     418          36 : }
     419             : 
     420             : }
     421             : }

Generated by: LCOV version 1.16