GLYLIB  0.3.0b
add_structure-X_to_structure-Y.c
Go to the documentation of this file.
00001 #include <mylib.h>
00002 #include <molecules.h>
00003 
00004 
00005 /** \file add_structure-X_to_structure-Y.c Functions for combining structures.
00006 
00007 Begun on 20100203 by BLFoley and expanded, as per usual, on a crisis to 
00008 crisis basis...
00009 */
00010 
00011 /******************** add_assembly_to_ensemble() *********************/
00012 /* Function add_assembly_to_ensemble(assembly *A, ensemble *E) will add
00013 the contents of the assembly pointed to by A to the ensemble pointed to
00014 by E.  Assuming the internal accounting in E has been done properly, the
00015 contents of A will not overwrite any preexisting data in E.
00016 
00017 The function will set assembly pointers from within the ensemble.  
00018 
00019 Please carefully read the notes below.
00020 
00021 This function does NOT update molecular weight, COM, etc., because the 
00022 programmer needs to specify which mass info, etc., should be used.  You 
00023 have to use other functions to set those values.
00024 
00025 *** NOTE ***  A should *NOT* already be a member of E.  If A is already
00026 a member of E, unexpected things might happen in your programs.  See the
00027 next note for more info.
00028 
00029 *** NOTE ***  If you use some sort of weird numbering in your molindex
00030 elements, you need to copy those elsewhere (say to an ensi).  This function
00031 will (re)set the moli's to be what it needs.
00032 
00033 *** NOTE ***  The **a and **r entries in A should ONLY BE POINTING to data
00034 in the normal m.r.a structures in **m.  Any data that has copied to 
00035 those locations might not be freed, which is bad for your data management.
00036 (risky to free here without knowing -- can't free empty space.)
00037 
00038 *** A VERY IMPORTANT NOTE ***  
00039 
00040         DO NOT FREE THE ASSEMBLY.  You can reset the assembly pointer to 
00041         go somewhere else, but do not free the memory.  If you do, you will
00042         be freeing part of the ensemble.
00043         
00044         Here is what the function does:
00045 
00046         1. Allocates and/or reallocates E so that it can accomodate the
00047                 information found in A.
00048         2. Copies atom information in A into the relevant locations in E.
00049                 * If A's information is not arranged in M.r.a format, the
00050                 function will currently complain and exit.  
00051         3. Make a list of the molecule indices for each atom in the double-
00052                 pointed atom and residue lists of A.  Also records the offset
00053                 between A's m.r.a sets and E's.  The molecules are all added
00054                 in the order encountered, so detailed indices are not required.
00055                 * Before proceeding, the program will reset all molecule 
00056                 indices in the m.r.a structures.  If the atom and residue 
00057                 pointers do not point there, results may be unexpected.
00058         4. Frees all the molecule space within A.  
00059         5. Resets the a** and r** pointers to the appropriate locations in E.  
00060                 Locations are based on the molecule indices saved earlier.
00061         6. Sets a new assembly double-pointer inside E to point to A[0].
00062         
00063         This is also why A should not already be a member of E.  If you
00064         want to duplicate an assembly, this is not the function to use.  
00065 */
00066 
00067 void add_assembly_to_ensemble(
00068         assembly *A, ///< pointer to the assembly being added (see docs)
00069         ensemble *E ///< pointer to the ensemble being grown
00070         ){
00071 int i; ///< generic counter
00072 int j; ///< generic counter
00073 int mi; ///< molecule counter
00074 int ri; ///< residue counter
00075 int ai; ///< atom counter
00076 int Enmi; ///< the initial value of nm in E
00077 molindex *rmoli; ///< list of direct indices for A's **r pointers
00078 molindex *amoli; ///< list of direct indices for A's **a pointers
00079 
00080 
00081 // check sanity of the Assembly for our purposes
00082 // while we're in here, set all molecule indices to what we need them to be 
00083 // If A's information is not arranged in M.r.a format, the function will currently complain and exit.  
00084 if(A[0].nm==0) mywhine("add_assembly_to_ensemble: cannot add assembly with no molecules to an ensemble");
00085 i=j=0;
00086 for(mi=0;mi<A[0].nm;mi++){
00087         i+=A[0].m[mi][0].nr; // get a count of all residues
00088         for(ri=0;ri<A[0].m[mi][0].nr;ri++){
00089 // Before proceeding, the program will reset all molecule indices in the m.r.a structures. 
00090                 A[0].m[mi][0].r[ri].moli.i=-1;
00091                 A[0].m[mi][0].r[ri].moli.m=mi;
00092                 A[0].m[mi][0].r[ri].moli.r=ri;
00093                 A[0].m[mi][0].r[ri].moli.a=-1; 
00094                 j+=A[0].m[mi][0].r[ri].na; // get a count of all atoms
00095                 for(ai=0;ai<A[0].m[mi][0].r[ri].na;ai++){ // set molecule indices for the atoms
00096                         A[0].m[mi][0].r[ri].a[ai].moli.i=-1;
00097                         A[0].m[mi][0].r[ri].a[ai].moli.m=mi;
00098                         A[0].m[mi][0].r[ri].a[ai].moli.r=ri;
00099                         A[0].m[mi][0].r[ri].a[ai].moli.a=ai; 
00100                         }
00101                 }
00102         }
00103 // If A's information is not arranged in M.r.a format, the function will currently complain and exit.  
00104 if(i==0) mywhine("add_assembly_to_ensemble: all molecules in assemnly have no residues; cannot add to ensemble");
00105 if(j==0) mywhine("add_assembly_to_ensemble: all residues in assemnly have no atoms; cannot add to ensemble");
00106 
00107 // Make a list of the molecule indices for each atom in the double-pointed atom and residue lists of A. 
00108 if(A[0].nr!=0){
00109         if(A[0].nr!=i){printf("add_assembly_to_ensemble: raw residue count does not equal A[0].nr (for **r).  Ignoring.\n");}
00110         if(A[0].nr>i){printf("add_assembly_to_ensemble WARNING: raw residue count is LESS than A[0].nr (for **r).  Ignoring.\n");}
00111         rmoli=(molindex *)calloc(A[0].nr,sizeof(molindex));
00112         for(ri=0;ri<A[0].nr;ri++){rmoli[ri]=A[0].r[ri][0].moli;}
00113         }
00114 if(A[0].na!=0){
00115         if(A[0].na!=j){printf("add_assembly_to_ensemble: raw atom count does not equal A[0].na (for **a).  Ignoring.\n");}
00116         if(A[0].na>j){printf("add_assembly_to_ensemble WARNING: raw atom count is LESS than A[0].na (for **a).  Ignoring.\n");}
00117         amoli=(molindex*)calloc(A[0].na,sizeof(molindex));
00118         for(ai=0;ai<A[0].na;ai++){amoli[ai]=A[0].a[ai][0].moli;}
00119         }
00120 
00121 // record the offset between A's m.r.a sets and E's. 
00122 Enmi=E[0].nm;
00123 // Allocates and/or reallocates E so that it can accomodate the information found in A.
00124 if(E[0].nm==0) E[0].m=(molecule*)calloc(1,sizeof(molecule)); // initialize if empty
00125 E[0].nm+=A[0].nm; // increment E[0].nm to accomodate new molecules
00126 E[0].m=(molecule*)realloc(E[0].m,E[0].nm*sizeof(molecule)); 
00127 
00128 //printf("Enmi is %d; E[0].nm is %d\n",Enmi,E[0].nm);
00129 
00130 // Copy atom information in A into the relevant locations in E.
00131 // The molecules are all added in the order encountered, so detailed indices are not required.
00132 for(mi=Enmi;mi<E[0].nm;mi++){
00133         E[0].m[mi]=A[0].m[mi-Enmi][0]; // copy whole molecule over
00134         // Free this molecule space within A.  
00135         free(A[0].m[mi-Enmi]); 
00136         A[0].m[mi-Enmi]=&E[0].m[mi];
00137         // reset molecule indicies for residues and atoms
00138         for(ri=0;ri<E[0].m[mi].nr;ri++){
00139                 E[0].m[mi].r[ri].moli.m+=Enmi;
00140                 for(ai=0;ai<E[0].m[mi].r[ri].na;ai++){ 
00141                         E[0].m[mi].r[ri].a[ai].moli.m+=Enmi;
00142                         }
00143                 }
00144         }
00145 
00146 // Reset the a** and r** pointers to the appropriate locations in E. 
00147 //      It bases the locations on the molecule indices it saved earlier.
00148 for(ri=0;ri<A[0].nr;ri++){ A[0].r[ri]=&E[0].m[rmoli[ri].m].r[rmoli[ri].r]; }
00149 for(ai=0;ai<A[0].na;ai++){ A[0].a[ai]=&E[0].m[amoli[ai].m].r[amoli[ai].r].a[amoli[ai].a]; }
00150 
00151 // Set a new assembly double-pointer inside E to point to A[0].
00152 E[0].nA++;
00153 if(E[0].nA==1) E[0].A=(assembly**)calloc(1,sizeof(assembly*)); // initialize if empty
00154 else E[0].A=(assembly**)realloc(E[0].A,E[0].nA*sizeof(assembly*));
00155 E[0].A[E[0].nA-1]=&A[0];
00156 
00157 free(rmoli);
00158 free(amoli);
00159 
00160 return;
00161 }
 All Classes Files Functions Variables Typedefs Defines