/* EGAD: GA_utilities.h Navin Pokala and Tracy Handel Dept. of Molecular and Cell Biology University of California, Berkeley Copyright (C) 2003 Regents of the University of California GNU Public License Aug 12 2003 Absolutely no warranties are made or are implied with the use of this program or its parts. This file is the header for GA_utilities.cpp. It also contains macros for mutating and copying GENE's and CHROMOSOME's */ #ifndef GA_utilities_header_flag #define GA_utilities_header_flag #include #include #include #include #include #include #include #include "structure_types.h" #include "moremath.h" #include "CHROMOSOME_to_lookupEnergy.h" #include "solubility.h" #include "sequence_restraint.h" /* copies GENE a into GENE b */ #define copyGENE(b,a) \ { \ b->seq_position = a->seq_position; \ b->choice_ptr = a->choice_ptr; \ b->j_choice_index = a->j_choice_index; \ b->lookupRot_index = a->lookupRot_index; \ b->lookupRot = a->lookupRot; \ b->varpos_ptr = a->varpos_ptr; \ b->chi = a->chi; \ } /* copies CHROMOSOME a into CHROMOSOME b */ #define copyCHROMOSOME(b,a) \ { \ (b).genes = (b).firstgene; \ (a).genes = (a).firstgene; \ \ (b).energy = (a).energy; \ (b).energy_list = (a).energy_list; \ (b).pop_energy = (a).pop_energy; \ (b).boltzProbab = (a).boltzProbab; \ \ while(a.genes!=NULL) \ { \ (b).genes->seq_position = (a).genes->seq_position; \ (b).genes->choice_ptr = (a).genes->choice_ptr; \ (b).genes->j_choice_index = (a).genes->j_choice_index; \ (b).genes->lookupRot_index = (a).genes->lookupRot_index; \ (b).genes->lookupRot = (a).genes->lookupRot; \ (b).genes->varpos_ptr =(a).genes->varpos_ptr; \ (b).genes->chi = (a).genes->chi; \ (b).genes = (b).genes->nextgene; \ (a).genes = (a).genes->nextgene; \ } \ \ (b).genes = (b).firstgene; \ (a).genes = (a).firstgene; \ \ if(b.first_bkbngene != NULL) \ { \ (b).bkbngenes = (b).first_bkbngene; \ (a).bkbngenes = (a).first_bkbngene; \ \ while(a.bkbngenes!=NULL) \ { \ (b).bkbngenes->seq_position = (a).bkbngenes->seq_position; \ (b).bkbngenes->phi = (a).bkbngenes->phi; \ (b).bkbngenes->psi = (a).bkbngenes->psi; \ (b).bkbngenes->omega = (a).bkbngenes->omega; \ (b).bkbngenes = (b).bkbngenes->nextbkbngene; \ (a).bkbngenes = (a).bkbngenes->nextbkbngene; \ } \ \ (b).bkbngenes = (b).first_bkbngene; \ (a).bkbngenes = (a).first_bkbngene; \ } \ } /* given a residuetype choice, select a rotamer for the gene if applicable */ #define CHOICE_to_GENE(gene, choice, choice_index) \ { \ (gene)->j_choice_index = choice_index; \ \ (gene)->choice_ptr = &(choice); \ (gene)->j_choice_index = (gene)->j_choice_index - 1; \ \ /* assign the rotamer if applicable */ \ if((gene)->choice_ptr->lookup_res_ptr!=NULL) /* the lookuptable has been generated, so we are making rotamer moves */ \ { \ (gene)->lookupRot_index = roll_loaded_dice((gene)->choice_ptr->resparam_ptr->rotamerlib_ptr->freq_array, \ (gene)->choice_ptr->resparam_ptr->rotamerlib_ptr->number_of_rotamers); \ \ /* copy library rotamer values */ \ (gene)->chi = (gene)->choice_ptr->resparam_ptr->rotamerlib_ptr->rotamer[(gene)->lookupRot_index].chi; \ \ /* pointer to lookupRotamer */ \ (gene)->lookupRot = &((gene)->choice_ptr->lookup_res_ptr->lookupRot[(gene)->lookupRot_index]); \ \ while((gene)->lookupRot->in_use_flag == 0) \ { \ (gene)->lookupRot_index = roll_loaded_dice((gene)->choice_ptr->resparam_ptr->rotamerlib_ptr->freq_array, \ (gene)->choice_ptr->resparam_ptr->rotamerlib_ptr->number_of_rotamers); \ \ /* copy library rotamer values */ \ (gene)->chi = (gene)->choice_ptr->resparam_ptr->rotamerlib_ptr->rotamer[(gene)->lookupRot_index].chi; \ \ /* pointer to lookupRotamer */ \ (gene)->lookupRot = &((gene)->choice_ptr->lookup_res_ptr->lookupRot[(gene)->lookupRot_index]); \ } \ } \ else /* lookuptable not generated; moves in seq. space only; put some default values */ \ { \ (gene)->lookupRot_index = 1; \ (gene)->lookupRot = NULL; \ (gene)->chi = (gene)->choice_ptr->resparam_ptr->rotamerlib_ptr->rotamer[(gene)->lookupRot_index].chi; \ } \ } /* This function picks a residuetype and rotamer for a GENE gene at a VARIABLE_POSITION var_pos */ #define level_1_mutate_sidechain(gene, var_pos) \ { \ \ (gene)->varpos_ptr = &(var_pos); \ \ /* pick the residuetype */ \ if((var_pos).number_of_choices==1) \ (gene)->j_choice_index = 1; \ else \ { \ (gene)->j_choice_index = roll_loaded_dice((var_pos).residue_freqs, (var_pos).number_of_choices); \ while((var_pos).choice[(gene)->j_choice_index].in_use_flag==0) /* find a choice that is in use */ \ (gene)->j_choice_index = roll_loaded_dice((var_pos).residue_freqs, (var_pos).number_of_choices); \ } \ \ CHOICE_to_GENE((gene), (var_pos).choice[(gene)->j_choice_index], (gene)->j_choice_index); \ \ } /* This function mutates a GENE to a permitted choice. It picks a residuetype from the allowed list, then picks a rotamer. If the selected rotamer is forbidden, it keeps trying. */ #define mutate_sidechain(gene, var_pos) \ { \ level_1_mutate_sidechain(gene, var_pos); /* make the mutation */ \ if(gene->lookupRot!=NULL) /* if this rotamer is not permitted, try again */ \ while(gene->lookupRot->in_use_flag==0) /* keep trying until a permitted rotamer is found */ \ { \ level_1_mutate_sidechain(gene, var_pos); \ } \ } /* This function calculates the boltzmann distribution for the first pop_size members of a sorted CHROMOSOME array at a given temperature T. The probabilities are stored in chr[i].boltzProbab (for energy-based probabilties) and in chr[i[.rankProbab for rank-based probabilties */ void boltzmann_CHROMOSOME(CHROMOSOME *chr, double *T, int *pop_size); /* This function de-allocates memory for a GENE linked-list */ void free_GENE(GENE gene); /* This function de-allocates memory for a BKBNGENE linked-list */ void free_BKBNGENE(bkbnGENE gene); /* This function de-allocates memory for a CHROMOSOME */ void free_CHROMOSOME(CHROMOSOME *chr); /* This function allocates memory for the GENE linked-list in CHROMOSOME, and seeds it with residues and sidechain rotamers. If check_solubility_flag=1, chr is sent to solubilize_CHROMOSOME to generate a soluble chromosome. */ void inoculate_sidechains(CHROMOSOME *chr, VARIABLE_POSITION *var_pos, int check_solubility_flag); /* This function randomizes GENEs for a CHROMOSOME; it assumes that memory has already been allocated by inoculate_sidechains.If check_solubility_flag=1, chr is sent to solubilize_CHROMOSOME to generate a soluble chromosome. */ void randomize_sidechains(CHROMOSOME *chr, int check_solubility_flag); /* This function mates an array of CHROMOSOME of size 2*pop_size (allocated by inoculate_sidechains). Members 1->pop_size are mated, based on their mating frequencies chr[i].boltzProbab and chr[i].rankProbab. Crossover occurs with recombination_freq probability. Mutations are permitted to occur on each child with mutation_freq probability. The children are stored in members pop_size+1 -> 2*pop_size and are solubilized w/ solubilize_CHROMOSOME */ void mate_sidechains(CHROMOSOME *chr, int pop_size, double recombination_freq, double mutation_freq); /* This function identifies isoenergetic CHROMOSOMEs and mutates them until they are no longer isoenergetic; solubility is also checked and insoluble chrs solubilized w/ solubilize_CHROMOSOME */ void get_rid_of_isoenergetic_chrs(CHROMOSOME *chr, double mut_freq, int pop_size, double fixedatoms_energy); /* This function mutagenizes the GENEs in chr w/ mut_freq probability */ void mutagenize_sidechains_CHROMOSOME(CHROMOSOME *chr, double mut_freq); /* if chr[i] is isoenergetic with any chr[1]->chr[i-1], returns 1; else 0; */ int is_chr_i_isoenergetic_with_others(int i, CHROMOSOME *chr, int popsize); /* returns 1 if successful, 0 if not (ie: chr[1].energy = chr[pop_size].energy */ int calculate_mating_frequencies(CHROMOSOME *chr, int pop_size, double T); /* linear cooling schedule for GA and MC temperatures */ double update_simulation_temperature(double T, double dT, double Tf); #endif