Пример #1
0
TrajectoryAnalysisModule *createTrajectoryAnalysisModule(const char *name)
{
    size_t len = strlen(name);
    int match_i = -1;

    for (int i = 0; modules[i].name != NULL; ++i)
    {
        if (gmx_strncasecmp(name, modules[i].name, len) == 0)
        {
            if (strlen(modules[i].name) == len)
            {
                match_i = i;
                break;
            }
            else if (match_i == -1)
            {
                match_i = i;
            }
            else
            {
                return NULL;
            }
        }
    }
    if (match_i != -1)
    {
        return modules[match_i].creator();
    }
    return NULL;
}
Пример #2
0
static gmx_bool comp_name(char *name, char *search)
{
    while (name[0] != '\0' && search[0] != '\0')
    {
        switch (search[0])
        {
            case '?':
                /* Always matches */
                break;
            case '*':
                if (search[1] != '\0')
                {
                    printf("WARNING: Currently '*' is only supported at the end of an expression\n");
                    return FALSE;
                }
                else
                {
                    return TRUE;
                }
                break;
            default:
                /* Compare a single character */
                if (( bCase && strncmp(name, search, 1)) ||
                    (!bCase && gmx_strncasecmp(name, search, 1)))
                {
                    return FALSE;
                }
        }
        name++;
        search++;
    }

    return (name[0] == '\0' && (search[0] == '\0' || search[0] == '*'));
}
Пример #3
0
static gmx_bool atomname_cmp_nr(const char *anm,t_hack *hack,int *nr)
{

    if (hack->nr == 1)
    {
        *nr = 0;
        
        return (gmx_strcasecmp(anm,hack->nname) == 0);
    }
    else
    {
        if (isdigit(anm[strlen(anm)-1]))
        {
            *nr = anm[strlen(anm)-1] - '0';
        }
        else
        {
            *nr = 0;
        }
        if (*nr <= 0 || *nr > hack->nr)
        {
            return FALSE;
        }
        else
        {
            return (strlen(anm) == strlen(hack->nname) + 1 &&
                    gmx_strncasecmp(anm,hack->nname,strlen(hack->nname)) == 0);
        }
    }
}
Пример #4
0
static void process_pull_dim(char *dim_buf, ivec dim, const t_pull_coord *pcrd)
{
    int           ndim, d, nchar;
    char         *ptr, pulldim1[STRLEN];

    ptr  = dim_buf;
    ndim = 0;
    for (d = 0; d < DIM; d++)
    {
        if (sscanf(ptr, "%s%n", pulldim1, &nchar) != 1)
        {
            gmx_fatal(FARGS, "Less than 3 pull dimensions given in pull_dim: '%s'",
                      dim_buf);
        }

        if (gmx_strncasecmp(pulldim1, "N", 1) == 0)
        {
            dim[d] = 0;
        }
        else if (gmx_strncasecmp(pulldim1, "Y", 1) == 0)
        {
            dim[d] = 1;
            ndim++;
        }
        else
        {
            gmx_fatal(FARGS, "Please use Y(ES) or N(O) for pull_dim only (not %s)",
                      pulldim1);
        }
        ptr += nchar;
    }
    if (ndim == 0)
    {
        gmx_fatal(FARGS, "All entries in pull dim are N");
    }
    if ((pcrd->eGeom == epullgDIHEDRAL) && (ndim < 3))
    {
        gmx_fatal(FARGS, "Pull geometry dihedral is only useful with pull-dim = Y Y Y");
    }
    if ((pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS ) && (ndim < 2))
    {
        gmx_fatal(FARGS, "Pull geometry %s is only useful with pull-dim = Y for at least 2 dimensions",
                  EPULLGEOM(pcrd->eGeom));
    }
}
Пример #5
0
static gmx_bool is_bond(int nnm, t_nm2type nmt[], char *ai, char *aj, real blen)
{
    int i, j;

    for (i = 0; (i < nnm); i++)
    {
        for (j = 0; (j < nmt[i].nbonds); j++)
        {
            if ((((gmx_strncasecmp(ai, nmt[i].elem, 1) == 0) &&
                  (gmx_strncasecmp(aj, nmt[i].bond[j], 1) == 0)) ||
                 ((gmx_strncasecmp(ai, nmt[i].bond[j], 1) == 0) &&
                  (gmx_strncasecmp(aj, nmt[i].elem, 1) == 0))) &&
                (fabs(blen-nmt[i].blen[j]) <= 0.1*nmt[i].blen[j]))
            {
                return TRUE;
            }
        }
    }
    return FALSE;
}
Пример #6
0
static int search_str2(int nstr,char **str,char *key)
{
  int  i,n;
  int  keylen = strlen(key);
  /* Linear search */
  n=0;
  while( (n<keylen) && ((key[n]<'0') || (key[n]>'9')) )
    n++;
  for(i=0; (i<nstr); i++) 
    if (gmx_strncasecmp(str[i],key,n)==0)
      return i;

  return -1;
}
Пример #7
0
static void process_pull_dim(char *dim_buf, ivec dim)
{
    int           ndim, d, nchar, c;
    char         *ptr, pulldim1[STRLEN];
    t_pull_coord *pcrd;

    ptr  = dim_buf;
    ndim = 0;
    for (d = 0; d < DIM; d++)
    {
        if (sscanf(ptr, "%s%n", pulldim1, &nchar) != 1)
        {
            gmx_fatal(FARGS, "Less than 3 pull dimensions given in pull_dim: '%s'",
                      dim_buf);
        }

        if (gmx_strncasecmp(pulldim1, "N", 1) == 0)
        {
            dim[d] = 0;
        }
        else if (gmx_strncasecmp(pulldim1, "Y", 1) == 0)
        {
            dim[d] = 1;
            ndim++;
        }
        else
        {
            gmx_fatal(FARGS, "Please use Y(ES) or N(O) for pull_dim only (not %s)",
                      pulldim1);
        }
        ptr += nchar;
    }
    if (ndim == 0)
    {
        gmx_fatal(FARGS, "All entries in pull dim are N");
    }
}
Пример #8
0
static gmx_bool enernm_equal(const char *nm1,const char *nm2)
{
  int len1,len2;

  len1 = strlen(nm1);
  len2 = strlen(nm2);

  /* Remove " (bar)" at the end of a name */
  if (len1 > 6 && strcmp(nm1+len1-6," (bar)") == 0) {
    len1 -= 6;
  }
  if (len2 > 6 && strcmp(nm2+len2-6," (bar)") == 0) {
    len2 -= 6;
  }

  return (len1 == len2 && gmx_strncasecmp(nm1,nm2,len1) == 0);
}
Пример #9
0
/* Compares if the strins match except for a sign at the end
 * of (only) one of the two.
 */
