/*------------------------------------------------------------------------------------------------*/
/*                                         OTHER FUNCTIONS                                        */
/*------------------------------------------------------------------------------------------------*/



int no_digits(double number)
{
    int length;
    
    if (abs(number) < 9.9995) {
        length = 1;
    }
    else if (abs(number) < 99.9995 && abs(number) >= 9.9995) {
        length = 2;
    }
    else if (abs(number) < 999.9995 && abs(number) >= 99.9995) {
        length = 3;
    }
    else if (abs(number) < 9999.9995 && abs(number) >= 999.9995) {
        length = 4;
    }
    else if (abs(number) <99999.9995 && abs(number) >= 9999.9995) {
        length = 5;
    }
    
    if (number < 0) {
        return length+1;
    }
    else {
        return length;
    }
}

/*------------------------------------------------------------------------------------------------*/

double dot_product(double A[3], double B[3])
{
    double result;
    
    result = A[0]*B[0] + A[1]*B[1] + A[2]*B[2];
    
    return result; 
}

/*------------------------------------------------------------------------------------------------*/

void vector_subtract(double A[3], double B[3], double AB[3])
{
    int i;
    
    for (i=0;i<3;i++) {
        AB[i] = B[i] - A[i];
    }
}

/*------------------------------------------------------------------------------------------------*/

void cross_product(double A[3], double B[3], double AxB[3])
{
    AxB[0] = A[1]*B[2] - A[2]*B[1];
    AxB[1] = A[2]*B[0] - A[0]*B[2];
    AxB[2] = A[0]*B[1] - A[1]*B[0];
}

/*------------------------------------------------------------------------------------------------*/

double magnitude(double vector[3])
{
    /*Calculate the magnitude of a vector*/
    
    double mag;
    
    mag = sqrt(pow(vector[0],2) + pow(vector[1],2) + pow(vector[2],2));
    
    return mag;
}

/*------------------------------------------------------------------------------------------------*/

double calculate_dihedral(double A[3], double B[3], double C[3], double D[3])
{
    /*Compute the dihedral angle given four points
    (http://math.stackexchange.com/questions/47059/how-do-i-calculate-a-dihedral-angle-given-
    cartesian-coordinates)*/

    double b1[3];
    double b2[3];
    double b3[3];
    double n1[3];
    double n2[3];
    double n1_mag;
    double n2_mag;
    double b2_mag;
    double n1_norm[3];
    double n2_norm[3];
    double b2_norm[3];
    double m1[3];
    double x;
    double y;
    //double r[3];
    double angle_radians;
    double angle_degrees;
    int i;
        
    vector_subtract(A, B, b1);    /*calculates AB (B-A)*/
    vector_subtract(B, C, b2);    /*calculates CB*/
    vector_subtract(C, D, b3);    /*calculates CD*/
     
    cross_product(b1, b2, n1);    /*calculates normal to plane containing AB and CB*/
    cross_product(b2, b3, n2);
    
    n1_mag = magnitude(n1);
    n2_mag = magnitude(n2);
    b2_mag = magnitude(b2);    
    
    for (i=0; i<3; i++) {
        n1_norm[i] = n1[i]/n1_mag;
        n2_norm[i] = n2[i]/n2_mag;
        b2_norm[i] = b2[i]/b2_mag;
    }
    
    cross_product(n1_norm, b2_norm, m1);
    
    x = dot_product(n1_norm, n2_norm);
    y = dot_product(m1, n2_norm);
    
    angle_radians = atan2(y,x);
    
    angle_degrees = angle_radians * 180 / pi;
    
    return -angle_degrees;
}

/*------------------------------------------------------------------------------------------------*/

double random_gaussian(double mean, double std)
{
    /*Produces a random number from a Gaussian distribution specified by the mean and standard
      deviation, using the Box-Muller transform*/

    double r1;
    double r2;
    double r3;
    double r_gaussian;
    
    r1 = (rand()+1.0)/(RAND_MAX+1.0);
    r2 = (rand()+1.0)/(RAND_MAX+1.0);
    
    r3 = sqrt(-2*log(r1)) * cos(2*pi*r2);
    
    r_gaussian = mean + std*r3;
    
    return r_gaussian;
}

/*------------------------------------------------------------------------------------------------*/

