Esempio n. 1
0
void calc_variograms(
    variogram_search_template_t * templ,
    hard_data_t * data,
    float * result_covariations,
    int result_length,
    int percentToUse)
{
    int lag_count = templ->m_num_lags <= result_length
                    ? templ->m_num_lags
                    : result_length;

    lag_statistics_t * lag_stats = (lag_statistics_t *) calloc(lag_count, sizeof(lag_statistics_t));
    for (int i = 0; i < lag_count; ++i)
    {
        lag_stats[i].m_cov_count = 0;
        lag_stats[i].m_cov_sum = 0.0;
    }

    //lag_t * lags = (lag_t*) calloc(lag_count, sizeof(lag_t));
    //init_lag_list(templ, lags, lag_count);

    search_template_window_t window;
    calc_search_template_window(templ, &window);

    for (int i2 = window.m_min_i; i2 <= window.m_max_i; ++i2)
        for (int j2 = window.m_min_j; j2 <= window.m_max_j; ++j2)
            for (int k2 = window.m_min_k; k2 <= window.m_max_k; ++k2)
            {
                vector_t vec;
                vec.m_data[0] = i2;
                vec.m_data[1] = j2;
                vec.m_data[2] = k2;

                int doffset = get_offset(&vec, data->m_data_strides);
                int moffset = get_offset(&vec, data->m_mask_strides);

                if (is_in_tunnel(templ, &vec))
                {
                    int x1, y1, z1;
                    float * dpx, * dpy, * dpz;
                    unsigned char * mpx, * mpy, *mpz;
                    for (z1 = 0, dpz = data->m_data, mpz = data->m_mask;
                            z1 < data->m_data_shape[2];
                            ++z1, dpz += data->m_data_strides[2], mpz += data->m_mask_strides[2])
                        for (y1 = 0, dpy = dpz, mpy = mpz;
                                y1 < data->m_data_shape[1];
                                ++y1, dpy += data->m_data_strides[1], mpy += data->m_mask_strides[1])
                            for (x1 = 0, dpx = dpy, mpx = mpy;
                                    x1 < data->m_data_shape[0];
                                    ++x1, dpx += data->m_data_strides[0], mpx += data->m_mask_strides[0])
                            {
                                if (*mpx != 0)
                                    //if (is_informed_nocheck(data, x1, y1, z1))
                                    //if (is_informed(data, x1, y1, z1))
                                {
                                    double v1 = *dpx;
                                    //double v1 = get_value(data, x1, y1, z1);
                                    int x = x1 + vec.m_data[0];
                                    int y = y1 + vec.m_data[1];
                                    int z = z1 + vec.m_data[2];
                                    if (is_inside(data, x,y,z) && mpx[moffset])
                                        //if (is_informed(data, x,y,z))
                                    {
                                        if ((rand() % 100) >= percentToUse)
                                            continue;
                                        double dist = calc_dist(&vec);
                                        double v2 = dpx[doffset];
                                        //double v2 = get_value(data, x, y, z);
                                        double var = v1 - v2;
                                        var = var*var;
                                        update_lags(templ, lag_stats, lag_count, dist, var);
                                    }
                                }
                            }
                }
            }

    for (int i = 0; i < lag_count; ++i)
    {
        result_covariations[i] = lag_stats[i].m_cov_sum / lag_stats[i].m_cov_count / 2;
    }

    free(lag_stats);
    //free(lags);
}
Esempio n. 2
0
int gmx_rmsdist(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] computes the root mean square deviation of atom distances,",
        "which has the advantage that no fit is needed like in standard RMS",
        "deviation as computed by [gmx-rms].",
        "The reference structure is taken from the structure file.",
        "The RMSD at time t is calculated as the RMS",
        "of the differences in distance between atom-pairs in the reference",
        "structure and the structure at time t.[PAR]",
        "[THISMODULE] can also produce matrices of the rms distances, rms distances",
        "scaled with the mean distance and the mean distances and matrices with",
        "NMR averaged distances (1/r^3 and 1/r^6 averaging). Finally, lists",
        "of atom pairs with 1/r^3 and 1/r^6 averaged distance below the",
        "maximum distance ([TT]-max[tt], which will default to 0.6 in this case)",
        "can be generated, by default averaging over equivalent hydrogens",
        "(all triplets of hydrogens named \\*[123]). Additionally a list of",
        "equivalent atoms can be supplied ([TT]-equiv[tt]), each line containing",
        "a set of equivalent atoms specified as residue number and name and",
        "atom name; e.g.:[PAR]",
        "[TT]HB* 3 SER  HB1 3 SER  HB2[tt][PAR]",
        "Residue and atom names must exactly match those in the structure",
        "file, including case. Specifying non-sequential atoms is undefined."

    };

    int             i, teller;
    real            t;

    t_topology      top;
    int             ePBC;
    t_atoms        *atoms;
    matrix          box;
    rvec           *x;
    FILE           *fp;

    t_trxstatus    *status;
    int             isize, gnr = 0;
    atom_id        *index, *noe_index;
    char           *grpname;
    real          **d_r, **d, **dtot, **dtot2, **mean, **rms, **rmsc, *resnr;
    real          **dtot1_3 = NULL, **dtot1_6 = NULL;
    real            rmsnow, meanmax, rmsmax, rmscmax;
    real            max1_3, max1_6;
    t_noe_gr       *noe_gr = NULL;
    t_noe         **noe    = NULL;
    t_rgb           rlo, rhi;
    gmx_bool        bRMS, bScale, bMean, bNOE, bNMR3, bNMR6, bNMR;

    static int      nlevels  = 40;
    static real     scalemax = -1.0;
    static gmx_bool bSumH    = TRUE;
    static gmx_bool bPBC     = TRUE;
    output_env_t    oenv;

    t_pargs         pa[] = {
        { "-nlevels",   FALSE, etINT,  {&nlevels},
          "Discretize RMS in this number of levels" },
        { "-max",   FALSE, etREAL, {&scalemax},
          "Maximum level in matrices" },
        { "-sumh",  FALSE, etBOOL, {&bSumH},
          "Average distance over equivalent hydrogens" },
        { "-pbc",   FALSE, etBOOL, {&bPBC},
          "Use periodic boundary conditions when computing distances" }
    };
    t_filenm        fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efDAT, "-equiv", "equiv",   ffOPTRD },
        { efXVG, NULL,   "distrmsd", ffWRITE },
        { efXPM, "-rms", "rmsdist",  ffOPTWR },
        { efXPM, "-scl", "rmsscale", ffOPTWR },
        { efXPM, "-mean", "rmsmean",  ffOPTWR },
        { efXPM, "-nmr3", "nmr3",     ffOPTWR },
        { efXPM, "-nmr6", "nmr6",     ffOPTWR },
        { efDAT, "-noe", "noe",     ffOPTWR },
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    bRMS   = opt2bSet("-rms", NFILE, fnm);
    bScale = opt2bSet("-scl", NFILE, fnm);
    bMean  = opt2bSet("-mean", NFILE, fnm);
    bNOE   = opt2bSet("-noe", NFILE, fnm);
    bNMR3  = opt2bSet("-nmr3", NFILE, fnm);
    bNMR6  = opt2bSet("-nmr6", NFILE, fnm);
    bNMR   = bNMR3 || bNMR6 || bNOE;

    max1_3 = 0;
    max1_6 = 0;

    /* check input */
    if (bNOE && scalemax < 0)
    {
        scalemax = 0.6;
        fprintf(stderr, "WARNING: using -noe without -max "
                "makes no sense, setting -max to %g\n\n", scalemax);
    }

    /* get topology and index */
    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &x, NULL, box, FALSE);

    if (!bPBC)
    {
        ePBC = epbcNONE;
    }
    atoms = &(top.atoms);

    get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);

    /* initialize arrays */
    snew(d, isize);
    snew(dtot, isize);
    snew(dtot2, isize);
    if (bNMR)
    {
        snew(dtot1_3, isize);
        snew(dtot1_6, isize);
    }
    snew(mean, isize);
    snew(rms, isize);
    snew(rmsc, isize);
    snew(d_r, isize);
    snew(resnr, isize);
    for (i = 0; (i < isize); i++)
    {
        snew(d[i], isize);
        snew(dtot[i], isize);
        snew(dtot2[i], isize);
        if (bNMR)
        {
            snew(dtot1_3[i], isize);
            snew(dtot1_6[i], isize);
        }
        snew(mean[i], isize);
        snew(rms[i], isize);
        snew(rmsc[i], isize);
        snew(d_r[i], isize);
        resnr[i] = i+1;
    }

    /*set box type*/
    calc_dist(isize, index, x, ePBC, box, d_r);
    sfree(x);

    /*open output files*/
    fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS Deviation", "Time (ps)", "RMSD (nm)",
                  oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"of distances between %s atoms\"\n", grpname);
    }

    /*do a first step*/
    read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    teller = 0;

    do
    {
        calc_dist_tot(isize, index, x, ePBC, box, d, dtot, dtot2, bNMR, dtot1_3, dtot1_6);

        rmsnow = rms_diff(isize, d, d_r);
        fprintf(fp, "%g  %g\n", t, rmsnow);
        teller++;
    }
    while (read_next_x(oenv, status, &t, x, box));
    fprintf(stderr, "\n");

    xvgrclose(fp);

    close_trj(status);

    calc_rms(isize, teller, dtot, dtot2, rms, &rmsmax, rmsc, &rmscmax, mean, &meanmax);
    fprintf(stderr, "rmsmax = %g, rmscmax = %g\n", rmsmax, rmscmax);

    if (bNMR)
    {
        calc_nmr(isize, teller, dtot1_3, dtot1_6, &max1_3, &max1_6);
    }

    if (scalemax > -1.0)
    {
        rmsmax  = scalemax;
        rmscmax = scalemax;
        meanmax = scalemax;
        max1_3  = scalemax;
        max1_6  = scalemax;
    }

    if (bNOE)
    {
        /* make list of noe atom groups */
        snew(noe_index, isize+1);
        snew(noe_gr, isize);
        gnr = analyze_noe_equivalent(opt2fn_null("-equiv", NFILE, fnm),
                                     atoms, isize, index, bSumH, noe_index, noe_gr);
        fprintf(stdout, "Found %d non-equivalent atom-groups in %d atoms\n",
                gnr, isize);
        /* make half matrix of of noe-group distances from atom distances */
        snew(noe, gnr);
        for (i = 0; i < gnr; i++)
        {
            snew(noe[i], gnr);
        }
        calc_noe(isize, noe_index, dtot1_3, dtot1_6, gnr, noe);
    }

    rlo.r = 1.0, rlo.g = 1.0, rlo.b = 1.0;
    rhi.r = 0.0, rhi.g = 0.0, rhi.b = 0.0;

    if (bRMS)
    {
        write_xpm(opt2FILE("-rms", NFILE, fnm, "w"), 0,
                  "RMS of distance", "RMS (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, rms, 0.0, rmsmax, rlo, rhi, &nlevels);
    }

    if (bScale)
    {
        write_xpm(opt2FILE("-scl", NFILE, fnm, "w"), 0,
                  "Relative RMS", "RMS", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, rmsc, 0.0, rmscmax, rlo, rhi, &nlevels);
    }

    if (bMean)
    {
        write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0,
                  "Mean Distance", "Distance (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, mean, 0.0, meanmax, rlo, rhi, &nlevels);
    }

    if (bNMR3)
    {
        write_xpm(opt2FILE("-nmr3", NFILE, fnm, "w"), 0, "1/r^3 averaged distances",
                  "Distance (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, dtot1_3, 0.0, max1_3, rlo, rhi, &nlevels);
    }
    if (bNMR6)
    {
        write_xpm(opt2FILE("-nmr6", NFILE, fnm, "w"), 0, "1/r^6 averaged distances",
                  "Distance (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, dtot1_6, 0.0, max1_6, rlo, rhi, &nlevels);
    }

    if (bNOE)
    {
        write_noe(opt2FILE("-noe", NFILE, fnm, "w"), gnr, noe, noe_gr, scalemax);
    }

    do_view(oenv, ftp2fn(efXVG, NFILE, fnm), NULL);

    return 0;
}
Esempio n. 3
0
void dist_plot(const char *fn, const char *afile, const char *dfile,
               const char *nfile, const char *rfile, const char *xfile,
               real rcut, gmx_bool bMat, t_atoms *atoms,
               int ng, atom_id *index[], int gnx[], char *grpn[], gmx_bool bSplit,
               gmx_bool bMin, int nres, atom_id *residue, gmx_bool bPBC, int ePBC,
               gmx_bool bGroup, gmx_bool bEachResEachTime, gmx_bool bPrintResName,
               const output_env_t oenv)
{
    FILE            *atm, *dist, *num;
    t_trxstatus     *trxout;
    char             buf[256];
    char           **leg;
    real             t, dmin, dmax, **mindres = NULL, **maxdres = NULL;
    int              nmin, nmax;
    t_trxstatus     *status;
    int              i = -1, j, k, natoms;
    int              min1, min2, max1, max2, min1r, min2r, max1r, max2r;
    atom_id          oindex[2];
    rvec            *x0;
    matrix           box;
    t_trxframe       frout;
    gmx_bool         bFirst;
    FILE            *respertime = NULL;

    if ((natoms = read_first_x(oenv, &status, fn, &t, &x0, box)) == 0)
    {
        gmx_fatal(FARGS, "Could not read coordinates from statusfile\n");
    }

    sprintf(buf, "%simum Distance", bMin ? "Min" : "Max");
    dist = xvgropen(dfile, buf, output_env_get_time_label(oenv), "Distance (nm)", oenv);
    sprintf(buf, "Number of Contacts %s %g nm", bMin ? "<" : ">", rcut);
    num    = nfile ? xvgropen(nfile, buf, output_env_get_time_label(oenv), "Number", oenv) : NULL;
    atm    = afile ? ffopen(afile, "w") : NULL;
    trxout = xfile ? open_trx(xfile, "w") : NULL;

    if (bMat)
    {
        if (ng == 1)
        {
            snew(leg, 1);
            sprintf(buf, "Internal in %s", grpn[0]);
            leg[0] = strdup(buf);
            xvgr_legend(dist, 0, (const char**)leg, oenv);
            if (num)
            {
                xvgr_legend(num, 0, (const char**)leg, oenv);
            }
        }
        else
        {
            snew(leg, (ng*(ng-1))/2);
            for (i = j = 0; (i < ng-1); i++)
            {
                for (k = i+1; (k < ng); k++, j++)
                {
                    sprintf(buf, "%s-%s", grpn[i], grpn[k]);
                    leg[j] = strdup(buf);
                }
            }
            xvgr_legend(dist, j, (const char**)leg, oenv);
            if (num)
            {
                xvgr_legend(num, j, (const char**)leg, oenv);
            }
        }
    }
    else
    {
        snew(leg, ng-1);
        for (i = 0; (i < ng-1); i++)
        {
            sprintf(buf, "%s-%s", grpn[0], grpn[i+1]);
            leg[i] = strdup(buf);
        }
        xvgr_legend(dist, ng-1, (const char**)leg, oenv);
        if (num)
        {
            xvgr_legend(num, ng-1, (const char**)leg, oenv);
        }
    }

    if (bEachResEachTime)
    {
        sprintf(buf, "%simum Distance", bMin ? "Min" : "Max");
        respertime = xvgropen(rfile, buf, output_env_get_time_label(oenv), "Distance (nm)", oenv);
        xvgr_legend(respertime, ng-1, (const char**)leg, oenv);
        if (bPrintResName)
        {
            fprintf(respertime, "# ");
        }
        for (j = 0; j < nres; j++)
        {
            fprintf(respertime, "%s%d ", *(atoms->resinfo[atoms->atom[index[0][residue[j]]].resind].name), atoms->atom[index[0][residue[j]]].resind);
        }
        fprintf(respertime, "\n");

    }

    j = 0;
    if (nres)
    {
        snew(mindres, ng-1);
        snew(maxdres, ng-1);
        for (i = 1; i < ng; i++)
        {
            snew(mindres[i-1], nres);
            snew(maxdres[i-1], nres);
            for (j = 0; j < nres; j++)
            {
                mindres[i-1][j] = 1e6;
            }
            /* maxdres[*][*] is already 0 */
        }
    }
    bFirst = TRUE;
    do
    {
        if (bSplit && !bFirst && abs(t/output_env_get_time_factor(oenv)) < 1e-5)
        {
            fprintf(dist, "&\n");
            if (num)
            {
                fprintf(num, "&\n");
            }
            if (atm)
            {
                fprintf(atm, "&\n");
            }
        }
        fprintf(dist, "%12e", output_env_conv_time(oenv, t));
        if (num)
        {
            fprintf(num, "%12e", output_env_conv_time(oenv, t));
        }

        if (bMat)
        {
            if (ng == 1)
            {
                calc_dist(rcut, bPBC, ePBC, box, x0, gnx[0], gnx[0], index[0], index[0], bGroup,
                          &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2);
                fprintf(dist, "  %12e", bMin ? dmin : dmax);
                if (num)
                {
                    fprintf(num, "  %8d", bMin ? nmin : nmax);
                }
            }
            else
            {
                for (i = 0; (i < ng-1); i++)
                {
                    for (k = i+1; (k < ng); k++)
                    {
                        calc_dist(rcut, bPBC, ePBC, box, x0, gnx[i], gnx[k], index[i], index[k],
                                  bGroup, &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2);
                        fprintf(dist, "  %12e", bMin ? dmin : dmax);
                        if (num)
                        {
                            fprintf(num, "  %8d", bMin ? nmin : nmax);
                        }
                    }
                }
            }
        }
        else
        {
            for (i = 1; (i < ng); i++)
            {
                calc_dist(rcut, bPBC, ePBC, box, x0, gnx[0], gnx[i], index[0], index[i], bGroup,
                          &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2);
                fprintf(dist, "  %12e", bMin ? dmin : dmax);
                if (num)
                {
                    fprintf(num, "  %8d", bMin ? nmin : nmax);
                }
                if (nres)
                {
                    for (j = 0; j < nres; j++)
                    {
                        calc_dist(rcut, bPBC, ePBC, box, x0, residue[j+1]-residue[j], gnx[i],
                                  &(index[0][residue[j]]), index[i], bGroup,
                                  &dmin, &dmax, &nmin, &nmax, &min1r, &min2r, &max1r, &max2r);
                        mindres[i-1][j] = min(mindres[i-1][j], dmin);
                        maxdres[i-1][j] = max(maxdres[i-1][j], dmax);
                    }
                }
            }
        }
        fprintf(dist, "\n");
        if (num)
        {
            fprintf(num, "\n");
        }
        if ( (bMin ? min1 : max1) != -1)
        {
            if (atm)
            {
                fprintf(atm, "%12e  %12d  %12d\n",
                        output_env_conv_time(oenv, t), 1+(bMin ? min1 : max1),
                        1+(bMin ? min2 : max2));
            }
        }

        if (trxout)
        {
            oindex[0] = bMin ? min1 : max1;
            oindex[1] = bMin ? min2 : max2;
            write_trx(trxout, 2, oindex, atoms, i, t, box, x0, NULL, NULL);
        }
        bFirst = FALSE;
        /*dmin should be minimum distance for residue and group*/
        if (bEachResEachTime)
        {
            fprintf(respertime, "%12e", t);
            for (i = 1; i < ng; i++)
            {
                for (j = 0; j < nres; j++)
                {
                    fprintf(respertime, " %7g", bMin ? mindres[i-1][j] : maxdres[i-1][j]);
                    /*reset distances for next time point*/
                    mindres[i-1][j] = 1e6;
                    maxdres[i-1][j] = 0;
                }
            }
            fprintf(respertime, "\n");
        }
    }
    while (read_next_x(oenv, status, &t, x0, box));

    close_trj(status);
    ffclose(dist);
    if (num)
    {
        ffclose(num);
    }
    if (atm)
    {
        ffclose(atm);
    }
    if (trxout)
    {
        close_trx(trxout);
    }

    if (nres && !bEachResEachTime)
    {
        FILE *res;

        sprintf(buf, "%simum Distance", bMin ? "Min" : "Max");
        res = xvgropen(rfile, buf, "Residue (#)", "Distance (nm)", oenv);
        xvgr_legend(res, ng-1, (const char**)leg, oenv);
        for (j = 0; j < nres; j++)
        {
            fprintf(res, "%4d", j+1);
            for (i = 1; i < ng; i++)
            {
                fprintf(res, " %7g", bMin ? mindres[i-1][j] : maxdres[i-1][j]);
            }
            fprintf(res, "\n");
        }
    }

    sfree(x0);
}
Esempio n. 4
0
void 
pml_hybrid(
    const float *data, int dy, int dt, int dx,
	const float *center, const float *theta,
    float *recon, int ngridx, int ngridy, int num_iter,
	const float *reg_pars)
{
    float *gridx = (float *)malloc((ngridx+1)*sizeof(float));
    float *gridy = (float *)malloc((ngridy+1)*sizeof(float));
    float *coordx = (float *)malloc((ngridy+1)*sizeof(float));
    float *coordy = (float *)malloc((ngridx+1)*sizeof(float));
    float *ax = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *ay = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *bx = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *by = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *coorx = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *coory = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *dist = (float *)malloc((ngridx+ngridy)*sizeof(float));
    int *indi = (int *)malloc((ngridx+ngridy)*sizeof(int));

    assert(coordx != NULL && coordy != NULL &&
        ax != NULL && ay != NULL && by != NULL && bx != NULL &&
        coorx != NULL && coory != NULL && dist != NULL && indi != NULL);

    int s, p, d, i, m, n, q;
    int quadrant;
    float theta_p, sin_p, cos_p;
    float mov, xi, yi;
    int asize, bsize, csize;
    float *simdata;
    float upd;
    int ind_data, ind_recon;
    float *sum_dist;
    float sum_dist2;
    float *E, *F, *G;
    int ind0, ind1, indg[8];
    float totalwg, wg[8], mg[8], rg[8], gammag[8];

    for (i=0; i<num_iter; i++) 
    {
        simdata = (float *)calloc((dt*dy*dx), sizeof(float));

        // For each slice
        for (s=0; s<dy; s++)
        {
            preprocessing(ngridx, ngridy, dx, center[s],
                &mov, gridx, gridy); // Outputs: mov, gridx, gridy
            
            sum_dist = (float *)calloc((ngridx*ngridy), sizeof(float));
            E = (float *)calloc((ngridx*ngridy), sizeof(float));
            F = (float *)calloc((ngridx*ngridy), sizeof(float));
            G = (float *)calloc((ngridx*ngridy), sizeof(float));
            
            // For each projection angle 
            for (p=0; p<dt; p++)
            {
                // Calculate the sin and cos values 
                // of the projection angle and find
                // at which quadrant on the cartesian grid.
                theta_p = fmod(theta[p], 2*M_PI);
                quadrant = calc_quadrant(theta_p);
                sin_p = sinf(theta_p);
                cos_p = cosf(theta_p);

                // For each detector pixel 
                for (d=0; d<dx; d++)
                {
                    // Calculate coordinates
                    xi = -ngridx-ngridy;
                    yi = (1-dx)/2.0+d+mov;
                    calc_coords(
                        ngridx, ngridy, xi, yi, sin_p, cos_p, gridx, gridy, 
                        coordx, coordy);

                    // Merge the (coordx, gridy) and (gridx, coordy)
                    trim_coords(
                        ngridx, ngridy, coordx, coordy, gridx, gridy, 
                        &asize, ax, ay, &bsize, bx, by);

                    // Sort the array of intersection points (ax, ay) and
                    // (bx, by). The new sorted intersection points are 
                    // stored in (coorx, coory). Total number of points 
                    // are csize.
                    sort_intersections(
                        quadrant, asize, ax, ay, bsize, bx, by, 
                        &csize, coorx, coory);

                    // Calculate the distances (dist) between the 
                    // intersection points (coorx, coory). Find the 
                    // indices of the pixels on the reconstruction grid.
                    calc_dist(
                        ngridx, ngridy, csize, coorx, coory, 
                        indi, dist);

                    // Calculate simdata 
                    calc_simdata(s, p, d, ngridx, ngridy, dt, dx,
                        csize, indi, dist, recon,
                        simdata); // Output: simdata


                    // Calculate dist*dist
                    sum_dist2 = 0.0;
                    for (n=0; n<csize-1; n++) 
                    {
                        sum_dist2 += dist[n]*dist[n];
                        sum_dist[indi[n]] += dist[n];
                    }

                    // Update
                    if (sum_dist2 != 0.0) 
                    {
                        ind_data = d+p*dx+s*dt*dx;
                        ind_recon = s*ngridx*ngridy;
                        upd = data[ind_data]/simdata[ind_data];
                        for (n=0; n<csize-1; n++) 
                        {
                            E[indi[n]] -= recon[indi[n]+ind_recon]*upd*dist[n];
                        }
                    }
                }
            }

            // Weights for inner neighborhoods.
            totalwg = 4+4/sqrt(2);
            wg[0] = 1/totalwg;
            wg[1] = 1/totalwg;
            wg[2] = 1/totalwg;
            wg[3] = 1/totalwg;
            wg[4] = 1/sqrt(2)/totalwg;
            wg[5] = 1/sqrt(2)/totalwg;
            wg[6] = 1/sqrt(2)/totalwg;
            wg[7] = 1/sqrt(2)/totalwg;

            // (inner region)
            for (n = 1; n < ngridx-1; n++) {
                for (m = 1; m < ngridy-1; m++) {
                    ind0 = m + n*ngridy;
                    ind1 = ind0 + s*ngridx*ngridy;
                    
                    indg[0] = ind1+1;
                    indg[1] = ind1-1;
                    indg[2] = ind1+ngridy;
                    indg[3] = ind1-ngridy;
                    indg[4] = ind1+ngridy+1; 
                    indg[5] = ind1+ngridy-1;
                    indg[6] = ind1-ngridy+1;
                    indg[7] = ind1-ngridy-1;
                    

                    for (q = 0; q < 8; q++) {
                        mg[q] = recon[ind1]+recon[indg[q]];
                        rg[q] = recon[ind1]-recon[indg[q]];
                        gammag[q] = 1/(1+fabs(rg[q]/reg_pars[1]));
                        F[ind0] += 2*reg_pars[0]*wg[q]*gammag[q];
                        G[ind0] -= 2*reg_pars[0]*wg[q]*gammag[q]*mg[q];
                    }
                }
            }

            // Weights for edges.
            totalwg = 3+2/sqrt(2);
            wg[0] = 1/totalwg;
            wg[1] = 1/totalwg;
            wg[2] = 1/totalwg;
            wg[3] = 1/sqrt(2)/totalwg;
            wg[4] = 1/sqrt(2)/totalwg;
            
            // (top)
            for (m = 1; m < ngridy-1; m++) {
                ind0 = m;
                ind1 = ind0 + s*ngridx*ngridy;
                
                indg[0] = ind1+1;
                indg[1] = ind1-1;
                indg[2] = ind1+ngridy;
                indg[3] = ind1+ngridy+1; 
                indg[4] = ind1+ngridy-1;
                    
                for (q = 0; q < 5; q++) {
                    mg[q] = recon[ind1]+recon[indg[q]];
                    rg[q] = recon[ind1]-recon[indg[q]];
                    gammag[q] = 1/(1+fabs(rg[q]/reg_pars[1]));
                    F[ind0] += 2*reg_pars[0]*wg[q]*gammag[q];
                    G[ind0] -= 2*reg_pars[0]*wg[q]*gammag[q]*mg[q];
                }
            }

            // (bottom)
            for (m = 1; m < ngridy-1; m++) {
                ind0 = m + (ngridx-1)*ngridy;
                ind1 = ind0 + s*ngridx*ngridy;
                
                indg[0] = ind1+1;
                indg[1] = ind1-1;
                indg[2] = ind1-ngridy;
                indg[3] = ind1-ngridy+1;
                indg[4] = ind1-ngridy-1;
                    
                for (q = 0; q < 5; q++) {
                    mg[q] = recon[ind1]+recon[indg[q]];
                    rg[q] = recon[ind1]-recon[indg[q]];
                    gammag[q] = 1/(1+fabs(rg[q]/reg_pars[1]));
                    F[ind0] += 2*reg_pars[0]*wg[q]*gammag[q];
                    G[ind0] -= 2*reg_pars[0]*wg[q]*gammag[q]*mg[q];
                }
            }

            // (left)  
            for (n = 1; n < ngridx-1; n++) {
                ind0 = n*ngridy;
                ind1 = ind0 + s*ngridx*ngridy;
                
                indg[0] = ind1+1;
                indg[1] = ind1+ngridy;
                indg[2] = ind1-ngridy;
                indg[3] = ind1+ngridy+1; 
                indg[4] = ind1-ngridy+1;
                    
                for (q = 0; q < 5; q++) {
                    mg[q] = recon[ind1]+recon[indg[q]];
                    rg[q] = recon[ind1]-recon[indg[q]];
                    gammag[q] = 1/(1+fabs(rg[q]/reg_pars[1]));
                    F[ind0] += 2*reg_pars[0]*wg[q]*gammag[q];
                    G[ind0] -= 2*reg_pars[0]*wg[q]*gammag[q]*mg[q];
                }
            }

            // (right)                
            for (n = 1; n < ngridx-1; n++) {
                ind0 = (ngridy-1) + n*ngridy;
                ind1 = ind0 + s*ngridx*ngridy;
                
                indg[0] = ind1-1;
                indg[1] = ind1+ngridy;
                indg[2] = ind1-ngridy;
                indg[3] = ind1+ngridy-1;
                indg[4] = ind1-ngridy-1;
                    
                for (q = 0; q < 5; q++) {
                    mg[q] = recon[ind1]+recon[indg[q]];
                    rg[q] = recon[ind1]-recon[indg[q]];
                    gammag[q] = 1/(1+fabs(rg[q]/reg_pars[1]));
                    F[ind0] += 2*reg_pars[0]*wg[q]*gammag[q];
                    G[ind0] -= 2*reg_pars[0]*wg[q]*gammag[q]*mg[q];
                }
            }
            
            // Weights for corners.
            totalwg = 2+1/sqrt(2);
            wg[0] = 1/totalwg;
            wg[1] = 1/totalwg;
            wg[2] = 1/sqrt(2)/totalwg;
            
            // (top-left)
            ind0 = 0;
            ind1 = ind0 + s*ngridx*ngridy;
            
            indg[0] = ind1+1;
            indg[1] = ind1+ngridy;
            indg[2] = ind1+ngridy+1; 
                    
            for (q = 0; q < 3; q++) {
                mg[q] = recon[ind1]+recon[indg[q]];
                rg[q] = recon[ind1]-recon[indg[q]];
                gammag[q] = 1/(1+fabs(rg[q]/reg_pars[1]));
                F[ind0] += 2*reg_pars[0]*wg[q]*gammag[q];
                G[ind0] -= 2*reg_pars[0]*wg[q]*gammag[q]*mg[q];
            }

            // (top-right)
            ind0 = (ngridy-1);
            ind1 = ind0 + s*ngridx*ngridy;
            
            indg[0] = ind1-1;
            indg[1] = ind1+ngridy;
            indg[2] = ind1+ngridy-1;
                    
            for (q = 0; q < 3; q++) {
                mg[q] = recon[ind1]+recon[indg[q]];
                rg[q] = recon[ind1]-recon[indg[q]];
                gammag[q] = 1/(1+fabs(rg[q]/reg_pars[1]));
                F[ind0] += 2*reg_pars[0]*wg[q]*gammag[q];
                G[ind0] -= 2*reg_pars[0]*wg[q]*gammag[q]*mg[q];
            }

            // (bottom-left)  
            ind0 = (ngridx-1)*ngridy;
            ind1 = ind0 + s*ngridx*ngridy;
            
            indg[0] = ind1+1;
            indg[1] = ind1-ngridy;
            indg[2] = ind1-ngridy+1;
                    
            for (q = 0; q < 3; q++) {
                mg[q] = recon[ind1]+recon[indg[q]];
                rg[q] = recon[ind1]-recon[indg[q]];
                gammag[q] = 1/(1+fabs(rg[q]/reg_pars[1]));
                F[ind0] += 2*reg_pars[0]*wg[q]*gammag[q];
                G[ind0] -= 2*reg_pars[0]*wg[q]*gammag[q]*mg[q];
            }

            // (bottom-right)           
            ind0 = (ngridy-1) + (ngridx-1)*ngridy;
            ind1 = ind0 + s*ngridx*ngridy;
            
            indg[0] = ind1-1;
            indg[1] = ind1-ngridy;
            indg[2] = ind1-ngridy-1;
                    
            for (q = 0; q < 3; q++) {
                mg[q] = recon[ind1]+recon[indg[q]];
                rg[q] = recon[ind1]-recon[indg[q]];
                gammag[q] = 1/(1+fabs(rg[q]/reg_pars[1]));
                F[ind0] += 2*reg_pars[0]*wg[q]*gammag[q];
                G[ind0] -= 2*reg_pars[0]*wg[q]*gammag[q]*mg[q];
            }

            q = 0;
            for (n = 0; n < ngridx*ngridy; n++) {
                G[q] += sum_dist[n];
                q++;
            }

            for (n = 0; n < ngridx; n++) {
                for (m = 0; m < ngridy; m++) {
                    q = m + n*ngridy;
                    if (F[q] != 0.0) {
                        ind0 = q + s*ngridx*ngridy;
                        recon[ind0] = (-G[q]+sqrt(G[q]*G[q]-8*E[q]*F[q]))/(4*F[q]);
                    }
                }
            }

            free(sum_dist);
            free(E);
            free(F);
            free(G);
        }

        free(simdata);
    }

    free(gridx);
    free(gridy);
    free(coordx);
    free(coordy);
    free(ax);
    free(ay);
    free(bx);
    free(by);
    free(coorx);
    free(coory);
    free(dist);
    free(indi);
}
Esempio n. 5
0
void
art(const float* data, int dy, int dt, int dx, const float* center,
    const float* theta, float* recon, int ngridx, int ngridy, int num_iter)
{
    float* gridx   = (float*) malloc((ngridx + 1) * sizeof(float));
    float* gridy   = (float*) malloc((ngridy + 1) * sizeof(float));
    float* coordx  = (float*) malloc((ngridy + 1) * sizeof(float));
    float* coordy  = (float*) malloc((ngridx + 1) * sizeof(float));
    float* ax      = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* ay      = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* bx      = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* by      = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* coorx   = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* coory   = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* dist    = (float*) malloc((ngridx + ngridy) * sizeof(float));
    int*   indi    = (int*) malloc((ngridx + ngridy) * sizeof(int));
    float* simdata = (float*) malloc((dy * dt * dx) * sizeof(float));

    assert(coordx != NULL && coordy != NULL && ax != NULL && ay != NULL &&
           by != NULL && bx != NULL && coorx != NULL && coory != NULL &&
           dist != NULL && indi != NULL && simdata != NULL);

    int   s, p, d, i, n;
    int   quadrant;
    float theta_p, sin_p, cos_p;
    float mov, xi, yi;
    int   asize, bsize, csize;
    float upd;
    int   ind_data, ind_recon;

    for(i = 0; i < num_iter; i++)
    {
        // initialize simdata to zero
        memset(simdata, 0, dy * dt * dx * sizeof(float));

        preprocessing(ngridx, ngridy, dx, center[0], &mov, gridx,
                      gridy);  // Outputs: mov, gridx, gridy

        // For each projection angle
        for(p = 0; p < dt; p++)
        {
            // Calculate the sin and cos values
            // of the projection angle and find
            // at which quadrant on the cartesian grid.
            theta_p  = fmodf(theta[p], 2.0f * (float) M_PI);
            quadrant = calc_quadrant(theta_p);
            sin_p    = sinf(theta_p);
            cos_p    = cosf(theta_p);

            // For each detector pixel
            for(d = 0; d < dx; d++)
            {
                // Calculate coordinates
                xi = -ngridx - ngridy;
                yi = 0.5f * (1 - dx) + d + mov;
                calc_coords(ngridx, ngridy, xi, yi, sin_p, cos_p, gridx, gridy,
                            coordx, coordy);

                // Merge the (coordx, gridy) and (gridx, coordy)
                trim_coords(ngridx, ngridy, coordx, coordy, gridx, gridy,
                            &asize, ax, ay, &bsize, bx, by);

                // Sort the array of intersection points (ax, ay) and
                // (bx, by). The new sorted intersection points are
                // stored in (coorx, coory). Total number of points
                // are csize.
                sort_intersections(quadrant, asize, ax, ay, bsize, bx, by,
                                   &csize, coorx, coory);

                // Calculate the distances (dist) between the
                // intersection points (coorx, coory). Find the
                // indices of the pixels on the reconstruction grid.
                calc_dist(ngridx, ngridy, csize, coorx, coory, indi, dist);

                // Calculate dist*dist
                float sum_dist2 = 0.0f;
                for(n = 0; n < csize - 1; n++)
                {
                    sum_dist2 += dist[n] * dist[n];
                }

                if(sum_dist2 != 0.0f)
                {
                    // For each slice
                    for(s = 0; s < dy; s++)
                    {
                        // Calculate simdata
                        calc_simdata(s, p, d, ngridx, ngridy, dt, dx, csize,
                                     indi, dist, recon,
                                     simdata);  // Output: simdata

                        // Update
                        ind_data  = d + p * dx + s * dt * dx;
                        ind_recon = s * ngridx * ngridy;
                        upd = (data[ind_data] - simdata[ind_data]) / sum_dist2;
                        for(n = 0; n < csize - 1; n++)
                        {
                            recon[indi[n] + ind_recon] += upd * dist[n];
                        }
                    }
                }
            }
        }
    }
    free(gridx);
    free(gridy);
    free(coordx);
    free(coordy);
    free(ax);
    free(ay);
    free(bx);
    free(by);
    free(coorx);
    free(coory);
    free(dist);
    free(indi);
    free(simdata);
}
Esempio n. 6
0
void do_coupling(FILE *log,const output_env_t oenv,int nfile,
                 const t_filenm fnm[], t_coupl_rec *tcr,real t,
                 int step,real ener[], t_forcerec *fr,t_inputrec *ir,
                 gmx_bool bMaster, t_mdatoms *md,t_idef *idef,real mu_aver,int nmols,
		 t_commrec *cr,matrix box,tensor virial,
		 tensor pres,rvec mu_tot,
		 rvec x[],rvec f[],gmx_bool bDoIt)
{
#define enm2Debye 48.0321
#define d2e(x) (x)/enm2Debye
#define enm2kjmol(x) (x)*0.0143952 /* = 2.0*4.0*M_PI*EPSILON0 */

  static real *f6,*f12,*fa,*fb,*fc,*fq;
  static gmx_bool bFirst = TRUE;
  
  int         i,j,ati,atj,atnr2,type,ftype;
  real        deviation[eoObsNR],prdev[eoObsNR],epot0,dist,rmsf;
  real        ff6,ff12,ffa,ffb,ffc,ffq,factor,dt,mu_ind;
  real        Epol,Eintern,Virial,muabs,xiH=-1,xiS=-1,xi6,xi12;
  rvec        fmol[2];
  gmx_bool        bTest,bPrint;
  t_coupl_LJ  *tclj;
  t_coupl_BU  *tcbu;
  t_coupl_Q   *tcq;
  t_coupl_iparams *tip;
  
  atnr2 = idef->atnr * idef->atnr;
  if (bFirst) {
    if (PAR(cr))
      fprintf(log,"GCT: this is parallel\n");
    else
      fprintf(log,"GCT: this is not parallel\n");
    fflush(log);
    snew(f6, atnr2);
    snew(f12,atnr2);
    snew(fa, atnr2);
    snew(fb, atnr2);
    snew(fc, atnr2);
    snew(fq, idef->atnr);
    
    if (tcr->bVirial) {
      int  nrdf = 0;
      real TTT  = 0;
      real Vol  = det(box);
      
      for(i=0; (i<ir->opts.ngtc); i++) {
	nrdf += ir->opts.nrdf[i];
	TTT  += ir->opts.nrdf[i]*ir->opts.ref_t[i];
      }
      TTT /= nrdf;
      
      /* Calculate reference virial from reference temperature and pressure */
      tcr->ref_value[eoVir] = 0.5*BOLTZ*nrdf*TTT - (3.0/2.0)*
	Vol*tcr->ref_value[eoPres];
      
      fprintf(log,"GCT: TTT = %g, nrdf = %d, vir0 = %g,  Vol = %g\n",
	      TTT,nrdf,tcr->ref_value[eoVir],Vol);
      fflush(log);
    }
    bFirst = FALSE;
  }
  
  bPrint = MASTER(cr) && do_per_step(step,ir->nstlog);
  dt     = ir->delta_t;

  /* Initiate coupling to the reference pressure and temperature to start
   * coupling slowly.
   */
  if (step == 0) {
    for(i=0; (i<eoObsNR); i++)
      tcr->av_value[i] = tcr->ref_value[i];
    if ((tcr->ref_value[eoDipole]) != 0.0) {
      mu_ind = mu_aver - d2e(tcr->ref_value[eoDipole]); /* in e nm */
      Epol   = mu_ind*mu_ind/(enm2kjmol(tcr->ref_value[eoPolarizability]));
      tcr->av_value[eoEpot] -= Epol;
      fprintf(log,"GCT: mu_aver = %g(D), mu_ind = %g(D), Epol = %g (kJ/mol)\n",
	      mu_aver*enm2Debye,mu_ind*enm2Debye,Epol);
    }
  }

  /* We want to optimize the LJ params, usually to the Vaporization energy 
   * therefore we only count intermolecular degrees of freedom.
   * Note that this is now optional. switch UseEinter to yes in your gct file
   * if you want this.
   */
  dist      = calc_dist(log,x);
  muabs     = norm(mu_tot);
  Eintern   = Ecouple(tcr,ener)/nmols;
  Virial    = virial[XX][XX]+virial[YY][YY]+virial[ZZ][ZZ];

  /*calc_force(md->nr,f,fmol);*/
  clear_rvec(fmol[0]);
  
  /* Use a memory of tcr->nmemory steps, so we actually couple to the
   * average observable over the last tcr->nmemory steps. This may help
   * in avoiding local minima in parameter space.
   */
  set_act_value(tcr,eoPres, ener[F_PRES],step);
  set_act_value(tcr,eoEpot, Eintern,     step);
  set_act_value(tcr,eoVir,  Virial,      step);
  set_act_value(tcr,eoDist, dist,        step);
  set_act_value(tcr,eoMu,   muabs,       step);
  set_act_value(tcr,eoFx,   fmol[0][XX], step);
  set_act_value(tcr,eoFy,   fmol[0][YY], step);
  set_act_value(tcr,eoFz,   fmol[0][ZZ], step);
  set_act_value(tcr,eoPx,   pres[XX][XX],step);
  set_act_value(tcr,eoPy,   pres[YY][YY],step);
  set_act_value(tcr,eoPz,   pres[ZZ][ZZ],step);
  
  epot0 = tcr->ref_value[eoEpot];
  /* If dipole != 0.0 assume we want to use polarization corrected coupling */
  if ((tcr->ref_value[eoDipole]) != 0.0) {
    mu_ind = mu_aver - d2e(tcr->ref_value[eoDipole]); /* in e nm */
    
    Epol = mu_ind*mu_ind/(enm2kjmol(tcr->ref_value[eoPolarizability]));
    
    epot0 -= Epol;
    if (debug) {
      fprintf(debug,"mu_ind: %g (%g D) mu_aver: %g (%g D)\n",
	      mu_ind,mu_ind*enm2Debye,mu_aver,mu_aver*enm2Debye);
      fprintf(debug,"Eref %g Epol %g Erunav %g Eact %g\n",
	      tcr->ref_value[eoEpot],Epol,tcr->av_value[eoEpot],
	      tcr->act_value[eoEpot]);
    }
  }

  if (bPrint) {
    pr_ff(tcr,t,idef,cr,nfile,fnm,oenv);
  }
  /* Calculate the deviation of average value from the target value */
  for(i=0; (i<eoObsNR); i++) {
    deviation[i] = calc_deviation(tcr->av_value[i],tcr->act_value[i],
				  tcr->ref_value[i]);
    prdev[i]     = tcr->ref_value[i] - tcr->act_value[i];
  }
  deviation[eoEpot] = calc_deviation(tcr->av_value[eoEpot],tcr->act_value[eoEpot],
				     epot0);
  prdev[eoEpot]     = epot0 - tcr->act_value[eoEpot];
  
  if (bPrint)
    pr_dev(tcr,t,prdev,cr,nfile,fnm,oenv);
  
  /* First set all factors to 1 */
  for(i=0; (i<atnr2); i++) {
    f6[i] = f12[i] = fa[i] = fb[i] = fc[i] = 1.0;
  }
  for(i=0; (i<idef->atnr); i++) 
    fq[i] = 1.0;

  /* Now compute the actual coupling compononents */   
  if (!fr->bBHAM) {
    if (bDoIt) {
      for(i=0; (i<tcr->nLJ); i++) {
	tclj=&(tcr->tcLJ[i]);
	
	ati=tclj->at_i;
	atj=tclj->at_j;
	
	ff6 = ff12 = 1.0;	
	
	if (tclj->eObs == eoForce) {
	  gmx_fatal(FARGS,"Hack code for this to work again ");
	  if (debug)
	    fprintf(debug,"Have computed derivatives: xiH = %g, xiS = %g\n",xiH,xiS);
	  if (ati == 1) {
	    /* Hydrogen */
	    ff12 += xiH; 
	  }
	  else if (ati == 2) {
	    /* Shell */
	    ff12 += xiS; 
	  }
	  else
	    gmx_fatal(FARGS,"No H, no Shell, edit code at %s, line %d\n",
			__FILE__,__LINE__);
	  if (ff6 > 0)
	    set_factor_matrix(idef->atnr,f6, sqrt(ff6), ati,atj);
	  if (ff12 > 0)
	    set_factor_matrix(idef->atnr,f12,sqrt(ff12),ati,atj);
	}
	else {
	  if (debug)
	    fprintf(debug,"tcr->tcLJ[%d].xi_6 = %g, xi_12 = %g deviation = %g\n",i,
		    tclj->xi_6,tclj->xi_12,deviation[tclj->eObs]);
	  factor=deviation[tclj->eObs];
	  
	  upd_f_value(log,idef->atnr,tclj->xi_6, dt,factor,f6, ati,atj);
	  upd_f_value(log,idef->atnr,tclj->xi_12,dt,factor,f12,ati,atj);
	}
      }
    }
    if (PAR(cr)) {
      gprod(cr,atnr2,f6);
      gprod(cr,atnr2,f12);
#ifdef DEBUGGCT
      dump_fm(log,idef->atnr,f6,"f6");
      dump_fm(log,idef->atnr,f12,"f12");
#endif
    }
    upd_nbfplj(log,fr->nbfp,idef->atnr,f6,f12,tcr->combrule);
    
    /* Copy for printing */
    for(i=0; (i<tcr->nLJ); i++) {
      tclj=&(tcr->tcLJ[i]);
      ati = tclj->at_i;
      atj = tclj->at_j;
      if (atj == -1) 
      {
          atj = ati;
      }
      /* nbfp now includes the 6.0/12.0 derivative prefactors */
      tclj->c6  =  C6(fr->nbfp,fr->ntype,ati,atj)/6.0;
      tclj->c12 = C12(fr->nbfp,fr->ntype,ati,atj)/12.0;
    }
  }
  else {
    if (bDoIt) {
      for(i=0; (i<tcr->nBU); i++) {
	tcbu   = &(tcr->tcBU[i]);
	factor = deviation[tcbu->eObs];
	ati    = tcbu->at_i;
	atj    = tcbu->at_j;
	
	upd_f_value(log,idef->atnr,tcbu->xi_a,dt,factor,fa,ati,atj);
	upd_f_value(log,idef->atnr,tcbu->xi_b,dt,factor,fb,ati,atj);
	upd_f_value(log,idef->atnr,tcbu->xi_c,dt,factor,fc,ati,atj);
      }
    }
    if (PAR(cr)) {
      gprod(cr,atnr2,fa);
      gprod(cr,atnr2,fb);
      gprod(cr,atnr2,fc);
    }
    upd_nbfpbu(log,fr->nbfp,idef->atnr,fa,fb,fc);
    /* Copy for printing */
    for(i=0; (i<tcr->nBU); i++) {
      tcbu=&(tcr->tcBU[i]);
      ati = tcbu->at_i;
      atj = tcbu->at_j;
      if (atj == -1) 
      {
          atj = ati;
      }
      /* nbfp now includes the 6.0 derivative prefactors */
      tcbu->a = BHAMA(fr->nbfp,fr->ntype,ati,atj);
      tcbu->b = BHAMB(fr->nbfp,fr->ntype,ati,atj);
      tcbu->c = BHAMC(fr->nbfp,fr->ntype,ati,atj)/6.0;
      if (debug)
	fprintf(debug,"buck (type=%d) = %e, %e, %e\n",
		tcbu->at_i,tcbu->a,tcbu->b,tcbu->c);
    }
  }
  if (bDoIt) {
    for(i=0; (i<tcr->nQ); i++) {
      tcq=&(tcr->tcQ[i]);
      if (tcq->xi_Q)     
	ffq = 1.0 + (dt/tcq->xi_Q) * deviation[tcq->eObs];
      else
	ffq = 1.0;
      fq[tcq->at_i] *= ffq;
    }
  }
  if (PAR(cr))
    gprod(cr,idef->atnr,fq);
  
  for(j=0; (j<md->nr); j++) {
    md->chargeA[j] *= fq[md->typeA[j]];
  }
  for(i=0; (i<tcr->nQ); i++) {
    tcq=&(tcr->tcQ[i]);
    for(j=0; (j<md->nr); j++) {
      if (md->typeA[j] == tcq->at_i) {
	tcq->Q = md->chargeA[j];
	break;
      }
    }
    if (j == md->nr)
      gmx_fatal(FARGS,"Coupling type %d not found",tcq->at_i);
  }  
  for(i=0; (i<tcr->nIP); i++) {
    tip    = &(tcr->tIP[i]);
    type   = tip->type;
    ftype  = idef->functype[type];
    factor = dt*deviation[tip->eObs];
      
    switch(ftype) {
    case F_BONDS:
      if (tip->xi.harmonic.krA) idef->iparams[type].harmonic.krA *= (1+factor/tip->xi.harmonic.krA);
      if (tip->xi.harmonic.rA) idef->iparams[type].harmonic.rA *= (1+factor/tip->xi.harmonic.rA);
	break;
    default:
      break;
    }
    tip->iprint=idef->iparams[type];
  }
}
Esempio n. 7
0
int gmx_cluster(int argc,char *argv[])
{
  static char *desc[] = {
    "g_cluster can cluster structures with several different methods.",
    "Distances between structures can be determined from a trajectory",
    "or read from an XPM matrix file with the [TT]-dm[tt] option.",
    "RMS deviation after fitting or RMS deviation of atom-pair distances",
    "can be used to define the distance between structures.[PAR]",
    
    "single linkage: add a structure to a cluster when its distance to any",
    "element of the cluster is less than [TT]cutoff[tt].[PAR]",
    
    "Jarvis Patrick: add a structure to a cluster when this structure",
    "and a structure in the cluster have each other as neighbors and",
    "they have a least [TT]P[tt] neighbors in common. The neighbors",
    "of a structure are the M closest structures or all structures within",
    "[TT]cutoff[tt].[PAR]",
    
    "Monte Carlo: reorder the RMSD matrix using Monte Carlo.[PAR]",
    
    "diagonalization: diagonalize the RMSD matrix.[PAR]"
    
    "gromos: use algorithm as described in Daura [IT]et al.[it]",
    "([IT]Angew. Chem. Int. Ed.[it] [BB]1999[bb], [IT]38[it], pp 236-240).",
    "Count number of neighbors using cut-off, take structure with",
    "largest number of neighbors with all its neighbors as cluster",
    "and eleminate it from the pool of clusters. Repeat for remaining",
    "structures in pool.[PAR]",
    
    "When the clustering algorithm assigns each structure to exactly one",
    "cluster (single linkage, Jarvis Patrick and gromos) and a trajectory",
    "file is supplied, the structure with",
    "the smallest average distance to the others or the average structure",
    "or all structures for each cluster will be written to a trajectory",
    "file. When writing all structures, separate numbered files are made",
    "for each cluster.[PAR]"
    
    "Two output files are always written:[BR]",
    "[TT]-o[tt] writes the RMSD values in the upper left half of the matrix",
    "and a graphical depiction of the clusters in the lower right half",
    "When [TT]-minstruct[tt] = 1 the graphical depiction is black",
    "when two structures are in the same cluster.",
    "When [TT]-minstruct[tt] > 1 different colors will be used for each",
    "cluster.[BR]",
    "[TT]-g[tt] writes information on the options used and a detailed list",
    "of all clusters and their members.[PAR]",
    
    "Additionally, a number of optional output files can be written:[BR]",
    "[TT]-dist[tt] writes the RMSD distribution.[BR]",
    "[TT]-ev[tt] writes the eigenvectors of the RMSD matrix",
    "diagonalization.[BR]",
    "[TT]-sz[tt] writes the cluster sizes.[BR]",
    "[TT]-tr[tt] writes a matrix of the number transitions between",
    "cluster pairs.[BR]",
    "[TT]-ntr[tt] writes the total number of transitions to or from",
    "each cluster.[BR]",
    "[TT]-clid[tt] writes the cluster number as a function of time.[BR]",
    "[TT]-cl[tt] writes average (with option [TT]-av[tt]) or central",
    "structure of each cluster or writes numbered files with cluster members",
    "for a selected set of clusters (with option [TT]-wcl[tt], depends on",
    "[TT]-nst[tt] and [TT]-rmsmin[tt]).[BR]",
  };
  
  FILE         *fp,*log;
  int          i,i1,i2,j,nf,nrms;

  matrix       box;
  rvec         *xtps,*usextps,*x1,**xx=NULL;
  char         *fn,*trx_out_fn;
  t_clusters   clust;
  t_mat        *rms;
  real         *eigval;
  t_topology   top;
  int          ePBC;
  t_atoms      useatoms;
  t_matrix     *readmat;
  real         *tmp;
  
  int      isize=0,ifsize=0,iosize=0;
  atom_id  *index=NULL, *fitidx, *outidx;
  char     *grpname;
  real     rmsd,**d1,**d2,*time,time_invfac,*mass=NULL;
  char     buf[STRLEN],buf1[80],title[STRLEN];
  bool     bAnalyze,bUseRmsdCut,bJP_RMSD=FALSE,bReadMat,bReadTraj;

  int method,ncluster=0;  
  static char *methodname[] = { 
    NULL, "linkage", "jarvis-patrick","monte-carlo", 
    "diagonalization", "gromos", NULL
  };
  enum { m_null, m_linkage, m_jarvis_patrick, 
	 m_monte_carlo, m_diagonalize, m_gromos, m_nr };
  /* Set colors for plotting: white = zero RMS, black = maximum */
  static t_rgb rlo_top = { 1.0, 1.0, 1.0 };
  static t_rgb rhi_top = { 0.0, 0.0, 0.0 };
  static t_rgb rlo_bot = { 1.0, 1.0, 1.0 };
  static t_rgb rhi_bot = { 0.0, 0.0, 1.0 };
  static int  nlevels=40,skip=1;
  static real scalemax=-1.0,rmsdcut=0.1,rmsmin=0.0;
  static bool bRMSdist=FALSE,bBinary=FALSE,bAverage=FALSE,bFit=TRUE;
  static int  niter=10000,seed=1993,write_ncl=0,write_nst=1,minstruct=1;
  static real kT=1e-3;
  static int  M=10,P=3;
  t_pargs pa[] = {
    { "-dista", FALSE, etBOOL, {&bRMSdist},
      "Use RMSD of distances instead of RMS deviation" },
    { "-nlevels",FALSE,etINT,  {&nlevels},
      "Discretize RMSD matrix in # levels" },
    { "-cutoff",FALSE, etREAL, {&rmsdcut},
      "RMSD cut-off (nm) for two structures to be neighbor" },
    { "-fit",   FALSE, etBOOL, {&bFit},
      "Use least squares fitting before RMSD calculation" },
    { "-max",   FALSE, etREAL, {&scalemax},
      "Maximum level in RMSD matrix" },
    { "-skip",  FALSE, etINT,  {&skip},
      "Only analyze every nr-th frame" },
    { "-av",    FALSE, etBOOL, {&bAverage},
      "Write average iso middle structure for each cluster" },
    { "-wcl",   FALSE, etINT,  {&write_ncl},
      "Write all structures for first # clusters to numbered files" },
    { "-nst",   FALSE, etINT,  {&write_nst},
      "Only write all structures if more than # per cluster" },
    { "-rmsmin",FALSE, etREAL, {&rmsmin},
      "minimum rms difference with rest of cluster for writing structures" },
    { "-method",FALSE, etENUM, {methodname},
      "Method for cluster determination" },
    { "-minstruct", FALSE, etINT, {&minstruct},
      "Minimum number of structures in cluster for coloring in the xpm file" },
    { "-binary",FALSE, etBOOL, {&bBinary},
      "Treat the RMSD matrix as consisting of 0 and 1, where the cut-off "
      "is given by -cutoff" },
    { "-M",     FALSE, etINT,  {&M},
      "Number of nearest neighbors considered for Jarvis-Patrick algorithm, "
      "0 is use cutoff" },
    { "-P",     FALSE, etINT,  {&P},
      "Number of identical nearest neighbors required to form a cluster" },
    { "-seed",  FALSE, etINT,  {&seed},
      "Random number seed for Monte Carlo clustering algorithm" },
    { "-niter", FALSE, etINT,  {&niter},
      "Number of iterations for MC" },
    { "-kT",    FALSE, etREAL, {&kT},
      "Boltzmann weighting factor for Monte Carlo optimization "
      "(zero turns off uphill steps)" }
  };
  t_filenm fnm[] = {
    { efTRX, "-f",     NULL,        ffOPTRD },
    { efTPS, "-s",     NULL,        ffOPTRD },
    { efNDX, NULL,     NULL,        ffOPTRD },
    { efXPM, "-dm",   "rmsd",       ffOPTRD },     
    { efXPM, "-o",    "rmsd-clust", ffWRITE },
    { efLOG, "-g",    "cluster",    ffWRITE },
    { efXVG, "-dist", "rmsd-dist",  ffOPTWR },
    { efXVG, "-ev",   "rmsd-eig",   ffOPTWR },
    { efXVG, "-sz",   "clust-size", ffOPTWR},
    { efXPM, "-tr",   "clust-trans",ffOPTWR},
    { efXVG, "-ntr",  "clust-trans",ffOPTWR},
    { efXVG, "-clid", "clust-id.xvg",ffOPTWR},
    { efTRX, "-cl",   "clusters.pdb", ffOPTWR }
  };
#define NFILE asize(fnm)
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL);

  /* parse options */
  bReadMat   = opt2bSet("-dm",NFILE,fnm);
  bReadTraj  = opt2bSet("-f",NFILE,fnm) || !bReadMat;
  if ( opt2parg_bSet("-av",asize(pa),pa) ||
       opt2parg_bSet("-wcl",asize(pa),pa) ||
       opt2parg_bSet("-nst",asize(pa),pa) ||
       opt2parg_bSet("-rmsmin",asize(pa),pa) ||
       opt2bSet("-cl",NFILE,fnm) )
    trx_out_fn = opt2fn("-cl",NFILE,fnm);
  else
    trx_out_fn = NULL;
  if (bReadMat && time_factor()!=1) {
    fprintf(stderr,
	    "\nWarning: assuming the time unit in %s is %s\n",
	    opt2fn("-dm",NFILE,fnm),time_unit());
  }
  if (trx_out_fn && !bReadTraj)
    fprintf(stderr,"\nWarning: "
	    "cannot write cluster structures without reading trajectory\n"
	    "         ignoring option -cl %s\n", trx_out_fn);

  method=1;
  while ( method < m_nr && strcasecmp(methodname[0], methodname[method])!=0 )
    method++;
  if (method == m_nr)
    gmx_fatal(FARGS,"Invalid method");
  
  bAnalyze = (method == m_linkage || method == m_jarvis_patrick ||
	      method == m_gromos );
  
  /* Open log file */
  log = ftp2FILE(efLOG,NFILE,fnm,"w");

  fprintf(stderr,"Using %s method for clustering\n",methodname[0]);
  fprintf(log,"Using %s method for clustering\n",methodname[0]);

  /* check input and write parameters to log file */
  bUseRmsdCut = FALSE;
  if (method == m_jarvis_patrick) {
    bJP_RMSD = (M == 0) || opt2parg_bSet("-cutoff",asize(pa),pa);
    if ((M<0) || (M == 1))
      gmx_fatal(FARGS,"M (%d) must be 0 or larger than 1",M);
    if (M < 2) {
      sprintf(buf1,"Will use P=%d and RMSD cutoff (%g)",P,rmsdcut);
      bUseRmsdCut = TRUE;
    } else {
      if (P >= M)
	gmx_fatal(FARGS,"Number of neighbors required (P) must be less than M");
      if (bJP_RMSD) {
	sprintf(buf1,"Will use P=%d, M=%d and RMSD cutoff (%g)",P,M,rmsdcut);
	bUseRmsdCut = TRUE;
      } else
	sprintf(buf1,"Will use P=%d, M=%d",P,M);
    }
    ffprintf1(stderr,log,buf,"%s for determining the neighbors\n\n",buf1);
  } else /* method != m_jarvis */
    bUseRmsdCut = ( bBinary || method == m_linkage || method == m_gromos );
  if (bUseRmsdCut && method != m_jarvis_patrick)
    fprintf(log,"Using RMSD cutoff %g nm\n",rmsdcut);
  if ( method==m_monte_carlo )
    fprintf(log,"Using %d iterations\n",niter);
  
  if (skip < 1)
    gmx_fatal(FARGS,"skip (%d) should be >= 1",skip);

  /* get input */
  if (bReadTraj) {
    /* don't read mass-database as masses (and top) are not used */
    read_tps_conf(ftp2fn(efTPS,NFILE,fnm),buf,&top,&ePBC,&xtps,NULL,box,
		  bAnalyze);
    
    fprintf(stderr,"\nSelect group for least squares fit%s:\n",
	    bReadMat?"":" and RMSD calculation");
    get_index(&(top.atoms),ftp2fn_null(efNDX,NFILE,fnm),
	      1,&ifsize,&fitidx,&grpname);
    if (trx_out_fn) {
      fprintf(stderr,"\nSelect group for output:\n");
      get_index(&(top.atoms),ftp2fn_null(efNDX,NFILE,fnm),
		1,&iosize,&outidx,&grpname);
      /* merge and convert both index groups: */
      /* first copy outidx to index. let outidx refer to elements in index */
      snew(index,iosize);
      isize = iosize;
      for(i=0; i<iosize; i++) {
	index[i]=outidx[i];
	outidx[i]=i;
      }
      /* now lookup elements from fitidx in index, add them if necessary
	 and also let fitidx refer to elements in index */
      for(i=0; i<ifsize; i++) {
	j=0;
	while (j<isize && index[j]!=fitidx[i])
	  j++;
	if (j>=isize) {
	  /* slow this way, but doesn't matter much */
	  isize++;
	  srenew(index,isize);
	}
	index[j]=fitidx[i];
	fitidx[i]=j;
      }
    } else { /* !trx_out_fn */
      isize = ifsize;
      snew(index, isize);
      for(i=0; i<ifsize; i++) {
	index[i]=fitidx[i];
	fitidx[i]=i;
      }
    }
  }
  /* Initiate arrays */
  snew(d1,isize);
  snew(d2,isize);
  for(i=0; (i<isize); i++) {
    snew(d1[i],isize);
    snew(d2[i],isize);
  }

  if (bReadTraj) {
    /* Loop over first coordinate file */
    fn = opt2fn("-f",NFILE,fnm);
    
    xx = read_whole_trj(fn,isize,index,skip,&nf,&time);
    convert_times(nf, time);
    if (!bRMSdist || bAnalyze) {
      /* Center all frames on zero */
      snew(mass,isize);
      for(i=0; i<ifsize; i++)
	mass[fitidx[i]] = top.atoms.atom[index[fitidx[i]]].m;
      if (bFit)
      for(i=0; i<nf; i++)
	reset_x(ifsize,fitidx,isize,NULL,xx[i],mass);
    }
  }
  if (bReadMat) {
    fprintf(stderr,"Reading rms distance matrix ");
    read_xpm_matrix(opt2fn("-dm",NFILE,fnm),&readmat);
    fprintf(stderr,"\n");
    if (readmat[0].nx != readmat[0].ny)
      gmx_fatal(FARGS,"Matrix (%dx%d) is not square",
		  readmat[0].nx,readmat[0].ny);
    if (bReadTraj && bAnalyze && (readmat[0].nx != nf))
      gmx_fatal(FARGS,"Matrix size (%dx%d) does not match the number of "
		  "frames (%d)",readmat[0].nx,readmat[0].ny,nf);

    nf = readmat[0].nx;
    sfree(time);
    time = readmat[0].axis_x;
    time_invfac = time_invfactor();
    for(i=0; i<nf; i++)
      time[i] *= time_invfac;

    rms = init_mat(readmat[0].nx,method == m_diagonalize);
    convert_mat(&(readmat[0]),rms);
    
    nlevels = readmat[0].nmap;
  } else { /* !bReadMat */
    rms = init_mat(nf,method == m_diagonalize);
    nrms = (nf*(nf-1))/2;
    if (!bRMSdist) {
      fprintf(stderr,"Computing %dx%d RMS deviation matrix\n",nf,nf);
      snew(x1,isize);
      for(i1=0; (i1<nf); i1++) {
	for(i2=i1+1; (i2<nf); i2++) {
	  for(i=0; i<isize; i++)
	    copy_rvec(xx[i1][i],x1[i]);
	  if (bFit)
	    do_fit(isize,mass,xx[i2],x1);
	  rmsd = rmsdev(isize,mass,xx[i2],x1);
	  set_mat_entry(rms,i1,i2,rmsd);
	}
	nrms -= (nf-i1-1);
	fprintf(stderr,"\r# RMSD calculations left: %d   ",nrms);
      }
    } else { /* bRMSdist */
      fprintf(stderr,"Computing %dx%d RMS distance deviation matrix\n",nf,nf);
      for(i1=0; (i1<nf); i1++) {
	calc_dist(isize,xx[i1],d1);
	for(i2=i1+1; (i2<nf); i2++) {
	  calc_dist(isize,xx[i2],d2);
	  set_mat_entry(rms,i1,i2,rms_dist(isize,d1,d2));
      }
	nrms -= (nf-i1-1);
	fprintf(stderr,"\r# RMSD calculations left: %d   ",nrms);
      }
    }
    fprintf(stderr,"\n\n");
  }
  ffprintf2(stderr,log,buf,"The RMSD ranges from %g to %g nm\n",
	    rms->minrms,rms->maxrms);
  ffprintf1(stderr,log,buf,"Average RMSD is %g\n",2*rms->sumrms/(nf*(nf-1)));
  ffprintf1(stderr,log,buf,"Number of structures for matrix %d\n",nf);
  ffprintf1(stderr,log,buf,"Energy of the matrix is %g nm\n",mat_energy(rms));
  if (bUseRmsdCut && (rmsdcut < rms->minrms || rmsdcut > rms->maxrms) )
    fprintf(stderr,"WARNING: rmsd cutoff %g is outside range of rmsd values "
	    "%g to %g\n",rmsdcut,rms->minrms,rms->maxrms);
  if (bAnalyze && (rmsmin < rms->minrms) )
    fprintf(stderr,"WARNING: rmsd minimum %g is below lowest rmsd value %g\n",
	    rmsmin,rms->minrms);
  if (bAnalyze && (rmsmin > rmsdcut) )
    fprintf(stderr,"WARNING: rmsd minimum %g is above rmsd cutoff %g\n",
	    rmsmin,rmsdcut);
  
  /* Plot the rmsd distribution */
  rmsd_distribution(opt2fn("-dist",NFILE,fnm),rms);
  
  if (bBinary) {
    for(i1=0; (i1 < nf); i1++) 
      for(i2=0; (i2 < nf); i2++)
	if (rms->mat[i1][i2] < rmsdcut)
	  rms->mat[i1][i2] = 0;
	else
	  rms->mat[i1][i2] = 1;
  }

  snew(clust.cl,nf);
  switch (method) {
  case m_linkage: 
    /* Now sort the matrix and write it out again */
    gather(rms,rmsdcut,&clust);
    break;
  case m_diagonalize:
    /* Do a diagonalization */
      snew(eigval,nf);
      snew(tmp,nf*nf);
      memcpy(tmp,rms->mat[0],nf*nf*sizeof(real));
      eigensolver(tmp,nf,0,nf,eigval,rms->mat[0]);
      sfree(tmp);
      
      fp = xvgropen(opt2fn("-ev",NFILE,fnm),"RMSD matrix Eigenvalues",
                    "Eigenvector index","Eigenvalues (nm\\S2\\N)");
      for(i=0; (i<nf); i++)
          fprintf(fp,"%10d  %10g\n",i,eigval[i]);
          ffclose(fp);
      break;
  case m_monte_carlo:
    mc_optimize(log,rms,niter,&seed,kT);
    swap_mat(rms);
    reset_index(rms);
    break;
  case m_jarvis_patrick:
    jarvis_patrick(rms->nn,rms->mat,M,P,bJP_RMSD ? rmsdcut : -1,&clust);
    break;
  case m_gromos:
    gromos(rms->nn,rms->mat,rmsdcut,&clust);
    break;
  default:
    gmx_fatal(FARGS,"DEATH HORROR unknown method \"%s\"",methodname[0]);
  }
  
  if (method == m_monte_carlo || method == m_diagonalize)
    fprintf(stderr,"Energy of the matrix after clustering is %g nm\n",
	    mat_energy(rms));
  
  if (bAnalyze) {
    if (minstruct > 1) {
      ncluster = plot_clusters(nf,rms->mat,&clust,nlevels,minstruct);
    } else {
      mark_clusters(nf,rms->mat,rms->maxrms,&clust);
    }
    init_t_atoms(&useatoms,isize,FALSE);
    snew(usextps, isize);
    useatoms.resname=top.atoms.resname;
    for(i=0; i<isize; i++) {
      useatoms.atomname[i]=top.atoms.atomname[index[i]];
      useatoms.atom[i].resnr=top.atoms.atom[index[i]].resnr;
      useatoms.nres=max(useatoms.nres,useatoms.atom[i].resnr+1);
      copy_rvec(xtps[index[i]],usextps[i]);
    }
    useatoms.nr=isize;
    analyze_clusters(nf,&clust,rms->mat,isize,&useatoms,usextps,mass,xx,time,
		     ifsize,fitidx,iosize,outidx,
		     bReadTraj?trx_out_fn:NULL,
		     opt2fn_null("-sz",NFILE,fnm),
		     opt2fn_null("-tr",NFILE,fnm),
		     opt2fn_null("-ntr",NFILE,fnm),
		     opt2fn_null("-clid",NFILE,fnm),
		     bAverage, write_ncl, write_nst, rmsmin, bFit, log,
		     rlo_bot,rhi_bot);
  }
  ffclose(log);
  
  if (bBinary && !bAnalyze)
    /* Make the clustering visible */
    for(i2=0; (i2 < nf); i2++)
       for(i1=i2+1; (i1 < nf); i1++)
	 if (rms->mat[i1][i2])
	   rms->mat[i1][i2] = rms->maxrms;

  fp = opt2FILE("-o",NFILE,fnm,"w");
  fprintf(stderr,"Writing rms distance/clustering matrix ");
  if (bReadMat) {
    write_xpm(fp,0,readmat[0].title,readmat[0].legend,readmat[0].label_x,
	      readmat[0].label_y,nf,nf,readmat[0].axis_x,readmat[0].axis_y,
	      rms->mat,0.0,rms->maxrms,rlo_top,rhi_top,&nlevels);
  } 
  else {
    sprintf(buf,"Time (%s)",time_unit());
    sprintf(title,"RMS%sDeviation / Cluster Index",
 	    bRMSdist ? " Distance " : " ");
    if (minstruct > 1) {
      write_xpm_split(fp,0,title,"RMSD (nm)",buf,buf,
		      nf,nf,time,time,rms->mat,0.0,rms->maxrms,&nlevels,
		      rlo_top,rhi_top,0.0,(real) ncluster,
		      &ncluster,TRUE,rlo_bot,rhi_bot);
    } else {
      write_xpm(fp,0,title,"RMSD (nm)",buf,buf,
		nf,nf,time,time,rms->mat,0.0,rms->maxrms,
		rlo_top,rhi_top,&nlevels);
    }
  }
  fprintf(stderr,"\n");
  ffclose(fp);
  
  /* now show what we've done */
  do_view(opt2fn("-o",NFILE,fnm),"-nxy");
  do_view(opt2fn_null("-sz",NFILE,fnm),"-nxy");
  if (method == m_diagonalize)
    do_view(opt2fn_null("-ev",NFILE,fnm),"-nxy");
  do_view(opt2fn("-dist",NFILE,fnm),"-nxy");
  if (bAnalyze) {
    do_view(opt2fn_null("-tr",NFILE,fnm),"-nxy");
    do_view(opt2fn_null("-ntr",NFILE,fnm),"-nxy");
    do_view(opt2fn_null("-clid",NFILE,fnm),"-nxy");
  }
  
  /* Thank the user for her patience */  
  thanx(stderr);
  
  return 0;
}
Esempio n. 8
0
void geocacheMenu(void)
{
    int pressedKey = mySwitch.checkKeypad();
    switch (menuState)
    {
    case MENU0:
        tft.fillScreen(ST7735_BLACK);
        setCursorTFT(0,0);
        tft.print(menuHeader);
        setCursorTFT(1,0);
        tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
        tft.print(monGPSLocn);
        setCursorTFT(2,0);
        tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
        tft.print(monGPSClk);
        setCursorTFT(3,0);
        tft.print(downldWays);
        setCursorTFT(4,0);
        tft.print(goToWaypts);
        setCursorTFT(5,0);
        tft.print(setActWays);
        setCursorTFT(6,0);
        tft.print(showWaypts);
        menuState = MENU0B;
        break;
    case MENU0B:
        if (pressedKey != NOKEY)
        {
            if ((pressedKey == SELECT) || (pressedKey == RIGHT))
            {
                tft.fillScreen(ST7735_BLACK);
                setCursorTFT(0,0);
                tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
                tft.print(monGPSLocn);
                tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
                clearLine(1);
                clearLine(2);
                clearLine(3);
                clearLine(4);
                clearLine(5);
                clearLine(6);
                menuState = MENU0C;
            }
            else if (pressedKey == DOWN)
                menuState = MENU1;
        }
        break;
    case MENU0C:
        if (pressedKey != NOKEY)
            menuState = MENU0;
        readGPS();
        break;
    case MENU1:
        tft.fillScreen(ST7735_BLACK);
        setCursorTFT(0,0);
        tft.print(menuHeader);
        setCursorTFT(1,0);
        tft.print(monGPSLocn);
        setCursorTFT(2,0);
        tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
        tft.print(monGPSClk);
        tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
        setCursorTFT(3,0);
        tft.print(downldWays);
        setCursorTFT(4,0);
        tft.print(goToWaypts);
        setCursorTFT(5,0);
        tft.print(setActWays);
        setCursorTFT(6,0);
        tft.print(showWaypts);
        menuState = MENU1B;
        break;
    case MENU1B:
        if (pressedKey != NOKEY)
        {
            if ((pressedKey == SELECT) || (pressedKey == RIGHT))
            {
                clearLine(0);
                tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
                tft.print(monGPSClk);
                tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
                clearLine(1);
                clearLine(2);
                clearLine(3);
                clearLine(4);
                clearLine(5);
                clearLine(6);
                menuState = MENU1C;
            }
            else if (pressedKey == UP)
                menuState = MENU0;
            else if (pressedKey == DOWN)
                menuState = MENU2;
        }
        break;
    case MENU1C:
        if (pressedKey != NOKEY)
        {
            tft.fillScreen(ST7735_BLACK);
            menuState = MENU1;
        }
        GPSClock();
        break;
    case MENU2:
        tft.fillScreen(ST7735_BLACK);
        setCursorTFT(0,0);
        tft.print(menuHeader);
        setCursorTFT(1,0);
        tft.print(monGPSLocn);
        setCursorTFT(2,0);
        tft.print(monGPSClk);
        setCursorTFT(3,0);
        tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
        tft.print(downldWays);
        tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
        setCursorTFT(4,0);
        tft.print(goToWaypts);
        setCursorTFT(5,0);
        tft.print(setActWays);
        setCursorTFT(6,0);
        tft.print(showWaypts);
        menuState = MENU2B;
        break;
    case MENU2B:
    {
        int charIn;
        if (pressedKey != NOKEY)
        {
            if ((pressedKey == SELECT) || (pressedKey == RIGHT))
            {
                rxCount = 0;
                clearLine(2);
                clearLine(3);
                clearLine(4);
                clearLine(5);
                clearLine(6);
                clearLine(1);
                tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
                tft.print(downldWays);
                tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
                setCursorTFT(2,0);
                menuState = MENU2C;
                while (Serial.available())    // flush the serial read port
                    charIn = Serial.read();
                Serial.println("<DL>");    // signals host that it's time to load waypoints
            }
            else if (pressedKey == UP)
                menuState = MENU1;
            else if (pressedKey == DOWN)
                menuState = MENU3;
        }
    }
    break;
    case MENU2C:
    {
        int charIn;
        int errorCode;
        if (Serial.available())
        {
            charIn = Serial.read();
            if (charIn == '\n')
            {
                tft.print(".");
                rxBuffer[rxCount] = 0;
                errorCode = parseRxBuffer();
                if (errorCode == -1)
                {
                    clearLine(2);
                    tft.print("Error: Missing equal");
                }
                else if (errorCode == -2)
                {
                    clearLine(2);
                    tft.print("Error: Bad waypt num");
                }
                rxCount = 0;
                Serial.write('A');
                if ((rxBuffer[0] == '1') && (rxBuffer[1]=='9'))
                {
                    clearLine(3);
                    tft.print("Download Completed  ");
                    EEPROM_writeAnything(0, myStoreVals);
                    Serial.println("</SERIN>");    // signals host that it's time to load waypoints
                    delay(2000);  // 2 second message
                    menuState = MENU2;
                }
            }
            else
            {
                rxBuffer[rxCount++] = charIn;
            }
        }
        if (pressedKey == UP)
        {
            Serial.println("</DL>");    // signals host that it's time to load waypoints
            clearLine(2);
            tft.print("Download Terminated ");
            delay(2000);  // 2 second message
            menuState = MENU2;
        }
    }
    break;
    case MENU3:
        tft.fillScreen(ST7735_BLACK);
        setCursorTFT(0,0);
        tft.print(menuHeader);
        setCursorTFT(1,0);
        tft.print(monGPSLocn);
        setCursorTFT(2,0);
        tft.print(monGPSClk);
        setCursorTFT(3,0);
        tft.print(downldWays);
        setCursorTFT(4,0);
        tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
        tft.print(goToWaypts);
        tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
        setCursorTFT(5,0);
        tft.print(setActWays);
        setCursorTFT(6,0);
        tft.print(showWaypts);
        menuState = MENU3B;
        break;
    case MENU3B:
        if (pressedKey != NOKEY)
        {
            if ((pressedKey == SELECT) || (pressedKey == RIGHT))
            {
                quietReadGPS();
                delay(500);
                menuState = MENU3C;
            }
            else if (pressedKey == UP)
                menuState = MENU2;
            else if (pressedKey == DOWN)
                menuState = MENU4;
        }
        break;
    case MENU3C:
        tft.fillScreen(ST7735_BLACK);
        tft.drawCircle(64,110,45,ST7735_WHITE);
        setCursorTFT(0,0);
        tft.print(menuHeader);
        setCursorTFT(1,0);
        tft.print("Going to Waypoint   ");
        setCursorTFT(1,18);
        tft.print(currentWayPoint, DEC);
        setCursorTFT(2,0);
        tft.print("Bearing =");
        setCursorTFT(3,0);
        tft.print("Distance =");
        setCursorTFT(4,0);
        tft.print("Direction =");
        setCursorTFT(5,0);
        tft.print("Satellites =");
        quietReadGPS();
        setCursorTFT(2,10);
        tft.print("         ");
        setCursorTFT(2,10);
        bearing = calc_bearing(fLat2,fLon2,myStoreVals.lats[currentWayPoint],myStoreVals.lons[currentWayPoint]);
        tft.print(bearing);
        lastLat = fLat2;
        setCursorTFT(3,11);
        tft.print("        ");
        setCursorTFT(3,11);
        tft.print(calc_dist(fLat2,fLon2,myStoreVals.lats[currentWayPoint],myStoreVals.lons[currentWayPoint]));
        lastLon = fLon2;
        setCursorTFT(4,12);
        tft.print(GPS.angle-bearing);
        lastAngle = GPS.angle;
        lastBearing = bearing;

        setCursorTFT(5,13);
        tft.print(GPS.satellites);
        lastSats = GPS.satellites;
        menuState = MENU3D;
        break;
    case MENU3D:
    {
        if (pressedKey != NOKEY)
        {
            menuState = MENU3;
            break;
        }
        if (quietReadGPS() != 0)
        {
            break;
        }
        float distCalc = calc_dist(fLat2,fLon2,myStoreVals.lats[currentWayPoint],myStoreVals.lons[currentWayPoint]);
        bearing = calc_bearing(fLat2,fLon2,myStoreVals.lats[currentWayPoint],myStoreVals.lons[currentWayPoint]);
        if ((fLat2 != lastLat) || (fLon2 != lastLon))
        {
            setCursorTFT(2,10);
            tft.print("           ");
            setCursorTFT(2,10);
            tft.print(bearing);
            setCursorTFT(3,11);
            tft.print("          ");
            setCursorTFT(3,11);
            tft.print(distCalc);
            lastLat = fLat2;
            lastLon = fLon2;
        }
        if ((GPS.angle != lastAngle) || (bearing != lastBearing))
        {
            setCursorTFT(4,12);
            tft.print("         ");
            setCursorTFT(4,12);
            tft.print(GPS.angle-bearing);
            drawVector(GPS.angle-bearing);
            lastAngle = GPS.angle;
            lastBearing = bearing;
        }
        if (lastSats != GPS.satellites)
        {
            setCursorTFT(5,13);
            tft.print(GPS.satellites);
            tft.print("  ");
        }
    }
    break;
    case MENU4:
        tft.fillScreen(ST7735_BLACK);
        setCursorTFT(0,0);
        tft.print(menuHeader);
        setCursorTFT(1,0);
        tft.print(monGPSLocn);
        setCursorTFT(2,0);
        tft.print(monGPSClk);
        setCursorTFT(3,0);
        tft.print(downldWays);
        setCursorTFT(4,0);
        tft.print(goToWaypts);
        setCursorTFT(5,0);
        tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
        tft.print(setActWays);
        tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
        setCursorTFT(6,0);
        tft.print(showWaypts);
        menuState = MENU4B;
        break;
    case MENU4B:
        if (pressedKey != NOKEY)
        {
            if ((pressedKey == SELECT) || (pressedKey == RIGHT))
            {
                tft.fillScreen(ST7735_BLACK);
                setCursorTFT(0,0);
                tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
                tft.print(setActWays);
                tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
                setCursorTFT(1,0);
                tft.print(currentWayPoint, DEC);
                menuState = MENU4C;
            }
            else if (pressedKey == UP)
            {
                menuState = MENU3;
            }
            else if (pressedKey == DOWN)
            {
                menuState = MENU5;
            }
        }
        break;
    case MENU4C:
    {
        if (pressedKey != NOKEY)
        {
            switch(pressedKey)
            {
            case SELECT:
                myStoreVals.myCurrentWayPoint = currentWayPoint;
                EEPROM_writeAnything(0, myStoreVals);
                menuState = MENU4;
                break;
            case UP:
                if (currentWayPoint < 19)
                    currentWayPoint++;
                delay(250);
                break;
            case DOWN:
                if (currentWayPoint > 0)
                    currentWayPoint--;
                delay(250);
                break;
            }
            clearLine(1);
            tft.print(currentWayPoint, DEC);
        }
    }
    break;
    case MENU5:
        tft.fillScreen(ST7735_BLACK);
        setCursorTFT(0,0);
        tft.print(menuHeader);
        setCursorTFT(1,0);
        tft.print(monGPSLocn);
        setCursorTFT(2,0);
        tft.print(monGPSClk);
        setCursorTFT(3,0);
        tft.print(downldWays);
        setCursorTFT(4,0);
        tft.print(goToWaypts);
        setCursorTFT(5,0);
        tft.print(setActWays);
        setCursorTFT(6,0);
        tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
        tft.print(showWaypts);
        tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
        menuState = MENU5B;
        break;
    case MENU5B:
        if (pressedKey != NOKEY)
        {
            if ((pressedKey == SELECT) || (pressedKey == RIGHT))
            {
                tft.fillScreen(ST7735_BLACK);
                setCursorTFT(0,0);
                tft.setTextColor(ST7735_WHITE,ST7735_BLUE);
                tft.print(showWaypts);
                tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
                for (int row = 0; row < 15; row++)
                {
                    setCursorTFT(row+1,0);
                    tft.print(row);
                    tft.print(",");
                    tft.print(myStoreVals.lats[row],4);
                    tft.print(",");
                    tft.print(myStoreVals.lons[row],4);
                }
                menuState = MENU5C;
            }
            else if (pressedKey == UP)
            {
                menuState = MENU4;
            }
        }
        break;
    case MENU5C:
    {
        if (pressedKey != NOKEY)
        {
            switch(pressedKey)
            {
            case SELECT:
            case UP:
                tft.fillScreen(ST7735_BLACK);
                menuState = MENU5;
                break;
            }
        }
        break;
    }
    }
}
Esempio n. 9
0
int gmx_saltbr(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] plots the distance between all combination of charged groups",
        "as a function of time. The groups are combined in different ways.",
        "A minimum distance can be given (i.e. a cut-off), such that groups",
        "that are never closer than that distance will not be plotted.[PAR]",
        "Output will be in a number of fixed filenames, [TT]min-min.xvg[tt], [TT]plus-min.xvg[tt]",
        "and [TT]plus-plus.xvg[tt], or files for every individual ion pair if the [TT]-sep[tt]",
        "option is selected. In this case, files are named as [TT]sb-(Resname)(Resnr)-(Atomnr)[tt].",
        "There may be [BB]many[bb] such files."
    };
    static gmx_bool bSep     = FALSE;
    static real     truncate = 1000.0;
    t_pargs         pa[]     = {
        { "-t",   FALSE, etREAL, {&truncate},
          "Groups that are never closer than this distance are not plotted" },
        { "-sep", FALSE, etBOOL, {&bSep},
          "Use separate files for each interaction (may be MANY)" }
    };
    t_filenm        fnm[] = {
        { efTRX, "-f",  NULL, ffREAD },
        { efTPR, NULL,  NULL, ffREAD },
    };