static int neq_str_sign(const char *a1, const char *a2)
{
    int l1, l2, lm;

    l1 = (int)strlen(a1);
    l2 = (int)strlen(a2);
    lm = std::min(l1, l2);

    if (lm >= 1 &&
        ((l1 == l2+1 && is_sign(a1[l1-1])) ||
         (l2 == l1+1 && is_sign(a2[l2-1]))) &&
        gmx_strncasecmp(a1, a2, lm) == 0)
    {
        return lm;
    }
    else
    {
        return 0;
    }
}
Пример #10
0
void read_resall(char *rrdb, int *nrtpptr, t_restp **rtp,
                 gpp_atomtype_t atype, t_symtab *tab,
                 gmx_bool bAllowOverrideRTP)
{
    FILE         *in;
    char          filebase[STRLEN], line[STRLEN], header[STRLEN];
    int           i, nrtp, maxrtp, bt, nparam;
    int           dum1, dum2, dum3;
    t_restp      *rrtp, *header_settings;
    gmx_bool      bNextResidue, bError;
    int           firstrtp;

    fflib_filename_base(rrdb, filebase, STRLEN);

    in = fflib_open(rrdb);

    if (debug)
    {
        fprintf(debug, "%9s %5s", "Residue", "atoms");
        for (i = 0; i < ebtsNR; i++)
        {
            fprintf(debug, " %10s", btsNames[i]);
        }
        fprintf(debug, "\n");
    }
    snew(header_settings, 1);

    /* these bonded parameters will overwritten be when  *
     * there is a [ bondedtypes ] entry in the .rtp file */
    header_settings->rb[ebtsBONDS].type  = 1; /* normal bonds     */
    header_settings->rb[ebtsANGLES].type = 1; /* normal angles    */
    header_settings->rb[ebtsPDIHS].type  = 1; /* normal dihedrals */
    header_settings->rb[ebtsIDIHS].type  = 2; /* normal impropers */
    header_settings->rb[ebtsEXCLS].type  = 1; /* normal exclusions */
    header_settings->rb[ebtsCMAP].type   = 1; /* normal cmap torsions */

    header_settings->bKeepAllGeneratedDihedrals    = FALSE;
    header_settings->nrexcl                        = 3;
    header_settings->bGenerateHH14Interactions     = TRUE;
    header_settings->bRemoveDihedralIfWithImproper = TRUE;

    /* Column 5 & 6 aren't really bonded types, but we include
     * them here to avoid introducing a new section:
     * Column 5 : This controls the generation of dihedrals from the bonding.
     *            All possible dihedrals are generated automatically. A value of
     *            1 here means that all these are retained. A value of
     *            0 here requires generated dihedrals be removed if
     *              * there are any dihedrals on the same central atoms
     *                specified in the residue topology, or
     *              * there are other identical generated dihedrals
     *                sharing the same central atoms, or
     *              * there are other generated dihedrals sharing the
     *                same central bond that have fewer hydrogen atoms
     * Column 6: Number of bonded neighbors to exclude.
     * Column 7: Generate 1,4 interactions between two hydrogen atoms
     * Column 8: Remove proper dihedrals if centered on the same bond
     *           as an improper dihedral
     */
    get_a_line(in, line, STRLEN);
    if (!get_header(line, header))
    {
        gmx_fatal(FARGS, "in .rtp file at line:\n%s\n", line);
    }
    if (gmx_strncasecmp("bondedtypes", header, 5) == 0)
    {
        get_a_line(in, line, STRLEN);
        if ((nparam = sscanf(line, "%d %d %d %d %d %d %d %d",
                             &header_settings->rb[ebtsBONDS].type, &header_settings->rb[ebtsANGLES].type,
                             &header_settings->rb[ebtsPDIHS].type, &header_settings->rb[ebtsIDIHS].type,
                             &dum1, &header_settings->nrexcl, &dum2, &dum3)) < 4)
        {
            gmx_fatal(FARGS, "need 4 to 8 parameters in the header of .rtp file %s at line:\n%s\n", rrdb, line);
        }
        header_settings->bKeepAllGeneratedDihedrals    = (dum1 != 0);
        header_settings->bGenerateHH14Interactions     = (dum2 != 0);
        header_settings->bRemoveDihedralIfWithImproper = (dum3 != 0);
        get_a_line(in, line, STRLEN);
        if (nparam < 5)
        {
            fprintf(stderr, "Using default: not generating all possible dihedrals\n");
            header_settings->bKeepAllGeneratedDihedrals = FALSE;
        }
        if (nparam < 6)
        {
            fprintf(stderr, "Using default: excluding 3 bonded neighbors\n");
            header_settings->nrexcl = 3;
        }
        if (nparam < 7)
        {
            fprintf(stderr, "Using default: generating 1,4 H--H interactions\n");
            header_settings->bGenerateHH14Interactions = TRUE;
        }
        if (nparam < 8)
        {
            fprintf(stderr, "Using default: removing proper dihedrals found on the same bond as a proper dihedral\n");
            header_settings->bRemoveDihedralIfWithImproper = TRUE;
        }
    }
    else
    {
        fprintf(stderr,
                "Reading .rtp file without '[ bondedtypes ]' directive,\n"
                "Will proceed as if the entry was:\n");
        print_resall_header(stderr, header_settings);
    }
    /* We don't know the current size of rrtp, but simply realloc immediately */
    nrtp   = *nrtpptr;
    rrtp   = *rtp;
    maxrtp = nrtp;
    while (!feof(in))
    {
        if (nrtp >= maxrtp)
        {
            maxrtp += 100;
            srenew(rrtp, maxrtp);
        }

        /* Initialise rtp entry structure */
        rrtp[nrtp] = *header_settings;
        if (!get_header(line, header))
        {
            gmx_fatal(FARGS, "in .rtp file at line:\n%s\n", line);
        }
        rrtp[nrtp].resname  = gmx_strdup(header);
        rrtp[nrtp].filebase = gmx_strdup(filebase);

        get_a_line(in, line, STRLEN);
        bError       = FALSE;
        bNextResidue = FALSE;
        do
        {
            if (!get_header(line, header))
            {
                bError = TRUE;
            }
            else
            {
                bt = get_bt(header);
                if (bt != NOTSET)
                {
                    /* header is an bonded directive */
                    bError = !read_bondeds(bt, in, line, &rrtp[nrtp]);
                }
                else if (gmx_strncasecmp("atoms", header, 5) == 0)
                {
                    /* header is the atoms directive */
                    bError = !read_atoms(in, line, &(rrtp[nrtp]), tab, atype);
                }
                else
                {
                    /* else header must be a residue name */
                    bNextResidue = TRUE;
                }
            }
            if (bError)
            {
                gmx_fatal(FARGS, "in .rtp file in residue %s at line:\n%s\n",
                          rrtp[nrtp].resname, line);
            }
        }
        while (!feof(in) && !bNextResidue);

        if (rrtp[nrtp].natom == 0)
        {
            gmx_fatal(FARGS, "No atoms found in .rtp file in residue %s\n",
                      rrtp[nrtp].resname);
        }
        if (debug)
        {
            fprintf(debug, "%3d %5s %5d",
                    nrtp+1, rrtp[nrtp].resname, rrtp[nrtp].natom);
            for (i = 0; i < ebtsNR; i++)
            {
                fprintf(debug, " %10d", rrtp[nrtp].rb[i].nb);
            }
            fprintf(debug, "\n");
        }

        firstrtp = -1;
        for (i = 0; i < nrtp; i++)
        {
            if (gmx_strcasecmp(rrtp[i].resname, rrtp[nrtp].resname) == 0)
            {
                firstrtp = i;
            }
        }

        if (firstrtp == -1)
        {
            nrtp++;
            fprintf(stderr, "\rResidue %d", nrtp);
            fflush(stderr);
        }
        else
        {
            if (firstrtp >= *nrtpptr)
            {
                gmx_fatal(FARGS, "Found a second entry for '%s' in '%s'",
                          rrtp[nrtp].resname, rrdb);
            }
            if (bAllowOverrideRTP)
            {
                fprintf(stderr, "\n");
                fprintf(stderr, "Found another rtp entry for '%s' in '%s', ignoring this entry and keeping the one from '%s.rtp'\n",
                        rrtp[nrtp].resname, rrdb, rrtp[firstrtp].filebase);
                /* We should free all the data for this entry.
                 * The current code gives a lot of dangling pointers.
                 */
                clear_t_restp(&rrtp[nrtp]);
            }
            else
            {
                gmx_fatal(FARGS, "Found rtp entries for '%s' in both '%s' and '%s'. If you want the first definition to override the second one, set the -rtpo option of pdb2gmx.", rrtp[nrtp].resname, rrtp[firstrtp].filebase, rrdb);
            }
        }
    }
    gmx_ffclose(in);
    /* give back unused memory */
    srenew(rrtp, nrtp);

    fprintf(stderr, "\nSorting it all out...\n");
    qsort(rrtp, nrtp, (size_t)sizeof(rrtp[0]), comprtp);

    check_rtp(nrtp, rrtp, rrdb);

    *nrtpptr = nrtp;
    *rtp     = rrtp;
}
Пример #11
0
int
gmx_fprintf_pdb_atomline(FILE *            fp,
                         enum PDB_record   record,
                         int               atom_seq_number,
                         const char *      atom_name,
                         char              alternate_location,
                         const char *      res_name,
                         char              chain_id,
                         int               res_seq_number,
                         char              res_insertion_code,
                         real              x,
                         real              y,
                         real              z,
                         real              occupancy,
                         real              b_factor,
                         const char *      element)
{
    char     tmp_atomname[6], tmp_resname[6];
    gmx_bool start_name_in_col13;
    int      n;

    if (record != epdbATOM && record != epdbHETATM)
    {
        gmx_fatal(FARGS, "Can only print PDB atom lines as ATOM or HETATM records");
    }

    /* Format atom name */
    if (atom_name != NULL)
    {
        /* If the atom name is an element name with two chars, it should start already in column 13.
         * Otherwise it should start in column 14, unless the name length is 4 chars.
         */
        if ( (element != NULL) && (std::strlen(element) >= 2) && (gmx_strncasecmp(atom_name, element, 2) == 0) )
        {
            start_name_in_col13 = TRUE;
        }
        else
        {
            start_name_in_col13 = (std::strlen(atom_name) >= 4);
        }
        sprintf(tmp_atomname, start_name_in_col13 ? "" : " ");
        std::strncat(tmp_atomname, atom_name, 4);
        tmp_atomname[5] = '\0';
    }
    else
    {
        tmp_atomname[0] = '\0';
    }

    /* Format residue name */
    std::strncpy(tmp_resname, (res_name != NULL) ? res_name : "", 4);
    /* Make sure the string is terminated if strlen was > 4 */
    tmp_resname[4] = '\0';
    /* String is properly terminated, so now we can use strcat. By adding a
     * space we can write it right-justified, and if the original name was
     * three characters or less there will be a space added on the right side.
     */
    std::strcat(tmp_resname, " ");

    /* Truncate integers so they fit */
    atom_seq_number = atom_seq_number % 100000;
    res_seq_number  = res_seq_number % 10000;

    n = fprintf(fp,
                "%-6s%5d %-4.4s%c%4.4s%c%4d%c   %8.3f%8.3f%8.3f%6.2f%6.2f          %2s\n",
                pdbtp[record],
                atom_seq_number,
                tmp_atomname,
                alternate_location,
                tmp_resname,
                chain_id,
                res_seq_number,
                res_insertion_code,
                x, y, z,
                occupancy,
                b_factor,
                (element != NULL) ? element : "");

    return n;
}
Пример #12
0
gmx_bool gmx_omp_check_thread_affinity(char **message)
{
    bool shouldSetAffinity = true;

    *message = NULL;
#ifdef GMX_OPENMP
    /* We assume that the affinity setting is available on all platforms
     * gcc supports. Even if this is not the case (e.g. Mac OS) the user
     * will only get a warning. */
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
    const char *programName;
    try
    {
        programName = gmx::getProgramContext().displayName();
    }
    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;

    const char *const gomp_env            = getenv("GOMP_CPU_AFFINITY");
    const bool        bGompCpuAffinitySet = (gomp_env != NULL);

    /* turn off internal pinning if GOMP_CPU_AFFINITY is set & non-empty */
    if (bGompCpuAffinitySet && *gomp_env != '\0')
    {
        try
        {
            std::string buf = gmx::formatString(
                        "NOTE: GOMP_CPU_AFFINITY set, will turn off %s internal affinity\n"
                        "      setting as the two can conflict and cause performance degradation.\n"
                        "      To keep using the %s internal affinity setting, unset the\n"
                        "      GOMP_CPU_AFFINITY environment variable.",
                        programName, programName);
            *message = gmx_strdup(buf.c_str());
        }
        GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
        shouldSetAffinity = false;
    }
#endif /* __GNUC__ || __INTEL_COMPILER */

#if defined(__INTEL_COMPILER)
    const char *const kmp_env         = getenv("KMP_AFFINITY");
    const bool        bKmpAffinitySet = (kmp_env != NULL);

    /* disable Intel OpenMP affinity if neither KMP_AFFINITY nor
     * GOMP_CPU_AFFINITY is set (Intel uses the GNU env. var as well) */
    if (!bKmpAffinitySet && !bGompCpuAffinitySet)
    {
        int retval;

#ifdef _MSC_VER
        /* Windows not POSIX */
        retval = _putenv_s("KMP_AFFINITY", "disabled");
#else
        /* POSIX */
        retval = setenv("KMP_AFFINITY", "disabled", 0);
#endif  /* _MSC_VER */

        if (debug)
        {
            fprintf(debug, "Disabling Intel OpenMP affinity by setting the KMP_AFFINITY=disabled env. var.\n");
        }

        if (retval != 0)
        {
            gmx_warning("Disabling Intel OpenMp affinity setting failed!");
        }
    }

    /* turn off internal pinning KMP_AFFINITY != "disabled" */
    if (bKmpAffinitySet && (gmx_strncasecmp(kmp_env, "disabled", 8) != 0))
    {
        try
        {
            std::string buf = gmx::formatString(
                        "NOTE: KMP_AFFINITY set, will turn off %s internal affinity\n"
                        "      setting as the two can conflict and cause performance degradation.\n"
                        "      To keep using the %s internal affinity setting, set the\n"
                        "      KMP_AFFINITY=disabled environment variable.",
                        programName, programName);
            *message = gmx_strdup(buf.c_str());
        }
        GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
        shouldSetAffinity = false;
    }
#endif /* __INTEL_COMPILER */

#endif /* GMX_OPENMP */
    return shouldSetAffinity;
}
Пример #13
0
/* Read a number of arguments from the command line.
 * For etINT, etREAL and etCHAR an extra argument is read (when present)
 * for etBOOL the gmx_boolean option is changed to the negate value
 */
