ErrorCode ReadCGNS::create_elements(char *sectionName, const Tag *file_id_tag, const EntityType &ent_type, const int& verts_per_elem, long §ion_offset, int elems_count, const std::vector<cgsize_t>& elemsConn) { ErrorCode result; // Create the element sequence; passes back a pointer to the internal storage for connectivity and the // starting entity handle EntityHandle* conn_array; EntityHandle handle = 0; result = readMeshIface->get_element_connect(elems_count, verts_per_elem, ent_type, 1, handle, conn_array);MB_CHK_SET_ERR(result, fileName << ": Trouble reading elements"); memcpy(conn_array, &elemsConn[0], elemsConn.size() * sizeof(EntityHandle)); // Notify MOAB of the new elements result = readMeshIface->update_adjacencies(handle, elems_count, verts_per_elem, conn_array); if (MB_SUCCESS != result) return result; // ////////////////////////////////// // Create sets and tags Range elements(handle, handle + elems_count - 1); // Store element IDs std::vector<int> id_list(elems_count); // Add 1 to offset id to 1-based numbering for (cgsize_t i = 0; i < elems_count; ++i) id_list[i] = i + 1 + section_offset; section_offset += elems_count; create_sets(sectionName, file_id_tag, ent_type, elements, id_list, 0); return MB_SUCCESS; }
//! Create an element sequence ErrorCode ReadGmsh::create_elements(const GmshElemType& type, const std::vector<int>& elem_ids, const std::vector<int>& matl_ids, const std::vector<int>& geom_ids, const std::vector<int>& prtn_ids, const std::vector<EntityHandle>& connectivity, const Tag* file_id_tag) { ErrorCode result; // Make sure input is consistent const unsigned long num_elem = elem_ids.size(); const int node_per_elem = type.num_nodes; if (matl_ids.size() != num_elem || geom_ids.size() != num_elem || prtn_ids.size() != num_elem || connectivity.size() != num_elem*node_per_elem) return MB_FAILURE; // Create the element sequence // do not do anything for point type if (type.mb_type==MBVERTEX) return MB_SUCCESS; // do not create anything EntityHandle handle = 0; EntityHandle* conn_array; result = readMeshIface->get_element_connect(num_elem, node_per_elem, type.mb_type, MB_START_ID, handle, conn_array); if (MB_SUCCESS != result) return result; // Copy passed element connectivity into entity sequence data. if (type.node_order) { for (unsigned long i = 0; i < num_elem; ++i) for (int j = 0; j < node_per_elem; ++j) conn_array[i*node_per_elem + type.node_order[j]] = connectivity[i*node_per_elem + j]; } else { memcpy(conn_array, &connectivity[0], connectivity.size() * sizeof(EntityHandle)); } // Notify MOAB of the new elements result = readMeshIface->update_adjacencies(handle, num_elem, node_per_elem, conn_array); if (MB_SUCCESS != result) return result; // Store element IDs Range elements(handle, handle + num_elem - 1); result = mdbImpl->tag_set_data(globalId, elements, &elem_ids[0]); if (MB_SUCCESS != result) return result; if (file_id_tag) { result = mdbImpl->tag_set_data(*file_id_tag, elements, &elem_ids[0]); if (MB_SUCCESS != result) return result; } // Add elements to material sets result = create_sets(type.mb_type, elements, matl_ids, 0); if (MB_SUCCESS != result) return result; // Add elements to geometric sets result = create_sets(type.mb_type, elements, geom_ids, 1); if (MB_SUCCESS != result) return result; // Add elements to parallel partitions result = create_sets(type.mb_type, elements, prtn_ids, 2); if (MB_SUCCESS != result) return result; return MB_SUCCESS; }
static sint malign(ALNPTR mult_aln,MULT_OPT mult_opt,sint output_order,Boolean verbose,ALNCOUNT *alncount) { Boolean use_maxid; sint i,j,n,tx,set; sint ix,t1,t2; sint status,entries; sint nsets; sint **sets; sint naligned_groups; sint *aligned_group; sint *aligned; lint score = 0; sint *seq_weight; IN_TREEPTR itree; float min_dist,mean_dist; float **group_dist; double **tmat; Boolean *delayed,ok; char *dsc_ss; char *jnet_ss; if (verbose) info("Start of Multiple Alignment"); /* get the guide tree (tree should be in phylip format) */ if (mult_aln->nseqs >= 2) { itree=(IN_TREEPTR)ckalloc(sizeof(IN_TREE)); status = read_tree(mult_aln->treename, mult_aln->seqs, (sint)0, mult_aln->nseqs,itree); if (status < 0) return((sint)0); } if(status<0) use_maxid=TRUE; else use_maxid=FALSE; /* group the sequences according to their relative divergence */ sets = (sint **) ckalloc( (mult_aln->nseqs+1) * sizeof (sint *) ); for(i=0;i<mult_aln->nseqs;i++) sets[i] = (sint *)ckalloc( (mult_aln->nseqs+1) * sizeof (sint) ); nsets=create_sets(mult_aln->nseqs,sets,itree); if(verbose) info("There are %d groups",(pint)nsets); if(debug>1) for(set=0;set<nsets;set++) { for (i=0;i<mult_aln->nseqs;i++) { printf("%d ",sets[set][i]); } printf("\n"); } /* calculate sequence weights according to branch lengths of the tree - weights are normalised to sum to 100 */ seq_weight = calc_seq_weights((sint)0, mult_aln->nseqs, itree,mult_opt.no_weights); for(i=0;i<mult_aln->nseqs;i++) mult_aln->seqs[i].weight=seq_weight[i]; /* calculate tmat matrix containing percent distances for all pairs of sequences */ tmat = pw_distances_from_tree(mult_aln->seqs,mult_aln->nseqs,itree); if (tmat == NULL) return((sint)0); /* clear the memory used for the phylogenetic tree */ if (mult_aln->nseqs >= 2) free_tree(itree); /* start the multiple alignments......... */ if(verbose) info("Aligning..."); if (output_order==INPUT) { for (i=0;i<mult_aln->nseqs;i++) mult_aln->seqs[i].output_index = i; } else { tx=0; for (i=0;i<mult_aln->nseqs;i++) mult_aln->seqs[i].output_index = -1; for(set=0;set<nsets;set++) { for (i=0;i<mult_aln->nseqs;i++) { if (sets[set][i] != 0) { if(mult_aln->seqs[i].output_index==(-1)) { mult_aln->seqs[i].output_index = tx++; } } } } } /* align the closely related groups first */ aligned_group = (sint *) ckalloc( (mult_aln->nseqs+1) * sizeof (sint) ); delayed = (Boolean *) ckalloc( (mult_aln->nseqs+1) * sizeof (Boolean) ); for(set=0;set<nsets;set++) { /* decide whether to do the alignment now - if the mean distance between sequences in the two groups to be aligned is greater than the cutoff, then don't align now */ mean_dist=0.0; entries=0; ok=TRUE; for (i=0,n=0;i<mult_aln->nseqs;i++) { if (sets[set][i] != 0 && mult_aln->seqs[i].len>0) { if(delayed[i]==TRUE) { ok=FALSE; break; } entries++; for (j=i+1;j<mult_aln->nseqs;j++) { if (sets[set][j] != 0 && mult_aln->seqs[j].len>0 && sets[set][i] != sets[set][j]) { if(delayed[j]==TRUE) { ok=FALSE; break; } mean_dist+=tmat[i][j]; n++; /* if(mean_dist>tmat[i][j]) mean_dist=tmat[i][j];*/ } } } } if(ok==TRUE && n>0) mean_dist=mean_dist/(float)(n); if ((ok==TRUE) && mean_dist < 1.0-(float)mult_opt.divergence_cutoff/100.0) { score = prfalign(0,mult_aln,sets[set],tmat,use_maxid,mult_opt,alncount,TRUE); /*if (score < 0) return(-1);*/ if(verbose) info("Group %d: Sequences:%4d Score:%d", (pint)set+1,(pint)entries,(pint)score); for (i=0;i<mult_aln->nseqs;i++) { if (sets[set][i] != 0) { aligned_group[i]=set+1; } } } else { if(verbose) info("Group %d: Sequences:%4d Delayed",(pint)set+1,(pint)entries); for (i=0;i<mult_aln->nseqs;i++) if (sets[set][i] != 0) { delayed[i]=TRUE; } } } /* renumber the groups and assign a group number to any orphan sequences, that haven't been aligned yet */ naligned_groups=renumber_groups(mult_aln->nseqs,aligned_group,0); if (verbose) fprintf(stdout,"done groups %d\n",naligned_groups); for(i=0;i<mult_aln->nseqs;i++) mult_aln->seqs[i].simgroup=aligned_group[i]; for(i=0;i<mult_aln->nseqs;i++) if(aligned_group[i]==0) { aligned_group[i]=naligned_groups+1; naligned_groups++; } if (verbose) fprintf(stdout,"done groups and added orphans %d\n",naligned_groups); if(naligned_groups==1) return naligned_groups; /* now align the two closest groups of sequences together */ /* the array aligned[] contains the group number of each sequence */ ix=0; if(naligned_groups>1) { for(i=0;i<mult_aln->nseqs;i++) mult_aln->seqs[i].output_index=(-1); group_dist = (float **) ckalloc( (naligned_groups+1) * sizeof (float *) ); for(i=0;i<naligned_groups+1;i++) group_dist[i] = (float *)ckalloc( (naligned_groups+1) * sizeof (float) ); aligned = (sint *) ckalloc( (mult_aln->nseqs+1) * sizeof (sint) ); /* calculate the distance between each pair of groups */ calc_group_dist(mult_aln->nseqs,naligned_groups,aligned_group,tmat,group_dist); for(i=0;i<mult_aln->nseqs;i++) sets[0][i] = 0; /* align the two closest groups together */ min_dist=1000.0; t1=t2=0; for (i=0;i<naligned_groups;i++) for (j=i+1;j<naligned_groups;j++) if(min_dist>=group_dist[i][j]) { min_dist=group_dist[i][j]; t1=i+1; t2=j+1; } for(i=0;i<mult_aln->nseqs;i++) if(aligned_group[i]==t1) { sets[0][i]=1; if (output_order==ALIGNED) mult_aln->seqs[i].output_index = ix++; } for(i=0;i<mult_aln->nseqs;i++) if(aligned_group[i]==t2) { sets[0][i]=2; aligned_group[i]=t1; if (output_order==ALIGNED) mult_aln->seqs[i].output_index = ix++; } for (i=0,tx=0;i<mult_aln->nseqs;i++) if (sets[0][i] != 0) { aligned[i]=1; tx++; } score = prfalign(0,mult_aln,sets[0],tmat,use_maxid,mult_opt,alncount,TRUE); /*if (score < 0) return(-1);*/ if(verbose) info("Group Align %d: Sequences:%4d Score:%d", (pint)tx,(pint)entries,(pint)score); } /* now align the remaining groups to the first two */ naligned_groups=renumber_groups(mult_aln->nseqs,aligned_group,t1); t1=1; while(naligned_groups>1) { /* calculate the distance of each remaining group to the first group */ calc_group_dist1(mult_aln->nseqs,naligned_groups,aligned_group,tmat,group_dist); /* align the next closest group with the first group */ for(i=0;i<mult_aln->nseqs;i++) sets[0][i] = 0; min_dist=100.0; t2=0; for (j=1;j<naligned_groups;j++) if(min_dist>=group_dist[0][j]) { min_dist=group_dist[0][j]; t2=j+1; } if (verbose) fprintf(stdout,"Aligning Group %d %d\n",t1,t2); for(i=0;i<mult_aln->nseqs;i++) if(aligned_group[i]==1) sets[0][i]=1; else if(aligned_group[i]==t2) { sets[0][i]=2; aligned_group[i]=1; if (output_order==ALIGNED) mult_aln->seqs[i].output_index = ix++; } if(debug>0) for(i=0;i<mult_aln->nseqs;i++) fprintf(stdout,"%s %d %d\n",mult_aln->seqs[i].name,mult_aln->seqs[i].output_index,aligned_group[i]); for (i=0,tx=0;i<mult_aln->nseqs;i++) if (sets[0][i] != 0) { aligned[i]=1; tx++; } score = prfalign(0,mult_aln,sets[0],tmat,use_maxid,mult_opt,alncount,TRUE); /*if (score < 0) return(-1);*/ if(verbose) info("Group Align %d: Sequences:%4d Score:%d", (pint)tx,(pint)entries,(pint)score); naligned_groups=renumber_groups(mult_aln->nseqs,aligned_group,t1); } for(i=0;i<mult_aln->nseqs;i++) tmat[i] = ckfree(tmat[i]); tmat = ckfree(tmat); for (i=0;i<naligned_groups;i++) group_dist[i]=ckfree((void *)group_dist[i]); group_dist=ckfree(group_dist); aligned=ckfree(aligned); for (i=0;i<naligned_groups;i++) sets[i]=ckfree((void *)sets[i]); sets=ckfree(sets); return((sint)1); }
ErrorCode ReadTemplate::load_file(const char* filename, const EntityHandle *file_set, const FileOptions& opts, const ReaderIface::SubsetList* subset_list, const Tag* /*file_id_tag*/) { if (subset_list) { // See src/moab/ReaderIface.hpp, definition of SubsetList struct; this basically specifies // an integer tag and tag values for sets to read on this proc, or a part number and total # parts // for reading a trivial partition of entities } // Save filename to member variable so we don't need to pass as an argument // to called functions fileName = filename; // Process options; see src/FileOptions.hpp for API for FileOptions class, and doc/metadata_info.doc for // a description of various options used by some of the readers in MOAB ErrorCode result = process_options(opts);MB_CHK_SET_ERR(result, fileName << ": problem reading options"); // Open file; filePtr is member of ReadTemplate, change to whatever mechanism is used to identify file FILE* filePtr = fopen(fileName, "r"); if (!filePtr) { MB_SET_ERR(MB_FILE_DOES_NOT_EXIST, fileName << ": fopen returned error"); } // Read number of verts, elements, sets long num_verts = 0, num_elems = 0, num_sets = 0; // read_ents keeps a running set of entities read from this file, including vertices, elements, and sets; // these will get added to file_set (if input) at the end of the read Range read_ents; // start_vertex is passed back so we know how to convert indices from the file into vertex handles; most // of the time this is done by adding start_vertex to the (0-based) index; if the index is 1-based, you also // need to subtract one; see read_elements for details EntityHandle start_vertex; result = read_vertices(num_verts, start_vertex, read_ents); if (MB_SUCCESS != result) { fclose(filePtr); return result; } // Create/read elements; this template assumes that all elements are the same type, so can be read in a single // call to read_elements, and kept track of with a single start_elem handle. If there are more entity types, // might have to keep these start handles in an array/vector. start_elem is only really needed if you're reading // sets later, and need to convert some file-based index to an entity handle EntityHandle start_elem; result = read_elements(num_elems, start_vertex, start_elem, read_ents); if (MB_SUCCESS != result) { fclose(filePtr); return result; } // Read/create entity sets; typically these sets have some tag identifying what they're for, see doc/metadata_info.doc // for examples of different kinds of sets and how they're marked result = create_sets(num_sets, start_vertex, num_verts, start_elem, num_elems, read_ents); if (MB_SUCCESS != result) { fclose(filePtr); return result; } // Finally, add all read_ents into the file set, if one was input if (file_set && *file_set) { result = mbImpl->add_entities(*file_set, read_ents); if (MB_SUCCESS != result) { fclose(filePtr); return result; } } fclose(filePtr); return result; }
sint malign(sint istart,char *phylip_name) /* full progressive alignment*/ { static sint *aligned; static sint *group; static sint ix; sint *maxid, max, sum; sint *tree_weight; sint i,j,set,iseq=0; sint status,entries; lint score = 0; info("Start of Multiple Alignment"); /* get the phylogenetic tree from *.ph */ if (nseqs >= 2) { status = read_tree(phylip_name, (sint)0, nseqs); if (status == 0) return((sint)0); } /* calculate sequence weights according to branch lengths of the tree - weights in global variable seq_weight normalised to sum to 100 */ calc_seq_weights((sint)0, nseqs, seq_weight); /* recalculate tmat matrix as percent similarity matrix */ status = calc_similarities(nseqs); if (status == 0) return((sint)0); /* for each sequence, find the most closely related sequence */ maxid = (sint *)ckalloc( (nseqs+1) * sizeof (sint)); for (i=1;i<=nseqs;i++) { maxid[i] = -1; for (j=1;j<=nseqs;j++) if (j!=i && maxid[i] < tmat[i][j]) maxid[i] = tmat[i][j]; } /* group the sequences according to their relative divergence */ if (istart == 0) { sets = (sint **) ckalloc( (nseqs+1) * sizeof (sint *) ); for(i=0;i<=nseqs;i++) sets[i] = (sint *)ckalloc( (nseqs+1) * sizeof (sint) ); create_sets((sint)0,nseqs); info("There are %d groups",(pint)nsets); /* clear the memory used for the phylogenetic tree */ if (nseqs >= 2) clear_tree(NULL); /* start the multiple alignments......... */ info("Aligning..."); /* first pass, align closely related sequences first.... */ ix = 0; aligned = (sint *)ckalloc( (nseqs+1) * sizeof (sint) ); for (i=0;i<=nseqs;i++) aligned[i] = 0; for(set=1;set<=nsets;++set) { entries=0; for (i=1;i<=nseqs;i++) { if ((sets[set][i] != 0) && (maxid[i] > divergence_cutoff)) { entries++; if (aligned[i] == 0) { if (output_order==INPUT) { ++ix; output_index[i] = i; } else output_index[++ix] = i; aligned[i] = 1; } } } if(entries > 0) score = prfalign(sets[set], aligned); else score=0.0; /* negative score means fatal error... exit now! */ if (score < 0) { return(-1); } if ((entries > 0) && (score > 0)) info("Group %d: Sequences:%4d Score:%d", (pint)set,(pint)entries,(pint)score); else info("Group %d: Delayed", (pint)set); } for (i=0;i<=nseqs;i++) sets[i]=ckfree((void *)sets[i]); sets=ckfree(sets); } else { /* clear the memory used for the phylogenetic tree */ if (nseqs >= 2) clear_tree(NULL); aligned = (sint *)ckalloc( (nseqs+1) * sizeof (sint) ); ix = 0; for (i=1;i<=istart+1;i++) { aligned[i] = 1; ++ix; output_index[i] = i; } for (i=istart+2;i<=nseqs;i++) aligned[i] = 0; } /* second pass - align remaining, more divergent sequences..... */ /* if not all sequences were aligned, for each unaligned sequence, find it's closest pair amongst the aligned sequences. */ group = (sint *)ckalloc( (nseqs+1) * sizeof (sint)); tree_weight = (sint *) ckalloc( (nseqs) * sizeof(sint) ); for (i=0;i<nseqs;i++) tree_weight[i] = seq_weight[i]; /* if we haven't aligned any sequences, in the first pass - align the two most closely related sequences now */ if(ix==0) { max = -1; iseq = 0; for (i=1;i<=nseqs;i++) { for (j=i+1;j<=nseqs;j++) { if (max < tmat[i][j]) { max = tmat[i][j]; iseq = i; } } } aligned[iseq]=1; if (output_order == INPUT) { ++ix; output_index[iseq] = iseq; } else output_index[++ix] = iseq; } while (ix < nseqs) { for (i=1;i<=nseqs;i++) { if (aligned[i] == 0) { maxid[i] = -1; for (j=1;j<=nseqs;j++) if ((maxid[i] < tmat[i][j]) && (aligned[j] != 0)) maxid[i] = tmat[i][j]; } } /* find the most closely related sequence to those already aligned */ max = -1; iseq = 0; for (i=1;i<=nseqs;i++) { if ((aligned[i] == 0) && (maxid[i] > max)) { max = maxid[i]; iseq = i; } } /* align this sequence to the existing alignment */ /* weight sequences with percent identity with profile*/ /* OR...., multiply sequence weights from tree by percent identity with new sequence */ if(no_weights==FALSE) { for (j=0;j<nseqs;j++) if (aligned[j+1] != 0) seq_weight[j] = tree_weight[j] * tmat[j+1][iseq]; /* Normalise the weights, such that the sum of the weights = INT_SCALE_FACTOR */ sum = 0; for (j=0;j<nseqs;j++) if (aligned[j+1] != 0) sum += seq_weight[j]; if (sum == 0) { for (j=0;j<nseqs;j++) seq_weight[j] = 1; sum = j; } for (j=0;j<nseqs;j++) if (aligned[j+1] != 0) { seq_weight[j] = (seq_weight[j] * INT_SCALE_FACTOR) / sum; if (seq_weight[j] < 1) seq_weight[j] = 1; } } entries = 0; for (j=1;j<=nseqs;j++) if (aligned[j] != 0) { group[j] = 1; entries++; } else if (iseq==j) { group[j] = 2; entries++; } aligned[iseq] = 1; score = prfalign(group, aligned); info("Sequence:%d Score:%d",(pint)iseq,(pint)score); if (output_order == INPUT) { ++ix; output_index[iseq] = iseq; } else output_index[++ix] = iseq; } group=ckfree((void *)group); aligned=ckfree((void *)aligned); maxid=ckfree((void *)maxid); tree_weight=ckfree((void *)tree_weight); aln_score(); /* make the rest (output stuff) into routine clustal_out in file amenu.c */ return(nseqs); }