void Align(const std::string& ref_seq, const std::string& read_seq,
	     std::string& ref_seq_al, std::string& read_seq_al,
	     float* score, std::vector<BamTools::CigarOp>& cigar_list) {
    int L1       = ref_seq.length();
    int L2       = read_seq.length();
    int mat_size = (L1+1)*(L2+1);
  
    // Scoring matrices
    std::vector<float> M(mat_size);      // Ref and read bases aligned 
    std::vector<float> Iref(mat_size);   // Ref  base aligned with gap
    std::vector<float> Iread(mat_size);  // Read base aligned with gap

    // Traceback matrices
    std::vector<int> traceM(mat_size);
    std::vector<int> traceIref(mat_size);
    std::vector<int> traceIread(mat_size);

    M[0]     = 0.0;
    Iref[0]  = -LARGE; // Impossible
    Iread[0] = -LARGE; // Impossible

    // Fill in row (0,n)
    for(int i = 1; i < L1+1; i++){
      // No penalty for leading affine gap in reference seq 
      Iref[i]       = 0.0;  
      traceIref[i]  = 1;

      // Impossible
      Iread[i]      = -LARGE;
      traceIread[i] = -1;

      // Impossible
      M[i]      = -LARGE;
      traceM[i] = -1;
    }

    // Fill in column (n, 0)
    for(int i = 1; i < L2+1; i++){
      int index = i*(L1+1);

      // Penalty for leading affine gap in read sequence
      Iread[index]      = -GAPOPEN-(i-1)*GAPEXTEND;
      traceIread[index] = 2;

      // Impossible
      Iref[index]       = -LARGE; 
      traceIref[index]  = -1;

      // Impossible
      M[index]      = -LARGE;
      traceM[index] = -1;
    }
    
    // Determine optimal alignment
    nw_helper(M, Iref, Iread, traceM, traceIref, traceIread,
	      ref_seq, read_seq, ref_seq_al, read_seq_al, score, cigar_list);
  }
 static int
process(Engine *ep, char *parname, char *resname)
{
	FILE *f;
	FileInfo fi;
	char *s;
	int *asv, asvkind[3], i, j, k, m1, n1, n2, nd, *p, rc;
	mxArray *X;
	real *x;

	rc = 1;
        if (!strcmp(parname,"setup") && 
            !strcmp(resname,"workspace"))
           { 
             printf("pre-processing with setupworkspace.m\n");
             fflush(stdout);
             engEvalString(ep, "setupworkspace");
	     return 0;
           }
	if (!(fi.f = fopen(parname,"r"))) {
		BadOpen("parameters_file", parname);
		goto done1;
		}
	fi.fname = s;
	fi.lineno = 0;

	n1 = Iread(&fi, "variables");
	X = mxCreateDoubleMatrix(1, n1, mxREAL);
	x = (real*)mxGetPr(X);

	for(i = 0; i < n1; i++)
		x[i] = Dread(&fi);

	m1 = Iread(&fi, "functions");

	asvkind[0] = asvkind[1] = asvkind[2] = 0;
	asv = (int*)Malloc((n1+m1)*sizeof(int));
	p = asv + m1;
	for(i = 0; i < m1; i++) {
		asv[i] = j = Iread(&fi,0);
		for(k = 0; k < 3 && j; k++, j >>= 1)
			if (j & 1)
				++asvkind[k];
		}
	nd = Iread(&fi, "derivative_variables");
	for(i = 0; i < nd; i++)
		p[i] = Iread(&fi, 0) - 1;
	fclose(fi.f);
	f = fopen(resname, "w");
	if (!f) {
		BadOpen("results_file", resname);
		mxDestroyArray(X);
		goto done1;
		}
	engPutVariable(ep, "x", X);
	mxDestroyArray(X);

	X = mxCreateDoubleMatrix(1, 3, mxREAL);
	x = (real*)mxGetPr(X);
	for(i = 0; i < 3; i++)
		x[i] = asvkind[i];
	engPutVariable(ep, "asv", X);
	mxDestroyArray(X);

	if (asvkind[0]) {
		engEvalString(ep, "eval(FunctionEvaluation);");
		//engEvalString(ep, "y = f(x);");
		X = engGetVariable(ep,"y");
		if (!X) {
			Squawk("MATLAB didn't return y = f(x)\n");
			goto done;
			}
		x = (real*)mxGetPr(X);
		for(i = 0; i < m1; i++)
			if (asv[i] & 1)
				fprintf(f, " %.17g\n", x[i]);
		mxDestroyArray(X);
		}
	if (asvkind[1]) {
		engEvalString(ep, "eval(GradientEvaluation);");
		//engEvalString(ep, "yp = fp(x);");
		X = engGetVariable(ep,"yp");
		if (!X) {
			Squawk("MATLAB didn't return yp = fp(x)\n");
			goto done;
			}
		x = (real*)mxGetPr(X);
		for(i = 0; i < m1; i++, x += n1)
			if (asv[i] & 2)
				grdout(f, n1, p, x);
		mxDestroyArray(X);
		}
	if (asvkind[2]) {
		engEvalString(ep, "eval(HessianEvaluation);");
		//engEvalString(ep, "ypp = fpp(x);");
		X = engGetVariable(ep,"ypp");
		if (!X) {
			Squawk("MATLAB didn't return ypp = fpp(x)\n");
			goto done;
			}
		x = (real*)mxGetPr(X);
		n2 = n1*n1;
		for(i = 0; i < m1; i++, x += n2)
			if (asv[i] & 4)
				hesout(f, n1, p, x);
		mxDestroyArray(X);
		}
	rc = 0;
 done:
	fclose(f);
 done1:
	free(asv);
	return rc;
	}