static void get_pargs(int *argc, char *argv[], int nparg, t_pargs pa[])
{
    int       i, j, k, match;
    gmx_bool *bKeep;
    char      buf[32];
    char     *ptr;

    snew(bKeep, *argc+1);
    bKeep[0]     = TRUE;
    bKeep[*argc] = TRUE;

    for (i = 1; (i < *argc); i++)
    {
        bKeep[i] = TRUE;
        for (j = 0; (j < nparg); j++)
        {
            if (pa[j].type == etBOOL)
            {
                sprintf(buf, "-no%s", pa[j].option+1);
                if (strcmp(pa[j].option, argv[i]) == 0)
                {
                    *pa[j].u.b = TRUE;
                    pa[j].bSet = TRUE;
                    bKeep[i]   = FALSE;
                }
                else if (strcmp(buf, argv[i]) == 0)
                {
                    *pa[j].u.b = FALSE;
                    pa[j].bSet = TRUE;
                    bKeep[i]   = FALSE;
                }
            }
            else if (strcmp(pa[j].option, argv[i]) == 0)
            {
                if (pa[j].bSet)
                {
                    fprintf(stderr, "Setting option %s more than once!\n",
                            pa[j].option);
                }
                pa[j].bSet = TRUE;
                bKeep[i]   = FALSE;
                switch (pa[j].type)
                {
                    case etINT:
                        *pa[j].u.i = iscan(*argc, argv, &i);
                        break;
                    case etINT64:
                        *pa[j].u.is = istepscan(*argc, argv, &i);
                        break;
                    case etTIME:
                    case etREAL:
                        *pa[j].u.r = dscan(*argc, argv, &i);
                        break;
                    case etSTR:
                        *(pa[j].u.c) = sscan(*argc, argv, &i);
                        break;
                    case etENUM:
                        match = -1;
                        ptr   = sscan(*argc, argv, &i);
                        for (k = 1; (pa[j].u.c[k] != NULL); k++)
                        {
                            /* only check ptr against beginning of
                               pa[j].u.c[k] */
                            if (gmx_strncasecmp(ptr, pa[j].u.c[k], strlen(ptr)) == 0)
                            {
                                if ( ( match == -1 ) ||
                                     ( strlen(pa[j].u.c[k]) <
                                       strlen(pa[j].u.c[match]) ) )
                                {
                                    match = k;
                                }
                            }
                        }
                        if (match != -1)
                        {
                            pa[j].u.c[0] = pa[j].u.c[match];
                        }
                        else
                        {
                            gmx_fatal(FARGS, "Invalid argument %s for option %s",
                                      ptr, pa[j].option);
                        }
                        break;
                    case etRVEC:
                        (*pa[j].u.rv)[0] = dscan(*argc, argv, &i);
                        if ( (i+1 == *argc) ||
                             ( (argv[i+1][0] == '-') &&
                               !isdigit(argv[i+1][1]) ) )
                        {
                            (*pa[j].u.rv)[1]     =
                                (*pa[j].u.rv)[2] =
                                    (*pa[j].u.rv)[0];
                        }
                        else
                        {
                            bKeep[i]         = FALSE;
                            (*pa[j].u.rv)[1] = dscan(*argc, argv, &i);
                            if ( (i+1 == *argc) ||
                                 ( (argv[i+1][0] == '-') &&
                                   !isdigit(argv[i+1][1]) ) )
                            {
                                gmx_fatal(FARGS,
                                          "%s: vector must have 1 or 3 real parameters",
                                          pa[j].option);
                            }
                            bKeep[i]         = FALSE;
                            (*pa[j].u.rv)[2] = dscan(*argc, argv, &i);
                        }
                        break;
                    default:
                        gmx_fatal(FARGS, "Invalid type %d in pargs", pa[j].type);
                }
                /* i may be incremented, so set it to not keep */
                bKeep[i] = FALSE;
            }
        }
    }

    /* Remove used entries */
    for (i = j = 0; (i <= *argc); i++)
    {
        if (bKeep[i])
        {
            argv[j++] = argv[i];
        }
    }
    (*argc) = j-1;
    sfree(bKeep);
}
Пример #14
0
void make_pull_coords(t_pull *pull)
{
    int           ndim, d, nchar, c;
    char         *ptr, pulldim1[STRLEN];
    t_pull_coord *pcrd;

    ptr  = pulldim;
    ndim = 0;
    for (d = 0; d < DIM; d++)
    {
        if (sscanf(ptr, "%s%n", pulldim1, &nchar) != 1)
        {
            gmx_fatal(FARGS, "Less than 3 pull dimensions given in pull_dim: '%s'",
                      pulldim);
        }

        if (gmx_strncasecmp(pulldim1, "N", 1) == 0)
        {
            pull->dim[d] = 0;
        }
        else if (gmx_strncasecmp(pulldim1, "Y", 1) == 0)
        {
            pull->dim[d] = 1;
            ndim++;
        }
        else
        {
            gmx_fatal(FARGS, "Please use Y(ES) or N(O) for pull_dim only (not %s)",
                      pulldim1);
        }
        ptr += nchar;
    }
    if (ndim == 0)
    {
        gmx_fatal(FARGS, "All entries in pull_dim are N");
    }

    for (c = 0; c < pull->ncoord; c++)
    {
        pcrd = &pull->coord[c];

        if (pcrd->group[0] < 0 || pcrd->group[0] >= pull->ngroup ||
            pcrd->group[1] < 0 || pcrd->group[1] >= pull->ngroup)
        {
            gmx_fatal(FARGS, "Pull group index in pull-coord%d-groups out of range, should be between %d and %d", c+1, 0, pull->ngroup+1);
        }

        if (pcrd->group[0] == pcrd->group[1])
        {
            gmx_fatal(FARGS, "Identical pull group indices in pull-coord%d-groups", c+1);
        }

        if (pull->eGeom == epullgCYL && pcrd->group[0] != 1)
        {
            gmx_fatal(FARGS, "With pull geometry %s, the first pull group should always be 1", EPULLGEOM(pull->eGeom));
        }

        if (pull->eGeom != epullgDIST)
        {
            for (d = 0; d < DIM; d++)
            {
                if (pcrd->vec[d] != 0 && pull->dim[d] == 0)
                {
                    gmx_fatal(FARGS, "ERROR: pull-group%d-vec has non-zero %c-component while pull_dim for the %c-dimension is N\n", c+1, 'x'+d, 'x'+d);
                }
            }
        }

        if ((pull->eGeom == epullgDIR || pull->eGeom == epullgCYL) &&
            norm2(pcrd->vec) == 0)
        {
            gmx_fatal(FARGS, "pull-group%d-vec can not be zero with geometry %s",
                      c+1, EPULLGEOM(pull->eGeom));
        }
    }
}
Пример #15
0
void read_resall(char *rrdb, int *nrtpptr, t_restp **rtp, 
                 gpp_atomtype_t atype, t_symtab *tab,
                 gmx_bool bAllowOverrideRTP)
{
  FILE      *in;
  char      filebase[STRLEN],*ptr,line[STRLEN],header[STRLEN];
  int       i,nrtp,maxrtp,bt,nparam;
  int       dum1,dum2,dum3;
  t_restp   *rrtp;
  gmx_bool      bNextResidue,bError;
  int       bts[ebtsNR];
  gmx_bool      bAlldih;
  int       nrexcl;
  gmx_bool      HH14;
  gmx_bool      bRemoveDih;
  int       firstrtp;

  fflib_filename_base(rrdb,filebase,STRLEN);

  in = fflib_open(rrdb);
  
  if (debug) {
    fprintf(debug,"%9s %5s", "Residue", "atoms");
    for(i=0; i<ebtsNR; i++)
      fprintf(debug," %10s",btsNames[i]);
    fprintf(debug,"\n");
  }

  /* these bonded parameters will overwritten be when  *
   * there is a [ bondedtypes ] entry in the .rtp file */
  bts[ebtsBONDS]  = 1; /* normal bonds     */
  bts[ebtsANGLES] = 1; /* normal angles    */
  bts[ebtsPDIHS]  = 1; /* normal dihedrals */
  bts[ebtsIDIHS]  = 2; /* normal impropers */
  bts[ebtsEXCLS]  = 1; /* normal exclusions */
  bts[ebtsCMAP]   = 1; /* normal cmap torsions */

  bAlldih    = FALSE;
  nrexcl     = 3;
  HH14       = TRUE;
  bRemoveDih = TRUE;
  
  /* Column 5 & 6 aren't really bonded types, but we include
   * them here to avoid introducing a new section:
   * Column 5: 1 means generate all dihedrals, 0 not.
   * Column 6: Number of bonded neighbors to exclude.
   * Coulmn 7: Generate 1,4 interactions between pairs of hydrogens
   * Column 8: Remove impropers over the same bond as a proper dihedral
   */
  
  get_a_line(in,line,STRLEN);
  if (!get_header(line,header))
    gmx_fatal(FARGS,"in .rtp file at line:\n%s\n",line);
  if (gmx_strncasecmp("bondedtypes",header,5)==0) {
    get_a_line(in,line,STRLEN);
    if ((nparam=sscanf(line,"%d %d %d %d %d %d %d %d",
		       &bts[ebtsBONDS],&bts[ebtsANGLES],
		       &bts[ebtsPDIHS],&bts[ebtsIDIHS],
		       &dum1,&nrexcl,&dum2,&dum3)) < 4 )
    {
      gmx_fatal(FARGS,"need at least 4 (up to 8) parameters in .rtp file at line:\n%s\n",line);
    }
    bAlldih    = (dum1 != 0);
    HH14       = (dum2 != 0);
    bRemoveDih = (dum3 != 0);
    get_a_line(in,line,STRLEN);
    if(nparam<5) {
      fprintf(stderr,"Using default: not generating all possible dihedrals\n");
      bAlldih = FALSE;
    }
    if(nparam<6) {
      fprintf(stderr,"Using default: excluding 3 bonded neighbors\n");
      nrexcl = 3;
    }
    if(nparam<7) {
      fprintf(stderr,"Using default: generating 1,4 H--H interactions\n");
      HH14 = TRUE;
    }
    if(nparam<8) {
      fprintf(stderr,"Using default: removing impropers on same bond as a proper\n");
      bRemoveDih = TRUE;
    }
  } else {
    fprintf(stderr,
	    "Reading .rtp file without '[ bondedtypes ]' directive,\n"
	    "Will proceed as if the entry\n"
	    "\n"
	    "\n[ bondedtypes ]"
	    "\n; bonds  angles  dihedrals  impropers all_dihedrals nr_exclusions HH14 remove_dih"
	    "\n   %3d     %3d        %3d        %3d           %3d           %3d   %3d    %3d"
	    "\n"
	    "was present at the beginning of %s",
	    bts[0],bts[1],bts[2],bts[3], bAlldih ? 1 : 0,nrexcl,HH14,bRemoveDih,rrdb);
  }
  /* We don't know the current size of rrtp, but simply realloc immediately */
  nrtp = *nrtpptr;
  rrtp = *rtp;
  maxrtp = nrtp;
  while (!feof(in)) {
    if (nrtp >= maxrtp) {
      maxrtp+=100;
      srenew(rrtp,maxrtp);
    }
    clear_t_restp(&rrtp[nrtp]);
    if (!get_header(line,header))
      gmx_fatal(FARGS,"in .rtp file at line:\n%s\n",line);
    rrtp[nrtp].resname  = strdup(header);
    rrtp[nrtp].filebase = strdup(filebase);

    /* Set the bonded types */
    rrtp[nrtp].bAlldih    = bAlldih;
    rrtp[nrtp].nrexcl     = nrexcl;
    rrtp[nrtp].HH14       = HH14;
    rrtp[nrtp].bRemoveDih = bRemoveDih;
    for(i=0; i<ebtsNR; i++) {
      rrtp[nrtp].rb[i].type = bts[i];
    }

    get_a_line(in,line,STRLEN);
    bError=FALSE;
    bNextResidue=FALSE;
    do {
      if (!get_header(line,header)) {
	bError = TRUE;
      } else {
	bt = get_bt(header);
	if (bt != NOTSET) {
	  /* header is an bonded directive */
	  bError = !read_bondeds(bt,in,line,&rrtp[nrtp]);
	} else if (gmx_strncasecmp("atoms",header,5) == 0) {
	  /* header is the atoms directive */
	  bError = !read_atoms(in,line,&(rrtp[nrtp]),tab,atype);
	} else {
	  /* else header must be a residue name */
	  bNextResidue = TRUE;
	}
      }
      if (bError)
	gmx_fatal(FARGS,"in .rtp file in residue %s at line:\n%s\n",
		    rrtp[nrtp].resname,line);
    } while (!feof(in) && !bNextResidue);

    if (rrtp[nrtp].natom == 0)
      gmx_fatal(FARGS,"No atoms found in .rtp file in residue %s\n",
		  rrtp[nrtp].resname);
    if (debug) {
      fprintf(debug,"%3d %5s %5d",
	      nrtp+1,rrtp[nrtp].resname,rrtp[nrtp].natom);
      for(i=0; i<ebtsNR; i++)
	fprintf(debug," %10d",rrtp[nrtp].rb[i].nb);
      fprintf(debug,"\n");
    }
    
    firstrtp = -1;
    for(i=0; i<nrtp; i++) {
        if (gmx_strcasecmp(rrtp[i].resname,rrtp[nrtp].resname) == 0) {
            firstrtp = i;
        }
    }
    
    if (firstrtp == -1) {
        nrtp++;
        fprintf(stderr,"\rResidue %d",nrtp);
    } else {
        if (firstrtp >= *nrtpptr)
        {
            gmx_fatal(FARGS,"Found a second entry for '%s' in '%s'",
                      rrtp[nrtp].resname,rrdb);
        }
        if (bAllowOverrideRTP)
        {
            fprintf(stderr,"\n");
            fprintf(stderr,"Found another rtp entry for '%s' in '%s', ignoring this entry and keeping the one from '%s.rtp'\n",
                    rrtp[nrtp].resname,rrdb,rrtp[firstrtp].filebase);
            /* We should free all the data for this entry.
             * The current code gives a lot of dangling pointers.
             */
            clear_t_restp(&rrtp[nrtp]);
        }
        else
        {
            gmx_fatal(FARGS,"Found rtp entries for '%s' in both '%s' and '%s'. If you want the first definition to override the second one, set the -rtpo option of pdb2gmx.",rrtp[nrtp].resname,rrtp[firstrtp].filebase,rrdb);
        }
    }
  }
  ffclose(in);
  /* give back unused memory */
  srenew(rrtp,nrtp);
  
  fprintf(stderr,"\nSorting it all out...\n");
  qsort(rrtp,nrtp,(size_t)sizeof(rrtp[0]),comprtp);
  
  check_rtp(nrtp,rrtp,rrdb);

  *nrtpptr = nrtp;
  *rtp     = rrtp;
}
Пример #16
0
static gmx_bool calc_vsite3out_param(gpp_atomtype_t atype,
				 t_param *param, t_atoms *at,
				 int nrbond, t_mybonded *bonds,
				 int nrang,  t_mybonded *angles)
{
  /* i = virtual site          |    ,k
   * j = 1st bonded heavy atom | i-j
   * k,l = 2nd bonded atoms    |    `l
   * NOTE: i is out of the j-k-l plane!
   */
  
  gmx_bool bXH3,bError,bSwapParity;
  real bij,bjk,bjl,aijk,aijl,akjl,pijk,pijl,a,b,c;
  
  /* check if this is part of a NH2-umbrella, NH3 or CH3 group,
   * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
  if (debug) {
    int i;
    for (i=0; i<4; i++)
      fprintf(debug,"atom %u type %s ",
	      param->a[i]+1,get_atomtype_name(at->atom[param->a[i]].type,atype));
    fprintf(debug,"\n");
  }
  bXH3 = 
    ( (gmx_strncasecmp(get_atomtype_name(at->atom[param->AK].type,atype),"MNH",3)==0) &&
      (gmx_strncasecmp(get_atomtype_name(at->atom[param->AL].type,atype),"MNH",3)==0) ) ||
    ( (gmx_strncasecmp(get_atomtype_name(at->atom[param->AK].type,atype),"MCH3",4)==0) &&
      (gmx_strncasecmp(get_atomtype_name(at->atom[param->AL].type,atype),"MCH3",4)==0) );
  
  /* check if construction parity must be swapped */  
  bSwapParity = ( param->C1 == -1 );
  
  bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
  bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
  bError = (bjk==NOTSET) || (bjl==NOTSET);
  if (bXH3) {
    /* now we get some XH3 group specific construction */
    /* note: we call the heavy atom 'C' and the X atom 'N' */
    real bMM,bCM,bCN,bNH,aCNH,dH,rH,rHx,rHy,dM,rM;
    int aN;
    
    /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
    bError = bError || (bjk!=bjl);
    
    /* the X atom (C or N) in the XH3 group is the first after the masses: */
    aN = max(param->AK,param->AL)+1;
    
    /* get all bondlengths and angles: */
    bMM = get_bond_length(nrbond, bonds, param->AK, param->AL);
    bCM = bjk;
    bCN = get_bond_length(nrbond, bonds, param->AJ, aN);
    bNH = get_bond_length(nrbond, bonds, aN, param->AI);
    aCNH= get_angle      (nrang, angles, param->AJ, aN, param->AI);
    bError = bError || 
      (bMM==NOTSET) || (bCN==NOTSET) || (bNH==NOTSET) || (aCNH==NOTSET);
    
    /* calculate */
    dH  = bCN - bNH * cos(aCNH);
    rH  = bNH * sin(aCNH);
    /* we assume the H's are symmetrically distributed */
    rHx = rH*cos(DEG2RAD*30);
    rHy = rH*sin(DEG2RAD*30);
    rM  = 0.5*bMM;
    dM  = sqrt( sqr(bCM) - sqr(rM) );
    a   = 0.5*( (dH/dM) - (rHy/rM) );
    b   = 0.5*( (dH/dM) + (rHy/rM) );
    c   = rHx / (2*dM*rM);
    
  } else {
    /* this is the general construction */
    
    bij = get_bond_length(nrbond, bonds, param->AI, param->AJ);
    aijk= get_angle      (nrang, angles, param->AI, param->AJ, param->AK);
    aijl= get_angle      (nrang, angles, param->AI, param->AJ, param->AL);
    akjl= get_angle      (nrang, angles, param->AK, param->AJ, param->AL);
    bError = bError || 
      (bij==NOTSET) || (aijk==NOTSET) || (aijl==NOTSET) || (akjl==NOTSET);
  
    pijk = cos(aijk)*bij;
    pijl = cos(aijl)*bij;
    a = ( pijk + (pijk*cos(akjl)-pijl) * cos(akjl) / sqr(sin(akjl)) ) / bjk;
    b = ( pijl + (pijl*cos(akjl)-pijk) * cos(akjl) / sqr(sin(akjl)) ) / bjl;
    c = - sqrt( sqr(bij) - 
		( sqr(pijk) - 2*pijk*pijl*cos(akjl) + sqr(pijl) ) 
		/ sqr(sin(akjl)) )
      / ( bjk*bjl*sin(akjl) );
  }
  
  param->C0 = a;
  param->C1 = b;
  if (bSwapParity)
    param->C2 = -c;
  else
    param->C2 =  c;
  if (debug)
    fprintf(debug,"params for vsite3out %u: %g %g %g\n",
	    param->AI+1,param->C0,param->C1,param->C2);
  return bError;
}
Пример #17
0
static gmx_bool calc_vsite3_param(gpp_atomtype_t atype,
			      t_param *param, t_atoms *at,
			      int nrbond, t_mybonded *bonds,
			      int nrang,  t_mybonded *angles )
{
  /* i = virtual site          |    ,k
   * j = 1st bonded heavy atom | i-j
   * k,l = 2nd bonded atoms    |    `l
   */
  
  gmx_bool bXH3,bError;
  real bjk,bjl,a=-1,b=-1;
  /* check if this is part of a NH3 , NH2-umbrella or CH3 group,
   * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */
  if (debug) {
    int i;
    for (i=0; i<4; i++)
      fprintf(debug,"atom %u type %s ",
	      param->a[i]+1,
	      get_atomtype_name(at->atom[param->a[i]].type,atype));
    fprintf(debug,"\n");
  }
  bXH3 = 
    ( (gmx_strncasecmp(get_atomtype_name(at->atom[param->AK].type,atype),"MNH",3)==0) &&
      (gmx_strncasecmp(get_atomtype_name(at->atom[param->AL].type,atype),"MNH",3)==0) ) ||
    ( (gmx_strncasecmp(get_atomtype_name(at->atom[param->AK].type,atype),"MCH3",4)==0) &&
      (gmx_strncasecmp(get_atomtype_name(at->atom[param->AL].type,atype),"MCH3",4)==0) );
  
  bjk = get_bond_length(nrbond, bonds, param->AJ, param->AK);
  bjl = get_bond_length(nrbond, bonds, param->AJ, param->AL);
  bError = (bjk==NOTSET) || (bjl==NOTSET);
  if (bXH3) {
    /* now we get some XH2/XH3 group specific construction */
    /* note: we call the heavy atom 'C' and the X atom 'N' */
    real bMM,bCM,bCN,bNH,aCNH,dH,rH,dM,rM;
    int aN;
    
    /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
    bError = bError || (bjk!=bjl);
    
    /* the X atom (C or N) in the XH2/XH3 group is the first after the masses: */
    aN = max(param->AK,param->AL)+1;
    
    /* get common bonds */
    bMM = get_bond_length(nrbond, bonds, param->AK, param->AL);
    bCM = bjk;
    bCN = get_bond_length(nrbond, bonds, param->AJ, aN);
    bError = bError || (bMM==NOTSET) || (bCN==NOTSET);
    
    /* calculate common things */
    rM  = 0.5*bMM;
    dM  = sqrt( sqr(bCM) - sqr(rM) );
    
    /* are we dealing with the X atom? */
    if ( param->AI == aN ) {
      /* this is trivial */
      a = b = 0.5 * bCN/dM;
      
    } else {
      /* get other bondlengths and angles: */
      bNH = get_bond_length(nrbond, bonds, aN, param->AI);
      aCNH= get_angle      (nrang, angles, param->AJ, aN, param->AI);
      bError = bError || (bNH==NOTSET) || (aCNH==NOTSET);
      
      /* calculate */
      dH  = bCN - bNH * cos(aCNH);
      rH  = bNH * sin(aCNH);
      
      a = 0.5 * ( dH/dM + rH/rM );
      b = 0.5 * ( dH/dM - rH/rM );
    }
  } else
    gmx_fatal(FARGS,"calc_vsite3_param not implemented for the general case "
		"(atom %d)",param->AI+1);
  
  param->C0 = a;
  param->C1 = b;
  
  if (debug)
    fprintf(debug,"params for vsite3 %u: %g %g\n",
	    param->AI+1,param->C0,param->C1);
  
  return bError;
}
Пример #18
0
static void analyse_prot(const char ** restype, t_atoms *atoms,
                         t_blocka *gb, char ***gn, gmx_bool bASK, gmx_bool bVerb)
{
    /* lists of atomnames to be used in constructing index groups: */
    static const char *pnoh[]    = { "H", "HN" };
    static const char *pnodum[]  = {
        "MN1",  "MN2",  "MCB1", "MCB2", "MCG1", "MCG2",
        "MCD1", "MCD2", "MCE1", "MCE2", "MNZ1", "MNZ2"
    };
    static const char *calpha[]  = { "CA" };
    static const char *bb[]      = { "N", "CA", "C" };
    static const char *mc[]      = { "N", "CA", "C", "O", "O1", "O2", "OC1", "OC2", "OT", "OXT" };
    static const char *mcb[]     = { "N", "CA", "CB", "C", "O", "O1", "O2", "OC1", "OC2", "OT", "OXT" };
    static const char *mch[]     = {
        "N", "CA", "C", "O", "O1", "O2", "OC1", "OC2", "OT", "OXT",
        "H1", "H2", "H3", "H", "HN"
    };

    static const t_gmx_help_make_index_group constructing_data[] =
    {{ NULL,   0, "Protein",      TRUE,  -1, -1},
     { pnoh,   asize(pnoh),   "Protein-H",    TRUE,  0,  -1},
     { calpha, asize(calpha), "C-alpha",      FALSE, -1, -1},
     { bb,     asize(bb),     "Backbone",     FALSE, -1, -1},
     { mc,     asize(mc),     "MainChain",    FALSE, -1, -1},
     { mcb,    asize(mcb),    "MainChain+Cb", FALSE, -1, -1},
     { mch,    asize(mch),    "MainChain+H",  FALSE, -1, -1},
     { mch,    asize(mch),    "SideChain",    TRUE,  -1, -1},
     { mch,    asize(mch),    "SideChain-H",  TRUE,  11, -1},
     { pnodum, asize(pnodum), "Prot-Masses",  TRUE,  -1, 0}, };
    const int   num_index_groups = asize(constructing_data);

    int         n, j;
    atom_id    *aid;
    int         nra, nnpres, npres;
    gmx_bool    match;
    char        ndx_name[STRLEN], *atnm;
    int         i;

    if (bVerb)
    {
        printf("Analysing Protein...\n");
    }
    snew(aid, atoms->nr);

    /* calculate the number of protein residues */
    npres = 0;
    for (i = 0; (i < atoms->nres); i++)
    {
        if (0 == gmx_strcasecmp(restype[i], "Protein"))
        {
            npres++;
        }
    }
    /* find matching or complement atoms */
    for (i = 0; (i < (int)num_index_groups); i++)
    {
        nra = 0;
        for (n = 0; (n < atoms->nr); n++)
        {
            if (0 == gmx_strcasecmp(restype[atoms->atom[n].resind], "Protein"))
            {
                match = FALSE;
                for (j = 0; (j < constructing_data[i].num_defining_atomnames); j++)
                {
                    /* skip digits at beginning of atomname, e.g. 1H */
                    atnm = *atoms->atomname[n];
                    while (isdigit(atnm[0]))
                    {
                        atnm++;
                    }
                    if ( (constructing_data[i].wholename == -1) || (j < constructing_data[i].wholename) )
                    {
                        if (0 == gmx_strcasecmp(constructing_data[i].defining_atomnames[j], atnm))
                        {
                            match = TRUE;
                        }
                    }
                    else
                    {
                        if (0 == gmx_strncasecmp(constructing_data[i].defining_atomnames[j], atnm, strlen(constructing_data[i].defining_atomnames[j])))
                        {
                            match = TRUE;
                        }
                    }
                }
                if (constructing_data[i].bTakeComplement != match)
                {
                    aid[nra++] = n;
                }
            }
        }
        /* if we want to add this group always or it differs from previous
           group, add it: */
        if (-1 == constructing_data[i].compareto || !grp_cmp(gb, nra, aid, constructing_data[i].compareto-i) )
        {
            add_grp(gb, gn, nra, aid, constructing_data[i].group_name);
        }
    }

    if (bASK)
    {
        for (i = 0; (i < (int)num_index_groups); i++)
        {
            printf("Split %12s into %5d residues (y/n) ? ", constructing_data[i].group_name, npres);
            if (gmx_ask_yesno(bASK))
            {
                int resind;
                nra = 0;
                for (n = 0; ((atoms->atom[n].resind < npres) && (n < atoms->nr)); )
                {
                    resind = atoms->atom[n].resind;
                    for (; ((atoms->atom[n].resind == resind) && (n < atoms->nr)); n++)
                    {
                        match = FALSE;
                        for (j = 0; (j < constructing_data[i].num_defining_atomnames); j++)
                        {
                            if (0 == gmx_strcasecmp(constructing_data[i].defining_atomnames[j], *atoms->atomname[n]))
                            {
                                match = TRUE;
                            }
                        }
                        if (constructing_data[i].bTakeComplement != match)
                        {
                            aid[nra++] = n;
                        }
                    }
                    /* copy the residuename to the tail of the groupname */
                    if (nra > 0)
                    {
                        t_resinfo *ri;
                        ri = &atoms->resinfo[resind];
                        sprintf(ndx_name, "%s_%s%d%c",
                                constructing_data[i].group_name, *ri->name, ri->nr, ri->ic == ' ' ? '\0' : ri->ic);
                        add_grp(gb, gn, nra, aid, ndx_name);
                        nra = 0;
                    }
                }
            }
        }
        printf("Make group with sidechain and C=O swapped (y/n) ? ");
        if (gmx_ask_yesno(bASK))
        {
            /* Make swap sidechain C=O index */
            int resind, hold;
            nra = 0;
            for (n = 0; ((atoms->atom[n].resind < npres) && (n < atoms->nr)); )
            {
                resind = atoms->atom[n].resind;
                hold   = -1;
                for (; ((atoms->atom[n].resind == resind) && (n < atoms->nr)); n++)
                {
                    if (strcmp("CA", *atoms->atomname[n]) == 0)
                    {
                        aid[nra++] = n;
                        hold       = nra;
                        nra       += 2;
                    }
                    else if (strcmp("C", *atoms->atomname[n]) == 0)
                    {
                        if (hold == -1)
                        {
                            gmx_incons("Atom naming problem");
                        }
                        aid[hold] = n;
                    }
                    else if (strcmp("O", *atoms->atomname[n]) == 0)
                    {
                        if (hold == -1)
                        {
                            gmx_incons("Atom naming problem");
                        }
                        aid[hold+1] = n;
                    }
                    else if (strcmp("O1", *atoms->atomname[n]) == 0)
                    {
                        if (hold == -1)
                        {
                            gmx_incons("Atom naming problem");
                        }
                        aid[hold+1] = n;
                    }
                    else
                    {
                        aid[nra++] = n;
                    }
                }
            }
            /* copy the residuename to the tail of the groupname */
            if (nra > 0)
            {
                add_grp(gb, gn, nra, aid, "SwapSC-CO");
                nra = 0;
            }
        }
    }
    sfree(aid);
}
Пример #19
0
void make_pull_groups(t_pull *pull, char **pgnames, t_blocka *grps, char **gnames)
{
    int        d, nchar, g, ig = -1, i;
    char      *ptr, pulldim1[STRLEN];
    t_pullgrp *pgrp;

    ptr = pulldim;
    i   = 0;
    for (d = 0; d < DIM; d++)
    {
        if (sscanf(ptr, "%s%n", pulldim1, &nchar) != 1)
        {
            gmx_fatal(FARGS, "Less than 3 pull dimensions given in pull_dim: '%s'",
                      pulldim);
        }

        if (gmx_strncasecmp(pulldim1, "N", 1) == 0)
        {
            pull->dim[d] = 0;
        }
        else if (gmx_strncasecmp(pulldim1, "Y", 1) == 0)
        {
            pull->dim[d] = 1;
            i++;
        }
        else
        {
            gmx_fatal(FARGS, "Please use Y(ES) or N(O) for pull_dim only (not %s)",
                      pulldim1);
        }
        ptr += nchar;
    }
    if (i == 0)
    {
        gmx_fatal(FARGS, "All entries in pull_dim are N");
    }

    for (g = 0; g < pull->ngrp+1; g++)
    {
        pgrp = &pull->grp[g];
        if (g == 0 && strcmp(pgnames[g], "") == 0)
        {
            pgrp->nat = 0;
        }
        else
        {
            ig        = search_string(pgnames[g], grps->nr, gnames);
            pgrp->nat = grps->index[ig+1] - grps->index[ig];
        }
        if (pgrp->nat > 0)
        {
            fprintf(stderr, "Pull group %d '%s' has %d atoms\n",
                    g, pgnames[g], pgrp->nat);
            snew(pgrp->ind, pgrp->nat);
            for (i = 0; i < pgrp->nat; i++)
            {
                pgrp->ind[i] = grps->a[grps->index[ig]+i];
            }

            if (pull->eGeom == epullgCYL && g == 0 && pgrp->nweight > 0)
            {
                gmx_fatal(FARGS, "Weights are not supported for the reference group with cylinder pulling");
            }
            if (pgrp->nweight > 0 && pgrp->nweight != pgrp->nat)
            {
                gmx_fatal(FARGS, "Number of weights (%d) for pull group %d '%s' does not match the number of atoms (%d)",
                          pgrp->nweight, g, pgnames[g], pgrp->nat);
            }

            if (pgrp->nat == 1)
            {
                /* No pbc is required for this group */
                pgrp->pbcatom = -1;
            }
            else
            {
                if (pgrp->pbcatom > 0)
                {
                    pgrp->pbcatom -= 1;
                }
                else if (pgrp->pbcatom == 0)
                {
                    pgrp->pbcatom = pgrp->ind[(pgrp->nat-1)/2];
                }
                else
                {
                    /* Use cosine weighting */
                    pgrp->pbcatom = -1;
                }
            }

            if (g > 0 && pull->eGeom != epullgDIST)
            {
                for (d = 0; d < DIM; d++)
                {
                    if (pgrp->vec[d] != 0 && pull->dim[d] == 0)
                    {
                        gmx_fatal(FARGS, "ERROR: pull_vec%d has non-zero %c-component while pull_dim in N\n", g, 'x'+d);
                    }
                }
            }

            if ((pull->eGeom == epullgDIR || pull->eGeom == epullgCYL) &&
                g > 0 && norm2(pgrp->vec) == 0)
            {
                gmx_fatal(FARGS, "pull_vec%d can not be zero with geometry %s",
                          g, EPULLGEOM(pull->eGeom));
            }
            if ((pull->eGeom == epullgPOS) && pgrp->rate != 0 &&
                g > 0 && norm2(pgrp->vec) == 0)
            {
                gmx_fatal(FARGS, "pull_vec%d can not be zero with geometry %s and non-zero rate",
                          g, EPULLGEOM(pull->eGeom));
            }
        }
        else
        {
            if (g == 0)
            {
                if (pull->eGeom == epullgCYL)
                {
                    gmx_fatal(FARGS, "Absolute reference groups are not supported with geometry %s", EPULLGEOM(pull->eGeom));
                }
            }
            else
            {
                gmx_fatal(FARGS, "Pull group %d '%s' is empty", g, pgnames[g]);
            }
            pgrp->pbcatom = -1;
        }
    }
}
Пример #20
0
static void analyse_prot(const char ** restype,t_atoms *atoms,
			 t_blocka *gb,char ***gn,gmx_bool bASK,gmx_bool bVerb)
{
  /* atomnames to be used in constructing index groups: */
  static const char *pnoh[]    = { "H" };
  static const char *pnodum[]  = { "MN1",  "MN2",  "MCB1", "MCB2", "MCG1", "MCG2", 
			     "MCD1", "MCD2", "MCE1", "MCE2", "MNZ1", "MNZ2" };
  static const char *calpha[]  = { "CA" };
  static const char *bb[]      = { "N","CA","C" };
  static const char *mc[]      = { "N","CA","C","O","O1","O2","OC1","OC2","OT","OXT" };
  static const char *mcb[]     = { "N","CA","CB","C","O","O1","O2","OC1","OC2","OT","OXT" };
  static const char *mch[]     = { "N","CA","C","O","O1","O2","OC1","OC2","OT","OXT",
			     "H1","H2","H3","H" };
  /* array of arrays of atomnames: */
  static const char **chains[] = { NULL,pnoh,calpha,bb,mc,mcb,mch,mch,mch,pnodum };
#define NCH asize(chains)
  /* array of sizes of arrays of atomnames: */
  const int       sizes[NCH] = { 
    0, asize(pnoh), asize(calpha), asize(bb), 
    asize(mc), asize(mcb), asize(mch), asize(mch), asize(mch), asize(pnodum)
  };
  /* descriptive names of index groups */
  const char   *ch_name[NCH] = { 
    "Protein", "Protein-H", "C-alpha", "Backbone", 
    "MainChain", "MainChain+Cb", "MainChain+H", "SideChain", "SideChain-H", 
    "Prot-Masses"
  };
  /* construct index group containing (TRUE) or excluding (FALSE)
     given atom names */
  const gmx_bool complement[NCH] = { 
    TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE
  };
  const int  wholename[NCH]  = { -1, 0,-1,-1,-1,-1,-1,-1, 11,-1 };
  /* the index in wholename gives the first item in the arrays of 
   * atomtypes that should be tested with 'gmx_strncasecmp' in stead of
   * gmx_strcasecmp, or -1 if all items should be tested with strcasecmp
   * This is comparable to using a '*' wildcard at the end of specific
   * atom names, but that is more involved to implement...
   */
  /* only add index group if it differs from the specified one, 
     specify -1 to always add group */
  const int compareto[NCH] = { -1,-1,-1,-1,-1,-1,-1,-1,-1, 0 };

  int     n,j;
  atom_id *aid;
  int     nra,nnpres,npres;
  gmx_bool    match;
  char    ndx_name[STRLEN],*atnm;
  int i;

  if (bVerb)
  {
    printf("Analysing Protein...\n");
  }
  snew(aid,atoms->nr);

  /* calculate the number of protein residues */
  npres=0;
  for(i=0; (i<atoms->nres); i++)
  if (!gmx_strcasecmp(restype[i],"Protein"))
  {
      npres++;
  }
  /* find matching or complement atoms */
  for(i=0; (i<(int)NCH); i++) {
    nra=0;
    for(n=0; (n<atoms->nr); n++) {
        if (!gmx_strcasecmp(restype[atoms->atom[n].resind],"Protein")) {

	match=FALSE;
	for(j=0; (j<sizes[i]); j++) {
	  /* skip digits at beginning of atomname, e.g. 1H */
	  atnm=*atoms->atomname[n];
	  while (isdigit(atnm[0]))
	    atnm++;
	  if ( (wholename[i]==-1) || (j<wholename[i]) ) {
	    if (gmx_strcasecmp(chains[i][j],atnm) == 0)
	      match=TRUE;
	  } else {
	    if (gmx_strncasecmp(chains[i][j],atnm,strlen(chains[i][j])) == 0)
	      match=TRUE;
	  }
	}
	if (match != complement[i])
	  aid[nra++]=n;
      }
    }
    /* if we want to add this group always or it differs from previous 
       group, add it: */
    if ( compareto[i] == -1 || !grp_cmp(gb,nra,aid,compareto[i]-i) )
      add_grp(gb,gn,nra,aid,ch_name[i]); 
  }
  
  if (bASK) {
    for(i=0; (i<(int)NCH); i++) {
      printf("Split %12s into %5d residues (y/n) ? ",ch_name[i],npres);
      if (gmx_ask_yesno(bASK)) {
	int resind;
	nra = 0;
	for(n=0;((atoms->atom[n].resind < npres) && (n<atoms->nr));) {
	  resind = atoms->atom[n].resind;
	  for(;((atoms->atom[n].resind==resind) && (n<atoms->nr));n++) {
	    match=FALSE;
	    for(j=0;(j<sizes[i]); j++) 
	      if (gmx_strcasecmp(chains[i][j],*atoms->atomname[n]) == 0)
		match=TRUE;
	    if (match != complement[i])
	      aid[nra++]=n;
	  }
	  /* copy the residuename to the tail of the groupname */
	  if (nra > 0) {
	    t_resinfo *ri;
	    ri = &atoms->resinfo[resind];
	    sprintf(ndx_name,"%s_%s%d%c",
		    ch_name[i],*ri->name,ri->nr,ri->ic==' ' ? '\0' : ri->ic);
	    add_grp(gb,gn,nra,aid,ndx_name);
	    nra = 0;
	  }
	}
      } 
    }
    printf("Make group with sidechain and C=O swapped (y/n) ? ");
    if (gmx_ask_yesno(bASK)) {
      /* Make swap sidechain C=O index */
      int resind,hold;
      nra = 0;
      for(n=0;((atoms->atom[n].resind < npres) && (n<atoms->nr));) {
	resind = atoms->atom[n].resind;
	hold  = -1;
	for(;((atoms->atom[n].resind==resind) && (n<atoms->nr));n++)
	  if (strcmp("CA",*atoms->atomname[n]) == 0) {
	    aid[nra++]=n;
	    hold=nra;
	    nra+=2;
	  } else if (strcmp("C",*atoms->atomname[n]) == 0) {
	    if (hold == -1)
	      gmx_incons("Atom naming problem");
	    aid[hold]=n;
	  } else if (strcmp("O",*atoms->atomname[n]) == 0) {
	    if (hold == -1)
	      gmx_incons("Atom naming problem");
	    aid[hold+1]=n;
	  } else if (strcmp("O1",*atoms->atomname[n]) == 0) {
	    if (hold == -1)
	      gmx_incons("Atom naming problem");
	    aid[hold+1]=n;
	  } else 
	    aid[nra++]=n;
      }
      /* copy the residuename to the tail of the groupname */
      if (nra > 0) {
	add_grp(gb,gn,nra,aid,"SwapSC-CO");
	nra = 0;
      } 
    }
  }
  sfree(aid);
}
Пример #21
0
double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                    const output_env_t oenv, gmx_bool bVerbose,gmx_bool bCompact,
                    int nstglobalcomm,
                    gmx_vsite_t *vsite,gmx_constr_t constr,
                    int stepout,t_inputrec *ir,
                    gmx_mtop_t *top_global,
                    t_fcdata *fcd,
                    t_state *state_global,
                    t_mdatoms *mdatoms,
                    t_nrnb *nrnb,gmx_wallcycle_t wcycle,
                    gmx_edsam_t ed,t_forcerec *fr,
                    int repl_ex_nst,int repl_ex_seed,
                    real cpt_period,real max_hours,
                    const char *deviceOptions,
                    unsigned long Flags,
                    gmx_runtime_t *runtime)
{
    gmx_mdoutf_t *outf;
    gmx_large_int_t step,step_rel;
    double     run_time;
    double     t,t0,lam0;
    gmx_bool       bSimAnn,
    bFirstStep,bStateFromTPX,bLastStep,bStartingFromCpt;
    gmx_bool       bInitStep=TRUE;
    gmx_bool       do_ene,do_log, do_verbose,
    bX,bV,bF,bCPT;
    tensor     force_vir,shake_vir,total_vir,pres;
    int        i,m;
    int        mdof_flags;
    rvec       mu_tot;
    t_vcm      *vcm;
    int        nchkpt=1;
    gmx_localtop_t *top;
    t_mdebin *mdebin=NULL;
    t_state    *state=NULL;
    rvec       *f_global=NULL;
    int        n_xtc=-1;
    rvec       *x_xtc=NULL;
    gmx_enerdata_t *enerd;
    rvec       *f=NULL;
    gmx_global_stat_t gstat;
    gmx_update_t upd=NULL;
    t_graph    *graph=NULL;
    globsig_t   gs;

    gmx_groups_t *groups;
    gmx_ekindata_t *ekind, *ekind_save;
    gmx_bool        bAppend;
    int         a0,a1;
    matrix      lastbox;
    real        reset_counters=0,reset_counters_now=0;
    char        sbuf[STEPSTRSIZE],sbuf2[STEPSTRSIZE];
    int         handled_stop_condition=gmx_stop_cond_none; 

    const char *ommOptions = NULL;
    void   *openmmData;

    bAppend  = (Flags & MD_APPENDFILES);
    check_ir_old_tpx_versions(cr,fplog,ir,top_global);

    groups = &top_global->groups;

    /* Initial values */
    init_md(fplog,cr,ir,oenv,&t,&t0,&state_global->lambda,&lam0,
            nrnb,top_global,&upd,
            nfile,fnm,&outf,&mdebin,
            force_vir,shake_vir,mu_tot,&bSimAnn,&vcm,state_global,Flags);

    clear_mat(total_vir);
    clear_mat(pres);
    /* Energy terms and groups */
    snew(enerd,1);
    init_enerdata(top_global->groups.grps[egcENER].nr,ir->n_flambda,enerd);
    snew(f,top_global->natoms);

    /* Kinetic energy data */
    snew(ekind,1);
    init_ekindata(fplog,top_global,&(ir->opts),ekind);
    /* needed for iteration of constraints */
    snew(ekind_save,1);
    init_ekindata(fplog,top_global,&(ir->opts),ekind_save);
    /* Copy the cos acceleration to the groups struct */
    ekind->cosacc.cos_accel = ir->cos_accel;

    gstat = global_stat_init(ir);
    debug_gmx();

    {
        double io = compute_io(ir,top_global->natoms,groups,mdebin->ebin->nener,1);
        if ((io > 2000) && MASTER(cr))
            fprintf(stderr,
                    "\nWARNING: This run will generate roughly %.0f Mb of data\n\n",
                    io);
    }

    top = gmx_mtop_generate_local_top(top_global,ir);

    a0 = 0;
    a1 = top_global->natoms;

    state = partdec_init_local_state(cr,state_global);
    f_global = f;

    atoms2md(top_global,ir,0,NULL,a0,a1-a0,mdatoms);

    if (vsite)
    {
        set_vsite_top(vsite,top,mdatoms,cr);
    }

    if (ir->ePBC != epbcNONE && !ir->bPeriodicMols)
    {
        graph = mk_graph(fplog,&(top->idef),0,top_global->natoms,FALSE,FALSE);
    }

    update_mdatoms(mdatoms,state->lambda);

    if (deviceOptions[0]=='\0')
    {
        /* empty options, which should default to OpenMM in this build */
        ommOptions=deviceOptions;
    }
    else
    {
        if (gmx_strncasecmp(deviceOptions,"OpenMM",6)!=0)
        {
            gmx_fatal(FARGS, "This Gromacs version currently only works with OpenMM. Use -device \"OpenMM:<options>\"");
        }
        else
        {
            ommOptions=strchr(deviceOptions,':');
            if (NULL!=ommOptions)
            {
                /* Increase the pointer to skip the colon */
                ommOptions++;
            }
        }
    }

    openmmData = openmm_init(fplog, ommOptions, ir, top_global, top, mdatoms, fr, state);
    please_cite(fplog,"Friedrichs2009");

    if (MASTER(cr))
    {
        /* Update mdebin with energy history if appending to output files */
        if ( Flags & MD_APPENDFILES )
        {
            restore_energyhistory_from_state(mdebin,&state_global->enerhist);
        }
        /* Set the initial energy history in state to zero by updating once */
        update_energyhistory(&state_global->enerhist,mdebin);
    }

    if (constr)
    {
        set_constraints(constr,top,ir,mdatoms,cr);
    }

    if (!ir->bContinuation)
    {
        if (mdatoms->cFREEZE && (state->flags & (1<<estV)))
        {
            /* Set the velocities of frozen particles to zero */
            for (i=mdatoms->start; i<mdatoms->start+mdatoms->homenr; i++)
            {
                for (m=0; m<DIM; m++)
                {
                    if (ir->opts.nFreeze[mdatoms->cFREEZE[i]][m])
                    {
                        state->v[i][m] = 0;
                    }
                }
            }
        }

        if (constr)
        {
            /* Constrain the initial coordinates and velocities */
            do_constrain_first(fplog,constr,ir,mdatoms,state,f,
                               graph,cr,nrnb,fr,top,shake_vir);
        }
        if (vsite)
        {
            /* Construct the virtual sites for the initial configuration */
            construct_vsites(fplog,vsite,state->x,nrnb,ir->delta_t,NULL,
                             top->idef.iparams,top->idef.il,
                             fr->ePBC,fr->bMolPBC,graph,cr,state->box);
        }
    }

    debug_gmx();

    if (MASTER(cr))
    {
        char tbuf[20];
        fprintf(fplog,"Initial temperature: %g K\n",enerd->term[F_TEMP]);
        fprintf(stderr,"starting mdrun '%s'\n",
                *(top_global->name));
        if (ir->nsteps >= 0)
        {
            sprintf(tbuf,"%8.1f",(ir->init_step+ir->nsteps)*ir->delta_t);
        }
        else
        {
            sprintf(tbuf,"%s","infinite");
        }
        if (ir->init_step > 0)
        {
            fprintf(stderr,"%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
                    gmx_step_str(ir->init_step+ir->nsteps,sbuf),tbuf,
                    gmx_step_str(ir->init_step,sbuf2),
                    ir->init_step*ir->delta_t);
        }
        else
        {
            fprintf(stderr,"%s steps, %s ps.\n",
                    gmx_step_str(ir->nsteps,sbuf),tbuf);
        }
    }

    fprintf(fplog,"\n");

    /* Set and write start time */
    runtime_start(runtime);
    print_date_and_time(fplog,cr->nodeid,"Started mdrun",runtime);
    wallcycle_start(wcycle,ewcRUN);
    if (fplog)
        fprintf(fplog,"\n");

    /* safest point to do file checkpointing is here.  More general point would be immediately before integrator call */

    debug_gmx();
    /***********************************************************
     *
     *             Loop over MD steps
     *
     ************************************************************/

    /* loop over MD steps or if rerunMD to end of input trajectory */
    bFirstStep = TRUE;
    /* Skip the first Nose-Hoover integration when we get the state from tpx */
    bStateFromTPX = !opt2bSet("-cpi",nfile,fnm);
    bInitStep = bFirstStep && bStateFromTPX;
    bStartingFromCpt = (Flags & MD_STARTFROMCPT) && bInitStep;
    bLastStep = FALSE;

    init_global_signals(&gs,cr,ir,repl_ex_nst);

    step = ir->init_step;
    step_rel = 0;

    while (!bLastStep)
    {
        wallcycle_start(wcycle,ewcSTEP);

        GMX_MPE_LOG(ev_timestep1);

        bLastStep = (step_rel == ir->nsteps);
        t = t0 + step*ir->delta_t;

        if (gs.set[eglsSTOPCOND] != 0)
        {
            bLastStep = TRUE;
        }

        do_log = do_per_step(step,ir->nstlog) || bFirstStep || bLastStep;
        do_verbose = bVerbose &&
                     (step % stepout == 0 || bFirstStep || bLastStep);

        if (MASTER(cr) && do_log)
        {
            print_ebin_header(fplog,step,t,state->lambda);
        }

        clear_mat(force_vir);
        GMX_MPE_LOG(ev_timestep2);

        /* We write a checkpoint at this MD step when:
         * either when we signalled through gs (in OpenMM NS works different),
         * or at the last step (but not when we do not want confout),
         * but never at the first step.
         */
        bCPT = ((gs.set[eglsCHKPT] ||
                 (bLastStep && (Flags & MD_CONFOUT))) &&
                step > ir->init_step );
        if (bCPT)
        {
            gs.set[eglsCHKPT] = 0;
        }

        /* Now we have the energies and forces corresponding to the
         * coordinates at time t. We must output all of this before
         * the update.
         * for RerunMD t is read from input trajectory
         */
        GMX_MPE_LOG(ev_output_start);

        mdof_flags = 0;
        if (do_per_step(step,ir->nstxout))
        {
            mdof_flags |= MDOF_X;
        }
        if (do_per_step(step,ir->nstvout))
        {
            mdof_flags |= MDOF_V;
        }
        if (do_per_step(step,ir->nstfout))
        {
            mdof_flags |= MDOF_F;
        }
        if (do_per_step(step,ir->nstxtcout))
        {
            mdof_flags |= MDOF_XTC;
        }
        if (bCPT)
        {
            mdof_flags |= MDOF_CPT;
        };
        do_ene = (do_per_step(step,ir->nstenergy) || bLastStep);

        if (mdof_flags != 0 || do_ene || do_log)
        {
            wallcycle_start(wcycle,ewcTRAJ);
            bF = (mdof_flags & MDOF_F);
            bX = (mdof_flags & (MDOF_X | MDOF_XTC | MDOF_CPT));
            bV = (mdof_flags & (MDOF_V | MDOF_CPT));

            openmm_copy_state(openmmData, state, &t, f, enerd, bX, bV, bF, do_ene);

            upd_mdebin(mdebin, FALSE,TRUE,
                       t,mdatoms->tmass,enerd,state,lastbox,
                       shake_vir,force_vir,total_vir,pres,
                       ekind,mu_tot,constr);
            print_ebin(outf->fp_ene,do_ene,FALSE,FALSE,do_log?fplog:NULL,
                       step,t,
                       eprNORMAL,bCompact,mdebin,fcd,groups,&(ir->opts));
            write_traj(fplog,cr,outf,mdof_flags,top_global,
                       step,t,state,state_global,f,f_global,&n_xtc,&x_xtc);
            if (bCPT)
            {
                nchkpt++;
                bCPT = FALSE;
            }
            debug_gmx();
            if (bLastStep && step_rel == ir->nsteps &&
                    (Flags & MD_CONFOUT) && MASTER(cr))
            {
                /* x and v have been collected in write_traj,
                 * because a checkpoint file will always be written
                 * at the last step.
                 */
                fprintf(stderr,"\nWriting final coordinates.\n");
                if (ir->ePBC != epbcNONE && !ir->bPeriodicMols)
                {
                    /* Make molecules whole only for confout writing */
                    do_pbc_mtop(fplog,ir->ePBC,state->box,top_global,state_global->x);
                }
                write_sto_conf_mtop(ftp2fn(efSTO,nfile,fnm),
                                    *top_global->name,top_global,
                                    state_global->x,state_global->v,
                                    ir->ePBC,state->box);
                debug_gmx();
            }
            wallcycle_stop(wcycle,ewcTRAJ);
        }
        GMX_MPE_LOG(ev_output_finish);


        /* Determine the wallclock run time up till now */
        run_time = gmx_gettime() - (double)runtime->real;

        /* Check whether everything is still allright */
        if (((int)gmx_get_stop_condition() > handled_stop_condition)
#ifdef GMX_THREADS
            && MASTER(cr)
#endif
            )
        {
           /* this is just make gs.sig compatible with the hack 
               of sending signals around by MPI_Reduce with together with
               other floats */
            /* NOTE: this only works for serial code. For code that allows
               MPI nodes to propagate their condition, see kernel/md.c*/
            if ( gmx_get_stop_condition() == gmx_stop_cond_next_ns )
                gs.set[eglsSTOPCOND]=1;
            if ( gmx_get_stop_condition() == gmx_stop_cond_next )
                gs.set[eglsSTOPCOND]=1;
            /* < 0 means stop at next step, > 0 means stop at next NS step */
            if (fplog)
            {
                fprintf(fplog,
                        "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
                        gmx_get_signal_name(),
                        gs.sig[eglsSTOPCOND]==1 ? "NS " : "");
                fflush(fplog);
            }
            fprintf(stderr,
                    "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
                    gmx_get_signal_name(),
                    gs.sig[eglsSTOPCOND]==1 ? "NS " : "");
            fflush(stderr);
            handled_stop_condition=(int)gmx_get_stop_condition();
        }
        else if (MASTER(cr) &&
                 (max_hours > 0 && run_time > max_hours*60.0*60.0*0.99) &&
                 gs.set[eglsSTOPCOND] == 0)
        {
            /* Signal to terminate the run */
            gs.set[eglsSTOPCOND] = 1;
            if (fplog)
            {
                fprintf(fplog,"\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99);
            }
            fprintf(stderr, "\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99);
        }

        /* checkpoints */
        if (MASTER(cr) && (cpt_period >= 0 &&
                           (cpt_period == 0 ||
                            run_time >= nchkpt*cpt_period*60.0)) &&
                gs.set[eglsCHKPT] == 0)
        {
            gs.set[eglsCHKPT] = 1;
        }

        /* Time for performance */
        if (((step % stepout) == 0) || bLastStep)
        {
            runtime_upd_proc(runtime);
        }

        if (do_per_step(step,ir->nstlog))
        {
            if (fflush(fplog) != 0)
            {
                gmx_fatal(FARGS,"Cannot flush logfile - maybe you are out of quota?");
            }
        }

        /* Remaining runtime */
        if (MULTIMASTER(cr) && (do_verbose || gmx_got_usr_signal() ))
        {
            print_time(stderr,runtime,step,ir,cr);
        }

        bFirstStep = FALSE;
        bInitStep = FALSE;
        bStartingFromCpt = FALSE;
        step++;
        step_rel++;

        openmm_take_one_step(openmmData);
    }
    /* End of main MD loop */
    debug_gmx();

    /* Stop the time */
    runtime_end(runtime);

    if (MASTER(cr))
    {
        if (ir->nstcalcenergy > 0) 
        {
            print_ebin(outf->fp_ene,FALSE,FALSE,FALSE,fplog,step,t,
                       eprAVER,FALSE,mdebin,fcd,groups,&(ir->opts));
        }
    }

    openmm_cleanup(fplog, openmmData);

    done_mdoutf(outf);

    debug_gmx();

    runtime->nsteps_done = step_rel;

    return 0;
}
Пример #22
0
static char *xvgrstr(const char *gmx, const output_env_t oenv,
                     char *buf, int buflen)
{
    /* Supported greek letter names and corresponding xmgrace/xmgr symbols */
    const char *sym[]  = { "beta", "chi", "delta", "eta", "lambda", "mu", "omega", "phi", "psi", "rho", "theta", NULL };
    const char  symc[] = { 'b',    'c',   'd',     'h',   'l',      'm',  'w',     'f',   'y',   'r',   'q',     '\0' };
    int         xvgf;
    gmx_bool    bXVGR;
    int         g, b, i;
    char        c;

    xvgf  = output_env_get_xvg_format(oenv);
    bXVGR = (xvgf == exvgXMGRACE || xvgf == exvgXMGR);

    g = 0;
    b = 0;
    while (gmx[g] != '\0')
    {
        /* Check with the largest string we have ("lambda"), add one for \0 */
        if (b + 6 + 1 >= buflen)
        {
            gmx_fatal(FARGS, "Output buffer length in xvgstr (%d) too small to process xvg input string '%s'", buflen, gmx);
        }
        if (gmx[g] == '\\')
        {
            g++;
            if (gmx[g] == 's')
            {
                /* Subscript */
                if (bXVGR)
                {
                    buf[b++] = '\\';
                    buf[b++] = 's';
                }
                else
                {
                    buf[b++] = '_';
                }
                g++;
            }
            else if (gmx[g] == 'S')
            {
                /* Superscript */
                if (bXVGR)
                {
                    buf[b++] = '\\';
                    buf[b++] = 'S';
                }
                else
                {
                    buf[b++] = '^';
                }
                g++;
            }
            else if (gmx[g] == 'N')
            {
                /* End sub/superscript */
                if (bXVGR)
                {
                    buf[b++] = '\\';
                    buf[b++] = 'N';
                }
                else
                {
                    if (gmx[g+1] != ' ')
                    {
                        buf[b++] = ' ';
                    }
                }
                g++;
            }
            else if (gmx[g] == '4')
            {
                /* Backward compatibility for xmgr normal font "\4" */
                switch (xvgf)
                {
                    case exvgXMGRACE:
                        sprintf(buf+b, "%s", "\\f{}");
                        break;
                    case exvgXMGR:
                        sprintf(buf+b, "%s", "\\4");
                        break;
                    default:
                        buf[b] = '\0';
                        break;
                }
                g++;
                b = strlen(buf);
            }
            else if (gmx[g] == '8')
            {
                /* Backward compatibility for xmgr symbol font "\8" */
                switch (xvgf)
                {
                    case exvgXMGRACE:
                        sprintf(buf+b, "%s", "\\x");
                        break;
                    case exvgXMGR:
                        sprintf(buf+b, "%s", "\\8");
                        break;
                    default:
                        buf[b] = '\0';
                        break;
                }
                g++;
                b = strlen(buf);
            }
            else
            {
                /* Check for special symbol */
                i = 0;
                while (sym[i] != NULL &&
                       gmx_strncasecmp(sym[i], gmx+g, strlen(sym[i])) != 0)
                {
                    i++;
                }
                if (sym[i] != NULL)
                {
                    c = symc[i];
                    if (isupper(gmx[g]))
                    {
                        c = toupper(c);
                    }
                    switch (xvgf)
                    {
                        case exvgXMGRACE:
                            sprintf(buf+b, "%s%c%s", "\\x", c, "\\f{}");
                            break;
                        case exvgXMGR:
                            sprintf(buf+b, "%s%c%s", "\\8", c, "\\4");
                            break;
                        default:
                            strncat(buf+b, gmx+g, strlen(sym[i]));
                            b += strlen(sym[i]);
                            if (gmx[g+strlen(sym[i])] != ' ')
                            {
                                buf[b++] = ' ';
                            }
                            buf[b] = '\0';
                            break;
                    }
                    g += strlen(sym[i]);
                    b  = strlen(buf);
                }
                else
                {
                    /* Unknown escape sequence, this should not happen.
                     * We do not generate a fatal error, since that might
                     * stop otherwise functioning code from working.
                     * Copy the backslash to the output and continue processing.
                     */
                    buf[b++] = '\\';
                }
            }
        }
        else
        {
            buf[b++] = gmx[g++];
        }
    }

    buf[b++] = '\0';

    return buf;
}
Пример #23
0
gmx_bool get_libdir(char *libdir)
{
#define GMX_BINNAME_MAX 512
    char bin_name[GMX_BINNAME_MAX];
    char buf[GMX_BINNAME_MAX];
    char full_path[GMX_PATH_MAX+GMX_BINNAME_MAX];
    char system_path[GMX_PATH_MAX];
    char *dir,*ptr,*s,*pdum;
    gmx_bool found=FALSE;
    int i;

    if (Program() != NULL)
    {

    /* First - detect binary name */
    if (strlen(Program()) >= GMX_BINNAME_MAX)
    {
        gmx_fatal(FARGS,"The name of the binary is longer than the allowed buffer size (%d):\n'%s'",GMX_BINNAME_MAX,Program());
    }
    strncpy(bin_name,Program(),GMX_BINNAME_MAX-1);

    /* On windows & cygwin we need to add the .exe extension
     * too, or we wont be able to detect that the file exists
     */
#if (defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64 || defined __CYGWIN__ || defined __CYGWIN32__)
    if(strlen(bin_name)<3 || gmx_strncasecmp(bin_name+strlen(bin_name)-4,".exe",4))
        strcat(bin_name,".exe");
#endif

    /* Only do the smart search part if we got a real name */
    if (NULL!=bin_name && strncmp(bin_name,"GROMACS",GMX_BINNAME_MAX)) {

        if (!strchr(bin_name,DIR_SEPARATOR)) {
            /* No slash or backslash in name means it must be in the path - search it! */
            /* Add the local dir since it is not in the path on windows */
#if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
            pdum=_getcwd(system_path,sizeof(system_path)-1);
#else
            pdum=getcwd(system_path,sizeof(system_path)-1);
#endif
            sprintf(full_path,"%s%c%s",system_path,DIR_SEPARATOR,bin_name);
            found = gmx_fexist(full_path);
            if (!found && (s=getenv("PATH")) != NULL)
            {
                char *dupped;
                
                dupped=gmx_strdup(s);
                s=dupped;
                while(!found && (dir=gmx_strsep(&s, PATH_SEPARATOR)) != NULL)
                {
                    sprintf(full_path,"%s%c%s",dir,DIR_SEPARATOR,bin_name);
                    found = gmx_fexist(full_path);
                }
                sfree(dupped);
            }
            if (!found)
            {
                return FALSE;
            }
        } else if (!filename_is_absolute(bin_name)) {
            /* name contains directory separators, but 
             * it does not start at the root, i.e.
             * name is relative to the current dir 
             */
#if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
            pdum=_getcwd(buf,sizeof(buf)-1);
#else
            pdum=getcwd(buf,sizeof(buf)-1);
#endif
            sprintf(full_path,"%s%c%s",buf,DIR_SEPARATOR,bin_name);
        } else {
            strncpy(full_path,bin_name,GMX_PATH_MAX);
        }

        /* Now we should have a full path and name in full_path,
         * but on unix it might be a link, or a link to a link to a link..
         */
#if (!defined WIN32 && !defined _WIN32 && !defined WIN64 && !defined _WIN64)
        while( (i=readlink(full_path,buf,sizeof(buf)-1)) > 0 ) {
            buf[i]='\0';
            /* If it doesn't start with "/" it is relative */
            if (buf[0]!=DIR_SEPARATOR) {
                strncpy(strrchr(full_path,DIR_SEPARATOR)+1,buf,GMX_PATH_MAX);
            } else
                strncpy(full_path,buf,GMX_PATH_MAX);
        }
#endif

        /* Remove the executable name - it always contains at least one slash */
        *(strrchr(full_path,DIR_SEPARATOR)+1)='\0';
        /* Now we have the full path to the gromacs executable.
         * Use it to find the library dir. 
         */
        found=FALSE;
        while(!found && ( (ptr=strrchr(full_path,DIR_SEPARATOR)) != NULL ) ) {
            *ptr='\0';
            found=search_subdirs(full_path,libdir);
        }
    }
    }
    /* End of smart searching. If we didn't find it in our parent tree,
     * or if the program name wasn't set, at least try some standard 
     * locations before giving up, in case we are running from e.g. 
     * a users home directory. This only works on unix or cygwin...
     */
#if ((!defined WIN32 && !defined _WIN32 && !defined WIN64 && !defined _WIN64) || defined __CYGWIN__ || defined __CYGWIN32__)
    if(!found) 
        found=search_subdirs("/usr/local",libdir);
    if(!found) 
        found=search_subdirs("/usr",libdir);
    if(!found) 
        found=search_subdirs("/opt",libdir);
#endif
    return found;
}
Пример #24
0
/*!
 * Thread affinity set by the OpenMP library can conflict with the GROMACS
 * internal affinity setting.
 *
 * While GNU OpenMP does not set affinity by default, the Intel OpenMP library
 * does. This conflicts with the internal affinity (especially thread-MPI)
 * setting, results in incorrectly locked threads, and causes dreadful performance.
 *
 * The KMP_AFFINITY environment variable is used by Intel, GOMP_CPU_AFFINITY
 * by the GNU compilers (Intel also honors it well). If any of the variables
 * is set, we honor it, disable the internal pinning, and warn the user.
 * When using Intel OpenMP, we will disable affinity if the user did not set it
 * anually through one of the aforementioned environment variables.
 *
 * Note that the Intel OpenMP affinity disabling iwll only take effect if this
 * function is called before the OpenMP library gets initialized which happens
 * when the first call is made into a compilation unit that contains OpenMP
 * pragmas.
 */
void gmx_omp_check_thread_affinity(FILE *fplog, const t_commrec *cr,
                                   gmx_hw_opt_t *hw_opt)
{
    gmx_bool bKmpAffinitySet, bGompCpuAffinitySet;
    char *kmp_env, *gomp_env;

    /* no need to worry if internal thread pinning is turned off */
    if (!hw_opt->bThreadPinning)
    {
        return;
    }

#if defined(GMX_OPENMP)

    /* We assume that the affinity setting is available on all platforms
     * gcc supports. Even if this is not the case (e.g. Mac OS) the user
     * will only get a warning.*/
    bGompCpuAffinitySet = FALSE;
    gomp_env = NULL;
#if defined(__GNUC__)
    gomp_env = getenv("GOMP_CPU_AFFINITY");
    bGompCpuAffinitySet = (gomp_env != NULL);
#endif /* __GNUC__ */

    bKmpAffinitySet = FALSE;
#if defined(__INTEL_COMPILER)
    kmp_env = getenv("KMP_AFFINITY");
    bKmpAffinitySet = (kmp_env != NULL);

    /* disable Intel OpenMP affinity if neither KMP_AFFINITY nor
     * GOMP_CPU_AFFINITY is set (Intel uses the GNU env. var as well) */
    if (!bKmpAffinitySet && !bGompCpuAffinitySet)
    {
        int retval;

#ifdef _MSC_VER
        /* Windows not POSIX */
        retval = _putenv_s("KMP_AFFINITY", "disabled");
#else
        /* POSIX */
        retval = setenv("KMP_AFFINITY", "disabled", 0);
#endif /* _MSC_VER */

        if (debug)
        {
            fprintf(debug, "Disabling Intel OpenMP affinity by setting the KMP_AFFINITY=disabled env. var.\n");
        }

        if (retval != 0)
        {
            gmx_warning("Disabling Intel OpenMp affinity setting failed!");
        }
    }

    /* turn off internal pinning KMP_AFFINITY != "disabled" */
    if (bKmpAffinitySet && (gmx_strncasecmp(kmp_env, "disabled", 8) != 0))
    {
        md_print_warn(cr, fplog, "WARNING: KMP_AFFINITY set, will turn off %s internal affinity\n"
                      "         setting as the two can conflict and cause performance degradation.\n"
                      "         To keep using the %s internal affinity setting, set the\n"
                      "         KMP_AFFINITY=disabled environment variable.",
                      ShortProgram(), ShortProgram());

        hw_opt->bThreadPinning = FALSE;
    }
#endif /* __INTEL_COMPILER */

#if defined(__INTEL_COMPILER) || defined(__GNUC__)
    /* turn off internal pinning f GOMP_CPU_AFFINITY is set & non-empty */
    if (bGompCpuAffinitySet && gomp_env != NULL && gomp_env != '\0')
    {
        md_print_warn(cr, fplog,
                      "WARNING: GOMP_CPU_AFFINITY set, will turn off %s internal affinity\n"
                      "         setting as the two can conflict and cause performance degradation.\n"
                      "         To keep using the %s internal affinity setting, unset the\n"
                      "         GOMP_CPU_AFFINITY environment variable.",
                      ShortProgram(), ShortProgram());

        hw_opt->bThreadPinning = FALSE;
    }
#endif /* __INTEL_COMPILER || __GNUC__ */

#endif /* GMX_OPENMP */
}