void find_foot_of_perpendicular(double A[3], double B[3], double C[3], double D[3])
{
    double x1 = A[0];
    double y1 = A[1];
    double z1 = A[2];
    
    double x2 = B[0];
    double y2 = B[1];
    double z2 = B[2];
    
    double x3 = C[0];
    double y3 = C[1];
    double z3 = C[2];
    
    double M = x2*x2 - 2*x2*x1 + x1*x1 + y2*y2 - 2*y1*y2 + y1*y1 + z2*z2 - 2*z1*z2 + z1*z1;
    
    double N = x1*x2 - x2*x3 - x1*x1 + x1*x3 + y1*y2 - y2*y3 - y1*y1 + y1*y3 + 
              z1*z2 - z2*z3 - z1*z1 + z1*z3;
    
    double t = -N / M;
    
    D[0] = (x2 - x1) * t + x1;
    D[1] = (y2 - y1) * t + y1;
    D[2] = (z2 - z1) * t + z1;
} 

/*------------------------------------------------------------------------------------------------*/

double calculate_RMSD(double **coordinates1, double coordinates2[][3], int start_index, 
                      int end_index)
{
    double sum_of_squared_differences = 0;
    double RMSD;
    int i;
    
    for (i=start_index; i<end_index; i++) {
        sum_of_squared_differences += pow((coordinates1[i][0] - coordinates2[i][0]),2) + 
                                      pow((coordinates1[i][1] - coordinates2[i][1]),2) +
                                      pow((coordinates1[i][2] - coordinates2[i][2]),2);
    }
                                      
    RMSD = sqrt(sum_of_squared_differences / (end_index - start_index));
    
    return RMSD;
}

/*------------------------------------------------------------------------------------------------*/

double calculate_RMSD2(double coordinates1[][3], double coordinates2[][3], int start_index, 
                      int end_index)
{
    double sum_of_squared_differences = 0;
    double RMSD;
    int i;
    
    for (i=start_index; i<end_index; i++) {
        sum_of_squared_differences += pow((coordinates1[i][0] - coordinates2[i][0]),2) + 
                                      pow((coordinates1[i][1] - coordinates2[i][1]),2) +
                                      pow((coordinates1[i][2] - coordinates2[i][2]),2);
    }
                                      
    RMSD = sqrt(sum_of_squared_differences / (end_index - start_index));
    
    return RMSD;
}

/*------------------------------------------------------------------------------------------------*/

void allocate_array(double ***array, int nrows)
{
    int i;
    
    *array = malloc(nrows * sizeof(double *));
    if (*array == NULL) {
        printf("Error: out of memory.\n");
        exit(0);
    }
    for (i=0; i<nrows; i++) {
        (*array)[i] = malloc(3 * sizeof(double));
        if ((*array)[i] == NULL) {
            printf("Error: out of memory.\n");
            exit(0);
        }
    }
}

void allocate_dihedral_array(int ***array, int nrows)
{
    int i;

    *array = malloc(nrows * sizeof(int *));
    for (i=0; i<nrows; i++) {
        (*array)[i] = malloc(2 * sizeof(int));
    }
}

/*------------------------------------------------------------------------------------------------*/