#define NFILE asize(fnm)

    FILE              *out[3], *fp;
    static const char *title[3] = {
        "Distance between positively charged groups",
        "Distance between negatively charged groups",
        "Distance between oppositely charged groups"
    };
    static const char *fn[3] = {
        "plus-plus.xvg",
        "min-min.xvg",
        "plus-min.xvg"
    };
    int                nset[3] = {0, 0, 0};

    t_topology        *top;
    int                ePBC;
    char              *buf;
    t_trxstatus       *status;
    int                i, j, k, m, nnn, teller, ncg;
    real               t, *time, qi, qj;
    t_charge          *cg;
    real            ***cgdist;
    int              **nWithin;

    t_pbc              pbc;
    rvec              *x;
    matrix             box;
    gmx_output_env_t  *oenv;

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    top = read_top(ftp2fn(efTPR, NFILE, fnm), &ePBC);
    cg  = mk_charge(&top->atoms, &(top->cgs), &ncg);
    snew(cgdist, ncg);
    snew(nWithin, ncg);
    for (i = 0; (i < ncg); i++)
    {
        snew(cgdist[i], ncg);
        snew(nWithin[i], ncg);
    }

    read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);

    teller = 0;
    time   = NULL;
    do
    {
        srenew(time, teller+1);
        time[teller] = t;

        set_pbc(&pbc, ePBC, box);

        for (i = 0; (i < ncg); i++)
        {
            for (j = i+1; (j < ncg); j++)
            {
                srenew(cgdist[i][j], teller+1);
                cgdist[i][j][teller] =
                    calc_dist(&pbc, x, &(top->cgs), cg[i].cg, cg[j].cg);
                if (cgdist[i][j][teller] < truncate)
                {
                    nWithin[i][j] = 1;
                }
            }
        }

        teller++;
    }
    while (read_next_x(oenv, status, &t, x, box));
    fprintf(stderr, "\n");
    close_trj(status);

    if (bSep)
    {
        snew(buf, 256);
        for (i = 0; (i < ncg); i++)
        {
            for (j = i+1; (j < ncg); j++)
            {
                if (nWithin[i][j])
                {
                    sprintf(buf, "sb-%s:%s.xvg", cg[i].label, cg[j].label);
                    fp = xvgropen(buf, buf, "Time (ps)", "Distance (nm)", oenv);
                    for (k = 0; (k < teller); k++)
                    {
                        fprintf(fp, "%10g  %10g\n", time[k], cgdist[i][j][k]);
                    }
                    xvgrclose(fp);
                }
            }
        }
        sfree(buf);
    }
    else
    {

        for (m = 0; (m < 3); m++)
        {
            out[m] = xvgropen(fn[m], title[m], "Time (ps)", "Distance (nm)", oenv);
        }

        snew(buf, 256);
        for (i = 0; (i < ncg); i++)
        {
            qi = cg[i].q;
            for (j = i+1; (j < ncg); j++)
            {
                qj = cg[j].q;
                if (nWithin[i][j])
                {
                    sprintf(buf, "%s:%s", cg[i].label, cg[j].label);
                    if (qi*qj < 0)
                    {
                        nnn = 2;
                    }
                    else if (qi+qj > 0)
                    {
                        nnn = 0;
                    }
                    else
                    {
                        nnn = 1;
                    }

                    if (nset[nnn] == 0)
                    {
                        xvgr_legend(out[nnn], 1, (const char**)&buf, oenv);
                    }
                    else
                    {
                        if (output_env_get_xvg_format(oenv) == exvgXMGR)
                        {
                            fprintf(out[nnn], "@ legend string %d \"%s\"\n", nset[nnn], buf);
                        }
                        else if (output_env_get_xvg_format(oenv) == exvgXMGRACE)
                        {
                            fprintf(out[nnn], "@ s%d legend \"%s\"\n", nset[nnn], buf);
                        }
                    }
                    nset[nnn]++;
                    nWithin[i][j] = nnn+1;
                }
            }
        }
        for (k = 0; (k < teller); k++)
        {
            for (m = 0; (m < 3); m++)
            {
                fprintf(out[m], "%10g", time[k]);
            }

            for (i = 0; (i < ncg); i++)
            {
                for (j = i+1; (j < ncg); j++)
                {
                    nnn = nWithin[i][j];
                    if (nnn > 0)
                    {
                        fprintf(out[nnn-1], "  %10g", cgdist[i][j][k]);
                    }
                }
            }
            for (m = 0; (m < 3); m++)
            {
                fprintf(out[m], "\n");
            }
        }
        for (m = 0; (m < 3); m++)
        {
            xvgrclose(out[m]);
            if (nset[m] == 0)
            {
                remove(fn[m]);
            }
        }
    }

    return 0;
}
Esempio n. 10
0
float calc_radius(struct halo *h, struct halo *p) {
  struct halo *p2 = find_parent_at_scale(h->scale, p);
  if (!p2) p2 = find_earliest_parent(p);
  if (!p2) return 0;
  return calc_dist(h, p2);
}
Esempio n. 11
0
char current_location(int* position)
{
    // int buffer to hold blob data
    unsigned int buffer[12];
    
    // read wii camera blob data into int buffer
    m_wii_read(buffer);
    
    // star points
    int x1 = (int)buffer[0];
    int y1 = (int)buffer[1];
    int x2 = (int)buffer[3];
    int y2 = (int)buffer[4];
    int x3 = (int)buffer[6];
    int y3 = (int)buffer[7];
    int x4 = (int)buffer[9];
    int y4 = (int)buffer[10];
    
    // array of points
    int x_points[4] = {x1, x2, x3, x4};
    int y_points[4] = {y1, y2, y3, y4};
    
    // lose star case
    int i;
    for(i = 0; i<=4;i++)
    {
        if (x_points[i]==1023 && y_points[i]==1023)
        {
            x_points[i] = NaN;
            y_points[i] = NaN;
        }
    }
    
    // calculate all possible distances
    int d12 = calc_dist(x_points[0], y_points[0], x_points[1], y_points[1]);
    int d13 = calc_dist(x_points[0], y_points[0], x_points[2], y_points[2]);
    int d14 = calc_dist(x_points[0], y_points[0], x_points[3], y_points[3]);
    int d23 = calc_dist(x_points[1], y_points[1], x_points[2], y_points[2]);
    int d24 = calc_dist(x_points[1], y_points[1], x_points[3], y_points[3]);
    int d34 = calc_dist(x_points[2], y_points[2], x_points[3], y_points[3]);
    
    // store all distances in an array
    int all_distances[6] = {d12,d13,d14,d23,d24,d34};
    
    // store all pair
    int all_pairs[6][2] = {{0,1},{0,2},{0,3},{1,2},{1,3},{2,3}};
    
    // index and value of max and min distance
    int max_dat[2];
    int min_dat[2];

    // find min and max arrays
    max_array(all_distances, 6, max_dat);
    min_array(all_distances, 6, min_dat);
    
    // index of max and min points
    int max_index = max_dat[1];
    int max = max_dat[0];
    int min_index = min_dat[1];

    // array of pair indicies
    int long_pair[2] = {all_pairs[max_index][0], all_pairs[max_index][1]};
    int short_pair[2] = {all_pairs[min_index][0], all_pairs[min_index][1]};
    
    int top_point[2];
    int bottom_point[2];
    
    // finds top and bottom points
    if (long_pair[0] == short_pair[0] || long_pair[0] == short_pair[1])
    {
        top_point[0] = x_points[long_pair[0]];
        top_point[1] = y_points[long_pair[0]];
        bottom_point[0] = x_points[long_pair[1]];
        bottom_point[1] = y_points[long_pair[1]];
    }
    else
    {
        top_point[0] =x_points[long_pair[1]];
        top_point[1] =y_points[long_pair[1]];
        bottom_point[0] =x_points[long_pair[0]];
        bottom_point[1] =y_points[long_pair[0]];

    }
    
    // calculate center of rink
    double x_center = ((double)top_point[0] + (double)bottom_point[0])/2;
    double y_center = ((double)top_point[1] + (double)bottom_point[1])/2;
    
    //double theta = acos(y_unit);
    double x_diff = (double)top_point[0] - x_center;
    double y_diff =(double)top_point[1] - y_center;
    
    // calculate position of camera relative to camera coordinate axes
    double camera_x = 512;
    double camera_y = 384;
    
    // calculate angle theta
    double theta = atan2(x_diff, y_diff);

    // rotated points
    float rotated_x = ((((camera_x-x_center)*cos(theta)) + ((camera_y-y_center)*-sin(theta))) + camera_x) - camera_x;
    float rotated_y = ((((camera_x-x_center)*sin(theta)) + ((camera_y-y_center)*cos(theta))) + camera_y) - camera_y;

    // position and angle relative to rink axes
    position[0] = (int) (29*(rotated_x))/max;
    position[1] = (int) (29*(rotated_y))/max;
    position[2] = (int) (theta*(180/M_PI));
    
    return 1;
    }
Esempio n. 12
0
int main(int argc, char** argv)
{
  int height ,width ,step ,channels;
  int same, lighter;
  float thresh;  
  uchar *dataB, *dataG, *dataR, *dataGray, *dataD;
  uchar b1, g1, r1, b2, g2, r2;
  int w = 3;
  int th = 50;
  int idx1, idx2;

  cv::Mat img = cv::imread(argv[1]);
  height = img.rows;
  width = img.cols;

  cv::namedWindow("Image0", cv::WINDOW_NORMAL);
  cv::Mat textImg(1000, 1200, CV_8UC1, cv::Scalar(255));
  cv::putText(textImg, "Original Image:", cv::Point(400, 500), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(0, 0, 0));
  //cv::imshow("Image0", textImg);
  //cv::waitKey();
  //cv::imshow("Image0", img);
  //cv::waitKey();

  textImg.setTo(cv::Scalar(255, 255, 255));
  cv::putText(textImg, "Next: Apply SUSAN algorithm to detect edge and cross.", cv::Point(200, 500), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  cv::putText(textImg, "Press any key to continue...", cv::Point(400, 600), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  //cv::imshow("Image0", textImg);
  //cv::waitKey();

  std::vector<cv::Mat> imgChannels;
  cv::split(img, imgChannels);
  cv::Mat dstSusan(height, width, CV_8UC1, cv::Scalar(0));
  cv::Mat grayImg(height, width, CV_8UC1, cv::Scalar(0));
    
  step = imgChannels[0].step[0];
  dataB = imgChannels[0].data;
  dataG = imgChannels[1].data;
  dataR = imgChannels[2].data;
  dataGray = grayImg.data;
  dataD= dstSusan.data;

  for (int x = w; x < width-w; x++)
    {
      for (int y = w; y < height-w; y++)
	{
	  same = 0;
	  idx1 = x + y * step;
	  b1 = dataB[idx1];
	  g1 = dataG[idx1];
	  r1 = dataR[idx1];
	  for (int u = 0; u < w+1; u++)
	    {
	      for (int v = 0; v < w+1; v++)
		{
		  if (u + v == 0)
		    {
		      continue;
		    }
		  idx2 = (x+u) + (y+v) * step;
		  b2 = dataB[idx2];
		  g2 = dataG[idx2];
		  r2 = dataR[idx2];
		  if (calc_dist(b1, g1, r1, b1, g2, r2) < th)
		    {
		      same += 1;
		    }

		  idx2 = (x-u) + (y+v) * step;
		  b2 = dataB[idx2];
		  g2 = dataG[idx2];
		  r2 = dataR[idx2];

		  if (u != 0 && calc_dist(b1, g1, r1, b1, g2, r2) < th)
		    {
		      same += 1;
		    }

		  idx2 = (x+u) + (y-v) * step;
		  b2 = dataB[idx2];
		  g2 = dataG[idx2];
		  r2 = dataR[idx2];
		  if (v != 0 && calc_dist(b1, g1, r1, b1, g2, r2) < th)
		    {
		      same += 1;
		    }

		  idx2 = (x-u) + (y-v) * step;
		  b2 = dataB[idx2];
		  g2 = dataG[idx2];
		  r2 = dataR[idx2];
		  if (u != 0 && v != 0 && calc_dist(b1, g1, r1, b1, g2, r2) < th)
		    {
		      same += 1;
		    }
		}
	    }
	  dataD[idx1] = uchar(255.0 * float(same) / ((2*w+1) * (2*w+1) - 1));
	  if (dataD[idx1] < 128)
	    {
	      dataD[idx1] = 255;
	    }
	  else
	    {
	      dataD[idx1] = 0;
	    }
	}
    }

  //cv::imshow("Image0", dstSusan);
  cv::imwrite("outimg_1.jpg", dstSusan);
  textImg.setTo(cv::Scalar(255, 255, 255));
  cv::putText(textImg, "Next: Apply Hough algorithm to detect lines.", cv::Point(300, 500), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  cv::putText(textImg, "Press any key to continue...", cv::Point(400, 600), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  //cv::waitKey();
  //cv::imshow("Image0", textImg);
  //cv::waitKey();

  //Hough line detection
  std::vector<cv::Vec4i> lines;
  HoughLinesP(dstSusan, lines, 1, CV_PI/180, 80, 500, 20);

  double thetaSum = 0.0;
  int thetaNum = 0;
  double theta;
  for(size_t i = 0; i < lines.size(); i++)
    {  
      cv::Vec4i l = lines[i];
      cv::line(img, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar(186,88,255), 1, CV_AA);
      if (l[0] == l[2])
	{
	  theta = CV_PI / 2;
	}
      else
	{
	  theta = std::atan(-double(l[3]-l[1]) / (l[2] - l[0]));
	}
      if (theta >= -CV_PI / 4 && theta <= CV_PI / 4)
	{
	  thetaSum += theta;
	  thetaNum += 1;
	}
    }

  theta = -thetaSum / thetaNum * 180 / CV_PI;
  
  //cv::imshow("Image0", img);
  cv::imwrite("outimg_2.jpg", img);
  //cv::waitKey();
  textImg.setTo(cv::Scalar(255, 255, 255));
  std::ostringstream textStr;
  textStr << "Find " << lines.size() << " lines.";
  cv::putText(textImg, textStr.str(), cv::Point(500, 400), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  textStr.str(std::string());
  textStr.clear();
  textStr << "Rotating angle is " << theta << " degree.";
  cv::putText(textImg, textStr.str(), cv::Point(350, 500), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  cv::putText(textImg, "Next: Rotating the image.", cv::Point(400, 600), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  cv::putText(textImg, "Press any key to continue...", cv::Point(400, 700), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  //cv::imshow("Image0", textImg);
  //cv::waitKey();

  img.release();
  img = cv::imread(argv[1]);
  imgChannels[0].release();
  imgChannels[1].release();
  imgChannels[2].release();
  imgChannels.clear();
  
  cv::Mat rotateImg(height, width, CV_8UC3);
  cv::Point2f center;
  center.x = float(width / 2.0 + 0.5);
  center.y = float(height / 2.0 + 0.5);
  cv::Mat affineMat = getRotationMatrix2D(center, theta, 1);
  cv::warpAffine(img,rotateImg, affineMat, cv::Size(width, height), CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS);

  //cv::imshow("Image0", rotateImg);
  cv::imwrite("outimg_3.jpg", rotateImg);
  //cv::waitKey();
  textImg.setTo(cv::Scalar(255, 255, 255));
  cv::putText(textImg, "Next: Transform the image to gray scale.", cv::Point(300, 500), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  cv::putText(textImg, "Press any key to continue...", cv::Point(400, 600), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  //cv::imshow("Image0", textImg);
  //cv::waitKey();

  cv::split(rotateImg, imgChannels);
  dataB = imgChannels[0].data;
  dataG = imgChannels[1].data;
  dataR = imgChannels[2].data;
  step = imgChannels[0].step[0];
  //imgChannels[2].setTo(cv::Scalar(0));
  for (int x = 0; x < rotateImg.cols; x++)
    {
      for (int y = 0; y < rotateImg.rows; y++)
	{
	  int idx = x + y * step;
	  if (dataB[idx] < dataG[idx] && dataB[idx] < dataR[idx])
	    {
	      dataG[idx] = dataB[idx];
	      dataR[idx] = dataB[idx];
	    }
	  if (dataG[idx] < dataB[idx] && dataG[idx] < dataR[idx])
	    {
	      dataB[idx] = dataG[idx];
	      dataR[idx] = dataG[idx];
	    }
	  if (dataR[idx] < dataB[idx] && dataR[idx] < dataG[idx])
	    {
	      dataB[idx] = dataR[idx];
	      dataG[idx] = dataR[idx];
	    }
	}
    }
  cv::Mat filterRedImg(rotateImg.rows, rotateImg.cols, CV_8UC3, cv::Scalar::all(255));
  cv::merge(imgChannels, filterRedImg);

  cv::cvtColor(filterRedImg, grayImg, CV_BGR2GRAY);

  //cv::imshow("Image0", grayImg);
  cv::imwrite("outimg_4.jpg", grayImg);
  //cv::waitKey();
  textImg.setTo(cv::Scalar(255, 255, 255));
  cv::putText(textImg, "Next: Clean the noise.", cv::Point(450, 500), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  cv::putText(textImg, "Press any key to continue...", cv::Point(400, 600), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  //cv::imshow("Image0", textImg);
  //cv::waitKey();

  step = grayImg.step[0];
  for (int x = 0; x < width; x++)
    {
      for (int y = 0; y < height; y++)
	{
	  int idx = x + y * step;
	  if (grayImg.data[idx] > 100)
	  //if(!is_gray(dataB[idx], dataG[idx], dataR[idx]))
	    {
	      grayImg.data[idx] = 255;
	    }
	}
    }

  //cv::imshow("Image0", grayImg);
  cv::imwrite("outimg_5.jpg", grayImg);
  //cv::waitKey();
  textImg.setTo(cv::Scalar(255, 255, 255));
  cv::putText(textImg, "Next: Digitizing the curves.", cv::Point(400, 500), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  cv::putText(textImg, "Press any key to continue...", cv::Point(400, 600), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  //cv::imshow("Image0", textImg);
  //cv::waitKey();

  cv::Mat newImg(height, width, CV_8UC3, cv::Scalar::all(255));
  
  SegmentFactory segFactory = SegmentFactory(0);
  std::vector<Segment *> segments;

  segFactory.makeSegments(grayImg, segments);

  std::vector<Segment *>::iterator itr;
  for (itr = segments.begin(); itr != segments.end(); itr++)
    {
      Segment *seg = *itr;
      std::vector<SegmentLine *>::iterator itr_l;
      for (itr_l = seg->m_lines.begin(); itr_l != seg->m_lines.end(); itr_l++)
	{
	  SegmentLine *line = *itr_l;
	  cv::line(newImg, cv::Point(line->m_x1, line->m_y1), cv::Point(line->m_x2, line->m_y2), cv::Scalar(186,88,255), 1, CV_AA);
	  std::cout << line->m_x1 << ", " << line->m_y1 << ", " << line->m_x2 << ", " << line->m_y2 << std::endl;
	}
    }

  //cv::imshow("Image0", newImg);
  cv::imwrite("outimg_6.jpg", newImg);
  //cv::waitKey();
  textImg.setTo(cv::Scalar(255, 255, 255));
  cv::putText(textImg, "Done.", cv::Point(550, 500), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 255));
  //cv::imshow("Image0", textImg);
  //cv::waitKey();

  return 0;  
}