int copy_arrays_h3()
{
    int i,j;

    memcpy(ALA_CCD_dist, ALA_CCD_dist_h3, sizeof(ALA_CCD_dist_h3));
    memcpy(ARG_CCD_dist, ARG_CCD_dist_h3, sizeof(ARG_CCD_dist_h3));
    memcpy(ASN_CCD_dist, ASN_CCD_dist_h3, sizeof(ASN_CCD_dist_h3));
    memcpy(ASP_CCD_dist, ASP_CCD_dist_h3, sizeof(ASP_CCD_dist_h3));
    memcpy(CYS_CCD_dist, CYS_CCD_dist_h3, sizeof(CYS_CCD_dist_h3));
    memcpy(GLN_CCD_dist, GLN_CCD_dist_h3, sizeof(GLN_CCD_dist_h3));
    memcpy(GLU_CCD_dist, GLU_CCD_dist_h3, sizeof(GLU_CCD_dist_h3));
    memcpy(GLY_CCD_dist, GLY_CCD_dist_h3, sizeof(GLY_CCD_dist_h3));
    memcpy(HIS_CCD_dist, HIS_CCD_dist_h3, sizeof(HIS_CCD_dist_h3));
    memcpy(ILE_CCD_dist, ILE_CCD_dist_h3, sizeof(ILE_CCD_dist_h3));
    memcpy(LEU_CCD_dist, LEU_CCD_dist_h3, sizeof(LEU_CCD_dist_h3));
    memcpy(LYS_CCD_dist, LYS_CCD_dist_h3, sizeof(LYS_CCD_dist_h3));
    memcpy(MET_CCD_dist, MET_CCD_dist_h3, sizeof(MET_CCD_dist_h3));
    memcpy(PHE_CCD_dist, PHE_CCD_dist_h3, sizeof(PHE_CCD_dist_h3));
    memcpy(PRO_CCD_dist, PRO_CCD_dist_h3, sizeof(PRO_CCD_dist_h3));
    memcpy(SER_CCD_dist, SER_CCD_dist_h3, sizeof(SER_CCD_dist_h3));
    memcpy(THR_CCD_dist, THR_CCD_dist_h3, sizeof(THR_CCD_dist_h3));
    memcpy(TRP_CCD_dist, TRP_CCD_dist_h3, sizeof(TRP_CCD_dist_h3));
    memcpy(TYR_CCD_dist, TYR_CCD_dist_h3, sizeof(TYR_CCD_dist_h3));
    memcpy(VAL_CCD_dist, VAL_CCD_dist_h3, sizeof(VAL_CCD_dist_h3));

    memcpy(ptr_array, ptr_array_h3, sizeof(ptr_array_h3));
    memcpy(dihedral_array_lengths, dihedral_array_lengths_h3, sizeof(dihedral_array_lengths_h3));

    allocate_dihedral_array(&ALA_dihedrals, dihedral_array_lengths[0]);
    for (i=0; i<dihedral_array_lengths[0]; i++) {
        for (j=0; j<2; j++) {
		ALA_dihedrals[i][j] = ALA_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&ARG_dihedrals, dihedral_array_lengths[1]);
    for (i=0; i<dihedral_array_lengths[1]; i++) {
        for (j=0; j<2; j++) {
                ARG_dihedrals[i][j] = ARG_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&ASN_dihedrals, dihedral_array_lengths[2]);
    for (i=0; i<dihedral_array_lengths[2]; i++) {
        for (j=0; j<2; j++) {
                ASN_dihedrals[i][j] = ASN_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&ASP_dihedrals, dihedral_array_lengths[3]);
    for (i=0; i<dihedral_array_lengths[3]; i++) {
        for (j=0; j<2; j++) {
                ASP_dihedrals[i][j] = ASP_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&CYS_dihedrals, dihedral_array_lengths[4]);
    for (i=0; i<dihedral_array_lengths[4]; i++) {
        for (j=0; j<2; j++) {
                CYS_dihedrals[i][j] = CYS_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&GLN_dihedrals, dihedral_array_lengths[5]);
    for (i=0; i<dihedral_array_lengths[5]; i++) {
        for (j=0; j<2; j++) {
                GLN_dihedrals[i][j] = GLN_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&GLU_dihedrals, dihedral_array_lengths[6]);
    for (i=0; i<dihedral_array_lengths[6]; i++) {
        for (j=0; j<2; j++) {
                GLU_dihedrals[i][j] = GLU_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&GLY_dihedrals, dihedral_array_lengths[7]);
    for (i=0; i<dihedral_array_lengths[7]; i++) {
        for (j=0; j<2; j++) {
                GLY_dihedrals[i][j] = GLY_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&HIS_dihedrals, dihedral_array_lengths[8]);
    for (i=0; i<dihedral_array_lengths[8]; i++) {
        for (j=0; j<2; j++) {
                HIS_dihedrals[i][j] = HIS_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&ILE_dihedrals, dihedral_array_lengths[9]);
    for (i=0; i<dihedral_array_lengths[9]; i++) {
        for (j=0; j<2; j++) {
                ILE_dihedrals[i][j] = ILE_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&LEU_dihedrals, dihedral_array_lengths[10]);
    for (i=0; i<dihedral_array_lengths[10]; i++) {
        for (j=0; j<2; j++) {
                LEU_dihedrals[i][j] = LEU_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&LYS_dihedrals, dihedral_array_lengths[11]);
    for (i=0; i<dihedral_array_lengths[11]; i++) {
        for (j=0; j<2; j++) {
                LYS_dihedrals[i][j] = LYS_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&MET_dihedrals, dihedral_array_lengths[12]);
    for (i=0; i<dihedral_array_lengths[12]; i++) {
        for (j=0; j<2; j++) {
                MET_dihedrals[i][j] = MET_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&PHE_dihedrals, dihedral_array_lengths[13]);
    for (i=0; i<dihedral_array_lengths[13]; i++) {
        for (j=0; j<2; j++) {
                PHE_dihedrals[i][j] = PHE_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&PRO_dihedrals, dihedral_array_lengths[14]);
    for (i=0; i<dihedral_array_lengths[14]; i++) {
        for (j=0; j<2; j++) {
                PRO_dihedrals[i][j] = PRO_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&SER_dihedrals, dihedral_array_lengths[15]);
    for (i=0; i<dihedral_array_lengths[15]; i++) {
        for (j=0; j<2; j++) {
                SER_dihedrals[i][j] = SER_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&THR_dihedrals, dihedral_array_lengths[16]);
    for (i=0; i<dihedral_array_lengths[16]; i++) {
        for (j=0; j<2; j++) {
                THR_dihedrals[i][j] = THR_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&TRP_dihedrals, dihedral_array_lengths[17]);
    for (i=0; i<dihedral_array_lengths[17]; i++) {
        for (j=0; j<2; j++) {
                TRP_dihedrals[i][j] = TRP_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&TYR_dihedrals, dihedral_array_lengths[18]);
    for (i=0; i<dihedral_array_lengths[18]; i++) {
        for (j=0; j<2; j++) {
                TYR_dihedrals[i][j] = TYR_dihedrals_h3[i][j];
        }
    }

    allocate_dihedral_array(&VAL_dihedrals, dihedral_array_lengths[19]);
    for (i=0; i<dihedral_array_lengths[19]; i++) {
        for (j=0; j<2; j++) {
                VAL_dihedrals[i][j] = VAL_dihedrals_h3[i][j];
        }
    }
}


/*------------------------------------------------------------------------------------------------*/

int copy_arrays_membrane()
{
    int i,j;

    memcpy(ALA_CCD_dist, ALA_CCD_dist_membrane, sizeof(ALA_CCD_dist_membrane));
    memcpy(ARG_CCD_dist, ARG_CCD_dist_membrane, sizeof(ARG_CCD_dist_membrane));
    memcpy(ASN_CCD_dist, ASN_CCD_dist_membrane, sizeof(ASN_CCD_dist_membrane));
    memcpy(ASP_CCD_dist, ASP_CCD_dist_membrane, sizeof(ASP_CCD_dist_membrane));
    memcpy(CYS_CCD_dist, CYS_CCD_dist_membrane, sizeof(CYS_CCD_dist_membrane));
    memcpy(GLN_CCD_dist, GLN_CCD_dist_membrane, sizeof(GLN_CCD_dist_membrane));
    memcpy(GLU_CCD_dist, GLU_CCD_dist_membrane, sizeof(GLU_CCD_dist_membrane));
    memcpy(GLY_CCD_dist, GLY_CCD_dist_membrane, sizeof(GLY_CCD_dist_membrane));
    memcpy(HIS_CCD_dist, HIS_CCD_dist_membrane, sizeof(HIS_CCD_dist_membrane));
    memcpy(ILE_CCD_dist, ILE_CCD_dist_membrane, sizeof(ILE_CCD_dist_membrane));
    memcpy(LEU_CCD_dist, LEU_CCD_dist_membrane, sizeof(LEU_CCD_dist_membrane));
    memcpy(LYS_CCD_dist, LYS_CCD_dist_membrane, sizeof(LYS_CCD_dist_membrane));
    memcpy(MET_CCD_dist, MET_CCD_dist_membrane, sizeof(MET_CCD_dist_membrane));
    memcpy(PHE_CCD_dist, PHE_CCD_dist_membrane, sizeof(PHE_CCD_dist_membrane));
    memcpy(PRO_CCD_dist, PRO_CCD_dist_membrane, sizeof(PRO_CCD_dist_membrane));
    memcpy(SER_CCD_dist, SER_CCD_dist_membrane, sizeof(SER_CCD_dist_membrane));
    memcpy(THR_CCD_dist, THR_CCD_dist_membrane, sizeof(THR_CCD_dist_membrane));
    memcpy(TRP_CCD_dist, TRP_CCD_dist_membrane, sizeof(TRP_CCD_dist_membrane));
    memcpy(TYR_CCD_dist, TYR_CCD_dist_membrane, sizeof(TYR_CCD_dist_membrane));
    memcpy(VAL_CCD_dist, VAL_CCD_dist_membrane, sizeof(VAL_CCD_dist_membrane));

    memcpy(ptr_array, ptr_array_membrane, sizeof(ptr_array_membrane));
    memcpy(dihedral_array_lengths, dihedral_array_lengths_membrane, sizeof(dihedral_array_lengths_membrane));

    allocate_dihedral_array(&ALA_dihedrals, dihedral_array_lengths[0]);
    for (i=0; i<dihedral_array_lengths[0]; i++) {
        for (j=0; j<2; j++) {
		ALA_dihedrals[i][j] = ALA_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&ARG_dihedrals, dihedral_array_lengths[1]);
    for (i=0; i<dihedral_array_lengths[1]; i++) {
        for (j=0; j<2; j++) {
                ARG_dihedrals[i][j] = ARG_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&ASN_dihedrals, dihedral_array_lengths[2]);
    for (i=0; i<dihedral_array_lengths[2]; i++) {
        for (j=0; j<2; j++) {
                ASN_dihedrals[i][j] = ASN_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&ASP_dihedrals, dihedral_array_lengths[3]);
    for (i=0; i<dihedral_array_lengths[3]; i++) {
        for (j=0; j<2; j++) {
                ASP_dihedrals[i][j] = ASP_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&CYS_dihedrals, dihedral_array_lengths[4]);
    for (i=0; i<dihedral_array_lengths[4]; i++) {
        for (j=0; j<2; j++) {
                CYS_dihedrals[i][j] = CYS_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&GLN_dihedrals, dihedral_array_lengths[5]);
    for (i=0; i<dihedral_array_lengths[5]; i++) {
        for (j=0; j<2; j++) {
                GLN_dihedrals[i][j] = GLN_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&GLU_dihedrals, dihedral_array_lengths[6]);
    for (i=0; i<dihedral_array_lengths[6]; i++) {
        for (j=0; j<2; j++) {
                GLU_dihedrals[i][j] = GLU_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&GLY_dihedrals, dihedral_array_lengths[7]);
    for (i=0; i<dihedral_array_lengths[7]; i++) {
        for (j=0; j<2; j++) {
                GLY_dihedrals[i][j] = GLY_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&HIS_dihedrals, dihedral_array_lengths[8]);
    for (i=0; i<dihedral_array_lengths[8]; i++) {
        for (j=0; j<2; j++) {
                HIS_dihedrals[i][j] = HIS_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&ILE_dihedrals, dihedral_array_lengths[9]);
    for (i=0; i<dihedral_array_lengths[9]; i++) {
        for (j=0; j<2; j++) {
                ILE_dihedrals[i][j] = ILE_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&LEU_dihedrals, dihedral_array_lengths[10]);
    for (i=0; i<dihedral_array_lengths[10]; i++) {
        for (j=0; j<2; j++) {
                LEU_dihedrals[i][j] = LEU_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&LYS_dihedrals, dihedral_array_lengths[11]);
    for (i=0; i<dihedral_array_lengths[11]; i++) {
        for (j=0; j<2; j++) {
                LYS_dihedrals[i][j] = LYS_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&MET_dihedrals, dihedral_array_lengths[12]);
    for (i=0; i<dihedral_array_lengths[12]; i++) {
        for (j=0; j<2; j++) {
                MET_dihedrals[i][j] = MET_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&PHE_dihedrals, dihedral_array_lengths[13]);
    for (i=0; i<dihedral_array_lengths[13]; i++) {
        for (j=0; j<2; j++) {
                PHE_dihedrals[i][j] = PHE_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&PRO_dihedrals, dihedral_array_lengths[14]);
    for (i=0; i<dihedral_array_lengths[14]; i++) {
        for (j=0; j<2; j++) {
                PRO_dihedrals[i][j] = PRO_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&SER_dihedrals, dihedral_array_lengths[15]);
    for (i=0; i<dihedral_array_lengths[15]; i++) {
        for (j=0; j<2; j++) {
                SER_dihedrals[i][j] = SER_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&THR_dihedrals, dihedral_array_lengths[16]);
    for (i=0; i<dihedral_array_lengths[16]; i++) {
        for (j=0; j<2; j++) {
                THR_dihedrals[i][j] = THR_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&TRP_dihedrals, dihedral_array_lengths[17]);
    for (i=0; i<dihedral_array_lengths[17]; i++) {
        for (j=0; j<2; j++) {
                TRP_dihedrals[i][j] = TRP_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&TYR_dihedrals, dihedral_array_lengths[18]);
    for (i=0; i<dihedral_array_lengths[18]; i++) {
        for (j=0; j<2; j++) {
                TYR_dihedrals[i][j] = TYR_dihedrals_membrane[i][j];
        }
    }

    allocate_dihedral_array(&VAL_dihedrals, dihedral_array_lengths[19]);
    for (i=0; i<dihedral_array_lengths[19]; i++) {
        for (j=0; j<2; j++) {
                VAL_dihedrals[i][j] = VAL_dihedrals_membrane[i][j];
        }
    }
}

        
/*------------------------------------------------------------------------------------------------*/

int copy_arrays_general()
{
    int i,j;

    memcpy(ALA_CCD_dist, ALA_CCD_dist_general, sizeof(ALA_CCD_dist_general));
    memcpy(ARG_CCD_dist, ARG_CCD_dist_general, sizeof(ARG_CCD_dist_general));
    memcpy(ASN_CCD_dist, ASN_CCD_dist_general, sizeof(ASN_CCD_dist_general));
    memcpy(ASP_CCD_dist, ASP_CCD_dist_general, sizeof(ASP_CCD_dist_general));
    memcpy(CYS_CCD_dist, CYS_CCD_dist_general, sizeof(CYS_CCD_dist_general));
    memcpy(GLN_CCD_dist, GLN_CCD_dist_general, sizeof(GLN_CCD_dist_general));
    memcpy(GLU_CCD_dist, GLU_CCD_dist_general, sizeof(GLU_CCD_dist_general));
    memcpy(GLY_CCD_dist, GLY_CCD_dist_general, sizeof(GLY_CCD_dist_general));
    memcpy(HIS_CCD_dist, HIS_CCD_dist_general, sizeof(HIS_CCD_dist_general));
    memcpy(ILE_CCD_dist, ILE_CCD_dist_general, sizeof(ILE_CCD_dist_general));
    memcpy(LEU_CCD_dist, LEU_CCD_dist_general, sizeof(LEU_CCD_dist_general));
    memcpy(LYS_CCD_dist, LYS_CCD_dist_general, sizeof(LYS_CCD_dist_general));
    memcpy(MET_CCD_dist, MET_CCD_dist_general, sizeof(MET_CCD_dist_general));
    memcpy(PHE_CCD_dist, PHE_CCD_dist_general, sizeof(PHE_CCD_dist_general));
    memcpy(PRO_CCD_dist, PRO_CCD_dist_general, sizeof(PRO_CCD_dist_general));
    memcpy(SER_CCD_dist, SER_CCD_dist_general, sizeof(SER_CCD_dist_general));
    memcpy(THR_CCD_dist, THR_CCD_dist_general, sizeof(THR_CCD_dist_general));
    memcpy(TRP_CCD_dist, TRP_CCD_dist_general, sizeof(TRP_CCD_dist_general));
    memcpy(TYR_CCD_dist, TYR_CCD_dist_general, sizeof(TYR_CCD_dist_general));
    memcpy(VAL_CCD_dist, VAL_CCD_dist_general, sizeof(VAL_CCD_dist_general));

    memcpy(ptr_array, ptr_array_general, sizeof(ptr_array_general));
    memcpy(dihedral_array_lengths, dihedral_array_lengths_general, sizeof(dihedral_array_lengths_general));

    allocate_dihedral_array(&ALA_dihedrals, dihedral_array_lengths[0]);
    for (i=0; i<dihedral_array_lengths[0]; i++) {
        for (j=0; j<2; j++) {
		ALA_dihedrals[i][j] = ALA_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&ARG_dihedrals, dihedral_array_lengths[1]);
    for (i=0; i<dihedral_array_lengths[1]; i++) {
        for (j=0; j<2; j++) {
                ARG_dihedrals[i][j] = ARG_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&ASN_dihedrals, dihedral_array_lengths[2]);
    for (i=0; i<dihedral_array_lengths[2]; i++) {
        for (j=0; j<2; j++) {
                ASN_dihedrals[i][j] = ASN_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&ASP_dihedrals, dihedral_array_lengths[3]);
    for (i=0; i<dihedral_array_lengths[3]; i++) {
        for (j=0; j<2; j++) {
                ASP_dihedrals[i][j] = ASP_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&CYS_dihedrals, dihedral_array_lengths[4]);
    for (i=0; i<dihedral_array_lengths[4]; i++) {
        for (j=0; j<2; j++) {
                CYS_dihedrals[i][j] = CYS_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&GLN_dihedrals, dihedral_array_lengths[5]);
    for (i=0; i<dihedral_array_lengths[5]; i++) {
        for (j=0; j<2; j++) {
                GLN_dihedrals[i][j] = GLN_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&GLU_dihedrals, dihedral_array_lengths[6]);
    for (i=0; i<dihedral_array_lengths[6]; i++) {
        for (j=0; j<2; j++) {
                GLU_dihedrals[i][j] = GLU_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&GLY_dihedrals, dihedral_array_lengths[7]);
    for (i=0; i<dihedral_array_lengths[7]; i++) {
        for (j=0; j<2; j++) {
                GLY_dihedrals[i][j] = GLY_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&HIS_dihedrals, dihedral_array_lengths[8]);
    for (i=0; i<dihedral_array_lengths[8]; i++) {
        for (j=0; j<2; j++) {
                HIS_dihedrals[i][j] = HIS_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&ILE_dihedrals, dihedral_array_lengths[9]);
    for (i=0; i<dihedral_array_lengths[9]; i++) {
        for (j=0; j<2; j++) {
                ILE_dihedrals[i][j] = ILE_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&LEU_dihedrals, dihedral_array_lengths[10]);
    for (i=0; i<dihedral_array_lengths[10]; i++) {
        for (j=0; j<2; j++) {
                LEU_dihedrals[i][j] = LEU_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&LYS_dihedrals, dihedral_array_lengths[11]);
    for (i=0; i<dihedral_array_lengths[11]; i++) {
        for (j=0; j<2; j++) {
                LYS_dihedrals[i][j] = LYS_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&MET_dihedrals, dihedral_array_lengths[12]);
    for (i=0; i<dihedral_array_lengths[12]; i++) {
        for (j=0; j<2; j++) {
                MET_dihedrals[i][j] = MET_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&PHE_dihedrals, dihedral_array_lengths[13]);
    for (i=0; i<dihedral_array_lengths[13]; i++) {
        for (j=0; j<2; j++) {
                PHE_dihedrals[i][j] = PHE_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&PRO_dihedrals, dihedral_array_lengths[14]);
    for (i=0; i<dihedral_array_lengths[14]; i++) {
        for (j=0; j<2; j++) {
                PRO_dihedrals[i][j] = PRO_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&SER_dihedrals, dihedral_array_lengths[15]);
    for (i=0; i<dihedral_array_lengths[15]; i++) {
        for (j=0; j<2; j++) {
                SER_dihedrals[i][j] = SER_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&THR_dihedrals, dihedral_array_lengths[16]);
    for (i=0; i<dihedral_array_lengths[16]; i++) {
        for (j=0; j<2; j++) {
                THR_dihedrals[i][j] = THR_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&TRP_dihedrals, dihedral_array_lengths[17]);
    for (i=0; i<dihedral_array_lengths[17]; i++) {
        for (j=0; j<2; j++) {
                TRP_dihedrals[i][j] = TRP_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&TYR_dihedrals, dihedral_array_lengths[18]);
    for (i=0; i<dihedral_array_lengths[18]; i++) {
        for (j=0; j<2; j++) {
                TYR_dihedrals[i][j] = TYR_dihedrals_general[i][j];
        }
    }

    allocate_dihedral_array(&VAL_dihedrals, dihedral_array_lengths[19]);
    for (i=0; i<dihedral_array_lengths[19]; i++) {
        for (j=0; j<2; j++) {
                VAL_dihedrals[i][j] = VAL_dihedrals_general[i][j];
        }
    }
}
